diff --git a/src/main/java/jobshop/BestKnownResults.java b/src/main/java/jobshop/BestKnownResults.java index 31949a5..77717ec 100644 --- a/src/main/java/jobshop/BestKnownResults.java +++ b/src/main/java/jobshop/BestKnownResults.java @@ -15,7 +15,7 @@ public class BestKnownResults { /** * Checks whether we have data available for the provided instance. * @param instanceName Name of the instance. - * @return True if the isntance is known, false otherwise. + * @return True if the instance is known, false otherwise. */ public static boolean isKnown(String instanceName) { return bests.containsKey(instanceName); diff --git a/src/main/java/jobshop/Main.java b/src/main/java/jobshop/Main.java index f0f9663..be17c5e 100644 --- a/src/main/java/jobshop/Main.java +++ b/src/main/java/jobshop/Main.java @@ -5,12 +5,10 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; import jobshop.solvers.*; -import jobshop.solvers.neighborhood.Nowicki; import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; diff --git a/src/main/java/jobshop/encodings/JobNumbers.java b/src/main/java/jobshop/encodings/JobNumbers.java index d29df37..957c4cf 100644 --- a/src/main/java/jobshop/encodings/JobNumbers.java +++ b/src/main/java/jobshop/encodings/JobNumbers.java @@ -16,6 +16,7 @@ public class JobNumbers extends Encoding { * element of `jobs` that has not been set yet. */ public int nextToSet = 0; + /** Creates a new empty encoding. */ public JobNumbers(Instance instance) { super(instance); @@ -23,6 +24,7 @@ public class JobNumbers extends Encoding { Arrays.fill(jobs, -1); } + /** Cerates a new encoding based on the given schedule. */ public JobNumbers(Schedule schedule) { super(schedule.instance); @@ -48,6 +50,7 @@ public class JobNumbers extends Encoding { } } + /** Schedule the next task of the given job. */ public void addTask(int jobNumber) { this.jobs[nextToSet++] = jobNumber; } diff --git a/src/main/java/jobshop/encodings/ResourceOrder.java b/src/main/java/jobshop/encodings/ResourceOrder.java index f13a84c..556a51e 100644 --- a/src/main/java/jobshop/encodings/ResourceOrder.java +++ b/src/main/java/jobshop/encodings/ResourceOrder.java @@ -10,10 +10,10 @@ public class ResourceOrder extends Encoding { // for each machine m, taskByMachine[m] is an array of tasks to be // executed on this machine in the same order - public final Task[][] tasksByMachine; + final Task[][] tasksByMachine; // for each machine, indicate how many tasks have been initialized - public final int[] nextFreeSlot; + final int[] nextFreeSlot; /** Creates a new empty resource order. */ public ResourceOrder(Instance instance) @@ -51,6 +51,8 @@ public class ResourceOrder extends Encoding { } } + /** Enqueues a task for the given job on the machine. We automatically, find the task + * that must be executed on this particular machine. */ public void addToMachine(int machine, int jobNumber) { addTaskToMachine(machine, new Task(jobNumber, instance.task_with_machine(jobNumber, machine))); } @@ -60,10 +62,16 @@ public class ResourceOrder extends Encoding { nextFreeSlot[machine] += 1; } - public void swapTasks(int machine, int indexFirstTask, int indexSecondTask) { - Task tmp = tasksByMachine[machine][indexFirstTask]; - tasksByMachine[machine][indexFirstTask] = tasksByMachine[machine][indexSecondTask]; - tasksByMachine[machine][indexSecondTask] = tmp; + /** Exchange the order of two tasks that are scheduled on a given machine. + * + * @param machine Machine on which the two tasks appear (line on which to perform the exchange) + * @param indexTask1 Position of the first task on the machine (column of the first element) + * @param indexTask2 Position of the second task on the machine (column of the second element) + */ + public void swapTasks(int machine, int indexTask1, int indexTask2) { + Task tmp = tasksByMachine[machine][indexTask1]; + tasksByMachine[machine][indexTask1] = tasksByMachine[machine][indexTask2]; + tasksByMachine[machine][indexTask2] = tmp; } @Override diff --git a/src/main/java/jobshop/encodings/Schedule.java b/src/main/java/jobshop/encodings/Schedule.java index 0507855..29be765 100644 --- a/src/main/java/jobshop/encodings/Schedule.java +++ b/src/main/java/jobshop/encodings/Schedule.java @@ -69,8 +69,8 @@ public class Schedule extends Encoding { for(int j2 = j1+1; j2< instance.numJobs ; j2++) { int t2 = instance.task_with_machine(j2, machine); - boolean t1_first = startTime(j1, t1) + instance.duration(j1, t1) <= startTime(j2, t2); - boolean t2_first = startTime(j2, t2) + instance.duration(j2, t2) <= startTime(j1, t1); + boolean t1_first = endTime(j1, t1) <= startTime(j2, t2); + boolean t2_first = endTime(j2, t2) <= startTime(j1, t1); if(!t1_first && !t2_first) return false; diff --git a/src/main/java/jobshop/solvers/BasicSolver.java b/src/main/java/jobshop/solvers/BasicSolver.java index 2f9cce6..9695e33 100644 --- a/src/main/java/jobshop/solvers/BasicSolver.java +++ b/src/main/java/jobshop/solvers/BasicSolver.java @@ -5,8 +5,7 @@ import jobshop.Result; import jobshop.encodings.JobNumbers; /** - * A very naïve solver that first schedules - * + * A very naïve solver that first schedules all first tasks, then all second tasks, ... **/ public class BasicSolver implements Solver { @Override diff --git a/src/main/java/jobshop/solvers/RandomSolver.java b/src/main/java/jobshop/solvers/RandomSolver.java index 8fc2100..f531441 100644 --- a/src/main/java/jobshop/solvers/RandomSolver.java +++ b/src/main/java/jobshop/solvers/RandomSolver.java @@ -6,6 +6,9 @@ import jobshop.encodings.Schedule; import java.util.Random; +/** A solver that generates random solutions until a deadline is met. + * Then returns the best solution that was generated. + */ public class RandomSolver implements Solver { @Override diff --git a/src/main/java/jobshop/solvers/neighborhood/Neighbor.java b/src/main/java/jobshop/solvers/neighborhood/Neighbor.java index 9380ab0..7faf2f2 100644 --- a/src/main/java/jobshop/solvers/neighborhood/Neighbor.java +++ b/src/main/java/jobshop/solvers/neighborhood/Neighbor.java @@ -1,8 +1,15 @@ package jobshop.solvers.neighborhood; -public abstract class Neighbor { +import jobshop.encodings.Encoding; - public abstract void applyOn(Encoding current); - public abstract void undoApplyOn(Encoding current); +/** This class provides a representation of neighbor by allowing to transform + * a solution in a particular encoding Enc into the neighbor and back.*/ +public abstract class Neighbor { + + /** Transform the given solution into the neighbor. */ + public abstract void applyOn(Enc current); + + /** Transform the neighbor back into the original solution. */ + public abstract void undoApplyOn(Enc current); } diff --git a/src/main/java/jobshop/solvers/neighborhood/Neighborhood.java b/src/main/java/jobshop/solvers/neighborhood/Neighborhood.java index cb9f562..285b0ac 100644 --- a/src/main/java/jobshop/solvers/neighborhood/Neighborhood.java +++ b/src/main/java/jobshop/solvers/neighborhood/Neighborhood.java @@ -1,9 +1,17 @@ package jobshop.solvers.neighborhood; +import jobshop.encodings.Encoding; + import java.util.List; -public abstract class Neighborhood { +/** For a particular encoding Enc, a neighborhood allow the generation of the neighbors of + * a particular solution. + * + * @param A subcless of Encoding for which this encoding can generate neighbors. + */ +public abstract class Neighborhood { - public abstract List> generateNeighbors(Encoding current); + /** Generates all neighbors for the current solution. */ + public abstract List> generateNeighbors(Enc current); } diff --git a/src/main/java/jobshop/solvers/neighborhood/Nowicki.java b/src/main/java/jobshop/solvers/neighborhood/Nowicki.java index eb2e109..8ee97ec 100644 --- a/src/main/java/jobshop/solvers/neighborhood/Nowicki.java +++ b/src/main/java/jobshop/solvers/neighborhood/Nowicki.java @@ -5,6 +5,13 @@ import jobshop.encodings.ResourceOrder; import java.util.ArrayList; import java.util.List; +/** Implementation of the Nowicki and Smutnicki neighborhood. + * + * It works on the ResourceOrder encoding by generating two neighbors for each block + * of the critical path. + * For each block, two neighbors should be generated that respectivly swap the first two and + * last two tasks of the block. + */ public class Nowicki extends Neighborhood { /** A block represents a subsequence of the critical path such that all tasks in it execute on the same machine.