Commit 65064b33 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Исправлена ошибка в оптимизации с объёмом хранилища, пересмотрено количество причалов.

Решена проблема взаимоисключения швартовки и отшвартовки.
parent 5d481aa8
......@@ -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",
......
......@@ -744,6 +744,11 @@ public class ConversionUtil {
ArrayList<Integer> loadingOpDelta = new ArrayList<>();
ArrayList<Integer> loadingOpN = new ArrayList<>();
ArrayList<Integer> loading_op_delta_of_main_obj = new ArrayList<>();
ArrayList<Integer> operations_main_stor = new ArrayList<>();
ArrayList<Integer> operations_secondary_stor = new ArrayList<>();
ArrayList<Integer> 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<Set<Integer>> 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");
......
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