added comments and clarified code
This commit is contained in:
parent
0b156ee40e
commit
6832369317
2 changed files with 39 additions and 32 deletions
|
@ -122,12 +122,13 @@ public class Main {
|
||||||
Instance instance = Instance.fromFile(path);
|
Instance instance = Instance.fromFile(path);
|
||||||
|
|
||||||
// print some general statistics on the instance
|
// print some general statistics on the instance
|
||||||
output.println("\u001b[36m" + "------------------------------------------------------------------------------------------------------------------" + "\u001b[0m");
|
output.println("\u001b[36m" + "-----------------------------".repeat(solvers.size() +1) + "\u001b[0m"); // adapts to the number of elements
|
||||||
output.printf("%-8s %-5s %4d ",instanceName, instance.numJobs +"x"+instance.numTasks, bestKnown);
|
output.printf("%-8s %-5s %4d ",instanceName, instance.numJobs +"x"+instance.numTasks, bestKnown);
|
||||||
|
|
||||||
|
|
||||||
// used to get a csv file of all compared makespans
|
// used to get a csv file of all compared makespans
|
||||||
ArrayList<Integer> instanceMakespans = new ArrayList<>();
|
ArrayList<Integer> instanceMakespans = new ArrayList<>();
|
||||||
|
instanceMakespans.add(bestKnown);
|
||||||
// run all selected solvers on the instance and print the results
|
// run all selected solvers on the instance and print the results
|
||||||
for(int solverId = 0 ; solverId < solvers.size() ; solverId++) {
|
for(int solverId = 0 ; solverId < solvers.size() ; solverId++) {
|
||||||
// Select the next solver to run. Given the solver name passed on the command line,
|
// Select the next solver to run. Given the solver name passed on the command line,
|
||||||
|
@ -157,7 +158,8 @@ public class Main {
|
||||||
avg_distances[solverId] += dist / (float) instances.size();
|
avg_distances[solverId] += dist / (float) instances.size();
|
||||||
|
|
||||||
output.printf("%7d %8s %5.1f ", runtime, makespan, dist);
|
output.printf("%7d %8s %5.1f ", runtime, makespan, dist);
|
||||||
instanceMakespans.add(makespan);
|
instanceMakespans.add(makespan); // to store the makespan time
|
||||||
|
//instanceMakespans.add(Math.toIntExact(runtime)); // to store the execution time
|
||||||
output.flush();
|
output.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@ import java.util.stream.IntStream;
|
||||||
public class TabooSolver implements Solver {
|
public class TabooSolver implements Solver {
|
||||||
final Neighborhood neighborhood;
|
final Neighborhood neighborhood;
|
||||||
final Solver baseSolver;
|
final Solver baseSolver;
|
||||||
|
private int historyForbidenSize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Creates a new descent solver with a given neighborhood and a solver for the initial solution.
|
/** Creates a new descent solver with a given neighborhood and a solver for the initial solution.
|
||||||
|
@ -28,6 +31,7 @@ public class TabooSolver implements Solver {
|
||||||
public TabooSolver(Neighborhood neighborhood, Solver baseSolver) {
|
public TabooSolver(Neighborhood neighborhood, Solver baseSolver) {
|
||||||
this.neighborhood = neighborhood;
|
this.neighborhood = neighborhood;
|
||||||
this.baseSolver = baseSolver;
|
this.baseSolver = baseSolver;
|
||||||
|
this.historyForbidenSize = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,11 +65,10 @@ public class TabooSolver implements Solver {
|
||||||
Arrays.fill(forbiddenNeighbours[i],zeroArray);
|
Arrays.fill(forbiddenNeighbours[i],zeroArray);
|
||||||
}
|
}
|
||||||
int iterationCount = 0;
|
int iterationCount = 0;
|
||||||
Boolean noMoreSolution = false;
|
|
||||||
Integer best = Integer.MAX_VALUE;
|
Integer best = Integer.MAX_VALUE;
|
||||||
ResourceOrder bestRO = order;
|
ResourceOrder bestRO = order;
|
||||||
ResourceOrder previousRO;
|
ResourceOrder previousRO;
|
||||||
while(System.currentTimeMillis() < deadline && !noMoreSolution) {
|
while(System.currentTimeMillis() < deadline) {
|
||||||
List<ResourceOrder> neighbours = neighborhood.generateNeighbors(order);
|
List<ResourceOrder> neighbours = neighborhood.generateNeighbors(order);
|
||||||
previousRO = order;
|
previousRO = order;
|
||||||
try {
|
try {
|
||||||
|
@ -91,12 +94,10 @@ public class TabooSolver implements Solver {
|
||||||
.toArray(ResourceOrder[]::new)[0];
|
.toArray(ResourceOrder[]::new)[0];
|
||||||
result = order;
|
result = order;
|
||||||
}
|
}
|
||||||
} catch (ArrayIndexOutOfBoundsException e2) { // no solution found ==> stop
|
} catch (ArrayIndexOutOfBoundsException e2) { // no solution found ==> wait
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have a cycle */
|
/* Check if we have a cycle */
|
||||||
// TODO : on ne mmet pas a jour l'historiaue ?
|
|
||||||
// todo add la liste des interdits dans le calcul du hash
|
|
||||||
if (isCycle(historic, result.toSchedule().get())){
|
if (isCycle(historic, result.toSchedule().get())){
|
||||||
System.out.println("CYCLE");
|
System.out.println("CYCLE");
|
||||||
break;
|
break;
|
||||||
|
@ -165,7 +166,7 @@ public class TabooSolver implements Solver {
|
||||||
if (changes[0] == -1) {return true;}
|
if (changes[0] == -1) {return true;}
|
||||||
|
|
||||||
if ((forbiddenNeighbours[changes[0]][changes[1]][changes[2]] == 0)
|
if ((forbiddenNeighbours[changes[0]][changes[1]][changes[2]] == 0)
|
||||||
|| (forbiddenNeighbours[changes[0]][changes[1]][changes[2]] < iterationCount - 10 /*to tune*/)){
|
|| (forbiddenNeighbours[changes[0]][changes[1]][changes[2]] < iterationCount - historyForbidenSize)){
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -184,36 +185,40 @@ public class TabooSolver implements Solver {
|
||||||
historic.add(schedule.hashCode());
|
historic.add(schedule.hashCode());
|
||||||
Boolean found = false;
|
Boolean found = false;
|
||||||
Boolean result = true;
|
Boolean result = true;
|
||||||
int indexCycle = 0;
|
int turtle = 1;
|
||||||
int testTurtle = 0;
|
int rabbit = 2;
|
||||||
int testRabbit = 0;
|
int lenCycle = 0;
|
||||||
if (historic.size() > 50) {
|
if (historic.size() > 1000) { // to only store the last thousand
|
||||||
historic.remove(0);
|
historic.remove(0);
|
||||||
}
|
}
|
||||||
int rabbit = 0;
|
|
||||||
for (int turtle = 1; turtle < (historic.size()/2); turtle ++){
|
/*find the first occurence of duplicate state*/
|
||||||
rabbit = 2*turtle;
|
if (historic.size() > 100) { // in order not to cut too short
|
||||||
if (historic.get(turtle).equals(historic.get(rabbit))){
|
for (turtle = 1; turtle < (historic.size() / 2); turtle++) {
|
||||||
indexCycle = turtle;
|
rabbit = 2 * turtle;
|
||||||
found = true;
|
if (historic.get(turtle).equals(historic.get(rabbit))) {
|
||||||
testTurtle = turtle;
|
lenCycle = rabbit - turtle;
|
||||||
testRabbit = rabbit;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found && 2 * rabbit - indexCycle < historic.size()){
|
|
||||||
for (int i = indexCycle; i < rabbit; i++) {
|
|
||||||
if (!historic.get(testTurtle).equals(historic.get(testRabbit))) {
|
|
||||||
result = false;
|
|
||||||
}
|
}
|
||||||
testTurtle++;
|
|
||||||
testRabbit++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result && found){
|
|
||||||
return true;
|
/*if there is one then checks that the sequence leading one to the other is the same n times*/
|
||||||
|
if (found) {
|
||||||
|
try {
|
||||||
|
result = true;
|
||||||
|
for (int k = 1; k < 5 /*tune this for more or less tolerance*/; k++){
|
||||||
|
result = result && historic.subList(turtle, rabbit).equals(historic.subList(turtle + lenCycle * k, rabbit + lenCycle * k));
|
||||||
|
};
|
||||||
|
} catch (IndexOutOfBoundsException e) { // if one occurs then the list is too short to include a cycle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue