diff --git a/src/inport/ConversionUtils/MZnFormat.java b/src/inport/ConversionUtils/MZnFormat.java index 5d3398e290a4627f8eb5baffa0e1eadf2c6af772..6dd2072c98bc76fe5ffab193956516abb7b8779d 100644 --- a/src/inport/ConversionUtils/MZnFormat.java +++ b/src/inport/ConversionUtils/MZnFormat.java @@ -6,23 +6,35 @@ import java.util.*; import java.util.function.Function; public class MZnFormat { + static public String strBoolToStrInt(String val) { + if (val.equals("true")) { + return "1"; + } + if (val.equals("false")) { + return "0"; + } + return val; + } static public void write2DArrayOfInt(FileWriter writer, String name, - ArrayList> operations) throws IOException { - locWrite2DArray(writer, name, operations, Object::toString, false); + ArrayList> operations, + Task.ConversionFormat format) throws IOException { + locWrite2DArray(writer, name, operations, Object::toString, false, format); } static public void write2DArrayOfInt(FileWriter writer, String name, ArrayList> operations, - boolean isNumberedFromZero) throws IOException { - locWrite2DArray(writer, name, operations, Object::toString, isNumberedFromZero); + boolean isNumberedFromZero, + Task.ConversionFormat format) throws IOException { + locWrite2DArray(writer, name, operations, Object::toString, isNumberedFromZero, format); } static public void write2DArrayOfSet(FileWriter writer, String name, - ArrayList>> operations) throws IOException { + ArrayList>> operations, + Task.ConversionFormat format) throws IOException { locWrite2DArray(writer, name, operations, (ArrayList a) -> { StringBuilder s = new StringBuilder(); @@ -38,15 +50,17 @@ public class MZnFormat { } s.append('}'); return s.toString(); - } + }, + format ); } static public void locWrite2DArray(FileWriter writer, String name, ArrayList> operations, - Function toMZNFormat) throws IOException { - locWrite2DArray(writer, name, operations, toMZNFormat, false); + Function toMZNFormat, + Task.ConversionFormat format) throws IOException { + locWrite2DArray(writer, name, operations, toMZNFormat, false, format); } static public int boolToInt(boolean b) { @@ -57,8 +71,35 @@ public class MZnFormat { String name, ArrayList> operations, Function toMZNFormat, - boolean isNumberedFromZero) throws IOException { + boolean isNumberedFromZero, + Task.ConversionFormat format) throws IOException { + if (format == Task.ConversionFormat.OPL) { + writer.write(name + " = ["); + + boolean isFirstArr = true; + for (ArrayList a : operations) { + if (isFirstArr) { + isFirstArr = false; + } else { + writer.write(", "); + } + writer.write("["); + + boolean isFirst = true; + for (T val : a) { + if (isFirst) { + isFirst = false; + } else { + writer.write(", "); + } + writer.write(strBoolToStrInt(toMZNFormat.apply(val))); + } + writer.write("]"); + } + writer.write("];\n"); + return; + } writer.write(name + " = array2d(" + (isNumberedFromZero ? 0 : 1) + ".." + (operations.size() - boolToInt(isNumberedFromZero)) + ", " + (isNumberedFromZero ? 0 : 1) + ".." + (operations.get(0).size() - boolToInt(isNumberedFromZero)) + ", ["); @@ -80,14 +121,16 @@ public class MZnFormat { static public > void write2DArrayOfSetAs3DArray(FileWriter writer, String name, - ArrayList> operations) throws IOException { - write2DArrayOfSetAs3DArray(writer, name, operations, false); + ArrayList> operations, + Task.ConversionFormat format) throws IOException { + write2DArrayOfSetAs3DArray(writer, name, operations, false, format); } static public > void write2DArrayOfSetAs3DArray(FileWriter writer, String name, ArrayList> operations, - boolean isNumberedFromZero) throws IOException { + boolean isNumberedFromZero, + Task.ConversionFormat format) throws IOException { int maxSize = 0; ArrayList> sizes = new ArrayList<>(); @@ -104,7 +147,53 @@ public class MZnFormat { sizes.add(locSizes); } writer.write(name + "_max_size = " + maxSize + ";\n"); - write2DArrayOfInt(writer, name + "_sizes", sizes, true); + write2DArrayOfInt(writer, name + "_sizes", sizes, true, format); + + if (format == Task.ConversionFormat.OPL) { + writer.write(name + " = ["); + boolean isFirst = true; + for (ArrayList a1 : operations) { + if (isFirst) { + isFirst = false; + } else { + writer.write(", "); + } + writer.write("["); + boolean isFirst2 = true; + + for (T a2 : a1) { + if (isFirst2) { + isFirst2 = false; + } else { + writer.write(", "); + } + writer.write("["); + + boolean isFirst3 = true; + + for (Integer val : a2) { + if (isFirst3) { + isFirst3 = false; + } else { + writer.write(", "); + } + writer.write(Integer.toString(val)); + } + for (int i = a2.size(); i < maxSize; i++) { + if (isFirst3) { + isFirst3 = false; + } else { + writer.write(", "); + } + writer.write(Integer.toString(0)); + } + writer.write("]"); + } + writer.write("]"); + } + writer.write("];\n"); + return; + } { String firstEl = Integer.toString(isNumberedFromZero ? 0 : 1); @@ -132,7 +221,7 @@ public class MZnFormat { } else { writer.write(", "); } - writer.write(Integer.toString(1)); + writer.write(Integer.toString(0)); } } } @@ -142,11 +231,43 @@ public class MZnFormat { static public void write3dArray(FileWriter writer, String name, ArrayList>> array, - Function toString) throws IOException { + Function toString, + Task.ConversionFormat format) throws IOException { int dim1 = array.size(); int dim2 = (dim1 > 0) ? array.get(0).size() : 0; int dim3 = (dim2 > 0) ? array.get(0).get(0).size() : 0; + if (format == Task.ConversionFormat.OPL) { + Function lToString = (T val) -> strBoolToStrInt(toString.apply(val)); + + writer.write(name + " = ["); + + boolean isFirst = true; + + for (ArrayList> a2 : array) { + if (isFirst) { + isFirst = false; + } else { + writer.write(", "); + } + boolean isFirst2 = true; + + writer.write("["); + + for (ArrayList a1 : a2) { + if (isFirst2) { + isFirst2 = false; + } else { + writer.write(", "); + } + writer.write("[" + String.join(", ", Utils.map(a1, lToString)) + "]"); + } + writer.write("]"); + } + writer.write("];\n"); + return; + } + writer.write(name + " = array3d(1.." + dim1 + ", 1.." + dim2 + ", 1.." + dim3 + ", "); ArrayList values = new ArrayList<>(); for (ArrayList> a2 : array) { @@ -161,15 +282,17 @@ public class MZnFormat { static public void writeArrayOfSetAs2DArray(FileWriter writer, String name, - ArrayList> operations) throws IOException { - writeArrayOfSetAs2DArray(writer, name, operations, true, false); + ArrayList> operations, + Task.ConversionFormat format) throws IOException { + writeArrayOfSetAs2DArray(writer, name, operations, true, false, format); } static public void writeArrayOfSetAs2DArray(FileWriter writer, String name, ArrayList> operations, boolean addAdditionalInfo, - boolean addDummyZeroElement) throws IOException { + boolean addDummyZeroElement, + Task.ConversionFormat format) throws IOException { int maxSize = 0; ArrayList sizes = new ArrayList<>(); for (ArrayList s : operations) { @@ -178,7 +301,7 @@ public class MZnFormat { } if (addAdditionalInfo) { writer.write(name + "_max_size = " + maxSize + ";\n"); - writeArray(writer, name + "_sizes", sizes); + writeArray(writer, name + "_sizes", sizes, format); } writer.write(name + " = array2d(1.." + operations.size() + ", " + (addDummyZeroElement ? "0" : "1") + ".." + maxSize + ", ["); @@ -213,10 +336,29 @@ public class MZnFormat { } static public void writeArray(FileWriter writer, - String name, - ArrayList data, - Function f, - Optional dummyZeroElement) throws IOException { + String name, + ArrayList data, + Function f, + Optional dummyZeroElement, + Task.ConversionFormat format) throws IOException { + if (format == Task.ConversionFormat.OPL) { + writer.write(name + " = ["); + boolean isFirst = true; + if (dummyZeroElement.isPresent()) { + isFirst = false; + writer.write(strBoolToStrInt(f.apply(dummyZeroElement.get()).toString())); + } + for (int i = 0; i < data.size(); i++) { + if (isFirst) { + isFirst = false; + } else { + writer.write(", "); + } + writer.write(strBoolToStrInt(f.apply(data.get(i)).toString())); + } + writer.write("];\n"); + return; + } writer.write(name + " = array1d(" + (dummyZeroElement.isPresent() ? 0 : 1) + ".." + data.size() + ", ["); boolean isFirst = true; if (dummyZeroElement.isPresent()) { @@ -234,22 +376,24 @@ public class MZnFormat { writer.write("]);\n"); } - static public void writeArray(FileWriter writer, String name, ArrayList data) throws IOException { - writeArray(writer, name, data, (T val) -> val, Optional.empty()); + static public void writeArray(FileWriter writer, String name, ArrayList data, Task.ConversionFormat format) throws IOException { + writeArray(writer, name, data, (T val) -> val, Optional.empty(), format); } static public void writeArray(FileWriter writer, String name, ArrayList data, - Function f) throws IOException { - writeArray(writer, name, data, f, Optional.empty()); + Function f, + Task.ConversionFormat format) throws IOException { + writeArray(writer, name, data, f, Optional.empty(), format); } - static public void writeArray(FileWriter writer, + static public void writeArray(FileWriter writer, String name, ArrayList data, - Optional dummyZeroElement) throws IOException { - writeArray(writer, name, data, (T val) -> val, dummyZeroElement); + Optional dummyZeroElement, + Task.ConversionFormat format) throws IOException { + writeArray(writer, name, data, (T val) -> val, dummyZeroElement, format); } static public String setToString(Set s) { diff --git a/src/inport/ConversionUtils/MZnResultsResolver.java b/src/inport/ConversionUtils/MZnResultsResolver.java index 536414f7dcef2425ac2b3a79a47383d2cf7b716a..b099f4f16f49498901e4a9f43b2be53917a6518b 100644 --- a/src/inport/ConversionUtils/MZnResultsResolver.java +++ b/src/inport/ConversionUtils/MZnResultsResolver.java @@ -20,6 +20,31 @@ public class MZnResultsResolver { public static ArrayList> parse2dArray(int pos, String line, TaskCase taskCase) { int index = line.indexOf("array", pos); + if (line.indexOf("[[", pos) != -1) { // Из opl. + if (line.contains("[[[")) { + return null; + } + index = line.indexOf("[[", pos); + + index++; + + ArrayList> res = new ArrayList<>(); + + while (true) { + int i1 = line.indexOf("[", index); + int i2 = line.indexOf("]", index); + + if (i1 == -1) { + break; + } + res.add(new ArrayList<>()); + for (String val : line.substring(i1 + 1, i2).split(" ")) { + res.get(res.size() - 1).add(val.trim()); + } + index = i2 + 1; + } + return res; + } if (index >= pos) { // Из flatzinc-а. if (line.charAt(index + "array".length()) == '2') { String[] values = line.substring(line.indexOf('[') + 1, line.indexOf(']')).split(","); @@ -97,12 +122,29 @@ public class MZnResultsResolver { try (FileInputStream fstream = new FileInputStream(fileName)) { BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); - String line; - Map>> arrays = new TreeMap<>(); - while (((line = br.readLine()) != null)) { + ArrayList lines = new ArrayList<>(); + + { + StringBuilder stringBuilder = new StringBuilder(); + String line; + while (((line = br.readLine()) != null)) { + + if ((line.length() > 0) && (line.charAt(0) == ' ')) { + stringBuilder.append(line); + } else { + lines.add(stringBuilder.toString()); + stringBuilder = new StringBuilder(line); + } + } + lines.add(stringBuilder.toString()); + } + + for (String line : lines) { line = line.trim(); + + if (line.equals("")) { continue; } @@ -119,7 +161,7 @@ public class MZnResultsResolver { if (name.equals("----------")) { break; } - if (name.matches("\\d+")) { + if ((name.matches("\\d+")) || (name.equals("//"))) { continue; } { @@ -140,6 +182,16 @@ public class MZnResultsResolver { } } + for (ArrayList a : arrays.get("op_status")) { // Если op_status из opl. + for (int i = 0; i < a.size(); i++) { + if (a.get(i).trim().equals("0")) { + a.set(i, "false"); + } else if (a.get(i).trim().equals("1")) { + a.set(i, "true"); + } + } + } + if (result == null) { ArrayList> opStatus = arrays.get("op_status"); result = 0; diff --git a/src/inport/ConversionUtils/Solver.java b/src/inport/ConversionUtils/Solver.java index ece7ea00783a893cc3fc555c53357b0239aab32d..7323b02453d6a3324987cd6439fc214fe9782818 100644 --- a/src/inport/ConversionUtils/Solver.java +++ b/src/inport/ConversionUtils/Solver.java @@ -37,17 +37,30 @@ public class Solver { private final Condition condition = lock.newCondition(); private Boolean isDestroyed; + private Task.ConversionFormat conversionFormat = Task.ConversionFormat.MiniZinc; + public Task.ConversionFormat getConversionFormat() { + return conversionFormat; + } + public void setConversionFormat(Task.ConversionFormat conversionFormat) { + this.conversionFormat = conversionFormat; + } + private TaskCase task; - private final String constraintName; - private final BiConsumer converterToMiniZincFormat; + + private String constraintName; + private final Utils.TriConsumer converterToMiniZincFormat; private final BiConsumer interpreter; private String tempDir = "temp_data"; private int timeLimitS; private String flatZincSolver = ""; + private String oplSolver = ""; private SolverName solverName = SolverName.Undefined; private String solverResults = ""; + public void setConstraintName(String constraintName) { + this.constraintName = constraintName; + } public void setSolverResults(String solverResults) { this.solverResults = solverResults; } @@ -63,6 +76,9 @@ public class Solver { public void setFlatZincSolver(String flatZincSolver) { this.flatZincSolver = flatZincSolver; } + public void setOPLSolver(String oplSolver) { + this.oplSolver = oplSolver; + } public void setSolverName(String solverName) { this.solverName = SolverName.fromString(solverName); } @@ -70,7 +86,7 @@ public class Solver { public String getFlatZincSolver() { return flatZincSolver; } - public BiConsumer getConverterToMiniZincFormat() { + public Utils.TriConsumer getConverterToMiniZincFormat() { return converterToMiniZincFormat; } public String getConstraintName() { @@ -78,7 +94,7 @@ public class Solver { } public Solver(String constraintName, - BiConsumer converterToMiniZincFormat, + Utils.TriConsumer converterToMiniZincFormat, BiConsumer interpreter) { this.constraintName = constraintName; this.converterToMiniZincFormat = converterToMiniZincFormat; @@ -127,7 +143,7 @@ public class Solver { res.write(line + "\n"); } } - converterToMiniZincFormat.accept(task, minizincData); + converterToMiniZincFormat.accept(task, minizincData, conversionFormat); ProcessBuilder pb; boolean isResultsInOutput; @@ -145,26 +161,30 @@ public class Solver { break; } case Undefined: { - if (flatZincSolver.isEmpty()) { - return "FlatZinc solver not defined!"; - } - isResultsInOutput = true; - { - ProcessBuilder lPB = new ProcessBuilder("mzn2fzn", "-o", flatZincConstraints, - constraints, minizincData); - Process process = lPB.start(); - process.waitFor(); - - BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); - String output = br.lines().collect(Collectors.joining("\n")); - - if (output.trim().equals("=====UNSATISFIABLE=====")) { - task.setSolution(new ArrayList<>()); - task.setSolution_result(-1); - return ""; + if (! flatZincSolver.isEmpty()) { + isResultsInOutput = true; + { + ProcessBuilder lPB = new ProcessBuilder("mzn2fzn", "-o", flatZincConstraints, + constraints, minizincData); + Process process = lPB.start(); + process.waitFor(); + + BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); + String output = br.lines().collect(Collectors.joining("\n")); + + if (output.trim().equals("=====UNSATISFIABLE=====")) { + task.setSolution(new ArrayList<>()); + task.setSolution_result(-1); + return ""; + } } + solverProcess = new ProcessBuilder(flatZincSolver, flatZincConstraints).start(); + } else if (! oplSolver.isEmpty()) { + isResultsInOutput = true; + solverProcess = new ProcessBuilder(oplSolver, constraints, minizincData).start(); + } else { + return "Solver not defined!"; } - solverProcess = new ProcessBuilder(flatZincSolver, flatZincConstraints).start(); break; } default: @@ -223,6 +243,14 @@ public class Solver { } if (isResultsInOutput) { + if (! oplSolver.isEmpty()) { + if (output.contains("<<< no solution")) { + task.setSolution(new ArrayList<>()); + task.setSolution_result(-1); + return ""; + } + output = output.substring(output.indexOf("<<< solve") + "<<< solve".length(), output.indexOf("<<< post process")); + } try (FileWriter res = new FileWriter(solverResults)) { for (byte b : output.getBytes("UTF8")) { res.write(b); diff --git a/src/inport/ConversionUtils/Task.java b/src/inport/ConversionUtils/Task.java index def6fded784906012fb7c7f2cd7b5e2861c49110..58ded1be205ba80431b6d812cc1502ebf872261a 100644 --- a/src/inport/ConversionUtils/Task.java +++ b/src/inport/ConversionUtils/Task.java @@ -8,11 +8,23 @@ import java.io.UncheckedIOException; import java.util.*; import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; -import static inport.ConversionUtils.MZnFormat.*; +import inport.ConversionUtils.MZnFormat.*; import static inport.ConversionUtils.Utils.*; public class Task { + public enum ConversionFormat { + MiniZinc, + OPL + } + + private ConversionFormat format = ConversionFormat.MiniZinc; + + public void setConversionFormat(ConversionFormat format) { + this.format = format; + } + private FileWriter writer = null; private final String fileName; private final TaskCase task; @@ -105,7 +117,103 @@ public class Task { private final ArrayList finalStorageVol; private final ArrayList maxStorageVol; + public void write2DArrayOfInt(FileWriter writer, + String name, + ArrayList> operations) throws IOException { + MZnFormat.write2DArrayOfInt(writer, name, operations, format); + } + + public void write2DArrayOfInt(FileWriter writer, + String name, + ArrayList> operations, + boolean isNumberedFromZero) throws IOException { + MZnFormat.write2DArrayOfInt(writer, name, operations, isNumberedFromZero, format); + } + + public void write2DArrayOfSet(FileWriter writer, + String name, + ArrayList>> operations) throws IOException { + MZnFormat.write2DArrayOfSet(writer, name, operations, format); + } + + + public void locWrite2DArray(FileWriter writer, + String name, + ArrayList> operations, + Function toMZNFormat) throws IOException { + MZnFormat.locWrite2DArray(writer, name, operations, toMZNFormat, format); + } + + public void locWrite2DArray(FileWriter writer, + String name, + ArrayList> operations, + Function toMZNFormat, + boolean isNumberedFromZero) throws IOException { + MZnFormat.locWrite2DArray(writer, name, operations, toMZNFormat, isNumberedFromZero, format); + } + + + public void writeArrayOfSetAs2DArray(FileWriter writer, + String name, + ArrayList> operations) throws IOException { + MZnFormat.writeArrayOfSetAs2DArray(writer, name, operations, true, false, format); + } + + public void writeArrayOfSetAs2DArray(FileWriter writer, + String name, + ArrayList> operations, + boolean addAdditionalInfo, + boolean addDummyZeroElement) throws IOException { + MZnFormat.writeArrayOfSetAs2DArray(writer, name, operations, addAdditionalInfo, addDummyZeroElement, format); + } + + public void writeArray(FileWriter writer, + String name, + ArrayList data, + Function f, + Optional dummyZeroElement) throws IOException { + MZnFormat.writeArray(writer, name, data, f, dummyZeroElement, format); + } + + public void writeArray(FileWriter writer, String name, ArrayList data) throws IOException { + MZnFormat.writeArray(writer, name, data, format); + } + + public void writeArray(FileWriter writer, + String name, + ArrayList data, + Function f) throws IOException { + MZnFormat.writeArray(writer, name, data, f, format); + } + + public void writeArray(FileWriter writer, + String name, + ArrayList data, + Optional dummyZeroElement) throws IOException { + MZnFormat.writeArray(writer, name, data, dummyZeroElement, format); + } + + + public > void write2DArrayOfSetAs3DArray(FileWriter writer, + String name, + ArrayList> operations) throws IOException { + MZnFormat.write2DArrayOfSetAs3DArray(writer, name, operations, format); + } + + public > void write2DArrayOfSetAs3DArray(FileWriter writer, + String name, + ArrayList> operations, + boolean isNumberedFromZero) throws IOException { + MZnFormat.write2DArrayOfSetAs3DArray(writer, name, operations, isNumberedFromZero, format); + } + + public Task(TaskCase task, String fileName) { + this(task, fileName, ConversionFormat.MiniZinc); + } + + public Task(TaskCase task, String fileName, ConversionFormat format) { + this.format = format; this.fileName = fileName; this.task = task; @@ -1140,7 +1248,7 @@ public class Task { locWrite2DArray(writer, "is_fixed", getIsFixedArray(), Objects::toString, true); locWrite2DArray(writer, "is_obj_involved_in_fixed_op", is_obj_involved_in_fixed_op, Objects::toString, true); - write3dArray(writer, "is_fixed_op_planned_in_future", is_fixed_op_planned_in_future, Objects::toString); + MZnFormat.write3dArray(writer, "is_fixed_op_planned_in_future", is_fixed_op_planned_in_future, Objects::toString, format); } void defDataForCurMovingOp() throws IOException { @@ -1550,27 +1658,52 @@ public class Task { static public void portToMiniZinc_0(TaskCase task, String fileName) { startConversion(task, fileName, Task::portToMiniZinc_0); } + static public void portToMiniZinc_1(TaskCase task, String fileName) { - startConversion(task, fileName, Task::portToMiniZinc_1); + portToMiniZinc_1(task, fileName, ConversionFormat.MiniZinc); + } + static public void portToMiniZinc_1(TaskCase task, String fileName, ConversionFormat format) { + startConversion(task, fileName, Task::portToMiniZinc_1, format); } + static public void portToMiniZinc_2(TaskCase task, String fileName) { - startConversion(task, fileName, Task::portToMiniZinc_2_inSep); + portToMiniZinc_2(task, fileName, ConversionFormat.MiniZinc); } + static public void portToMiniZinc_2(TaskCase task, String fileName, ConversionFormat format) { + startConversion(task, fileName, Task::portToMiniZinc_2_inSep, format); + } + static public void portToMiniZinc_2_separable(TaskCase task, String fileName) { - startConversion(task, fileName, Task::portToMiniZinc_2_sep); + portToMiniZinc_2_separable(task, fileName, ConversionFormat.MiniZinc); + } + static public void portToMiniZinc_2_separable(TaskCase task, String fileName, ConversionFormat format) { + startConversion(task, fileName, Task::portToMiniZinc_2_sep, format); } + static public void portToMiniZincGreedy(TaskCase task, String fileName) { - startConversion(task, fileName, Task::portToMiniZinc_2_greedy); + portToMiniZincGreedy(task, fileName, ConversionFormat.MiniZinc); + } + static public void portToMiniZincGreedy(TaskCase task, String fileName, ConversionFormat format) { + startConversion(task, fileName, Task::portToMiniZinc_2_greedy, format); } + static public void portToMiniZincGreedyV2(TaskCase task, String fileName) { - startConversion(task, fileName, Task::portToMiniZinc_2_greedy_v2); + portToMiniZincGreedyV2(task, fileName, ConversionFormat.MiniZinc); + } + static public void portToMiniZincGreedyV2(TaskCase task, String fileName, ConversionFormat format) { + startConversion(task, fileName, Task::portToMiniZinc_2_greedy_v2, format); } static private void startConversion(TaskCase task, String fileName, Consumer conversion) { + startConversion(task, fileName, conversion, ConversionFormat.MiniZinc); + } + + static private void startConversion(TaskCase task, String fileName, Consumer conversion, ConversionFormat format) { try { Task taskData = new Task(task, fileName); try { taskData.writer = new FileWriter(fileName, false); + taskData.format = format; conversion.accept(taskData); } finally { if (taskData.writer != null) { diff --git a/src/inport/ConversionUtils/Utils.java b/src/inport/ConversionUtils/Utils.java index 4ab62221f0b8903cb20e5d80e6207111c19ff0fd..1436b5e4234c36f18305c7328938627cb227eba5 100644 --- a/src/inport/ConversionUtils/Utils.java +++ b/src/inport/ConversionUtils/Utils.java @@ -5,6 +5,32 @@ import java.util.*; import java.util.function.Function; public class Utils { + @FunctionalInterface + public interface TriFunction { + + R apply(A a, B b, C c); + + default TriFunction andThen( + Function after) { + Objects.requireNonNull(after); + return (A a, B b, C c) -> after.apply(apply(a, b, c)); + } + } + + @FunctionalInterface + public interface TriConsumer { + void accept(A a, B b, C c); + + public default TriConsumer andThen(final TriConsumer after) { + Objects.requireNonNull(after); + return (A a, B b, C c) -> { + accept(a, b, c); + after.accept(a, b, c); + }; + } + } + + public static Collection map(Collection as, Function f) { Collection b; try { diff --git a/src/inport/Main.java b/src/inport/Main.java index 5820ad943c0e69db790600486c57654dc0138829..3598e5062a3684817f55002a8476de05fd056aa0 100644 --- a/src/inport/Main.java +++ b/src/inport/Main.java @@ -70,9 +70,12 @@ public class Main { private static void solve(Collection args) { try { class Arguments { - @Option(name = "-fzs", aliases = "--flat_zinc_solver", usage = "Path to executable of flatZinc solver.", forbids = {"-s"}) + @Option(name = "-fzs", aliases = "--flat_zinc_solver", usage = "Path to executable of flatZinc solver.", forbids = {"-s", "-opls"}) private String flatZincSolver = ""; + @Option(name = "-opls", aliases = "--opl_solver", usage = "Path to \"oplrun\" from CPLEX.", forbids = {"-s", "-fzs"}) + private String oplSolver = ""; + @Argument(usage = "Path to task.", required = true) private String pathToTask = ""; @@ -80,7 +83,7 @@ public class Main { private String conversionType = ConversionType.WithoutSplitting.text; @Option(name = "-s", aliases = "--solver", usage = "Solver from list : " + Solver.SolverName.legalValues + ".", - forbids = {"-fzs"}) + forbids = {"-fzs", "-opls"}) private String solverName = Solver.SolverName.Chuffed.text; } @@ -114,14 +117,19 @@ public class Main { solver.setTimeLimitS(DEFAULT_TIME_LIMIT_S); solver.setTempDir("temp_data"); - if (arguments.flatZincSolver.isEmpty()) { - solver.setSolverName(arguments.solverName); - } else { + if (! arguments.flatZincSolver.isEmpty()) { solver.setFlatZincSolver(arguments.flatZincSolver); + } else if (! arguments.oplSolver.isEmpty()) { + solver.setOPLSolver(arguments.oplSolver); + solver.setConstraintName(solver.getConstraintName().replace(".mzn", ".mod")); + solver.setConversionFormat(Task.ConversionFormat.OPL); + } else { + solver.setSolverName(arguments.solverName); } String error = solver.solve(); + long finish = System.currentTimeMillis(); System.out.println((finish - start) + " milliseconds"); @@ -173,7 +181,7 @@ public class Main { Solver solver = type.solversGetter.get(); - solver.getConverterToMiniZincFormat().accept(task, minizincData); + solver.getConverterToMiniZincFormat().accept(task, minizincData, solver.getConversionFormat()); try (FileWriter res = new FileWriter(constraints)) { BufferedReader reader = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream("/constraints/" + solver.getConstraintName()))); @@ -189,6 +197,58 @@ public class Main { } } + private static void tippToOpl(Collection args) { + try { + class Arguments { + @Argument(usage = "Path to task.", required = true) + private String pathToTask = ""; + + @Option(name = "-ct", usage = "Type of conversion, one of " + ConversionType.legalValues + ".") + private String conversionType = ConversionType.WithoutSplitting.text; + + @Option(name = "-o", usage = "Directory for results.") + private String outDir = "."; + } + + Arguments arguments = new Arguments(); + CmdLineParser parser = new CmdLineParser(arguments); + + if (args.isEmpty()) { + parser.printUsage(System.out); + return; + } + parser.parseArgument(args); + + ConversionType type = ConversionType.fromString(arguments.conversionType); + if (type.equals(ConversionType.Undefined)) { + System.out.println(undefinedTypeErrorMess(arguments.conversionType)); + return; + } + + TaskCase task = new TaskCase(); + task.deserialize(arguments.pathToTask); + + String constraints = arguments.outDir + "/conversion.mod"; + String minizincData = arguments.outDir + "/cplex_data.dat"; + + Solver solver = type.solversGetter.get(); + + solver.getConverterToMiniZincFormat().accept(task, minizincData, Task.ConversionFormat.OPL); + + try (FileWriter res = new FileWriter(constraints)) { + BufferedReader reader = new BufferedReader(new InputStreamReader(Main.class.getResourceAsStream("/constraints/" + solver.getConstraintName().replace(".mzn", ".mod")))); + String line; + while ((line = reader.readLine()) != null) { + res.write(line + "\n"); + } + } + } catch (CmdLineException ex) { + System.out.println("Illegal arguments: " + ex.getLocalizedMessage()); + } catch (IOException ex) { + System.out.println("Error : " + ex.getMessage()); + } + } + private static void debug(Collection args) { class Arguments { @Option(name = "-fzs", aliases = "--flat_zinc_solver", usage = "Path to executable of flatZinc solver.", forbids = {"-s"}) @@ -254,8 +314,7 @@ public class Main { task.deserialize(arguments.pathToTask); MZnResultsResolver.resolveMiniZincResults(task, arguments.pathToSolution); - - task.deserialize(arguments.pathToTask); + task.serialize(arguments.pathToTask); } catch (CmdLineException ex) { System.out.println("Illegal arguments: " + ex.getLocalizedMessage()); } catch (IOException ex) { @@ -320,6 +379,12 @@ public class Main { "Производит два файла - conversion.mzn и minizinc_data.dzn ." , Main::tippToMzn)); + mainCommands.put("tippToOpl", + new MainCommandsData( + false + , "Сводит задачу к формату OPL используя заданное сведение. " + , Main::tippToOpl)); + mainCommands.put("debug", new MainCommandsData(true, "", Main::debug)); mainCommands.put("resolve_results",