Commit 752f9425 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Добавлены оптимизации.

parent 30d0fc31
...@@ -142,6 +142,26 @@ int can_obj_leave_loc_only_alone[1..n_moving_obj, 1..n_locations] = ...; ...@@ -142,6 +142,26 @@ int can_obj_leave_loc_only_alone[1..n_moving_obj, 1..n_locations] = ...;
int is_fixed_op_planned_in_future[1..n_moving_obj, 1..n_locations, 1..n_intervals] = ...; int is_fixed_op_planned_in_future[1..n_moving_obj, 1..n_locations, 1..n_intervals] = ...;
// Возможно ли начать операцию в данный интервал (если предположить, что операция длится 1 интервал).
dvar boolean is_op_possible[0..n_operations, 1..n_intervals];
// Счётчик ресурсов, которые могут быть потенциально задействованы в операции.
dvar int possible_resources_counter[1..n_resources_counters , 1..n_intervals];
dvar boolean is_enough_free_resources[0..n_operations, 1..n_intervals];
dvar boolean can_obj_theoretically_use_cargo_op[0..n_moving_obj, 0..(n_intervals + 1)];
// Остановился ли объект окончательно, начиная с данного интервала.
dvar boolean is_obj_totally_terminated[0..n_moving_obj, 0..(n_intervals + 1)];
dvar int prev_m_obj_loc[0..n_moving_obj, 0..(n_intervals + 1)] in 1..n_locations;
dvar boolean is_obj_involved_in_useful_operation[0..n_moving_obj, 0..(n_intervals + 1)];
// Успел ли объект поучаствовать в полезной операции к концу данного интервала.
dvar boolean is_attended_useful_op_in_cur_loc[0..n_moving_obj, 0..(n_intervals + 1)];
dvar boolean is_not_terminated[1..(n_intervals + 1)]; dvar boolean is_not_terminated[1..(n_intervals + 1)];
minimize sum (i in 1..(n_intervals + 1)) is_not_terminated[i]; minimize sum (i in 1..(n_intervals + 1)) is_not_terminated[i];
...@@ -430,171 +450,153 @@ subject to { ...@@ -430,171 +450,153 @@ subject to {
// // Оптимизация - сдвиг в начало. // Оптимизация - сдвиг в начало.
// // Возможно ли начать операцию в данный интервал (если предположить, что операция длится 1 интервал). forall (t in 1..n_intervals) (is_op_possible[0, t] == false); // Фиктивный объект.
// array [0..n_operations, 1..n_intervals] of var bool : is_op_possible;
// // Определение possible_resources_counter.
// forall (t in 1..n_intervals) (is_op_possible[0, t] == false); // Фиктивный объект. 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) &&
// array [1..n_resources_counters , 1..n_intervals] of var int : possible_resources_counter; (current_moving_operation[obj, t] == 0) &&
// (m_obj_loc[obj, t] == operations_resources_start_loc[counter])
// // Определение possible_resources_counter. )
// 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]) forall (t in 1..n_intervals) (is_enough_free_resources[0, t] == false); // Фиктивный объект.
// )
// ); forall (op in 1..n_operations, t in 1..n_intervals) (
// is_enough_free_resources[op, t] == and (counter in counters_of_operation[op]) (
// // Достаточно ли свободных ресурсов для операции. possible_resources_counter[counter, t] >= required_counter_values[counter]
// array [0..n_operations, 1..n_intervals] of var bool : is_enough_free_resources; )
// );
// forall (t in 1..n_intervals) (is_enough_free_resources[0, t] == false); // Фиктивный объект.
// // Определение is_op_possible.
// forall (op in 1..n_operations, t in 1..n_intervals) ( forall (op in 1..n_operations, t in 1..n_intervals) (
// is_enough_free_resources[op, t] == forall (counter in counters_of_operation[op]) ( is_op_possible[op, t] == (
// possible_resources_counter[counter, t] >= required_counter_values[counter] (bad_weather[op, t] == 0) && // Погода не мешает.
// ) (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_op_possible. && // Главный объект не участвует в операции перемещеня.
// forall (op in 1..n_operations, t in 1..n_intervals) ( (is_enough_free_resources[op, t] == true) && // Достаточно свободных ресурсов на нужном месте.
// is_op_possible[op, t] == ( (and (conf_op in conflicting_operations[op]) (op_status[conf_op, t] == false))
// (bad_weather[op, t] == false) && // Погода не мешает. && // Не выполняется ни одной конфликтующей операции.
// (m_obj_loc[main_obj_of_operation[op], t] == main_obj_start_loc[op]) ((is_moving_operation[op] == 1) => is_involved_in_cargo_op[main_obj_of_operation[op], t] == false)
// && // Главный объект на месте. && // Если это операция перемещения, то главный объект
// (current_moving_operation[main_obj_of_operation[op], t] == 0) // не участвует в операциях погрузки.
// && // Главный объект не участвует в операции перемещеня. (((is_mooring_op[op] == 1) && (operations_destination[op] mod 2 == 0)) => (
// (is_enough_free_resources[op, t] == true) && // Достаточно свободных ресурсов на нужном месте. current_moored_obj[operations_destination[op], t] == 0)
// (forall (conf_op in conflicting_operations[op]) (op_status[conf_op, t] == false)) ) && // Если это операция пришвартовки, то в этот интервал
// && // Не выполняется ни одной конфликтующей операции. // причал должен быть свободным.
// (is_moving_operation[op] -> not is_involved_in_cargo_op[main_obj_of_operation[op], t]) ((is_moving_operation[op] == 0) => (
// && // Если это операция перемещения, то главный объект (storage_used_volume[operations_main_stor[op], t] + loading_op_delta_of_main_obj[op] >= 0) &&
// // не участвует в операциях погрузки. (storage_used_volume[operations_main_stor[op], t] + loading_op_delta_of_main_obj[op] <= max_storage_vol[operations_main_stor[op]]) &&
// ((is_mooring_op[op] && (operations_destination[op] mod 2 = 0)) -> ( (storage_used_volume[operations_secondary_stor[op], t] - loading_op_delta_of_main_obj[op] >= 0) &&
// current_moored_obj[operations_destination[op], t] = 0) (storage_used_volume[operations_secondary_stor[op], t] - loading_op_delta_of_main_obj[op] <= max_storage_vol[operations_secondary_stor[op]])
// ) && // Если это операция пришвартовки, то в этот интервал )) && // Если это операция грузообработки, то она не выведет
// // причал должен быть свободным. // объём берегового хранилища и хранилища судна за
// ((not is_moving_operation[op]) -> ( // границы дозволенного.
// let {1..n_all_storage_sections : m_stor = operations_main_stor[op]; (((is_moving_operation[op] == 0) && (main_obj_start_loc[op] mod 2 == 1)) =>
// 1..n_all_storage_sections : s_stor = operations_secondary_stor[op]; ((current_moored_obj[twin_location[main_obj_start_loc[op]], t] == 0) ||
// int : delta = loading_op_delta_of_main_obj[op]; (current_moored_obj[twin_location[main_obj_start_loc[op]], t] == main_obj_of_operation[op]))
// } in ) && // Если это операция грузообработки без пришвартовки,
// (storage_used_volume[m_stor, t] + delta >= 0) /\ // то причал должен быть свободен в этот интервал, либо
// (storage_used_volume[m_stor, t] + delta <= max_storage_vol[m_stor]) /\ // главный объект должен быть уже условно пришвартован.
// (storage_used_volume[s_stor, t] - delta >= 0) /\ (((bunker_of_cargo_op[op] != 0) && (op_status[op, t] == 0)) =>
// (storage_used_volume[s_stor, t] - delta <= max_storage_vol[s_stor]) ((m_obj_loc[bunker_of_cargo_op[op], t] == bunker_start_loc[op]) &&
// )) /\ // Если это операция грузообработки, то она не выведет (current_moving_operation[bunker_of_cargo_op[op], t] == 0))
// // объём берегового хранилища и хранилища судна за ) // Бункеровщик (если есть) находится в нужной локации
// // границы дозволенного. // и не участвует в операциях перемещения.
// (((not is_moving_operation[op]) /\ (main_obj_start_loc[op] mod 2 = 1)) -> )
// ((current_moored_obj[twin_location[main_obj_start_loc[op]], t] = 0) \/ );
// (current_moored_obj[twin_location[main_obj_start_loc[op]], t] = main_obj_of_operation[op]))
// ) /\ // Если это операция грузообработки без пришвартовки, // Сам критерий оптимизации - если если операцию можно было начать на 1 интервал раньше, то её нужно начать раньше.
// // то причал должен быть свободен в этот интервал, либо forall (op in 1..n_operations, t in 2..n_intervals) (
// // главный объект должен быть уже условно пришвартован. ((op_start[op, t] == 1) && (is_fixed[op, t] == 0)) => (is_op_possible[op, t - 1] == 0)
// (((bunker_of_cargo_op[op] != 0) /\ (op_status[op, t])) -> );
// ((m_obj_loc[bunker_of_cargo_op[op], t] = bunker_start_loc[op]) /\
// (current_moving_operation[bunker_of_cargo_op[op], t] = 0))
// ) // Бункеровщик (если есть) находится в нужной локации
// // и не участвует в операциях перемещения.
// )
// );
//
// // Сам критерий оптимизации - если если операцию можно было начать на 1 интервал раньше, то её нужно начать раньше.
// forall (op in 1..n_operations, t in 2..n_intervals) (
// (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; forall (t in 0..(n_intervals + 1)) (prev_m_obj_loc[0, t] == 1);
// array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_involved_in_useful_operation; forall (t in 0..(n_intervals + 1)) (is_obj_involved_in_useful_operation[0, t] == 0);
//
// constraint forall (t in 0..(n_intervals + 1)) (prev_m_obj_loc[0, t] = 1); // Определение prev_m_obj_loc
// constraint forall (t in 0..(n_intervals + 1)) (is_obj_involved_in_useful_operation[0, t] = false); 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])
// // Определение prev_m_obj_loc );
// constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) ( 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]) (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, t in 1..(n_intervals + 1)) ( forall (obj in 1..n_moving_obj) (prev_m_obj_loc[obj, 0] == m_obj_loc[obj, 0]);
// (m_obj_loc[obj, t - 1] == m_obj_loc[obj, t]) -> (prev_m_obj_loc[obj, t] = prev_m_obj_loc[obj, t - 1])
// ); // Определение is_obj_involved_in_useful_operation
// constraint forall (obj in 1..n_moving_obj) (prev_m_obj_loc[obj, 0] = m_obj_loc[obj, 0]); forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
// is_obj_involved_in_useful_operation[obj, t] == (
// // Определение is_obj_involved_in_useful_operation (participation_as_resource[obj, t] != 0)
// constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) ( || (or (op in related_cargo_op[obj]) (op_status[op, t] == 1))
// is_obj_involved_in_useful_operation[obj, t] = ( || (is_obj_involved_in_fixed_op[obj, t] == 1)
// (participation_as_resource[obj, t] != 0) || (or (op in related_unmooring_op[obj]) (op_status[op, t] == 1))
// \/ (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])) forall (obj in 1..n_moving_obj) (is_obj_involved_in_useful_operation[obj, 0] == 0);
// )
// ); // Определение is_attended_useful_op_in_cur_loc
// constraint forall (obj in 1..n_moving_obj) (is_obj_involved_in_useful_operation[obj, 0] = false); forall (t in 0..(n_intervals + 1)) (is_attended_useful_op_in_cur_loc[0, t] == 0);
//
// // Успел ли объект поучаствовать в полезной операции к концу данного интервала. forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
// 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[obj, t] == (
// // Определение is_attended_useful_op_in_cur_loc ((is_attended_useful_op_in_cur_loc[obj, t - 1] == 1) && (m_obj_loc[obj, t - 1] == m_obj_loc[obj, t])) // Предыдущее значение в текущей локации.
// constraint forall (t in 0..(n_intervals + 1)) (is_attended_useful_op_in_cur_loc[0, t] = false); ||
// (is_obj_involved_in_useful_operation[obj, t] == 1)
// constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) ( ||
// is_attended_useful_op_in_cur_loc[obj, t] = ( (is_obj_involved_in_useful_operation[obj, t - 1] == 1) // Учитывает случай когда операция перемещения, из-за которой объект попал в локацию была нужна.
// (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] // Учитывает случай когда операция перемещения, из-за которой объект попал в локацию была нужна. 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] == 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]
// ); // Определение can_obj_theoretically_use_cargo_op.
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] == 1)
// ||
// array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : can_obj_theoretically_use_cargo_op; or (section in sections_of_moving_obj[obj]) (
// // Определение can_obj_theoretically_use_cargo_op. (storage_used_volume[section, t - 1] + min_positive_cargo_val[section, main_location[m_obj_loc[obj, t]]] <= max_storage_vol[section])
// constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) ( || (storage_used_volume[section, t - 1] + max_negative_cargo_val[section, main_location[m_obj_loc[obj, t]]] >= 0)
// can_obj_theoretically_use_cargo_op[obj, t] = ( )
// is_sections_of_moving_obj_empty[obj] )
// \/ );
// exists (section in sections_of_moving_obj[obj]) ( forall (t in 0..(n_intervals + 1)) (can_obj_theoretically_use_cargo_op[0, t] == false);
// (storage_used_volume[section, t - 1] + min_positive_cargo_val[section, main_location[m_obj_loc[obj, t]]] <= max_storage_vol[section]) forall (obj in 1..n_moving_obj) (can_obj_theoretically_use_cargo_op[obj, 0] == false);
// \/ (storage_used_volume[section, t - 1] + max_negative_cargo_val[section, main_location[m_obj_loc[obj, t]]] >= 0)
// )
// ) forall (obj in 1..n_moving_obj) (is_obj_totally_terminated[obj, n_intervals + 1] == true);
// ); forall (t in 0..(n_intervals + 1)) (is_obj_totally_terminated[0, t] == true);
// 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); forall (obj in 1..n_moving_obj, t in 0..n_intervals) (
// is_obj_totally_terminated[obj, t] == (
// // Остановился ли объект окончательно, начиная с данного интервала. (current_moving_operation[obj, t] == 0)
// array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_totally_terminated; && (is_involved_in_cargo_op[obj, t] == 0)
// constraint forall (obj in 1..n_moving_obj) (is_obj_totally_terminated[obj, n_intervals + 1] = true); && (is_obj_totally_terminated[obj, t + 1] == 1)
// 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) forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
// /\ (not is_involved_in_cargo_op[obj, t]) ( (can_obj_leave_loc_only_alone[obj, m_obj_loc[obj, t]] == 1)
// /\ (is_obj_totally_terminated[obj, t + 1]) && (can_obj_theoretically_use_cargo_op[obj, t] == 0)
// ) && (is_fixed_op_planned_in_future[obj, m_obj_loc[obj, t], t] == 0)
// ); ) =>
// ((is_obj_totally_terminated[obj, t] == 1) || (current_moving_operation[obj, t] != 0))
// // Само ограничение. );
// 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))
// );
// Критерий оптимизации // Критерий оптимизации
// В конце всё остановится. // В конце всё остановится.
...@@ -624,5 +626,8 @@ execute { ...@@ -624,5 +626,8 @@ execute {
writeln("participation_as_resource = ", participation_as_resource, ";"); writeln("participation_as_resource = ", participation_as_resource, ";");
writeln("is_involved_in_cargo_op = ", is_involved_in_cargo_op, ";"); writeln("is_involved_in_cargo_op = ", is_involved_in_cargo_op, ";");
writeln("is_op_possible = ", is_op_possible, ";");
} }
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