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
op_status[op, t] -> ((current_moving_operation[obj, t] != 0) /\
(moving_op_of_obj[obj, current_moving_operation[obj, t]] = op))
);
% Если операция, затрагивающая данный объект в качестве ресурса
% TODO упростить в conversion_1
% Связь current_moving_operation c op_status.
......@@ -102,7 +101,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
(current_moving_operation[obj, t - 1] != 0) /\
((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])
);
......@@ -163,6 +162,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
)
);
/* TODO разобраться и удалить лишнее.
% { Если объект участвует как ресурс в операции перемещения (не швартовки), то это согласованно с current_moving_operation,
% иначе (как ресурс в погрузке или швартове) - он должен стоять на месте. }
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; % Локац
) -> 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) (
......@@ -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;
array [1..n_conflicting_op] of 1..n_operations : confl_op_2;
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]
constraint forall (op in 1..n_operations, t in 0..(n_intervals + 1), conf_op in conflicting_operations[op]) (
op_status[op, t] -> not op_status[conf_op, t]
);
% Окна непогоды.
int : n_bad_weather_windows;
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; % Включительно.
array [1..n_operations, 1..n_intervals] of bool : bad_weather;
constraint forall (i in 1..n_bad_weather_windows, t in bw_start[i]..bw_fin[i]) (
op_status[bw_op[i], t] == false
constraint forall (op in 1..n_operations, t in 1..n_intervals) (
bad_weather[op, t] -> (op_status[op, t] = false)
);
% Грузообработка.
......@@ -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;
constraint (is_not_terminated[0] == false /\ is_not_terminated[n_intervals + 1] == false);
......@@ -366,4 +442,11 @@ output [show(sum(is_not_terminated)), "\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",
/*
"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 {
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 {
ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0);
......@@ -994,18 +1016,21 @@ public class ConversionUtil {
}
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 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) &&
(operationTemplates.get(j) instanceof LoadingTemplate)) {
LoadingTemplate op1 = (LoadingTemplate) operationTemplates.get(i);
LoadingTemplate op2 = (LoadingTemplate) operationTemplates.get(j);
if ((op1.getLoader() == op2.getLoader()) &&
(op1.getStorage() == op2.getStorage()) &&
if ((op1.getStorage() == op2.getStorage()) &&
(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 {
if (((t1 instanceof MovingTemplate) || (t1 instanceof MooringTemplate))
&& (t2 instanceof LoadingTemplate)) {
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 {
MooringTemplate op2 = (MooringTemplate) operationTemplates.get(j);
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, "confl_op_1", conflictingPairs, Pair::getKey);
writeArray(writer, "confl_op_2", conflictingPairs, Pair::getValue);
writer.write("\n");
writeArray(writer, "conflicting_operations", conflictingOperationsG, ConversionUtil::setToString);
}
private void typifiedResourcesDefinition() throws IOException {
......@@ -1131,7 +1153,7 @@ public class ConversionUtil {
movingObjectLocationDefinition();
initialLocations();
finalLocations();
weatherWindows();
weatherWindowsNewFormat();
conflictingOperationsOnStorageAndOnTypeOnMainObject();
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