No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Main.java 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package jobshop;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.io.PrintStream;
  6. import java.nio.file.Path;
  7. import java.nio.file.Paths;
  8. import java.util.ArrayList;
  9. import java.util.Arrays;
  10. import java.util.List;
  11. import java.util.stream.Collectors;
  12. import jobshop.encodings.Schedule;
  13. import jobshop.solvers.*;
  14. import net.sourceforge.argparse4j.ArgumentParsers;
  15. import net.sourceforge.argparse4j.inf.ArgumentParser;
  16. import net.sourceforge.argparse4j.inf.ArgumentParserException;
  17. import net.sourceforge.argparse4j.inf.Namespace;
  18. /**
  19. * This class is the main entry point for doing comparative performance tests of solvers.
  20. */
  21. public class Main {
  22. public static void main(String[] args) {
  23. boolean csv = true;
  24. // configure the argument parser
  25. ArgumentParser parser = ArgumentParsers.newFor("jsp-solver").build()
  26. .defaultHelp(true)
  27. .description("Solves jobshop problems.");
  28. parser.addArgument("-t", "--timeout")
  29. .setDefault(1L)
  30. .type(Long.class)
  31. .help("Solver timeout in seconds for each instance. Default is 1 second.");
  32. parser.addArgument("--solver")
  33. .nargs("+")
  34. .required(true)
  35. .help("Solver(s) to use (space separated if more than one)");
  36. parser.addArgument("--instance")
  37. .nargs("+")
  38. .required(true)
  39. .help("Instance(s) to solve (space separated if more than one). All instances starting with the given " +
  40. "string will be selected. (e.g. \"ft\" will select the instances ft06, ft10 and ft20.");
  41. parser.addArgument("--iterMax")
  42. .type(Integer.class)
  43. .setDefault(100)
  44. .help("Iteration max le taboo");
  45. parser.addArgument("--pts")
  46. .type(Integer.class)
  47. .setDefault(20)
  48. .help("Nombre de points sur la méthode taboo");
  49. // parse command line arguments
  50. Namespace ns = null;
  51. try {
  52. ns = parser.parseArgs(args);
  53. } catch (ArgumentParserException e) {
  54. // error while parsing arguments, provide helpful error message and exit.
  55. System.err.println("Invalid arguments provided to the program.\n");
  56. System.err.println("In IntelliJ, you can provide arguments to the program by opening the dialog,");
  57. System.err.println("\"Run > Edit Configurations\" and filling in the \"program arguments\" box.");
  58. System.err.println("See the README for a documentation of the expected arguments.");
  59. System.err.println();
  60. parser.handleError(e);
  61. System.exit(0);
  62. }
  63. File file = new File("data_" + String.join("-",ns.getList("instance")) + "_instances_" + ns.getInt("iterMax") + "_iters_" + ns.getInt("pts") + "_pts.csv");
  64. try {
  65. file.createNewFile();
  66. } catch (IOException e) {
  67. e.printStackTrace();
  68. }
  69. PrintStream output = null;
  70. if (csv) {
  71. try {
  72. output = new PrintStream(file);
  73. } catch (FileNotFoundException e) {
  74. e.printStackTrace();
  75. }
  76. } else {
  77. output = System.out;
  78. }
  79. // convert the timeout from seconds to milliseconds.
  80. long solveTimeMs = ns.getLong("timeout") * 1000 * 1000;
  81. // Get the list of solvers that we should benchmark.
  82. // We also check that we have a solver available for the given name and print an error message otherwise.
  83. List<String> solversToTest = ns.getList("solver");
  84. List<Solver> solvers = solversToTest.stream().map(Solver::getSolver).collect(Collectors.toList());
  85. // retrieve all instances on which we should run the solvers.
  86. List<String> instances = new ArrayList<>();
  87. List<String> instancePrefixes = ns.getList("instance");
  88. for(String instancePrefix : instancePrefixes) {
  89. List<String> matches = BestKnownResults.instancesMatching(instancePrefix);
  90. if(matches.isEmpty()) {
  91. System.err.println("ERROR: instance prefix \"" + instancePrefix + "\" does not match any instance.");
  92. System.err.println(" available instances: " + Arrays.toString(BestKnownResults.instances));
  93. System.exit(1);
  94. }
  95. instances.addAll(matches);
  96. }
  97. float[][] avg_distances = new float[solversToTest.size()][ns.getInt("pts")];
  98. float[][] avg_voisins = new float[solversToTest.size()][ns.getInt("pts")];
  99. int i;
  100. for (i=0; i<solversToTest.size(); i++) {
  101. int j;
  102. for (j=0; j<ns.getInt("pts"); j++) {
  103. avg_distances[i][j] = 0;
  104. avg_voisins[i][j] = 0;
  105. }
  106. }
  107. if (csv) {
  108. try {
  109. output.print("iterMax;");
  110. for (String s : solversToTest)
  111. output.printf("%s;;", s);
  112. output.println();
  113. for (String s : solversToTest) {
  114. output.print(";ecart;voisins");
  115. }
  116. output.println();
  117. for (int solverId = 0; solverId < solvers.size(); solverId++) {
  118. System.out.println("Solver : " + solversToTest.get(solverId));
  119. Solver solver = solvers.get(solverId);
  120. solver.setIterMax(ns.getInt("iterMax"));
  121. solver.setpts(ns.getInt("pts"));
  122. //Table des resultats
  123. ArrayList<ArrayList<Result>> table = new ArrayList<>();
  124. int[] bestKnownResults = new int[instances.size()];
  125. int index = 0;
  126. for (String instanceName : instances) {
  127. // get the best known result for this instance
  128. bestKnownResults[index] = BestKnownResults.of(instanceName);
  129. index++;
  130. // load instance from file.
  131. Path path = Paths.get("instances/", instanceName);
  132. Instance instance = Instance.fromFile(path);
  133. long deadline = System.currentTimeMillis() + solveTimeMs;
  134. // run the solver on the current instance
  135. table.add(solver.solve(instance, deadline));
  136. }
  137. int k;
  138. for (k=0; k<ns.getInt("pts"); k++) {
  139. int numInstance;
  140. for (numInstance=0; numInstance<instances.size(); numInstance++) {
  141. // check that the solver returned a valid solution
  142. if (table.get(numInstance).get(k).schedule.isEmpty() || !table.get(numInstance).get(k).schedule.get().isValid()) {
  143. System.err.println("ERROR: solver returned an invalid schedule");
  144. System.exit(1); // bug in implementation, bail out
  145. }
  146. // we have a valid schedule
  147. Schedule schedule = table.get(numInstance).get(k).schedule.get();
  148. // compute some statistics on the solution and print them.
  149. int makespan = schedule.makespan();
  150. float dist = 100f * (makespan - bestKnownResults[numInstance]) / (float) bestKnownResults[numInstance];
  151. avg_distances[solverId][k] += dist / (float) instances.size();
  152. avg_voisins[solverId][k] += (float) table.get(numInstance).get(k).getVoisinsVisites() / (float) instances.size();
  153. }
  154. }
  155. }
  156. // we have finished all benchmarks, compute the average solve time and distance of each solver.
  157. for (int k = 0; k<ns.getInt("pts"); k++) {
  158. output.printf("%d;", (k+1) * (ns.getInt("iterMax") / ns.getInt("pts")));
  159. for (int solverId = 0; solverId < solversToTest.size(); solverId++) {
  160. output.printf("%.2f;%.2f;", avg_distances[solverId][k], avg_voisins[solverId][k]);
  161. }
  162. output.println();
  163. output.flush();
  164. }
  165. output.println();
  166. output.flush();
  167. } catch (Exception e) {
  168. // there was uncaught exception, print the stack trace and exit with error.
  169. e.printStackTrace();
  170. System.exit(1);
  171. }
  172. }
  173. }
  174. }