improved cycle detection and withdrawal

This commit is contained in:
alejeune 2023-04-05 11:51:27 +02:00
parent 8c11d274fc
commit 640e695533
2 changed files with 54 additions and 13 deletions

View file

@ -27,6 +27,12 @@
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.knowm.xchart</groupId>
<artifactId>xchart</artifactId>
<version>3.8.3</version>
</dependency>
</dependencies>
<build>

View file

@ -6,14 +6,20 @@ import jobshop.Instance;
import jobshop.encodings.ResourceOrder;
import jobshop.encodings.Schedule;
import jobshop.solvers.neighborhood.Neighborhood;
import org.knowm.xchart.SwingWrapper;
import org.knowm.xchart.XYChart;
import org.knowm.xchart.XYChartBuilder;
import java.time.format.ResolverStyle;
import java.util.*;
import java.util.stream.IntStream;
public class TabooSolver implements Solver {
final Neighborhood neighborhood;
final Solver baseSolver;
/** Creates a new descent solver with a given neighborhood and a solver for the initial solution.
*
* @param neighborhood Neighborhood object that should be used to generates neighbor solutions to the current candidate.
@ -32,6 +38,10 @@ public class TabooSolver implements Solver {
// Create an array to store the cycle
ArrayList<Integer> historic = new ArrayList<Integer>();
ArrayList<Integer> makespans = new ArrayList<>();
ArrayList<Integer> bests = new ArrayList<>();
/*for output writing*/
FileWriter fw = null;
try {
@ -85,6 +95,8 @@ public class TabooSolver implements Solver {
}
/* 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())){
System.out.println("CYCLE");
break;
@ -94,12 +106,15 @@ public class TabooSolver implements Solver {
+ "\u001b[32m" + "Current best makespam : " + best + "\u001b[0m, "
+ "\u001b[33m" + "Number of neighbours : " + getNumberOfNeighbours(neighbours) + "\u001b[0m, "
+ "\u001b[37m" + "Number of non-forbidden neighbours : " + getNumberOfNonForbiddenNeighbours(neighbours,previousRO, forbiddenNeighbours, iterationCount) + "\u001b[0m");
// print to csv
pw.println(result.toSchedule().get().makespan() + ","
+ best + ","
+ getNumberOfNeighbours(neighbours) + ","
+ getNumberOfNonForbiddenNeighbours(neighbours,previousRO, forbiddenNeighbours, iterationCount));
// add to graph data
makespans.add(result.toSchedule().get().makespan());
bests.add(best);
best = Integer.min(result.toSchedule().get().makespan(),best);
if (bestRO.toSchedule().get().makespan() > result.toSchedule().get().makespan()) {
@ -109,6 +124,25 @@ public class TabooSolver implements Solver {
iterationCount++;
}
Double[] makespansDataD = makespans.stream().map(e -> Double.valueOf(e)).toArray(Double[]::new);
Double[] bestDataD = bests.stream().map(e -> Double.valueOf(e)).toArray(Double[]::new);
// removing the starting value
bestDataD[0] = bestDataD[1];
double[] makespansData = Arrays.stream(makespansDataD).mapToDouble(Double::doubleValue).toArray();
double[] bestData = Arrays.stream(bestDataD).mapToDouble(Double::doubleValue).toArray();
double xData[] = new double[makespansData.length];
for (int i = 0; i < makespansData.length; xData[i] = Double.valueOf(i++));
final XYChart chart = new XYChartBuilder().width(600).height(400).title("Area Chart").xAxisTitle("X").yAxisTitle("Y").build();
chart.addSeries("a", xData, makespansData);
chart.addSeries("b", xData, bestData);
new SwingWrapper(chart).displayChart();
return bestRO.toSchedule();
}
// used to compute the number of neighbours seen
@ -153,30 +187,31 @@ public class TabooSolver implements Solver {
int indexCycle = 0;
int testTurtle = 0;
int testRabbit = 0;
if (historic.size() > 20) {
if (historic.size() > 50) {
historic.remove(0);
}
int rabbit = 2;
for (int turtle = 1; turtle < (historic.size()/2) - 1; turtle ++){
if (historic.get(turtle) == historic.get(rabbit)){
int rabbit = 0;
for (int turtle = 1; turtle < (historic.size()/2); turtle ++){
rabbit = 2*turtle;
if (historic.get(turtle).equals(historic.get(rabbit))){
indexCycle = turtle;
found = true;
testTurtle = turtle;
testRabbit = rabbit;
break;
}
rabbit = 2*turtle;
}
if (found){
for (int i = indexCycle; i < historic.size() - rabbit; i++)
if (historic.get(testTurtle) != historic.get(testRabbit)){
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 ++;
}
testTurtle++;
testRabbit++;
}
}
if (result && found){
return result;
return true;
}
return false;
}