Skip to content

Commit

Permalink
Yes pls
Browse files Browse the repository at this point in the history
  • Loading branch information
TiagoDvl committed Mar 23, 2015
1 parent 0b8f6ba commit f0a596f
Show file tree
Hide file tree
Showing 9 changed files with 518 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="output" path="bin"/>
</classpath>
17 changes: 17 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Dynamic_ACO_Example</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
11 changes: 11 additions & 0 deletions .settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
20 changes: 20 additions & 0 deletions Testberlin52.tsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION: 52
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
11 1605.0 620.0
12 1220.0 580.0
EOF

60 changes: 60 additions & 0 deletions berlin52.tsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION: 52
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
11 1605.0 620.0
12 1220.0 580.0
13 1465.0 200.0
14 1530.0 5.0
15 845.0 680.0
16 725.0 370.0
17 145.0 665.0
18 415.0 635.0
19 510.0 875.0
20 560.0 365.0
21 300.0 465.0
22 520.0 585.0
23 480.0 415.0
24 835.0 625.0
25 975.0 580.0
26 1215.0 245.0
27 1320.0 315.0
28 1250.0 400.0
29 660.0 180.0
30 410.0 250.0
31 420.0 555.0
32 575.0 665.0
33 1150.0 1160.0
34 700.0 580.0
35 685.0 595.0
36 685.0 610.0
37 770.0 610.0
38 795.0 645.0
39 720.0 635.0
40 760.0 650.0
41 475.0 960.0
42 95.0 260.0
43 875.0 920.0
44 700.0 500.0
45 555.0 815.0
46 830.0 485.0
47 1170.0 65.0
48 830.0 610.0
49 605.0 625.0
50 595.0 360.0
51 1340.0 725.0
52 1740.0 245.0
EOF

