-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
518 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
|
||
} | ||
|
||
} |
Oops, something went wrong.