package efruchter.project2.examples;
import java.util.*;
import java.text.*;
import dist.*;
import efruchter.project2.Expirements;
import opt.*;
import opt.example.*;
import opt.ga.*;
import opt.prob.*;
import shared.*;
import util.ABAGAILArrays;
/**
* TS
*/
public class TSMExpirement {
private static final int N = 50, maxNumIterations = 1000;
private static OptimizationAlgorithm[] oa = new OptimizationAlgorithm[4];
private static String[] oaNames = { "RHC", "SA", "GA", "MIMIC" };
private static String results = "";
private static DecimalFormat df = new DecimalFormat("0.000");
public static void run() {
Random random = new Random();
double[][] points = new double[N][2];
for (int i = 0; i < points.length; i++) {
points[i][0] = random.nextDouble();
points[i][1] = random.nextDouble();
}
// for rhc, sa, and ga we use a permutation based encoding
TravelingSalesmanEvaluationFunction[] ef = { new TSMEvaluationFunction(points), new TSMEvaluationFunctionMIMIC(points) };
Distribution odd = new DiscretePermutationDistribution(N);
NeighborFunction nf = new SwapNeighbor();
MutationFunction mf = new SwapMutation();
CrossoverFunction cf = new TravelingSalesmanCrossOver(ef[0]);
HillClimbingProblem hcp = new GenericHillClimbingProblem(ef[0], odd, nf);
GeneticAlgorithmProblem gap = new GenericGeneticAlgorithmProblem(ef[0], odd, mf, cf);
oa[0] = new RandomizedHillClimbing(hcp);
oa[1] = new SimulatedAnnealing(1E12, Expirements.alpha, hcp);
oa[2] = new StandardGeneticAlgorithm(Expirements.popSize, Expirements.toMate, Expirements.toMutate, gap);
int[] ranges = new int[N];
Arrays.fill(ranges, N);
odd = new DiscreteUniformDistribution(ranges);
Distribution df = new DiscreteDependencyTree(.1, ranges);
ProbabilisticOptimizationProblem pop = new GenericProbabilisticOptimizationProblem(ef[1], odd, df);
oa[3] = new MIMIC(Expirements.samples, Expirements.toKeep, pop);
if (Expirements.onlyAlgo == -1) {
for (int i = 1; i < oa.length; i++)
train(oa[i], ef[i / 3], oaNames[i]);
} else {
train(oa[Expirements.onlyAlgo], ef[Expirements.onlyAlgo / 3], oaNames[Expirements.onlyAlgo]);
}
System.out.println(results);
}
private static void train(OptimizationAlgorithm oa, TravelingSalesmanEvaluationFunction ef, String oaName) {
System.out.println("\nTraining " + oaName);
double optimal = 0.0, start = System.nanoTime(), stamp = 0, end, trainingTime, temp;
for (int i = 0; i < maxNumIterations; i++) {
oa.train();
temp = ef.value(oa.getOptimal());
System.out.println(temp);
if (optimal < temp) {
optimal = temp;
stamp = System.nanoTime();
}
if(optimal < temp) { stamp = System.nanoTime(); optimal = temp;
System.out.println("Iteration " + i + ": " + optimal); }
}
end = System.nanoTime();
trainingTime = end - start;
trainingTime /= Math.pow(10, 9);
stamp -= start;
stamp /= Math.pow(10, 9);
results += "\n\nResults for " + oaName + ":\nTraining time: " + df.format(trainingTime) + " seconds."
+ "\nOptimal instance found after " + stamp + " seconds.\nFinal optimal solution found: " + optimal;
}
private static class TSMEvaluationFunction extends TravelingSalesmanEvaluationFunction implements EvaluationFunction {
double[][] distances;
public TSMEvaluationFunction(double[][] points) {
super(points);
distances = new double[points.length][];
for (int i = 0; i < points.length; i++) {
distances[i] = new double[i];
for (int j = 0; j < i; j++) {
double[] a = points[i];
double[] b = points[j];
distances[i][j] = Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2));
}
}
}
public double getDistance(int i, int j) {
if (i == j) {
return 0;
} else {
int a = Math.max(i, j);
int b = Math.min(i, j);
return distances[a][b];
}
}
public double value(Instance d) {
double distance = 0;
for (int i = 0; i < d.size() - 1; i++) {
distance += getDistance(d.getDiscrete(i), d.getDiscrete(i + 1));
}
distance += getDistance(d.getDiscrete(d.size() - 1), d.getDiscrete(0));
return 1 / distance;
}
}
private static class TSMEvaluationFunctionMIMIC extends TravelingSalesmanEvaluationFunction {
public TSMEvaluationFunctionMIMIC(double[][] points) {
super(points);
}
public double value(Instance d) {
double[] data = new double[d.size()];
for (int i = 0; i < data.length; i++) {
data[i] = d.getContinuous(i);
}
int[] order = ABAGAILArrays.indices(d.size());
ABAGAILArrays.quicksort(data, order);
double distance = 0;
for (int i = 0; i < order.length - 1; i++) {
distance += getDistance(order[i], order[i + 1]);
}
distance += getDistance(order[order.length - 1], order[0]);
return 1 / distance;
}
}
}