From 8af8ce778f442241ee2866744536179300415668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=81=D0=B5=D0=BB=D1=91=D0=B2=20=D0=92=D0=BB?= =?UTF-8?q?=D0=B0=D0=B4=D0=B8=D1=81=D0=BB=D0=B0=D0=B2?= Date: Tue, 13 Nov 2018 15:05:42 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B5=D0=BF=D1=80=D0=B5=D1=80=D1=8B?= =?UTF-8?q?=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D1=88=D0=B2=D0=B0=D1=80?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=D0=BA=D0=B8,=20=D0=BF=D0=B0=D1=80=D1=81?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82?= =?UTF-8?q?=D0=B0=D1=82=D0=B0,=20=D1=83=D0=BF=D1=80=D0=BE=D1=89=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/inport/ConversionUtil.java | 104 ++++++++++++++++++++++++++++---- src/inport/Main.java | 44 +++++++++++--- src/inport/ParserException.java | 7 +++ test/conversion_0.mzn | 12 ++-- 4 files changed, 140 insertions(+), 27 deletions(-) create mode 100644 src/inport/ParserException.java diff --git a/src/inport/ConversionUtil.java b/src/inport/ConversionUtil.java index 560bd83..8f06208 100644 --- a/src/inport/ConversionUtil.java +++ b/src/inport/ConversionUtil.java @@ -2,9 +2,9 @@ package inport; import javafx.util.Pair; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.*; +import java.util.function.BiFunction; import java.util.function.Function; public class ConversionUtil { @@ -177,6 +177,9 @@ public class ConversionUtil { } writer.write("n_locations = " + locationNumberById.size() + ";\n"); + BiFunction getLocNById = + (Integer id, Boolean isMoored) -> locationNumberById.get(new Pair<>(id, isMoored)); + ArrayList movingObjects = new ArrayList<>(); Map mObjNumberById = new TreeMap<>(); for (MovingObject obj : task.getShips()) { @@ -216,19 +219,18 @@ public class ConversionUtil { movingObjN.add(mObjToN.apply(op.getMover())); for (Integer n : movingObjN) { - arrivalOp.get(n).get(locationNumberById.get(new Pair<>(op.getDestination().getId(), false))).add(i); - departureOp.get(n).get(locationNumberById.get(new Pair<>(op.getStartLocation().getId(), false))).add(i); + arrivalOp.get(n).get(getLocNById.apply(op.getDestination().getId(), false)).add(i); + departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), false)).add(i); } } } write2DArray(writer, "arrival_op", arrivalOp); write2DArray(writer, "departure_op", departureOp); } - { // Начальные положения объектов. ArrayList initialStates = integerArray(movingObjects.size(), 0); for (MovingObjectState state : task.getVesselInitialState()) { - initialStates.set(mObjToN.apply(state.getVessel()), locationNumberById.get(new Pair<>(state.getLocation().getId(), false))); + initialStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false)); } writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1); writer.write("\n"); @@ -254,27 +256,31 @@ public class ConversionUtil { writeArray(writer, "bw_fin", bw_fin); writer.write("\n"); } - { // Непрерывность перемещения. + { // Непрерывность перемещения и швартовки. ArrayList operationsDuration = integerArray(operationTemplates.size(), 0); ArrayList isMovingObj = new ArrayList<>(); for (int i = 0; i < operationTemplates.size(); i++) { if (operationTemplates.get(i) instanceof MovingTemplate) { MovingTemplate op = (MovingTemplate)operationTemplates.get(i); - int duration = (int)Math.ceil(op.getDuration()); - operationsDuration.set(i, duration); + operationsDuration.set(i, (int)Math.ceil(op.getDuration())); + isMovingObj.add(true); + } else if (operationTemplates.get(i) instanceof MooringTemplate) { + MooringTemplate op = (MooringTemplate) operationTemplates.get(i); + + operationsDuration.set(i, (int)Math.ceil(op.getDuration())); isMovingObj.add(true); } else { isMovingObj.add(false); } } writeArray(writer, "operations_duration", operationsDuration); - writeArray(writer, "is_moving_operation", isMovingObj); + writeArray(writer, "is_continuous_operation", isMovingObj); } { // Конечные положения объектов. ArrayList finalStates = integerArray(movingObjects.size(), 0); for (MovingObjectState state : task.getVesselEndState()) { - finalStates.set(mObjToN.apply(state.getVessel()), locationNumberById.get(new Pair<>(state.getLocation().getId(), false))); + finalStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false)); } writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1); } @@ -293,7 +299,7 @@ public class ConversionUtil { s.add(mObjToN.apply(obj) + 1); } operationsResources.set(i, s); - operationsStartLoc.set(i, locationNumberById.get(new Pair<>(op.getStartLocation().getId(), false)) + 1); + operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), false) + 1); } // TODO швартовка, погрузка. } @@ -315,4 +321,78 @@ public class ConversionUtil { } } } + + static public void resolveMiniZincResults(TaskCase task, String fileName) throws IOException, ParserException { + List operations = null; + Integer result = null; + + try (FileInputStream fstream = new FileInputStream(fileName)) { + BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); + + String line; + + while (((line = br.readLine()) != null)) { + line = line.trim(); + if (line.equals("")) { + continue; + } + + String regexpr = "^\\[((true)|(false))(,\\s((true)|(false)))*]\\z"; + if (line.matches(regexpr)) { + if (operations != null) { + continue; + } + String []rawTokens = line.split("[\\s\\[\\],]"); + ArrayList tokens = new ArrayList<>(); + for (String str : rawTokens) { + if (!str.isEmpty()) { + tokens.add(str); + } + } + final int n_intervals = (int)task.getPlanningInterval(); + + if (tokens.size() != (n_intervals + 2) * task.getTemplates().size()) { + throw new ParserException("Invalid length of \"op_status\""); + } + + operations = new ArrayList<>(); + + for (int i = 0; i < task.getTemplates().size(); i++) { + int duration = 0; + for (int j = 0; j < n_intervals + 2; j++) { + if (tokens.get(i * (n_intervals + 2) + j).equals("true")) { + duration++; + } else if (duration != 0) { + Operation op = new Operation(); + op.setStart(j - duration - 1); + op.setDuration(duration); + op.setTemplate(task.getTemplates().get(i)); + + operations.add(op); + + duration = 0; + } + } + } + continue; + } + if (line.matches("\\d+")) { + if (result != null) { + continue; + } + result = Integer.parseInt(line); + continue; + } + break; + } + if (operations == null) { + throw new ParserException("No \"op_status\" in input"); + } + if (result == null) { + throw new ParserException("No result in input"); + } + task.setSolution(operations); + task.setSolution_result(result); + } + } } diff --git a/src/inport/Main.java b/src/inport/Main.java index 2120da5..ff9fdef 100644 --- a/src/inport/Main.java +++ b/src/inport/Main.java @@ -3,19 +3,45 @@ package inport; import java.io.IOException; public class Main { - public static void main(String[] args) { - if (args.length < 2) { + if (args.length < 1) { System.out.println("To few arguments."); return; } - TaskCase task = new TaskCase(); - try { - task.deserialize(args[0]); -// task.simpleMiniZincConversion(args[1]); - ConversionUtil.portToMiniZinc(task, args[1]); - } catch (IOException ex) { - System.out.println(ex.getMessage()); + String type = args[0]; + + switch (type) { + case "to_MiniZinc" : { + String input = args[1]; + String output = args[2]; + TaskCase task = new TaskCase(); + try { + task.deserialize(input); + ConversionUtil.portToMiniZinc(task, output); + } catch (IOException ex) { + System.out.println(ex.getMessage()); + } + break; + } + case "resolve_result" : { + String input = args[1]; + String fileWIthResult = args[2]; + String output = args[3]; + + try { + TaskCase task = new TaskCase(); + task.deserialize(input); + + ConversionUtil.resolveMiniZincResults(task, fileWIthResult); + + task.serialize(output); + } catch (IOException | ParserException ex) { + System.out.println(ex.getMessage()); + } + break; + } + default: + System.out.println("Unknown type \"" + type + "\""); } } } diff --git a/src/inport/ParserException.java b/src/inport/ParserException.java new file mode 100644 index 0000000..45cd39a --- /dev/null +++ b/src/inport/ParserException.java @@ -0,0 +1,7 @@ +package inport; + +public class ParserException extends Exception { + ParserException(String mess) { + super(mess); + } +} diff --git a/test/conversion_0.mzn b/test/conversion_0.mzn index 94a5d22..8611cec 100644 --- a/test/conversion_0.mzn +++ b/test/conversion_0.mzn @@ -42,13 +42,13 @@ constraint forall (op in 1..n_operations, j in {0, n_intervals + 1}) constraint forall (i in 1..n_operations, j in 1..(n_intervals + 1)) (op_start[i, j] = (op_status[i, j] /\ not op_status[i, j - 1])); constraint forall (i in 1..n_operations, j in 1..n_intervals ) (op_fin [i, j] = (op_status[i, j] /\ not op_status[i, j + 1])); -% Непрерывность перемещения. +% Непрерывность перемещения и швартовки. array [1..n_operations] of var int : operations_duration; -array [1..n_operations] of var bool : is_moving_operation; +array [1..n_operations] of var bool : is_continuous_operation; % TODO %constraint forall (i in 1..n_operations) ( -% if (is_moving_operation[i]) then ( +% if (is_continuous_operation[i]) then ( % forall (j in 1..n_intervals) ( % let {var int : len = operations_duration[i]} in % if (j + len > n_intervals + 1) then @@ -69,7 +69,7 @@ array [1..n_operations] of var bool : is_moving_operation; constraint forall (i in 1..n_operations) ( - if (is_moving_operation[i]) then ( + if (is_continuous_operation[i]) then ( let {var int : len = operations_duration[i]} in (forall (j in 1..(n_intervals - len + 1)) ( (op_start[i, j] == 1) -> ( @@ -131,8 +131,8 @@ constraint forall (t in 1..n_intervals) ( solve minimize sum(is_not_terminated); -output ["res = ", show(sum(is_not_terminated)), "\n\n", - "op_status = ", show(op_status), "\n\n", +output [show(sum(is_not_terminated)), "\n", + show(op_status), "\n\n", "m_obj_loc = ", show(m_obj_loc), "\n\n", "op_fin = ", show(op_fin), "\n\n", "op_start = ", show(op_start), "\n\n", -- GitLab