Commit 55a142e2 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Добавлена возможность работы с OPL.

parent f59dbfe1
This diff is collapsed.
......@@ -20,6 +20,31 @@ public class MZnResultsResolver {
public static ArrayList<ArrayList<String>> 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<ArrayList<String>> 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<String, ArrayList<ArrayList<String>>> arrays = new TreeMap<>();
ArrayList<String> 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<String> 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<ArrayList<String>> opStatus = arrays.get("op_status");
result = 0;
......
......@@ -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<TaskCase, String> converterToMiniZincFormat;
private String constraintName;
private final Utils.TriConsumer<TaskCase, String, Task.ConversionFormat> converterToMiniZincFormat;
private final BiConsumer<TaskCase, String> 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<TaskCase, String> getConverterToMiniZincFormat() {
public Utils.TriConsumer<TaskCase, String, Task.ConversionFormat> getConverterToMiniZincFormat() {
return converterToMiniZincFormat;
}
public String getConstraintName() {
......@@ -78,7 +94,7 @@ public class Solver {
}
public Solver(String constraintName,
BiConsumer<TaskCase, String> converterToMiniZincFormat,
Utils.TriConsumer<TaskCase, String, Task.ConversionFormat> converterToMiniZincFormat,
BiConsumer<TaskCase, String> 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,9 +161,7 @@ public class Solver {
break;
}
case Undefined: {
if (flatZincSolver.isEmpty()) {
return "FlatZinc solver not defined!";
}
if (! flatZincSolver.isEmpty()) {
isResultsInOutput = true;
{
ProcessBuilder lPB = new ProcessBuilder("mzn2fzn", "-o", flatZincConstraints,
......@@ -165,6 +179,12 @@ public class Solver {
}
}
solverProcess = new ProcessBuilder(flatZincSolver, flatZincConstraints).start();
} else if (! oplSolver.isEmpty()) {
isResultsInOutput = true;
solverProcess = new ProcessBuilder(oplSolver, constraints, minizincData).start();
} else {
return "Solver not defined!";
}
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);
......
......@@ -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<Integer> finalStorageVol;
private final ArrayList<Integer> maxStorageVol;
public void write2DArrayOfInt(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations) throws IOException {
MZnFormat.write2DArrayOfInt(writer, name, operations, format);
}
public void write2DArrayOfInt(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations,
boolean isNumberedFromZero) throws IOException {
MZnFormat.write2DArrayOfInt(writer, name, operations, isNumberedFromZero, format);
}
public void write2DArrayOfSet(FileWriter writer,
String name,
ArrayList<ArrayList<ArrayList<Integer>>> operations) throws IOException {
MZnFormat.write2DArrayOfSet(writer, name, operations, format);
}
public <T> void locWrite2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations,
Function<T, String> toMZNFormat) throws IOException {
MZnFormat.locWrite2DArray(writer, name, operations, toMZNFormat, format);
}
public <T> void locWrite2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations,
Function<T, String> toMZNFormat,
boolean isNumberedFromZero) throws IOException {
MZnFormat.locWrite2DArray(writer, name, operations, toMZNFormat, isNumberedFromZero, format);
}
public void writeArrayOfSetAs2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations) throws IOException {
MZnFormat.writeArrayOfSetAs2DArray(writer, name, operations, true, false, format);
}
public void writeArrayOfSetAs2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations,
boolean addAdditionalInfo,
boolean addDummyZeroElement) throws IOException {
MZnFormat.writeArrayOfSetAs2DArray(writer, name, operations, addAdditionalInfo, addDummyZeroElement, format);
}
public <T, E> void writeArray(FileWriter writer,
String name,
ArrayList<T> data,
Function<T, E> f,
Optional<T> dummyZeroElement) throws IOException {
MZnFormat.writeArray(writer, name, data, f, dummyZeroElement, format);
}
public <T> void writeArray(FileWriter writer, String name, ArrayList<T> data) throws IOException {
MZnFormat.writeArray(writer, name, data, format);
}
public <T, E> void writeArray(FileWriter writer,
String name,
ArrayList<T> data,
Function<T, E> f) throws IOException {
MZnFormat.writeArray(writer, name, data, f, format);
}
public <T> void writeArray(FileWriter writer,
String name,
ArrayList<T> data,
Optional<T> dummyZeroElement) throws IOException {
MZnFormat.writeArray(writer, name, data, dummyZeroElement, format);
}
public <T extends Collection<Integer>> void write2DArrayOfSetAs3DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations) throws IOException {
MZnFormat.write2DArrayOfSetAs3DArray(writer, name, operations, format);
}
public <T extends Collection<Integer>> void write2DArrayOfSetAs3DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> 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<Task> conversion) {
startConversion(task, fileName, conversion, ConversionFormat.MiniZinc);
}
static private void startConversion(TaskCase task, String fileName, Consumer<Task> 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) {
......
......@@ -5,6 +5,32 @@ import java.util.*;
import java.util.function.Function;
public class Utils {
@FunctionalInterface
public interface TriFunction<A,B,C,R> {
R apply(A a, B b, C c);
default <V> TriFunction<A, B, C, V> andThen(
Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (A a, B b, C c) -> after.apply(apply(a, b, c));
}
}
@FunctionalInterface
public interface TriConsumer<A, B, C> {
void accept(A a, B b, C c);
public default TriConsumer<A, B, C> andThen(final TriConsumer<? super A, ? super B, ? super C> after) {
Objects.requireNonNull(after);
return (A a, B b, C c) -> {
accept(a, b, c);
after.accept(a, b, c);
};
}
}
public static <A, B> Collection<B> map(Collection<A> as, Function<A, B> f) {
Collection<B> b;
try {
......
......@@ -70,9 +70,12 @@ public class Main {
private static void solve(Collection<String> 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<String> 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<String> 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",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment