Paul Faure 4 months ago
parent
commit
c604d1ff3e

BIN
doc/src/TP_Meta-20-21-Version2.pdf View File


+ 6
- 5
src/main/java/jobshop/Main.java View File

@@ -81,6 +81,7 @@ public class Main {
81 81
         float[] avg_runtimes = new float[solversToTest.size()];
82 82
         // average distance to best known result for each solver
83 83
         float[] avg_distances = new float[solversToTest.size()];
84
+        float[] avg_voisins = new float[solversToTest.size()];
84 85
 
85 86
         try {
86 87
             // header of the result table :
@@ -88,11 +89,11 @@ public class Main {
88 89
             //   - name of each column (second line)
89 90
             output.print(  "                         ");
90 91
             for(String s : solversToTest)
91
-                output.printf("%-30s", s);
92
+                output.printf("%-38s", s);
92 93
             output.println();
93 94
             output.print("instance size  best      ");
94 95
             for(String s : solversToTest) {
95
-                output.print("runtime makespan ecart        ");
96
+                output.print("runtime makespan ecart voisins        ");
96 97
             }
97 98
             output.println();
98 99
 
@@ -135,8 +136,8 @@ public class Main {
135 136
                     float dist = 100f * (makespan - bestKnown) / (float) bestKnown;
136 137
                     avg_runtimes[solverId] += (float) runtime / (float) instances.size();
137 138
                     avg_distances[solverId] += dist / (float) instances.size();
138
-
139
-                    output.printf("%7d %8s %5.1f        ", runtime, makespan, dist);
139
+                    avg_voisins[solverId] += (float) result.getVoisinsVisites() / (float) instances.size();
140
+                    output.printf("%7d %8s %5.1f %7d        ", runtime, makespan, dist, result.getVoisinsVisites());
140 141
                     output.flush();
141 142
                 }
142 143
                 output.println();
@@ -146,7 +147,7 @@ public class Main {
146 147
             // we have finished all benchmarks, compute the average solve time and distance of each solver.
147 148
             output.printf("%-8s %-5s %4s      ", "AVG", "-", "-");
148 149
             for(int solverId = 0 ; solverId < solversToTest.size() ; solverId++) {
149
-                output.printf("%7.1f %8s %5.1f        ", avg_runtimes[solverId], "-", avg_distances[solverId]);
150
+                output.printf("%7.1f %8s %5.1f %7.1f        ", avg_runtimes[solverId], "-", avg_distances[solverId], avg_voisins[solverId]);
150 151
             }
151 152
 
152 153
 

+ 11
- 0
src/main/java/jobshop/Result.java View File

@@ -16,11 +16,22 @@ public class Result {
16 16
     /** Reason why the solver exited with this solution. */
17 17
     public final ExitCause cause;
18 18
 
19
+    private int voisinsVisites;
20
+
19 21
     /** Creates a new Result object with the corresponding fields. */
20 22
     public Result(Instance instance, Optional<Schedule> schedule, ExitCause cause) {
21 23
         this.instance = instance;
22 24
         this.schedule = schedule;
23 25
         this.cause = cause;
26
+        this.voisinsVisites = 0;
27
+    }
28
+
29
+    public int getVoisinsVisites() {
30
+        return voisinsVisites;
31
+    }
32
+
33
+    public void setVoisinsVisites(int voisinsVisites) {
34
+        this.voisinsVisites = voisinsVisites;
24 35
     }
25 36
 
26 37
     /** Documents the reason why a solver returned the solution. */

+ 12
- 2
src/main/java/jobshop/solvers/DescentSolver.java View File

@@ -38,14 +38,16 @@ public class DescentSolver implements Solver {
38 38
         boolean ended = false;
39 39
         int bestMakespan;
40 40
         Neighbor<ResourceOrder> bestNeighbor;
41
+        int voisinsVisites = 0;
41 42
 
42
-        while (!ended) {
43
+        while (!ended && deadline - System.currentTimeMillis() > 0) {
43 44
             schedule = resourceOrder.toSchedule().get();
44 45
             bestMakespan = schedule.makespan();
45 46
             bestNeighbor = null;
46 47
             List<Neighbor<ResourceOrder>> generatedNeighbors = neighborhood.generateNeighbors(resourceOrder);
47 48
             Iterator<Neighbor<ResourceOrder>> iter = generatedNeighbors.iterator();
48 49
             while (iter.hasNext()) {
50
+                voisinsVisites++;
49 51
                 Neighbor<ResourceOrder> neighbor = iter.next();
50 52
                 neighbor.applyOn(resourceOrder);
51 53
                 try {
@@ -65,7 +67,15 @@ public class DescentSolver implements Solver {
65 67
                 bestNeighbor.applyOn(resourceOrder);
66 68
             }
67 69
         }
68
-        return new Result(instance, resourceOrder.toSchedule(), Result.ExitCause.ProvedOptimal);
70
+
71
+        Result result;
72
+        if (ended) {
73
+            result = new Result(instance, resourceOrder.toSchedule(), Result.ExitCause.Blocked);
74
+        } else {
75
+            result = new Result(instance, resourceOrder.toSchedule(), Result.ExitCause.Timeout);
76
+        }
77
+        result.setVoisinsVisites(voisinsVisites);
78
+        return result;
69 79
     }
70 80
 
71 81
 }

+ 9
- 2
src/main/java/jobshop/solvers/GreedySolver.java View File

@@ -179,7 +179,7 @@ public class GreedySolver implements Solver {
179 179
         Task nextTask;
180 180
 
181 181
         //Itérations
182
-        while (!this.tachesRestantes.isEmpty()) {
182
+        while (!this.tachesRestantes.isEmpty() && deadline - System.currentTimeMillis() > 0) {
183 183
             task = this.getTask(instance);
184 184
             int startTime = getEarliestDate(instance, task);
185 185
             resourceOrder.addTaskToMachine(instance.machine(task), task);
@@ -190,6 +190,13 @@ public class GreedySolver implements Solver {
190 190
                 this.addTask(instance, new Task(task.job, task.task + 1));
191 191
             }
192 192
         }
193
-        return new Result (instance, resourceOrder.toSchedule(), ProvedOptimal);
193
+
194
+        Result result;
195
+        if (this.tachesRestantes.isEmpty()) {
196
+            result = new Result(instance, resourceOrder.toSchedule(), Result.ExitCause.Blocked);
197
+        } else {
198
+            result = new Result(instance, resourceOrder.toSchedule(), Result.ExitCause.Timeout);
199
+        }
200
+        return result;
194 201
     }
195 202
 }

+ 8
- 0
src/main/java/jobshop/solvers/Solver.java View File

@@ -38,6 +38,14 @@ public interface Solver {
38 38
             case "descent_est_lpt": return new DescentSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.EST_LPT));
39 39
             case "descent_est_srpt": return new DescentSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.EST_SRPT));
40 40
             case "descent_est_lrpt": return new DescentSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.EST_LRPT));
41
+            case "taboo_spt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.SPT));
42
+            case "taboo_lpt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.LPT));
43
+            case "taboo_srpt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.SRPT));
44
+            case "taboo_lrpt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.LRPT));
45
+            case "taboo_est_spt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.EST_SPT));
46
+            case "taboo_est_lpt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.EST_LPT));
47
+            case "taboo_est_srpt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.EST_SRPT));
48
+            case "taboo_est_lrpt": return new TabooSolver(new Nowicki(), new GreedySolver(GreedySolver.Priority.EST_LRPT));
41 49
             // TODO: add new solvers
42 50
             default: throw new RuntimeException("Unknown solver: "+ name);
43 51
         }

+ 101
- 0
src/main/java/jobshop/solvers/TabooSolver.java View File

@@ -0,0 +1,101 @@
1
+package jobshop.solvers;
2
+
3
+import jobshop.Instance;
4
+import jobshop.Result;
5
+import jobshop.encodings.ResourceOrder;
6
+import jobshop.encodings.Schedule;
7
+import jobshop.solvers.neighborhood.Neighbor;
8
+import jobshop.solvers.neighborhood.Neighborhood;
9
+import jobshop.solvers.neighborhood.Nowicki;
10
+
11
+import java.io.IOException;
12
+import java.nio.file.Paths;
13
+import java.util.ArrayList;
14
+import java.util.Iterator;
15
+import java.util.List;
16
+import java.util.stream.Collectors;
17
+
18
+/** An empty shell to implement a descent solver. */
19
+public class TabooSolver implements Solver {
20
+
21
+    final Neighborhood<ResourceOrder> neighborhood;
22
+    final Solver baseSolver;
23
+    int maxIter = 100;
24
+    int dureeTaboo = 4;
25
+
26
+    /** Creates a new taboo solver with a given neighborhood and a solver for the initial solution.
27
+     *
28
+     * @param neighborhood Neighborhood object that should be used to generates neighbor solutions to the current candidate.
29
+     * @param baseSolver A solver to provide the initial solution.
30
+     */
31
+    public TabooSolver(Neighborhood<ResourceOrder> neighborhood, Solver baseSolver) {
32
+        this.neighborhood = neighborhood;
33
+        this.baseSolver = baseSolver;
34
+    }
35
+
36
+    @Override
37
+    public Result solve(Instance instance, long deadline) {
38
+        Schedule schedule = baseSolver.solve(instance, deadline).schedule.get();
39
+        ResourceOrder resourceOrder = new ResourceOrder(schedule);
40
+        int nbKey = Nowicki.Swap.getNbKey(instance.numMachines, instance.numJobs);
41
+        int[] taboo = new int[nbKey];
42
+        for (int i = 0; i<nbKey; i++) {
43
+            taboo[i] = -1;
44
+        }
45
+        int starMakespan = resourceOrder.toSchedule().get().makespan();
46
+        ResourceOrder starResourceOrder = resourceOrder.copy();
47
+        int bestMakespan;
48
+        Neighbor<ResourceOrder> bestNeighbor;
49
+        int voisinsVisites = 0;
50
+        int k = 0;
51
+        while (deadline - System.currentTimeMillis() > 0 && k < maxIter) {
52
+            k++;
53
+            bestMakespan = Integer.MAX_VALUE;
54
+            bestNeighbor = null;
55
+            List<Neighbor<ResourceOrder>> generatedNeighbors = neighborhood.generateNeighbors(resourceOrder);
56
+            Iterator<Neighbor<ResourceOrder>> iter = generatedNeighbors.iterator();
57
+            while (iter.hasNext()) {
58
+                voisinsVisites++;
59
+                Neighbor<ResourceOrder> neighbor = iter.next();
60
+                Nowicki.Swap currentSwap = (Nowicki.Swap) neighbor.getChange();
61
+                int currentMakespan = Integer.MAX_VALUE;
62
+                try {
63
+                    neighbor.applyOn(resourceOrder);
64
+                    Schedule currentSchedule = resourceOrder.toSchedule().get();
65
+                    currentMakespan = currentSchedule.makespan();
66
+                    neighbor.undoApplyOn(resourceOrder);
67
+                } catch (Exception e) {
68
+                }
69
+                if (taboo[currentSwap.generateKey(instance.numJobs)] < k || currentMakespan < starMakespan) {
70
+                    neighbor.applyOn(resourceOrder);
71
+                    try {
72
+                        Schedule currentSchedule = resourceOrder.toSchedule().get();
73
+                        currentMakespan = currentSchedule.makespan();
74
+                        if (currentMakespan < bestMakespan) {
75
+                            bestMakespan = currentMakespan;
76
+                            bestNeighbor = neighbor;
77
+                        }
78
+                    } catch (Exception e) {
79
+                    }
80
+                    neighbor.undoApplyOn(resourceOrder);
81
+                }
82
+            }
83
+
84
+            if (bestNeighbor != null) {
85
+                Nowicki.Swap swap = (Nowicki.Swap) bestNeighbor.getChange();
86
+                taboo[swap.generateKey(instance.numJobs)] = k + dureeTaboo;
87
+                bestNeighbor.applyOn(resourceOrder);
88
+                if (bestMakespan < starMakespan) {
89
+                    starMakespan = bestMakespan;
90
+                    starResourceOrder = resourceOrder.copy();
91
+                }
92
+            }
93
+        }
94
+
95
+        Result result;
96
+        result = new Result(instance, starResourceOrder.toSchedule(), Result.ExitCause.Timeout);
97
+        result.setVoisinsVisites(voisinsVisites);
98
+        return result;
99
+    }
100
+
101
+}

+ 3
- 0
src/main/java/jobshop/solvers/neighborhood/Neighbor.java View File

@@ -15,4 +15,7 @@ public abstract class Neighbor<Enc extends Encoding> {
15 15
     /** Transform the neighbor back into the original solution. */
16 16
     public abstract void undoApplyOn(Enc current);
17 17
 
18
+    /** Renvoi l'objet caracterisant le changement **/
19
+    public abstract Object getChange();
20
+
18 21
 }

+ 33
- 1
src/main/java/jobshop/solvers/neighborhood/Nowicki.java View File

@@ -70,7 +70,7 @@ public class Nowicki extends Neighborhood<ResourceOrder> {
70 70
         public final int t2;
71 71
 
72 72
         /** Creates a new swap of two tasks. */
73
-        Swap(int machine, int t1, int t2) {
73
+        public Swap(int machine, int t1, int t2) {
74 74
             this.machine = machine;
75 75
             this.t1 = t1;
76 76
             this.t2 = t2;
@@ -88,6 +88,38 @@ public class Nowicki extends Neighborhood<ResourceOrder> {
88 88
         public void undoApplyOn(ResourceOrder current) {
89 89
             current.swapTasks(machine, t1, t2);
90 90
         }
91
+
92
+        public int generateKey(int nbJobs) {
93
+            int myT1;
94
+            int myT2;
95
+            if (t2 < t1) {
96
+                myT1 = t2;
97
+                myT2 = t1;
98
+            } else {
99
+                myT1 = t1;
100
+                myT2 = t2;
101
+            }
102
+            int a = (((nbJobs - 1)*nbJobs*(machine + 1))/2);
103
+            int b = (((nbJobs-1-myT1)*(nbJobs-myT1))/2);
104
+            int c = (myT2 - myT1 - 1);
105
+            //System.out.println(a + " " + b + " " + c);
106
+            return a - b + c;
107
+        }
108
+
109
+        public static int getNbKey(int nbMachines, int nbJobs) {
110
+            return ((nbJobs - 1)*nbJobs*nbMachines)/2;
111
+        }
112
+
113
+        @Override
114
+        public boolean equals (Object o) {
115
+            Swap obj = (Swap) o;
116
+            return (machine == obj.machine && ((t1 == obj.t1 && t2 == obj.t2) || (t1 == obj.t2 && t2 == obj.t1 )));
117
+        }
118
+
119
+        @Override
120
+        public Object getChange() {
121
+            return this;
122
+        }
91 123
     }
92 124
 
93 125
 

+ 26
- 0
src/test/java/jobshop/swap/SwapTest.java View File

@@ -0,0 +1,26 @@
1
+package jobshop.swap;
2
+
3
+import jobshop.solvers.neighborhood.Nowicki;
4
+import org.junit.Test;
5
+
6
+
7
+public class SwapTest {
8
+    @Test
9
+    public void test() {
10
+        int nbJobs = 5;
11
+        int nbMachine = 8;
12
+        int k = -1;
13
+        for (int machine = 0; machine<nbMachine; machine++) {
14
+            for (int t1 = 0; t1<nbJobs; t1++) {
15
+                for (int t2 = (t1 + 1); t2<nbJobs; t2++) {
16
+                    Nowicki.Swap swap = new Nowicki.Swap(machine, t1, t2);
17
+                    int key = swap.generateKey(nbJobs);
18
+                    k++;
19
+                    //System.out.println("m : " + machine + "; t1 : " + t1 + "; t2 : " + t2);
20
+                    //System.out.println("Key : " + key + "; K : " + k);
21
+                    assert (key == k);
22
+                }
23
+            }
24
+        }
25
+    }
26
+}

Loading…
Cancel
Save