261 changes: 261 additions & 0 deletions src/ACO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class ACO {

private static final int MAX_ANTS = 2048 * 20;
private final String TSP_FILE;
private double[][] problem;
private double[][] pheromones;
private Random random;
private ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

private LinkedBlockingQueue<AntResult> results;

public static final double PHEROMONE_PERSISTENCE = 0.3d; // between 0 and 1

// greedy
public static final double ALPHA = -0.2d;
// rapid selection
public static final double BETA = 9.6d;

public static final double Q = 0.0001d; // somewhere between 0 and 1

public ACO(String file) {
this.TSP_FILE = file;
this.random = new Random(System.currentTimeMillis());
this.results = new LinkedBlockingQueue<AntResult>();
}

private final double[][] readMatrixFromFile() throws IOException {

final BufferedReader br = new BufferedReader(new FileReader(new File(TSP_FILE)));

final ArrayList<Record> records = new ArrayList<Record>();

boolean readAhead = false;
String line;

// Read the TSP file containind coordinates and populate a List of Record object.
while ((line = br.readLine()) != null) {

if (line.equals("EOF")) {
break;
}

if (readAhead) {
String[] split = sweepNumbers(line.trim());
records.add(new Record(Double.parseDouble(split[1].trim()), Double.parseDouble(split[2].trim())));
}

if (line.equals("NODE_COORD_SECTION")) {
readAhead = true;
}
}

br.close();

// Create a matrix N x N; N is the size of the list that was populated.
final double[][] localMatrix = new double[records.size()][records.size()];
System.out.println(records.size());

int rIndex = 0;
// For each record populated in the matrix,
for (Record r : records) {
int hIndex = 0;
for (Record h : records) {
// Calculate the euclidian distance between them.
localMatrix[rIndex][hIndex] = calculateEuclidianDistance(r.x, r.y, h.x, h.y);
hIndex++;
}
rIndex++;
}
// The matrix with all the distances within it's vertices.
return localMatrix;
}

private final String[] sweepNumbers(String trim) {
String[] arr = new String[3];
int currentIndex = 0;
for (int i = 0; i < trim.length(); i++) {
final char c = trim.charAt(i);
if ((c) != 32) {
for (int f = i + 1; f < trim.length(); f++) {
final char x = trim.charAt(f);
if ((x) == 32) {
arr[currentIndex] = trim.substring(i, f);
currentIndex++;
break;
} else if (f == trim.length() - 1) {
arr[currentIndex] = trim.substring(i, trim.length());
break;
}
}
i = i + arr[currentIndex - 1].length();
}
}
return arr;
}

private final double calculateEuclidianDistance(double x1, double y1, double x2, double y2) {
// In mathematics, the Euclidean distance or Euclidean metric is the "ordinary" distance between two points in Euclidean space. With this distance, Euclidean space becomes a metric space. The
// associated norm is called the Euclidean norm. Older literature refers to the metric as Pythagorean metric.
// http://en.wikipedia.org/wiki/Euclidean_distance
final double xDiff = x2 - x1;
final double yDiff = y2 - y1;
return Math.abs((Math.sqrt((xDiff * xDiff) + (yDiff * yDiff))));
}

private final double[][] initializePheromones() {
double randValue = this.random.nextDouble();
final double[][] localMatrix = new double[problem.length][problem.length];

for (int i = 0; i < localMatrix.length; i++) {
for (int j = 0; j < localMatrix[i].length; j++) {
localMatrix[i][j] = randValue;
}
}

return localMatrix;
}

private AntResult bestResult(ArrayList<AntResult> list) {
AntResult ar, bestResult;
double bestDistance = Double.MAX_VALUE;
bestResult = null;

for (int i = 0; i < list.size(); i++) {
ar = list.get(i);
if (ar.getDistance() < bestDistance) {
bestResult = ar;
bestDistance = ar.getDistance();
}
}

return bestResult;
}

private void printBest(ArrayList<AntResult> list) {
AntResult best;

best = this.bestResult(list);

if (best != null)
System.out.printf("%s\n", best);
}

private void findBestWay() {

ArrayList<AntResult> partialResult = new ArrayList<AntResult>(ACO.MAX_ANTS);
for (int i = 0; i < ACO.MAX_ANTS; i++)
this.service.execute(new Ant(this, this.random.nextInt(this.problem.length)));

for (int i = 0, j = 0; i < ACO.MAX_ANTS; i++, j++) {
try {
AntResult ar = this.results.take();
partialResult.add(ar);

// Pretty cool
if (j % 10000 == 0){
this.printBest(partialResult);
}

} catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.printf("----Final Result----\n");
this.printBest(partialResult);
this.service.shutdown();
}

private final double calculatePheromones(double current, double newPheromone) {
final double result = (1 - ACO.PHEROMONE_PERSISTENCE) * current + newPheromone;
return result;
}

public synchronized void adjustPheromone(int x, int y, double newPheromone) {
final double result = calculatePheromones(this.pheromones[x][y], newPheromone);
if (result >= 0.0) {
this.pheromones[x][y] = result;
} else {
this.pheromones[x][y] = 0;
}
}

public synchronized double readPheromone(int x, int y) {
return pheromones[x][y];
}

public void start() throws IOException {
this.problem = this.readMatrixFromFile();
this.pheromones = this.initializePheromones();
this.findBestWay();

// Print the matrix with all the distance values.
for (int i = 0; i < problem.length; i++) {
for (int j = 0; j < problem[i].length; j++) {
System.out.printf("%g\t", problem[i][j]);
}
System.out.printf("\n");
}

}

public double[][] getProblem() {
return problem;
}

public LinkedBlockingQueue<AntResult> getResults() {
return results;
}

}

class AntResult {

private int[] way;
private double distance;

public AntResult(int[] w, double d) {
this.way = w;
this.distance = d;
}

public int[] getWay() {
return way;
}

public void setWay(int[] way) {
this.way = way;
}

public double getDistance() {
return distance;
}

public void setDistance(double distance) {
this.distance = distance;
}

public String toString() {
StringBuffer r = new StringBuffer("");

r.append("Distance:" + String.valueOf(distance) + "\nNodes:");

for (int i = 0; i < way.length; i++)
r.append(String.valueOf(way[i]) + "\t");

return r.toString();

}

}
Loading

0 comments on commit f0a596f

Please sign in to comment.