From 65064b3331476fd4466d38285718b43abb239707 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, 30 Apr 2019 15:14:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=B2=20=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8=20=D1=81=20=D0=BE=D0=B1=D1=8A=D1=91=D0=BC=D0=BE?= =?UTF-8?q?=D0=BC=20=D1=85=D1=80=D0=B0=D0=BD=D0=B8=D0=BB=D0=B8=D1=89=D0=B0?= =?UTF-8?q?,=20=D0=BF=D0=B5=D1=80=D0=B5=D1=81=D0=BC=D0=BE=D1=82=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B2=D0=BE=20=D0=BF=D1=80=D0=B8=D1=87=D0=B0=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2.=20=D0=A0=D0=B5=D1=88=D0=B5=D0=BD=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D0=B0=20=D0=B2=D0=B7=D0=B0=D0=B8?= =?UTF-8?q?=D0=BC=D0=BE=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D1=88=D0=B2=D0=B0=D1=80=D1=82=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D0=BE=D1=82=D1=88=D0=B2=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constraints/conversion_2.mzn | 39 ++++++++++++++++++++--- src/inport/ConversionUtil.java | 54 ++++++++++++++++++++++++-------- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/src/constraints/conversion_2.mzn b/src/constraints/conversion_2.mzn index ba628db..4c8c61b 100644 --- a/src/constraints/conversion_2.mzn +++ b/src/constraints/conversion_2.mzn @@ -31,9 +31,18 @@ array [1..n_moving_obj, 1..n_operations] of bool : moving_op_of_obj; % Счётчик объектов в локации (только в чётных - в состоянии пришвартованности). array [1..n_locations, 0..(n_intervals + 1)] of var int : obj_in_loc_counter; + array [1..n_locations] of 1..n_locations : twin_location = [i - 1 + (i mod 2) * 2 | i in 1..n_locations]; + + % Операции грузообработки, проводимые без пришвартовки на этой локации. + array [1..n_locations] of set of 1..n_operations : related_unmoored_cargo_op; + % Определение obj_in_loc_counter. - constraint forall (loc in 1..n_locations, t in 0..(n_intervals + 1)) ( - obj_in_loc_counter[loc, t] = sum (obj in 1..n_moving_obj) (m_obj_loc[obj, t] = loc) + constraint forall (loc in 1..n_locations, t in 0..n_intervals where (loc mod 2) = 0) ( + obj_in_loc_counter[loc, t] = (sum (obj in 1..n_moving_obj) (m_obj_loc[obj, t + 1] = loc)) % Швартовка и нахождение у причала. + + (sum (op in related_unmoored_cargo_op[twin_location[loc]]) (op_status[op, t])) % Погрузка без швартовки. + + (sum (op in 1..n_operations where (is_mooring_op[op] /\ (main_obj_start_loc[op] mod 2 = 0))) % Отшвартовка. + (op_status[op, t]) + ) ); % Само ограничение. @@ -284,6 +293,11 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац int : n_loading_op; + array [1..n_operations] of int : loading_op_delta_of_main_obj; + array [1..n_operations] of 1..n_obj_with_storage : operations_main_stor; + array [1..n_operations] of 1..n_obj_with_storage : operations_secondary_stor; + array [1..n_operations] of 1..n_cargo_types : operations_cargo_t; + array [1..n_loading_op] of int : loading_op_delta; array [1..n_loading_op] of 1..n_operations : loading_op_n; % Номера среди общего списка операций. @@ -358,8 +372,25 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац % не участвует в операциях погрузки. ((is_mooring_op[op] /\ (operations_destination[op] mod 2 = 0)) -> ( obj_in_loc_counter[operations_destination[op], t] = 0) - ) % Если это операция пришвартовки, то в этот интервал + ) /\ % Если это операция пришвартовки, то в этот интервал % причал должен быть свободным. + ((not is_moving_operation[op]) -> ( + let {1..n_obj_with_storage : m_stor = operations_main_stor[op]; + 1..n_obj_with_storage : s_stor = operations_secondary_stor[op]; + 1..n_cargo_types : cargo = operations_cargo_t[op]; + int : delta = loading_op_delta_of_main_obj[op]; + } in + (storage_used_volume[m_stor, t, cargo] + delta >= 0) /\ + ((sum (c in 1..n_cargo_types) (storage_used_volume[m_stor, t, cargo])) + delta <= max_storage_vol[m_stor]) /\ + (storage_used_volume[s_stor, t, cargo] - delta >= 0) /\ + ((sum (c in 1..n_cargo_types) (storage_used_volume[s_stor, t, cargo])) - delta <= max_storage_vol[s_stor]) + )) /\ % Если это операция грузообработки, то она не выведет + % объём берегового хранилища и хранилища судна за + % границы дозволенного. + (((not is_moving_operation[op]) /\ (main_obj_start_loc[op] mod 2 = 1)) -> + (obj_in_loc_counter[twin_location[main_obj_start_loc[op]], t] = 0) + ) % Если это операция грузообработки без пришвартовки, + % то причал должен быть свободен в этот интервал. ) ); @@ -395,8 +426,6 @@ output [show(sum(is_not_terminated)), "\n", "resources_counter {", show(n_intervals), "} = ", show(resources_counter), "\n\n", "operation_of_counter {", show(n_resources_counters), "} = ", show(operation_of_counter), "\n\n", "participation_as_resource = ", show(participation_as_resource), "\n\n", - - "real_current_moving_operation = ", show(current_moving_operation), "\n\n", /* "is_op_possible {", show(n_intervals), "} = ", show(is_op_possible), "\n\n", "debug_1 {", show(n_intervals), "} = ", show(debug_1), "\n\n", diff --git a/src/inport/ConversionUtil.java b/src/inport/ConversionUtil.java index 0be5821..5299cfc 100644 --- a/src/inport/ConversionUtil.java +++ b/src/inport/ConversionUtil.java @@ -744,6 +744,11 @@ public class ConversionUtil { ArrayList loadingOpDelta = new ArrayList<>(); ArrayList loadingOpN = new ArrayList<>(); + ArrayList loading_op_delta_of_main_obj = new ArrayList<>(); + ArrayList operations_main_stor = new ArrayList<>(); + ArrayList operations_secondary_stor = new ArrayList<>(); + ArrayList operations_cargo_t = new ArrayList<>(); + for (int i = 0; i < nObjWithStorage; i++) { involvedOperations.add(new ArrayList<>()); for (int j = 0; j < cargoes.size(); j++) { @@ -765,6 +770,16 @@ public class ConversionUtil { loadingOpDelta.add((int)op.getIntensity()); loadingOpN.add(i); involvedOperations.get(shipN).get(cargoN).add(loadingOpDelta.size()); + + loading_op_delta_of_main_obj.add((int)op.getIntensity()); + operations_main_stor.add(shipN + 1); + operations_secondary_stor.add(storageN + movingObjects.size() + 1); + operations_cargo_t.add(cargoN + 1); + } else { + loading_op_delta_of_main_obj.add(0); + operations_main_stor.add(1); + operations_secondary_stor.add(1); + operations_cargo_t.add(1); } } writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n"); @@ -775,6 +790,12 @@ public class ConversionUtil { } writeArray(writer, "loading_op_delta", loadingOpDelta); writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1); + + writeArray(writer, "loading_op_delta_of_main_obj", loading_op_delta_of_main_obj); + writeArray(writer, "operations_main_stor", operations_main_stor); + writeArray(writer, "operations_secondary_stor", operations_secondary_stor); + writeArray(writer, "operations_cargo_t", operations_cargo_t); + writer.write("\n"); } @@ -927,6 +948,22 @@ public class ConversionUtil { writer.write("\n"); } + private void unmooredCargoOp() throws IOException { + ArrayList> relatedUnmooredCargoOp = new ArrayList<>(); + for (int i = 0; i < locationNumberById.size(); i++) { + relatedUnmooredCargoOp.add(new TreeSet<>()); + } + for (int i = 0; i < operationTemplates.size(); i++) { + if (operationTemplates.get(i) instanceof LoadingTemplate) { + LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i); + if (! op.getWithMooring()) { + relatedUnmooredCargoOp.get(getLocNById(op.getStartLocation().getId(), false)).add(i + 1); + } + } + } + writeArray(writer, "related_unmoored_cargo_op", relatedUnmooredCargoOp, ConversionUtil::setToString); + } + void portToMiniZinc_0() throws IOException { if (task.isTypified()) { throw new ParserException("Attempt to convert typified task as untyped."); @@ -1073,7 +1110,8 @@ public class ConversionUtil { LoadingTemplate op2 = (LoadingTemplate) operationTemplates.get(j); if ((op1.getStorage() == op2.getStorage()) && - (op1.getStartLocation() == op2.getStartLocation())) { + (op1.getStartLocation() == op2.getStartLocation()) && + (op1.getLoader() == op2.getLoader())) { conflictingOperationsG.get(i).add(j + 1); } } @@ -1093,18 +1131,6 @@ public class ConversionUtil { } } } - { // Взаимоисключение операций швартовки/отшвартовки с одним причалом. - // TODO выделить в отдельный constraint - if ((operationTemplates.get(i) instanceof MooringTemplate) && - (operationTemplates.get(j) instanceof MooringTemplate)) { - MooringTemplate op1 = (MooringTemplate) operationTemplates.get(i); - MooringTemplate op2 = (MooringTemplate) operationTemplates.get(j); - - if (op1.getStartLocation() == op2.getStartLocation()) { - conflictingOperationsG.get(i).add(j + 1); - } - } - } } } writeArray(writer, "conflicting_operations", conflictingOperationsG, ConversionUtil::setToString); @@ -1203,6 +1229,8 @@ public class ConversionUtil { operationsContinuity(); typifiedResourcesDefinition(); + unmooredCargoOp(); + writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n"); writer.write("n_cargo_types = " + cargoes.size() + ";\n"); -- GitLab