diff --git a/src/constraints/conversion_2.mzn b/src/constraints/conversion_2.mzn index ba628db8e718829b8b72fe91a6d7309b438267c2..4c8c61b2433b6fdf82083fb4c1d492673db5007c 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 0be5821cd8ad1c2c8fd391f1f022e1a5993d12b3..5299cfc102a8d1e16c299604f488ffaacd908c34 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");