Improve documentation
This commit is contained in:
parent
9802bd39fd
commit
dce9b786e9
7 changed files with 140 additions and 54 deletions
61
README.md
61
README.md
|
@ -2,21 +2,48 @@
|
||||||
|
|
||||||
This repository contains the starter code for the assignment.
|
This repository contains the starter code for the assignment.
|
||||||
|
|
||||||
|
## Working in IntelliJ
|
||||||
|
|
||||||
## Compile
|
For working on this project, we recommend using the IntelliJ-IDEA development environment. It is available in INSA's
|
||||||
|
classrooms as well as on `montp.insa-toulouse.fr`.
|
||||||
|
|
||||||
Compilation instructions are given for Linux. On windows you can use the `gradlew.bat` script.
|
To import the project in IntelliJ (once IntelliJ is running):
|
||||||
|
|
||||||
|
- Open a new project : `Open project` or `File > Open`
|
||||||
|
- Select the `gradle.build` file in the cloned repository.
|
||||||
|
- Select `Open as project`.
|
||||||
|
|
||||||
|
To run the program in IntelliJ, you can
|
||||||
|
|
||||||
|
- Right click on the `src/main/java/Jobshop/Main` class in the project view.
|
||||||
|
- Select `Run Main.main()`. It should complain that some arguments are missing.
|
||||||
|
- Give it the expected command line arguments : `Run > Edit Configuration`, then fill in the `Program arguments` text box.
|
||||||
|
|
||||||
|
|
||||||
|
## Working on the command line (Gradle)
|
||||||
|
|
||||||
|
Compilation instructions are given for Linux. On Windows you can use the `gradlew.bat` script (but you are on your own).
|
||||||
|
|
||||||
```
|
```
|
||||||
❯ ./gradlew build # Compiles the project
|
❯ ./gradlew build # Compiles the project
|
||||||
❯ ./gradlew jar # Creates a fat-jar in build/libs/JSP.jar
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The compiled jar is now `build/libs/JSP.jar` can be executed like so :
|
The project can be executed directly with `gradle` by specifying the arguments like so :
|
||||||
|
|
||||||
```
|
```
|
||||||
|
❯ ./gradlew run --args="--solver basic random --instance aaa1 ft"
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also build an executable jar file, and run it with the java command.
|
||||||
|
This is especially useful if you want to run it on another machine.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Create a jar file with all dependencies in build/libs/JSP.jar
|
||||||
|
❯ ./gradlew jar
|
||||||
|
# Run the jar file. Only requires a Java Runtime Environment (JRE)
|
||||||
❯ java -jar build/libs/JSP.jar --solver basic --instance ft06
|
❯ java -jar build/libs/JSP.jar --solver basic --instance ft06
|
||||||
```
|
```
|
||||||
|
|
||||||
The command line above indicates that we want to solve the instance named`ft06` with the `basic` solver. It should give an output like the following :
|
The command line above indicates that we want to solve the instance named`ft06` with the `basic` solver. It should give an output like the following :
|
||||||
```
|
```
|
||||||
basic
|
basic
|
||||||
|
@ -48,36 +75,26 @@ AVG - - 0.3 - 31.5 999.0 - 20.4
|
||||||
Here the last line give the average `runtime` and `ecart` for each solver.
|
Here the last line give the average `runtime` and `ecart` for each solver.
|
||||||
|
|
||||||
```
|
```
|
||||||
usage: jsp-solver [-h] [-t TIMEOUT] --solver SOLVER [SOLVER ...]
|
sage: jsp-solver [-h] [-t TIMEOUT] --solver SOLVER [SOLVER ...]
|
||||||
--instance INSTANCE [INSTANCE ...]
|
--instance INSTANCE [INSTANCE ...]
|
||||||
|
|
||||||
Solves jobshop problems.
|
Solves jobshop problems.
|
||||||
|
|
||||||
named arguments:
|
named arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
|
-t TIMEOUT, --timeout TIMEOUT
|
||||||
|
Solver timeout in seconds for each instance.
|
||||||
|
(default: 1)
|
||||||
--solver SOLVER [SOLVER ...]
|
--solver SOLVER [SOLVER ...]
|
||||||
Solver(s) to use (space separated if more than
|
Solver(s) to use (space separated if more than
|
||||||
one)
|
one)
|
||||||
-t TIMEOUT, --timeout TIMEOUT
|
|
||||||
Solver timeout in seconds for each instance
|
|
||||||
(default: 1)
|
|
||||||
--instance INSTANCE [INSTANCE ...]
|
--instance INSTANCE [INSTANCE ...]
|
||||||
Instance(s) to solve (space separated if more
|
Instance(s) to solve (space separated if more
|
||||||
than one)
|
than one). All instances starting with the given
|
||||||
|
String will be selected. (e.g. "ft" will select
|
||||||
|
the instances ft06, ft10 and ft20.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running directly from Gradle
|
|
||||||
|
|
||||||
The project can be executed directly with `gradle` by specifying the arguments like so :
|
|
||||||
|
|
||||||
```
|
|
||||||
❯ ./gradlew run --args="--solver basic random --instance aaa1 ft06 ft10 ft20"
|
|
||||||
```
|
|
||||||
|
|
||||||
This notably ensures that sources have been recompiled whenever necessary.
|
|
||||||
|
|
||||||
|
|
||||||
## IDE Support
|
## IDE Support
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,28 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class BestKnownResult {
|
/**
|
||||||
|
* This class contains the best known results for common jobshop instances.
|
||||||
|
* Note that the best known result might not have been proven to be the optimal solution
|
||||||
|
* for the instance.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
public static boolean isKnown(String instanceName) {
|
public static boolean isKnown(String instanceName) {
|
||||||
return bests.containsKey(instanceName);
|
return bests.containsKey(instanceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all instances that start with the given prefix.
|
||||||
|
* For example, the prefix "ft" should match the instances "ft06", "ft10" and "ft20"
|
||||||
|
* @param namePrefix Prefix that should be looked-up.
|
||||||
|
* @return All instances that start with the given prefix, in alphabetical order.
|
||||||
|
*/
|
||||||
public static List<String> instancesMatching(String namePrefix) {
|
public static List<String> instancesMatching(String namePrefix) {
|
||||||
return Arrays.stream(instances)
|
return Arrays.stream(instances)
|
||||||
.filter(i -> i.startsWith(namePrefix))
|
.filter(i -> i.startsWith(namePrefix))
|
||||||
|
@ -18,6 +34,11 @@ public class BestKnownResult {
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the best known result for the given instance name.
|
||||||
|
* @param instanceName Instance of which we want to retrieve the best result.
|
||||||
|
* @return Best makespan that has ever been found for this instance.
|
||||||
|
*/
|
||||||
public static int of(String instanceName) {
|
public static int of(String instanceName) {
|
||||||
if(!bests.containsKey(instanceName)) {
|
if(!bests.containsKey(instanceName)) {
|
||||||
throw new RuntimeException("Unknown best result for "+instanceName);
|
throw new RuntimeException("Unknown best result for "+instanceName);
|
||||||
|
@ -25,8 +46,12 @@ public class BestKnownResult {
|
||||||
return bests.get(instanceName);
|
return bests.get(instanceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static private HashMap<String, Integer> bests;
|
// all best results.
|
||||||
|
static final private HashMap<String, Integer> bests;
|
||||||
|
// a sorted array of instance names
|
||||||
static String[] instances;
|
static String[] instances;
|
||||||
|
|
||||||
|
// initialize the internal data structures.
|
||||||
static {
|
static {
|
||||||
bests = new HashMap<>();
|
bests = new HashMap<>();
|
||||||
bests.put("aaa1", 11);
|
bests.put("aaa1", 11);
|
|
@ -27,8 +27,7 @@ public class DebuggingMain {
|
||||||
System.out.println("\nENCODING: " + enc);
|
System.out.println("\nENCODING: " + enc);
|
||||||
|
|
||||||
Schedule sched = enc.toSchedule();
|
Schedule sched = enc.toSchedule();
|
||||||
// TODO: make it print something meaningful
|
// TODO: make it print something meaningful by implementing the Schedule.toString() method
|
||||||
// by implementing the toString() method
|
|
||||||
System.out.println("SCHEDULE: " + sched);
|
System.out.println("SCHEDULE: " + sched);
|
||||||
System.out.println("VALID: " + sched.isValid());
|
System.out.println("VALID: " + sched.isValid());
|
||||||
System.out.println("MAKESPAN: " + sched.makespan());
|
System.out.println("MAKESPAN: " + sched.makespan());
|
||||||
|
|
|
@ -20,18 +20,28 @@ public class Instance {
|
||||||
/** Number of machines, assumed to be same as number of tasks. */
|
/** Number of machines, assumed to be same as number of tasks. */
|
||||||
public final int numMachines;
|
public final int numMachines;
|
||||||
|
|
||||||
|
/** Matrix containing the duration of all tasks. */
|
||||||
final int[][] durations;
|
final int[][] durations;
|
||||||
|
|
||||||
|
/** Matrix containing the machine on which each task must be scheduled. */
|
||||||
final int[][] machines;
|
final int[][] machines;
|
||||||
|
|
||||||
|
/** Duration of the given task. */
|
||||||
public int duration(int job, int task) {
|
public int duration(int job, int task) {
|
||||||
return durations[job][task];
|
return durations[job][task];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Duration of the given task. */
|
||||||
public int duration(Task t) {
|
public int duration(Task t) {
|
||||||
return duration(t.job, t.task);
|
return duration(t.job, t.task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Machine on which the given task must be scheduled. */
|
||||||
public int machine(int job, int task) {
|
public int machine(int job, int task) {
|
||||||
return machines[job][task];
|
return machines[job][task];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Machine on which the given task must be scheduled. */
|
||||||
public int machine(Task t) {
|
public int machine(Task t) {
|
||||||
return this.machine(t.job, t.task);
|
return this.machine(t.job, t.task);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +55,11 @@ public class Instance {
|
||||||
throw new RuntimeException("No task targeting machine "+wanted_machine+" on job "+job);
|
throw new RuntimeException("No task targeting machine "+wanted_machine+" on job "+job);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance, with uninitialized durations and machines.
|
||||||
|
* This should no be called directly. Instead, Instance objects should be created with the
|
||||||
|
* <code>Instance.fromFile()</code> static method.
|
||||||
|
*/
|
||||||
Instance(int numJobs, int numTasks) {
|
Instance(int numJobs, int numTasks) {
|
||||||
this.numJobs = numJobs;
|
this.numJobs = numJobs;
|
||||||
this.numTasks = numTasks;
|
this.numTasks = numTasks;
|
||||||
|
|
|
@ -8,82 +8,101 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
import jobshop.solvers.*;
|
import jobshop.solvers.*;
|
||||||
import net.sourceforge.argparse4j.ArgumentParsers;
|
import net.sourceforge.argparse4j.ArgumentParsers;
|
||||||
import net.sourceforge.argparse4j.inf.ArgumentParser;
|
import net.sourceforge.argparse4j.inf.ArgumentParser;
|
||||||
import net.sourceforge.argparse4j.inf.ArgumentParserException;
|
import net.sourceforge.argparse4j.inf.ArgumentParserException;
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is the main entry point for testing solver on instances.
|
||||||
|
* It provides
|
||||||
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
/** All solvers available in this program */
|
/** All solvers available in this program */
|
||||||
private static HashMap<String, Solver> solvers;
|
private static final HashMap<String, Solver> solvers;
|
||||||
static {
|
static {
|
||||||
solvers = new HashMap<>();
|
solvers = new HashMap<>();
|
||||||
solvers.put("basic", new BasicSolver());
|
solvers.put("basic", new BasicSolver());
|
||||||
solvers.put("random", new RandomSolver());
|
solvers.put("random", new RandomSolver());
|
||||||
// add new solvers here
|
// TODO: add new solvers here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
// configure the argument parser
|
||||||
ArgumentParser parser = ArgumentParsers.newFor("jsp-solver").build()
|
ArgumentParser parser = ArgumentParsers.newFor("jsp-solver").build()
|
||||||
.defaultHelp(true)
|
.defaultHelp(true)
|
||||||
.description("Solves jobshop problems.");
|
.description("Solves jobshop problems.");
|
||||||
|
|
||||||
parser.addArgument("-t", "--timeout")
|
parser.addArgument("-t", "--timeout")
|
||||||
.setDefault(1L)
|
.setDefault(1L)
|
||||||
.type(Long.class)
|
.type(Long.class)
|
||||||
.help("Solver timeout in seconds for each instance");
|
.help("Solver timeout in seconds for each instance. Default is 1 second.");
|
||||||
parser.addArgument("--solver")
|
parser.addArgument("--solver")
|
||||||
.nargs("+")
|
.nargs("+")
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("Solver(s) to use (space separated if more than one)");
|
.help("Solver(s) to use (space separated if more than one)");
|
||||||
|
|
||||||
parser.addArgument("--instance")
|
parser.addArgument("--instance")
|
||||||
.nargs("+")
|
.nargs("+")
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("Instance(s) to solve (space separated if more than one)");
|
.help("Instance(s) to solve (space separated if more than one). All instances starting with the given " +
|
||||||
|
"string will be selected. (e.g. \"ft\" will select the instances ft06, ft10 and ft20.");
|
||||||
|
|
||||||
|
// parse command line arguments
|
||||||
Namespace ns = null;
|
Namespace ns = null;
|
||||||
try {
|
try {
|
||||||
ns = parser.parseArgs(args);
|
ns = parser.parseArgs(args);
|
||||||
} catch (ArgumentParserException e) {
|
} catch (ArgumentParserException e) {
|
||||||
|
// error while parsing arguments, provide helpful error message and exit.
|
||||||
|
System.err.println("Invalid arguments provided to the program.\n");
|
||||||
|
System.err.println("In IntelliJ, you can provide arguments to the program by opening the dialog,");
|
||||||
|
System.err.println("\"Run > Edit Configurations\" and filling in the \"program arguments\" box.");
|
||||||
|
System.err.println("See the README for a documentation of the expected arguments.");
|
||||||
|
System.err.println();
|
||||||
parser.handleError(e);
|
parser.handleError(e);
|
||||||
System.exit(1);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintStream output = System.out;
|
PrintStream output = System.out;
|
||||||
|
|
||||||
|
// convert the timeout from seconds to milliseconds.
|
||||||
long solveTimeMs = ns.getLong("timeout") * 1000;
|
long solveTimeMs = ns.getLong("timeout") * 1000;
|
||||||
|
|
||||||
|
// Get the list of solvers that we should benchmark.
|
||||||
|
// We also check that we have a solver available for the given name and print an error message otherwise.
|
||||||
List<String> solversToTest = ns.getList("solver");
|
List<String> solversToTest = ns.getList("solver");
|
||||||
for(String solverName : solversToTest) {
|
for(String solverName : solversToTest) {
|
||||||
if(!solvers.containsKey(solverName)) {
|
if(!solvers.containsKey(solverName)) {
|
||||||
System.err.println("ERROR: Solver \"" + solverName + "\" is not avalaible.");
|
System.err.println("ERROR: Solver \"" + solverName + "\" is not avalaible.");
|
||||||
System.err.println(" Available solvers: " + solvers.keySet().toString());
|
System.err.println(" Available solvers: " + solvers.keySet().toString());
|
||||||
System.err.println(" You can provide your own solvers by adding them to the `Main.solvers` HashMap.");
|
System.err.println(" You can provide your own solvers by adding them to the `Main.solvers` HashMap.");
|
||||||
System.exit(1);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<String> instancePrefixes = ns.getList("instance");
|
|
||||||
|
// retrieve all instances on which we should run the solvers.
|
||||||
List<String> instances = new ArrayList<>();
|
List<String> instances = new ArrayList<>();
|
||||||
|
List<String> instancePrefixes = ns.getList("instance");
|
||||||
for(String instancePrefix : instancePrefixes) {
|
for(String instancePrefix : instancePrefixes) {
|
||||||
List<String> matches = BestKnownResult.instancesMatching(instancePrefix);
|
List<String> matches = BestKnownResults.instancesMatching(instancePrefix);
|
||||||
if(matches.isEmpty()) {
|
if(matches.isEmpty()) {
|
||||||
System.err.println("ERROR: instance prefix \"" + instancePrefix + "\" does not match any instance.");
|
System.err.println("ERROR: instance prefix \"" + instancePrefix + "\" does not match any instance.");
|
||||||
System.err.println(" available instances: " + Arrays.toString(BestKnownResult.instances));
|
System.err.println(" available instances: " + Arrays.toString(BestKnownResults.instances));
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
instances.addAll(matches);
|
instances.addAll(matches);
|
||||||
}
|
}
|
||||||
|
|
||||||
float[] runtimes = new float[solversToTest.size()];
|
// average runtime of each solver
|
||||||
float[] distances = new float[solversToTest.size()];
|
float[] avg_runtimes = new float[solversToTest.size()];
|
||||||
|
// average distance to best known result for each solver
|
||||||
|
float[] avg_distances = new float[solversToTest.size()];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// header of the result table :
|
||||||
|
// - solver names (first line)
|
||||||
|
// - name of each column (second line)
|
||||||
output.print( " ");
|
output.print( " ");
|
||||||
for(String s : solversToTest)
|
for(String s : solversToTest)
|
||||||
output.printf("%-30s", s);
|
output.printf("%-30s", s);
|
||||||
|
@ -94,51 +113,62 @@ public class Main {
|
||||||
}
|
}
|
||||||
output.println();
|
output.println();
|
||||||
|
|
||||||
|
// for all instances, load it from f
|
||||||
for(String instanceName : instances) {
|
for(String instanceName : instances) {
|
||||||
int bestKnown = BestKnownResult.of(instanceName);
|
// get the best known result for this instance
|
||||||
|
int bestKnown = BestKnownResults.of(instanceName);
|
||||||
|
|
||||||
|
// load instance from file.
|
||||||
Path path = Paths.get("instances/", instanceName);
|
Path path = Paths.get("instances/", instanceName);
|
||||||
Instance instance = Instance.fromFile(path);
|
Instance instance = Instance.fromFile(path);
|
||||||
|
|
||||||
|
// print some general statistics on the instance
|
||||||
output.printf("%-8s %-5s %4d ",instanceName, instance.numJobs +"x"+instance.numTasks, bestKnown);
|
output.printf("%-8s %-5s %4d ",instanceName, instance.numJobs +"x"+instance.numTasks, bestKnown);
|
||||||
|
|
||||||
|
// run all selected solvers on the instance and print the results
|
||||||
for(int solverId = 0 ; solverId < solversToTest.size() ; solverId++) {
|
for(int solverId = 0 ; solverId < solversToTest.size() ; solverId++) {
|
||||||
|
// Select the next solver to run. Given the solver name passed on the command line,
|
||||||
|
// we lookup the `Main.solvers` hash map to get the solver object with the given name.
|
||||||
String solverName = solversToTest.get(solverId);
|
String solverName = solversToTest.get(solverId);
|
||||||
Solver solver = solvers.get(solverName);
|
Solver solver = solvers.get(solverName);
|
||||||
|
|
||||||
|
// start chronometer and compute deadline for the solver to provide a result.
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
long deadline = System.currentTimeMillis() + solveTimeMs;
|
long deadline = System.currentTimeMillis() + solveTimeMs;
|
||||||
|
// run the solver on the current instance
|
||||||
Result result = solver.solve(instance, deadline);
|
Result result = solver.solve(instance, deadline);
|
||||||
|
// measure elapsed time (in milliseconds)
|
||||||
long runtime = System.currentTimeMillis() - start;
|
long runtime = System.currentTimeMillis() - start;
|
||||||
|
|
||||||
|
// check that the solver returned a valid solution
|
||||||
if(!result.schedule.isValid()) {
|
if(!result.schedule.isValid()) {
|
||||||
System.err.println("ERROR: solver returned an invalid schedule");
|
System.err.println("ERROR: solver returned an invalid schedule");
|
||||||
System.exit(1);
|
System.exit(1); // bug in implementation, bail out
|
||||||
}
|
}
|
||||||
|
|
||||||
assert result.schedule.isValid();
|
// compute some statistics on the solution and print them.
|
||||||
int makespan = result.schedule.makespan();
|
int makespan = result.schedule.makespan();
|
||||||
float dist = 100f * (makespan - bestKnown) / (float) bestKnown;
|
float dist = 100f * (makespan - bestKnown) / (float) bestKnown;
|
||||||
runtimes[solverId] += (float) runtime / (float) instances.size();
|
avg_runtimes[solverId] += (float) runtime / (float) instances.size();
|
||||||
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);
|
||||||
output.flush();
|
output.flush();
|
||||||
}
|
}
|
||||||
output.println();
|
output.println();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// we have finished all benchmarks, compute the average solve time and distance of each solver.
|
||||||
output.printf("%-8s %-5s %4s ", "AVG", "-", "-");
|
output.printf("%-8s %-5s %4s ", "AVG", "-", "-");
|
||||||
for(int solverId = 0 ; solverId < solversToTest.size() ; solverId++) {
|
for(int solverId = 0 ; solverId < solversToTest.size() ; solverId++) {
|
||||||
output.printf("%7.1f %8s %5.1f ", runtimes[solverId], "-", distances[solverId]);
|
output.printf("%7.1f %8s %5.1f ", avg_runtimes[solverId], "-", avg_distances[solverId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
// there was uncought exception, print the stack trace and exit with error.
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class ResourceOrder extends Encoding {
|
||||||
for(int m = 0 ; m<schedule.pb.numMachines ; m++) {
|
for(int m = 0 ; m<schedule.pb.numMachines ; m++) {
|
||||||
final int machine = m;
|
final int machine = m;
|
||||||
|
|
||||||
// for thi machine, find all tasks that are executed on it and sort them by their start time
|
// for this machine, find all tasks that are executed on it and sort them by their start time
|
||||||
tasksByMachine[m] =
|
tasksByMachine[m] =
|
||||||
IntStream.range(0, pb.numJobs) // all job numbers
|
IntStream.range(0, pb.numJobs) // all job numbers
|
||||||
.mapToObj(j -> new Task(j, pb.task_with_machine(j, machine))) // all tasks on this machine (one per job)
|
.mapToObj(j -> new Task(j, pb.task_with_machine(j, machine))) // all tasks on this machine (one per job)
|
||||||
|
|
|
@ -2,10 +2,10 @@ package jobshop.encodings;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/** Represents a task (job,task) of an jobshop problem.
|
/** Represents a task (job,task) of a jobshop problem.
|
||||||
*
|
*
|
||||||
* Example : (2, 3) repesents the fourth task of the third job. (remeber that we tart counting at 0)
|
* Example : (2, 3) represents the fourth task of the third job. (remember that we start counting at 0)
|
||||||
* */
|
**/
|
||||||
public final class Task {
|
public final class Task {
|
||||||
|
|
||||||
/** Identifier of the job */
|
/** Identifier of the job */
|
||||||
|
|
Loading…
Reference in a new issue