Commit 17da7eb2 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Добавлено несколько оптимизаций из conversion_2.mzn

parent 20b4658c
......@@ -82,6 +82,7 @@ array [0..n_moving_obj, 0..n_operations] of bool : moving_op_of_obj;
);
array [1..n_locations] of 0..n_locations : twin_location = [i - 1 + (i mod 2) * 2 | i in 1..n_locations];
array [1..n_locations] of 1..n_locations : main_location = [i - ((i + 1) mod 2)| i in 1..n_locations];
array [0..n_operations] of 0..n_locations : operations_destination; % Локация в которой окажется объект после завершения операции.
......@@ -637,13 +638,100 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
(op_start[op, t] /\ (not is_fixed[op, t])) -> not is_op_possible[op, t - 1]
);
% Для оптимизаций.
% Оптимизация - судно возвращается откуда перед этим пришло -> оно сделало или делает что-то "полезное".
array [0..n_moving_obj, 0..(n_intervals + 1)] of var 1..n_locations : prev_m_obj_loc;
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_involved_in_useful_operation;
constraint forall (t in 0..(n_intervals + 1)) (prev_m_obj_loc[0, t] = 1);
constraint forall (t in 0..(n_intervals + 1)) (is_obj_involved_in_useful_operation[0, t] = false);
% Определение prev_m_obj_loc
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
(m_obj_loc[obj, t - 1] != m_obj_loc[obj, t]) -> (prev_m_obj_loc[obj, t] = m_obj_loc[obj, t - 1])
);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
(m_obj_loc[obj, t - 1] == m_obj_loc[obj, t]) -> (prev_m_obj_loc[obj, t] = prev_m_obj_loc[obj, t - 1])
);
constraint forall (obj in 1..n_moving_obj) (prev_m_obj_loc[obj, 0] = m_obj_loc[obj, 0]);
% Определение is_obj_involved_in_useful_operation
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
is_obj_involved_in_useful_operation[obj, t] = (
(participation_as_resource[obj, t] != 0)
\/ (exists (op in related_cargo_op[obj]) (op_status[op, t]))
\/ (is_obj_involved_in_fixed_op[obj, t])
\/ (exists (op in related_unmooring_op[obj]) (op_status[op, t]))
)
);
constraint forall (obj in 1..n_moving_obj) (is_obj_involved_in_useful_operation[obj, 0] = false);
% Успел ли объект поучаствовать в полезной операции к концу данного интервала.
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_attended_useful_op_in_cur_loc;
% Определение is_attended_useful_op_in_cur_loc
constraint forall (t in 0..(n_intervals + 1)) (is_attended_useful_op_in_cur_loc[0, t] = false);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
is_attended_useful_op_in_cur_loc[obj, t] = (
(is_attended_useful_op_in_cur_loc[obj, t - 1] /\ (m_obj_loc[obj, t - 1] == m_obj_loc[obj, t])) % Предыдущее значение в текущей локации.
\/
is_obj_involved_in_useful_operation[obj, t]
\/
is_obj_involved_in_useful_operation[obj, t - 1] % Учитывает случай когда операция перемещения, из-за которой объект попал в локацию была нужна.
)
);
% Сама оптимизация - если объект
constraint forall (obj in 1..n_moving_obj, t in 2..(n_intervals + 1)) (
((m_obj_loc[obj, t - 1] != m_obj_loc[obj, t]) /\ (prev_m_obj_loc[obj, t - 1] == m_obj_loc[obj, t])
) -> is_attended_useful_op_in_cur_loc[obj, t - 1]
);
% Оптимизация - если объект не может совершить в данной локации операции без выхода за границы хранилища, а так же если он
% может уйти только своим ходом, то он либо уходит немедленно, либо остаётся на месте навсегда.
array [1..n_all_storage_sections, 1..n_locations] of int : min_positive_cargo_val; % Объём максимальной положительной операции, которая может быть произведена с этой секцией в этом хранилище. Если в локации таковой нет, то это значение объёма хранилища + 1.
array [1..n_all_storage_sections, 1..n_locations] of int : max_negative_cargo_val;
array [1..n_moving_obj, 1..n_locations] of bool : can_obj_leave_loc_only_alone;
array [1..n_moving_obj, 1..n_locations, 1..n_intervals] of bool : is_fixed_op_planned_in_future;
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : can_obj_theoretically_use_cargo_op;
% Определение can_obj_theoretically_use_cargo_op.
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
can_obj_theoretically_use_cargo_op[obj, t] = (
is_sections_of_moving_obj_empty[obj]
\/
exists (section in sections_of_moving_obj[obj]) (
(storage_used_volume[section, t - 1] + min_positive_cargo_val[section, main_location[m_obj_loc[obj, t]]] <= max_storage_vol[section])
\/ (storage_used_volume[section, t - 1] + max_negative_cargo_val[section, main_location[m_obj_loc[obj, t]]] >= 0)
)
)
);
constraint forall (t in 0..(n_intervals + 1)) (can_obj_theoretically_use_cargo_op[0, t] = false);
constraint forall (obj in 1..n_moving_obj) (can_obj_theoretically_use_cargo_op[obj, 0] = false);
% Остановился ли объект окончательно, начиная с данного интервала.
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_totally_terminated;
constraint forall (obj in 1..n_moving_obj) (is_obj_totally_terminated[obj, n_intervals + 1] = true);
constraint forall (t in 0..(n_intervals + 1)) (is_obj_totally_terminated[0, t] = true);
constraint forall (obj in 1..n_moving_obj, t in 0..n_intervals) (
is_obj_totally_terminated[obj, t] = (
(current_moving_operation[obj, t] = 0)
/\ (not is_involved_in_cargo_op[obj, t])
/\ (is_obj_totally_terminated[obj, t + 1])
)
);
% Само ограничение.
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
( (can_obj_leave_loc_only_alone[obj, m_obj_loc[obj, t]])
/\ (not can_obj_theoretically_use_cargo_op[obj, t])
/\ (not is_fixed_op_planned_in_future[obj, m_obj_loc[obj, t], t])
) ->
(is_obj_totally_terminated[obj, t] \/ (current_moving_operation[obj, t] != 0))
);
% Критерий оптимизации
array [1..(n_intervals + 1)] of var bool : is_not_terminated;
% В конце всё остановится.
......
......@@ -81,6 +81,7 @@ array [0..n_moving_obj, 0..n_operations] of bool : moving_op_of_obj;
);
array [1..n_locations] of 0..n_locations : twin_location = [i - 1 + (i mod 2) * 2 | i in 1..n_locations];
array [1..n_locations] of 1..n_locations : main_location = [i - ((i + 1) mod 2)| i in 1..n_locations];
array [0..n_operations] of 0..n_locations : operations_destination; % Локация в которой окажется объект после завершения операции.
......@@ -499,12 +500,101 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
)
);
% Оптимизация - судно возвращается откуда перед этим пришло -> оно сделало или делает что-то "полезное".
array [0..n_moving_obj, 0..(n_intervals + 1)] of var 1..n_locations : prev_m_obj_loc;
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_involved_in_useful_operation;
constraint forall (t in 0..(n_intervals + 1)) (prev_m_obj_loc[0, t] = 1);
constraint forall (t in 0..(n_intervals + 1)) (is_obj_involved_in_useful_operation[0, t] = false);
% Определение prev_m_obj_loc
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
(m_obj_loc[obj, t - 1] != m_obj_loc[obj, t]) -> (prev_m_obj_loc[obj, t] = m_obj_loc[obj, t - 1])
);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
(m_obj_loc[obj, t - 1] == m_obj_loc[obj, t]) -> (prev_m_obj_loc[obj, t] = prev_m_obj_loc[obj, t - 1])
);
constraint forall (obj in 1..n_moving_obj) (prev_m_obj_loc[obj, 0] = m_obj_loc[obj, 0]);
% Определение is_obj_involved_in_useful_operation
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
is_obj_involved_in_useful_operation[obj, t] = (
(participation_as_resource[obj, t] != 0)
\/ (exists (op in related_cargo_op[obj]) (op_status[op, t]))
\/ (is_obj_involved_in_fixed_op[obj, t])
\/ (exists (op in related_unmooring_op[obj]) (op_status[op, t]))
)
);
constraint forall (obj in 1..n_moving_obj) (is_obj_involved_in_useful_operation[obj, 0] = false);
% Успел ли объект поучаствовать в полезной операции к концу данного интервала.
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_attended_useful_op_in_cur_loc;
% Определение is_attended_useful_op_in_cur_loc
constraint forall (t in 0..(n_intervals + 1)) (is_attended_useful_op_in_cur_loc[0, t] = false);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
is_attended_useful_op_in_cur_loc[obj, t] = (
(is_attended_useful_op_in_cur_loc[obj, t - 1] /\ (m_obj_loc[obj, t - 1] == m_obj_loc[obj, t])) % Предыдущее значение в текущей локации.
\/
is_obj_involved_in_useful_operation[obj, t]
\/
is_obj_involved_in_useful_operation[obj, t - 1] % Учитывает случай когда операция перемещения, из-за которой объект попал в локацию была нужна.
)
);
% Сама оптимизация - если объект
constraint forall (obj in 1..n_moving_obj, t in 2..(n_intervals + 1)) (
((m_obj_loc[obj, t - 1] != m_obj_loc[obj, t]) /\ (prev_m_obj_loc[obj, t - 1] == m_obj_loc[obj, t])
) -> is_attended_useful_op_in_cur_loc[obj, t - 1]
);
% Оптимизация - если объект не может совершить в данной локации операции без выхода за границы хранилища, а так же если он
% может уйти только своим ходом, то он либо уходит немедленно, либо остаётся на месте навсегда.
array [1..n_all_storage_sections, 1..n_locations] of int : min_positive_cargo_val; % Объём максимальной положительной операции, которая может быть произведена с этой секцией в этом хранилище. Если в локации таковой нет, то это значение объёма хранилища + 1.
array [1..n_all_storage_sections, 1..n_locations] of int : max_negative_cargo_val;
array [1..n_moving_obj, 1..n_locations] of bool : can_obj_leave_loc_only_alone;
array [1..n_moving_obj, 1..n_locations, 1..n_intervals] of bool : is_fixed_op_planned_in_future;
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : can_obj_theoretically_use_cargo_op;
% Определение can_obj_theoretically_use_cargo_op.
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
can_obj_theoretically_use_cargo_op[obj, t] = (
is_sections_of_moving_obj_empty[obj]
\/
exists (section in sections_of_moving_obj[obj]) (
(storage_used_volume[section, t - 1] + min_positive_cargo_val[section, main_location[m_obj_loc[obj, t]]] <= max_storage_vol[section])
\/ (storage_used_volume[section, t - 1] + max_negative_cargo_val[section, main_location[m_obj_loc[obj, t]]] >= 0)
)
)
);
constraint forall (t in 0..(n_intervals + 1)) (can_obj_theoretically_use_cargo_op[0, t] = false);
constraint forall (obj in 1..n_moving_obj) (can_obj_theoretically_use_cargo_op[obj, 0] = false);
% Остановился ли объект окончательно, начиная с данного интервала.
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_totally_terminated;
constraint forall (obj in 1..n_moving_obj) (is_obj_totally_terminated[obj, n_intervals + 1] = true);
constraint forall (t in 0..(n_intervals + 1)) (is_obj_totally_terminated[0, t] = true);
constraint forall (obj in 1..n_moving_obj, t in 0..n_intervals) (
is_obj_totally_terminated[obj, t] = (
(current_moving_operation[obj, t] = 0)
/\ (not is_involved_in_cargo_op[obj, t])
/\ (is_obj_totally_terminated[obj, t + 1])
)
);
% Само ограничение.
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
( (can_obj_leave_loc_only_alone[obj, m_obj_loc[obj, t]])
/\ (not can_obj_theoretically_use_cargo_op[obj, t])
/\ (not is_fixed_op_planned_in_future[obj, m_obj_loc[obj, t], t])
) ->
(is_obj_totally_terminated[obj, t] \/ (current_moving_operation[obj, t] != 0))
);
% Критерий оптимизации
array [1..(n_intervals + 1)] of var bool : is_not_terminated;
% В конце всё остановится.
......
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