diff --git a/constraints/conversion_0.mzn b/constraints/conversion_0.mzn index 2ac921959fb3d21ea81f3d53f49531390cb531b2..ec5c3c1664a9ebf7456349d7ca5a70859a365da3 100644 --- a/constraints/conversion_0.mzn +++ b/constraints/conversion_0.mzn @@ -68,12 +68,16 @@ constraint forall (i in 1..n_operations where is_continuous_operation[i]) ( ); % Наличие всех ресурсов на месте во время начала операции перемещения. -array [1..n_operations] of set of 1..n_moving_obj : operations_resources; + +int : operations_resources_max_size; +array [1..n_operations] of 0..operations_resources_max_size : operations_resources_sizes; +array [1..n_operations, 1..operations_resources_max_size] of 1..n_moving_obj : operations_resources; + array [1..n_operations] of 0..n_locations : operations_start_loc; constraint forall (op in 1..n_operations, j in 1..n_intervals) ( - forall (obj in operations_resources[op]) ( - (op_start[op, j]) -> (m_obj_loc[obj, j] == operations_start_loc[op]) + forall (op_res_id in 1..operations_resources_sizes[op]) ( + (op_start[op, j]) -> (m_obj_loc[operations_resources[op, op_res_id], j] == operations_start_loc[op]) ) ); @@ -130,16 +134,34 @@ constraint forall (storage in 1..n_obj_with_storage, cargo in 1..n_cargo_types) array [1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types] of int : cargo_flows; int : n_loading_op; -array [1..n_obj_with_storage, 1..n_cargo_types] of set of 1..n_loading_op : involved_operations; + array [1..n_loading_op] of int : loading_op_delta; array [1..n_loading_op] of 1..n_operations : loading_op_n; % Номера среди общего списка операций. +/* + array [1..n_obj_with_storage, 1..n_cargo_types] of set of 1..n_loading_op : involved_operations; + + constraint forall (storage in 1..n_obj_with_storage, cargo in 1..n_cargo_types, t in 1..(n_intervals + 1)) ( + storage_used_volume[storage, t, cargo] == ( + storage_used_volume[storage, t - 1, cargo] + + cargo_flows[storage, t, cargo] + + sum (inv_op in involved_operations[storage, cargo]) ( + loading_op_delta[inv_op] * op_status[loading_op_n[inv_op], t] + ) + ) + ); +*/ + +int : involved_operations_max_size; +array [1..n_obj_with_storage, 1..n_cargo_types] of 0..involved_operations_max_size : involved_operations_sizes; +array [1..n_obj_with_storage, 1..n_cargo_types, 1..involved_operations_max_size] of 1..n_loading_op : involved_operations; constraint forall (storage in 1..n_obj_with_storage, cargo in 1..n_cargo_types, t in 1..(n_intervals + 1)) ( storage_used_volume[storage, t, cargo] == ( storage_used_volume[storage, t - 1, cargo] + cargo_flows[storage, t, cargo] + - sum (inv_op in involved_operations[storage, cargo]) ( - loading_op_delta[inv_op] * op_status[loading_op_n[inv_op], t] + sum (inv_op_no in 1..involved_operations_sizes[storage, cargo]) ( + loading_op_delta[involved_operations[storage, cargo, inv_op_no]] * + op_status[loading_op_n[involved_operations[storage, cargo, inv_op_no]], t] ) ) ); @@ -182,17 +204,24 @@ array [1..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_locations : prev_m_obj endif ); -array [1..n_moving_obj] of set of 1..n_operations : obj_useful_operations; % Все полезные операции касающиеся данного объекта. - array [1..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_m_obj_useful; % Был ли объект задействован в "полезной" операции (не движении в качестве главного объекта). + +int : obj_useful_operations_max_size; +array [1..n_moving_obj] of 0..obj_useful_operations_max_size : obj_useful_operations_sizes; +array [1..n_moving_obj, 1..obj_useful_operations_max_size] of 1..n_operations : obj_useful_operations; % Все полезные операции касающиеся данного объекта. + constraint forall (obj in 1..n_moving_obj, t in 0..(n_intervals + 1)) ( - is_m_obj_useful[obj, t] = exists (useful_op in obj_useful_operations[obj]) (op_status[useful_op, t]) + is_m_obj_useful[obj, t] = exists (useful_op_no in 1..obj_useful_operations_sizes[obj]) + (op_status[obj_useful_operations[obj, useful_op_no], t]) ); array [1..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_in_moving; -array [1..n_moving_obj] of set of 1..n_operations : moving_op_of_obj; % Операции перемещения затрагивающие данный объект. + +int : moving_op_of_obj_max_size; +array [1..n_moving_obj] of 0..moving_op_of_obj_max_size : moving_op_of_obj_sizes; +array [1..n_moving_obj, 1..moving_op_of_obj_max_size] of 1..n_operations : moving_op_of_obj; % Операции перемещения затрагивающие данный объект. constraint forall (obj in 1..n_moving_obj, t in 0..(n_intervals + 1)) ( - is_obj_in_moving[obj, t] = exists (moving_op in moving_op_of_obj[obj]) (op_status[moving_op, t]) + is_obj_in_moving[obj, t] = exists (moving_op_no in 1..moving_op_of_obj_sizes[obj]) (op_status[moving_op_of_obj[obj, moving_op_no], t]) ); array [1..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_interval_useful; % Была ли на текущем интервале полезная операция. diff --git a/src/inport/ConversionUtil.java b/src/inport/ConversionUtil.java index da0bc8ca72750d19bda5ba6c0098ec977cf0a1d2..61eb49ec30ad9c3ffd74c4825c5eb33e19991ee3 100644 --- a/src/inport/ConversionUtil.java +++ b/src/inport/ConversionUtil.java @@ -87,6 +87,41 @@ public class ConversionUtil { writer.write("]);\n"); } + static private void writeArrayOfSetAs2DArray(FileWriter writer, + String name, + ArrayList> operations) throws IOException { + int maxSize = 0; + ArrayList sizes = new ArrayList<>(); + for (Set s : operations) { + maxSize = Math.max(maxSize, s.size()); + sizes.add(s.size()); + } + writer.write(name + "_max_size = " + maxSize + ";\n"); + writeArray(writer, name + "_sizes", sizes); + writer.write(name + " = array2d(1.." + operations.size() + ", 1.." + name + "_max_size, ["); + + boolean isFirst = true; + for (Set s : operations) { + for (Integer val : s) { + if (isFirst) { + isFirst = false; + } else { + writer.write(", "); + } + writer.write(Integer.toString(val)); + } + for (int i = s.size(); i < maxSize; i++) { + if (isFirst) { + isFirst = false; + } else { + writer.write(", "); + } + writer.write("1"); + } + } + writer.write("]);\n"); + } + static private void locWrite2DArray(FileWriter writer, String name, ArrayList> operations, @@ -401,7 +436,9 @@ public class ConversionUtil { // TODO швартовка, погрузка. } writeArray(writer, "operations_start_loc", operationsStartLoc); - writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString); + //writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString); + writeArrayOfSetAs2DArray(writer, "operations_resources", operationsResources); + writer.write("\n"); } { // Конфликтующие операции. ArrayList> conflictingPairs = new ArrayList<>(); @@ -554,7 +591,8 @@ public class ConversionUtil { } } writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n"); - write2DArrayOfSet(writer, "involved_operations", involvedOperations); +// write2DArrayOfSet(writer, "involved_operations", involvedOperations); + write2DArrayOfSetAs3DArray(writer, "involved_operations", involvedOperations); writeArray(writer, "loading_op_delta", loadingOpDelta); writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1); writer.write("\n"); @@ -602,8 +640,8 @@ public class ConversionUtil { } } - writeArray(writer, "obj_useful_operations", objUsefulOperations, ConversionUtil::setToString); - writeArray(writer, "moving_op_of_obj", movingOpOfObj, ConversionUtil::setToString); + writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations); + writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj); writer.write("\n"); } }