Commit 7f3d6101 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Переделаны окна погоды и конфликтующте операции. Добавлена оптимизация.

parent 2e554245
...@@ -27,7 +27,6 @@ array [1..n_moving_obj, 0..moving_op_of_obj_max_size] of 1..n_operations : movin ...@@ -27,7 +27,6 @@ array [1..n_moving_obj, 0..moving_op_of_obj_max_size] of 1..n_operations : movin
op_status[op, t] -> ((current_moving_operation[obj, t] != 0) /\ op_status[op, t] -> ((current_moving_operation[obj, t] != 0) /\
(moving_op_of_obj[obj, current_moving_operation[obj, t]] = op)) (moving_op_of_obj[obj, current_moving_operation[obj, t]] = op))
); );
% Если операция, затрагивающая данный объект в качестве ресурса
% TODO упростить в conversion_1 % TODO упростить в conversion_1
% Связь current_moving_operation c op_status. % Связь current_moving_operation c op_status.
...@@ -102,7 +101,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -102,7 +101,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
(current_moving_operation[obj, t - 1] != 0) /\ (current_moving_operation[obj, t - 1] != 0) /\
((obj != main_obj_of_operation[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]]) ((obj != main_obj_of_operation[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]])
/\ /\
(is_mooring_op[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]]) ( is_mooring_op[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]])
) )
) -> (m_obj_loc[obj, t] = m_obj_loc[obj, t - 1]) ) -> (m_obj_loc[obj, t] = m_obj_loc[obj, t - 1])
); );
...@@ -163,6 +162,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -163,6 +162,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
) )
); );
/* TODO разобраться и удалить лишнее.
% { Если объект участвует как ресурс в операции перемещения (не швартовки), то это согласованно с current_moving_operation, % { Если объект участвует как ресурс в операции перемещения (не швартовки), то это согласованно с current_moving_operation,
% иначе (как ресурс в погрузке или швартове) - он должен стоять на месте. } % иначе (как ресурс в погрузке или швартове) - он должен стоять на месте. }
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) ( constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
...@@ -181,6 +181,18 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -181,6 +181,18 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
) -> current_moving_operation[obj, t] = 0) ) -> current_moving_operation[obj, t] = 0)
) )
); );
*/
% Если объект участвует как ресурс в операции перемещения, то это согласованно с current_moving_operation.
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
(participation_as_resource[obj, t] != 0) -> (
(is_moving_operation[participation_as_resource[obj, t]]) -> (
(current_moving_operation[obj, t] != 0)
/\
(participation_as_resource[obj, t] = moving_op_of_obj[obj, current_moving_operation[obj, t]])
)
)
);
% { Объект участвует где-то в качестве ресурса - соответствующая операция обязана быть активной. } % { Объект участвует где-то в качестве ресурса - соответствующая операция обязана быть активной. }
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) ( constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
...@@ -262,23 +274,17 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -262,23 +274,17 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
); );
% Конфликтующие операции. % Конфликтующие операции.
int : n_conflicting_op; array [1..n_operations] of set of 1..n_operations : conflicting_operations;
array [1..n_conflicting_op] of 1..n_operations : confl_op_1; constraint forall (op in 1..n_operations, t in 0..(n_intervals + 1), conf_op in conflicting_operations[op]) (
array [1..n_conflicting_op] of 1..n_operations : confl_op_2; op_status[op, t] -> not op_status[conf_op, t]
);
constraint forall (t in 0..(n_intervals + 1), i in 1..n_conflicting_op) (
op_status[confl_op_1[i], t] -> not op_status[confl_op_2[i], t]
);
% Окна непогоды. % Окна непогоды.
int : n_bad_weather_windows; array [1..n_operations, 1..n_intervals] of bool : bad_weather;
array [1..n_bad_weather_windows] of 1..n_operations : bw_op;
array [1..n_bad_weather_windows] of 0..(n_intervals + 1) : bw_start;
array [1..n_bad_weather_windows] of 0..(n_intervals + 1) : bw_fin; % Включительно.
constraint forall (i in 1..n_bad_weather_windows, t in bw_start[i]..bw_fin[i]) ( constraint forall (op in 1..n_operations, t in 1..n_intervals) (
op_status[bw_op[i], t] == false bad_weather[op, t] -> (op_status[op, t] = false)
); );
% Грузообработка. % Грузообработка.
...@@ -335,6 +341,76 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -335,6 +341,76 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
) )
); );
% Оптимизация - сдвиг в начало.
% Возможно ли начать операцию в данный интервал (если предположить, что операция длится 1 интервал).
array [1..n_operations, 1..n_intervals] of var bool : is_op_possible;
% Счётчик ресурсов, которые могут быть потенциально задействованы в операции.
array [1..n_resources_counters , 1..n_intervals] of var int : possible_resources_counter;
% Определение possible_resources_counter.
constraint forall (counter in 1..n_resources_counters, t in 1..n_intervals) (
possible_resources_counter[counter, t] = sum (obj in objects_of_type[counter_type[counter]]) (
(participation_as_resource[obj, t] = 0) /\
(current_moving_operation[obj, t] = 0) /\
(m_obj_loc[obj, t] = operations_resources_start_loc[counter])
)
);
% Достаточно ли свободных ресурсов для операции.
array [1..n_operations, 1..n_intervals] of var bool : is_enough_free_resources;
constraint forall (op in 1..n_operations, t in 1..n_intervals) (
is_enough_free_resources[op, t] = forall (counter in counters_of_operation[op]) (
possible_resources_counter[counter, t] >= required_counter_values[counter]
)
);
% Участвует ли данный объект в операции грузообработки в качестве главного.
array [1..n_moving_obj, 1..n_intervals] of var bool : is_obj_involved_in_cargo_op;
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
is_obj_involved_in_cargo_op[obj, t] = (
((participation_as_resource[obj, t] != 0) /\ (current_moving_operation[obj, t] = 1)) % В качестве ресурса.
\/
exists (op in 1..n_operations where main_obj_of_operation[op] = obj) ( % В качестве главного объекта.
op_status[op, t]
)
)
);
array [1..n_operations, 1..n_intervals] of var bool : debug_1;
constraint forall (op in 1..n_operations, t in 1..n_intervals) (
debug_1[op, t] =
(m_obj_loc[main_obj_of_operation[op], t] = main_obj_start_loc[op]) % Главный объект на месте.
);
% Определение is_op_possible.
constraint forall (op in 1..n_operations, t in 1..n_intervals) (
is_op_possible[op, t] = (
(bad_weather[op, t] = false) /\ % Погода не мешает.
(m_obj_loc[main_obj_of_operation[op], t] = main_obj_start_loc[op])
/\ % Главный объект на месте.
(current_moving_operation[main_obj_of_operation[op], t] = 0)
/\ % Главный объект не участвует в операции перемещеня.
(is_enough_free_resources[op, t] = true) /\ % Достаточно свободных ресурсов на нужном месте.
(forall (conf_op in conflicting_operations[op]) (op_status[op, t] = false))
/\ % Не выполняется ни одной конфликтующей операции.
(is_moving_operation[op] -> not is_obj_involved_in_cargo_op[main_obj_of_operation[op], t])
/\ % Если это операция перемещения, то главный объект
% не участвует в операциях погрузки.
((is_mooring_op[op] /\ (operations_destination[op] mod 2 = 0)) -> (
obj_in_loc_counter[operations_destination[op], t] = 0)
) % Если это операция пришвартовки, то в этот интервал
% причал должен быть свободным.
)
);
% Сам критерий оптимизации - если если операцию можно было начать на 1 интервал раньше, то её нужно начать раньше.
constraint forall (op in 1..n_operations, t in 2..n_intervals) (
op_start[op, t] -> not is_op_possible[op, t - 1]
);
% Критерий оптимизации % Критерий оптимизации
array [0..(n_intervals + 1)] of var bool : is_not_terminated; array [0..(n_intervals + 1)] of var bool : is_not_terminated;
constraint (is_not_terminated[0] == false /\ is_not_terminated[n_intervals + 1] == false); constraint (is_not_terminated[0] == false /\ is_not_terminated[n_intervals + 1] == false);
...@@ -366,4 +442,11 @@ output [show(sum(is_not_terminated)), "\n", ...@@ -366,4 +442,11 @@ output [show(sum(is_not_terminated)), "\n",
"real_current_moving_operation = ", show(current_moving_operation), "\n\n", "real_current_moving_operation = ", show(current_moving_operation), "\n\n",
"moving_op_of_obj {", show(moving_op_of_obj_max_size + 1), "}= ", show(moving_op_of_obj), "\n\n", "moving_op_of_obj {", show(moving_op_of_obj_max_size + 1), "}= ", show(moving_op_of_obj), "\n\n",
/*
"is_op_possible {", show(n_intervals), "} = ", show(is_op_possible), "\n\n",
"debug_1 {", show(n_intervals), "} = ", show(debug_1), "\n\n",
"is_enough_free_resources {", show(n_intervals), "} = ", show(is_enough_free_resources), "\n\n",
"operation_of_counter {", show(n_resources_counters), "} = ", show(operation_of_counter), "\n\n",
"possible_resources_counter {", show(n_intervals), "} = ", show(possible_resources_counter), "\n\n",
*/
""]; ""];
...@@ -510,6 +510,28 @@ public class ConversionUtil { ...@@ -510,6 +510,28 @@ public class ConversionUtil {
writer.write("\n"); writer.write("\n");
} }
/* Окна погоды. Новый формат. */
private void weatherWindowsNewFormat() throws IOException {
ArrayList<ArrayList<Boolean>> badWeather = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
ArrayList<Boolean> curLine = new ArrayList<>();
for (int j = 0; j < n_intervals; j++) {
curLine.add(false);
}
operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> {
for (int j = (int)Math.floor(start); j < (int)Math.ceil(start + duration); j++) {
curLine.set(j, true);
}
}
);
badWeather.add(curLine);
}
locWrite2DArray(writer, "bad_weather", badWeather, Objects::toString);
}
/* Непрерывность перемещения и швартовки. */ /* Непрерывность перемещения и швартовки. */
private void operationsContinuity() throws IOException { private void operationsContinuity() throws IOException {
ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0); ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0);
...@@ -994,18 +1016,21 @@ public class ConversionUtil { ...@@ -994,18 +1016,21 @@ public class ConversionUtil {
} }
private void conflictingOperationsOnStorageAndOnTypeOnMainObject() throws IOException { private void conflictingOperationsOnStorageAndOnTypeOnMainObject() throws IOException {
ArrayList<Pair<Integer, Integer>> conflictingPairs = new ArrayList<>(); ArrayList<Set<Integer>> conflictingOperationsG = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i < operationTemplates.size(); i++) {
for (int j = i + 1; j < operationTemplates.size(); j++) { conflictingOperationsG.add(new TreeSet<>());
for (int j = 0; j < operationTemplates.size(); j++) {
if (i == j) {
continue;
}
if ((operationTemplates.get(i) instanceof LoadingTemplate) && if ((operationTemplates.get(i) instanceof LoadingTemplate) &&
(operationTemplates.get(j) instanceof LoadingTemplate)) { (operationTemplates.get(j) instanceof LoadingTemplate)) {
LoadingTemplate op1 = (LoadingTemplate) operationTemplates.get(i); LoadingTemplate op1 = (LoadingTemplate) operationTemplates.get(i);
LoadingTemplate op2 = (LoadingTemplate) operationTemplates.get(j); LoadingTemplate op2 = (LoadingTemplate) operationTemplates.get(j);
if ((op1.getLoader() == op2.getLoader()) && if ((op1.getStorage() == op2.getStorage()) &&
(op1.getStorage() == op2.getStorage()) &&
(op1.getStartLocation() == op2.getStartLocation())) { (op1.getStartLocation() == op2.getStartLocation())) {
conflictingPairs.add(new Pair<>(i + 1, j + 1)); conflictingOperationsG.get(i).add(j + 1);
} }
} }
{ // Взаимоисключение операций перемещения и грузообработки с общим деятелем. { // Взаимоисключение операций перемещения и грузообработки с общим деятелем.
...@@ -1020,7 +1045,7 @@ public class ConversionUtil { ...@@ -1020,7 +1045,7 @@ public class ConversionUtil {
if (((t1 instanceof MovingTemplate) || (t1 instanceof MooringTemplate)) if (((t1 instanceof MovingTemplate) || (t1 instanceof MooringTemplate))
&& (t2 instanceof LoadingTemplate)) { && (t2 instanceof LoadingTemplate)) {
if (getExecutor(t1) == getExecutor(t2)) { if (getExecutor(t1) == getExecutor(t2)) {
conflictingPairs.add(new Pair<>(i + 1, j + 1)); conflictingOperationsG.get(i).add(j + 1);
} }
} }
} }
...@@ -1032,16 +1057,13 @@ public class ConversionUtil { ...@@ -1032,16 +1057,13 @@ public class ConversionUtil {
MooringTemplate op2 = (MooringTemplate) operationTemplates.get(j); MooringTemplate op2 = (MooringTemplate) operationTemplates.get(j);
if (op1.getStartLocation() == op2.getStartLocation()) { if (op1.getStartLocation() == op2.getStartLocation()) {
conflictingPairs.add(new Pair<>(i + 1, j + 1)); conflictingOperationsG.get(i).add(j + 1);
} }
} }
} }
} }
} }
writer.write("n_conflicting_op = " + conflictingPairs.size() + ";\n"); writeArray(writer, "conflicting_operations", conflictingOperationsG, ConversionUtil::setToString);
writeArray(writer, "confl_op_1", conflictingPairs, Pair::getKey);
writeArray(writer, "confl_op_2", conflictingPairs, Pair::getValue);
writer.write("\n");
} }
private void typifiedResourcesDefinition() throws IOException { private void typifiedResourcesDefinition() throws IOException {
...@@ -1131,7 +1153,7 @@ public class ConversionUtil { ...@@ -1131,7 +1153,7 @@ public class ConversionUtil {
movingObjectLocationDefinition(); movingObjectLocationDefinition();
initialLocations(); initialLocations();
finalLocations(); finalLocations();
weatherWindows(); weatherWindowsNewFormat();
conflictingOperationsOnStorageAndOnTypeOnMainObject(); conflictingOperationsOnStorageAndOnTypeOnMainObject();
operationsContinuity(); operationsContinuity();
......
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