Commit 2766a7f9 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Добавлена возможность бункеровки, упрощено сведение.

parent c22255ea
...@@ -5,14 +5,19 @@ int : n_operations; ...@@ -5,14 +5,19 @@ int : n_operations;
int : n_locations; int : n_locations;
int : n_moving_obj; int : n_moving_obj;
array [1..n_operations, 0..(n_intervals + 1)] of var bool : op_status; array [0..n_operations, 0..(n_intervals + 1)] of var bool : op_status;
array [1..n_operations, 0..(n_intervals + 1)] of var bool : op_start; array [0..n_operations, 0..(n_intervals + 1)] of var bool : op_start;
array [1..n_moving_obj, 1..n_operations] of bool : moving_op_of_obj; constraint forall (t in 0..(n_intervals + 1)) (op_status[0, t] = false); % Фиктивная операция.
constraint forall (t in 0..(n_intervals + 1)) ( op_start[0, t] = false); % Фиктивная операция.
array [0..n_moving_obj, 0..n_operations] of bool : moving_op_of_obj;
% Определение current_moving_operation. % Определение current_moving_operation.
% Текущая операция операция перемещения, в которой задействован данный объект. % Текущая операция операция перемещения, в которой задействован данный объект.
array [1..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_operations : current_moving_operation; array [0..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_operations : current_moving_operation;
constraint forall (t in 0..(n_intervals + 1)) (current_moving_operation[0, t] = 0); % Фиктивный объект.
% Крайние значения. % Крайние значения.
constraint forall (obj in 1..n_moving_obj, t in {0, n_intervals + 1}) ( constraint forall (obj in 1..n_moving_obj, t in {0, n_intervals + 1}) (
...@@ -32,59 +37,62 @@ array [1..n_moving_obj, 1..n_operations] of bool : moving_op_of_obj; ...@@ -32,59 +37,62 @@ array [1..n_moving_obj, 1..n_operations] of bool : moving_op_of_obj;
(current_moving_operation[obj, t] != 0) -> (op_status[current_moving_operation[obj, t], t]) (current_moving_operation[obj, t] != 0) -> (op_status[current_moving_operation[obj, t], t])
); );
% Ограничение на количество пришвартованных кораблей. % Определение current_moored_obj.
% Счётчик объектов в локации (только в чётных - в состоянии пришвартованности). % Объект, пришвартованный к данной локации.
array [1..n_locations, 0..(n_intervals + 1)] of var int : obj_in_loc_counter; array [0..n_locations, 0..(n_intervals + 1)] of var 0..n_moving_obj : current_moored_obj;
array [1..n_locations] of 1..n_locations : twin_location = [i - 1 + (i mod 2) * 2 | i in 1..n_locations]; constraint forall (t in 0..(n_intervals + 1)) (current_moored_obj[0, t] = 0); % Фиктивная локация.
% Операции грузообработки, проводимые без пришвартовки на этой локации. % Фиксирование неиспользуемых значений.
array [1..n_locations] of set of 1..n_operations : related_unmoored_cargo_op; constraint forall (loc in 1..n_locations, t in 0..(n_intervals + 1) where loc mod 2 = 1) (
current_moored_obj[loc, t] = 0
% Определение obj_in_loc_counter.
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 ((not is_moving_operation[op]) /\ (main_obj_start_loc[op] = twin_location[loc]))) % Погрузка без швартовки.
% (op_status[op, t])
% ) % TODO узнать, почему медленнее варианта выше.
+ (sum (op in 1..n_operations where (is_mooring_op[op] /\ (main_obj_start_loc[op] = loc))) % Отшвартовка.
(op_status[op, t])
)
); );
% Само ограничение. % Крайние значения.
constraint forall (loc in 1..n_locations, t in 0..(n_intervals + 1) where (loc mod 2) = 0) ( constraint forall (loc in 1..n_locations, t in {0, n_intervals + 1}) (
obj_in_loc_counter[loc, t] <= 1 current_moored_obj[loc, t] = 0
); );
% Определение is_m_obj_in_movement_before_start. % Операции с условной швартовкой.
% Находится ли объект в движении перед началом интервала. int : op_with_nominally_mooring_max_size;
array [1..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_m_obj_in_movement_before_start; array [0..n_locations, 0..n_moving_obj] of 0..op_with_nominally_mooring_max_size : op_with_nominally_mooring_sizes;
array [0..n_locations, 0..n_moving_obj, 1..op_with_nominally_mooring_max_size] of 1..n_operations : op_with_nominally_mooring;
% current_moored_obj соответствуе какому-либо реально пришвартованному объекту.
constraint forall (loc in 1..n_locations, t in 1..n_intervals, obj = current_moored_obj[loc, t]
where loc mod 2 = 0) (
(obj != 0) -> ((m_obj_loc[obj, t] = loc) \/
(exists (op in [op_with_nominally_mooring[loc, obj, id] | id in 1..op_with_nominally_mooring_sizes[loc, obj]])
(op_status[op, t]))
)
);
% В начале никто не движется. % Если объект пришвартован или швартуется, то current_moored_obj об это знает.
constraint forall (obj in 1..n_moving_obj) (not is_m_obj_in_movement_before_start[obj, 0]); constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals, loc = m_obj_loc[obj, t]) (
% Перед первым интервалом все тоже стоят на месте. (loc mod 2 = 0) -> (current_moored_obj[loc, t] = obj)
constraint forall (obj in 1..n_moving_obj) (not is_m_obj_in_movement_before_start[obj, 1]); );
% Если в предыдущем интервале объект не движется - то в начале этого он не движется, иначе он движется если предыдущая операция не закончилась. % Если выполняется операция, где судно условно пришвартовано, то current_moored_obj знает об этом.
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) ( constraint forall (loc in 1..n_locations,
(current_moving_operation[obj, t - 1] = 0) obj in 1..n_moving_obj,
-> is_m_obj_in_movement_before_start[obj, t] = false op in [op_with_nominally_mooring[loc, obj, id] | id in 1..op_with_nominally_mooring_sizes[loc, obj]],
); t in 1..n_intervals) (
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) ( op_status[op, t] -> (current_moored_obj[loc, t] = obj)
(current_moving_operation[obj, t - 1] != 0) );
-> is_m_obj_in_movement_before_start[obj, t] = (current_moving_operation[obj, t - 1] == current_moving_operation[obj, t])
);
array [1..n_operations] of 1..n_locations : operations_destination; % Локация в которой окажется объект после завершения операции. array [1..n_locations] of 0..n_locations : twin_location = [i - 1 + (i mod 2) * 2 | i in 1..n_locations];
% TODO нумерация с нуля
array [0..n_operations] of 0..n_locations : operations_destination; % Локация в которой окажется объект после завершения операции.
% Определение m_obj_loc. % Определение m_obj_loc.
% Местоположение объекта или пункт назначения (если объект движется) перед началом определённого интервала. % Местоположение объекта или пункт назначения (если объект движется) перед началом определённого интервала.
array [1..n_moving_obj, 0..(n_intervals + 1)] of var 1..n_locations : m_obj_loc; array [0..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_locations : m_obj_loc;
constraint forall (t in 0..(n_intervals + 1)) (m_obj_loc[0, t] = 0); % Фиктивный объект.
% Главный объект (субъект) операции. % Главный объект (субъект) операции.
array [0..n_operations] of 1..n_moving_obj : main_obj_of_operation; array [0..n_operations] of 0..n_moving_obj : main_obj_of_operation;
% Является ли операция швартовкой/отшвартовкой. % Является ли операция швартовкой/отшвартовкой.
array [0..n_operations] of bool : is_mooring_op; array [0..n_operations] of bool : is_mooring_op;
...@@ -115,11 +123,11 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -115,11 +123,11 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
); );
% Начальное состояние. % Начальное состояние.
array [1..n_moving_obj] of 0..n_locations : initial_m_obj_loc; array [0..n_moving_obj] of 0..n_locations : initial_m_obj_loc;
constraint forall (i in 1..n_moving_obj) (m_obj_loc[i, 0] = initial_m_obj_loc[i]); constraint forall (i in 1..n_moving_obj) (m_obj_loc[i, 0] = initial_m_obj_loc[i]);
% Конечное состояние. % Конечное состояние.
array [1..n_moving_obj] of 0..n_locations : final_m_obj_loc; array [0..n_moving_obj] of 0..n_locations : final_m_obj_loc;
constraint forall (i in 1..n_moving_obj) ( constraint forall (i in 1..n_moving_obj) (
(final_m_obj_loc[i] != 0) -> (final_m_obj_loc[i] != 0) ->
(m_obj_loc[i, n_intervals + 1] = final_m_obj_loc[i]) (m_obj_loc[i, n_intervals + 1] = final_m_obj_loc[i])
...@@ -133,13 +141,15 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -133,13 +141,15 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Связь ресурсов с операцией и основным объектом. % Связь ресурсов с операцией и основным объектом.
% Операции, которые могут задействовать данный объект как ресурс. % Операции, которые могут задействовать данный объект как ресурс.
array [1..n_moving_obj] of set of 1..n_operations : operations_that_used_obj_as_resource; array [0..n_moving_obj] of set of 1..n_operations : operations_that_used_obj_as_resource;
% Является ли данная операция операцией перемещения. % Является ли данная операция операцией перемещения.
array [0..n_operations] of bool : is_moving_operation; array [0..n_operations] of bool : is_moving_operation;
% Операция, в которой участвует данный объект как ресурс. % Операция, в которой участвует данный объект как ресурс.
array [1..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_operations : participation_as_resource; array [0..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_operations : participation_as_resource;
constraint forall (t in 0..(n_intervals + 1)) (participation_as_resource[0, t] = 0); % Фиктивный объект.
% Граничные значения. % Граничные значения.
constraint forall (obj in 1..n_moving_obj) (participation_as_resource[obj, 0] = 0); constraint forall (obj in 1..n_moving_obj) (participation_as_resource[obj, 0] = 0);
...@@ -187,7 +197,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -187,7 +197,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
array [1..n_resources_counters] of 1..n_resources_types : counter_type; % Типы ресурсов, за которыми следят счётчики. array [1..n_resources_counters] of 1..n_resources_types : counter_type; % Типы ресурсов, за которыми следят счётчики.
array [1..n_resources_counters] of 1..n_operations : operation_of_counter; % Операция, которой принадлежит данный счётчик. array [1..n_resources_counters] of 1..n_operations : operation_of_counter; % Операция, которой принадлежит данный счётчик.
array [1..n_resources_counters] of int : required_counter_values; % Необходимые значения на счётчиках ресурсов для выполнения операции. array [1..n_resources_counters] of int : required_counter_values; % Необходимые значения на счётчиках ресурсов для выполнения операции.
array [1..n_operations] of set of 1..n_resources_counters : counters_of_operation; % Счётчики, которые относятся к данной операции. array [0..n_operations] of set of 1..n_resources_counters : counters_of_operation; % Счётчики, которые относятся к данной операции.
% Участие всех необходимых ресурсов в операции. % Участие всех необходимых ресурсов в операции.
constraint forall (t in 1..n_intervals, op in 1..n_operations, counter in counters_of_operation[op]) ( constraint forall (t in 1..n_intervals, op in 1..n_operations, counter in counters_of_operation[op]) (
...@@ -202,20 +212,22 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -202,20 +212,22 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
); );
% Участие объекта в операциях грузообработки. % Участие объекта в операциях грузообработки.
array [1..n_moving_obj, 1..n_intervals] of var bool : is_involved_in_cargo_op; array [0..n_moving_obj, 1..n_intervals] of var bool : is_involved_in_cargo_op;
constraint forall (t in 1..n_intervals) (is_involved_in_cargo_op[0, t] = false); % Фиктивный объект.
array [1..n_moving_obj] of set of 1..n_operations : related_cargo_op_using_obj_as_main; % Операции погрузки, которые используют этот объект в качестве главного или в качестве бункеровщика.
array [0..n_moving_obj] of set of 0..n_operations : related_cargo_op;
% TODO узнать про where % TODO узнать про where
% Определение is_involved_in_cargo_op. % Определение is_involved_in_cargo_op.
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) (
is_involved_in_cargo_op[obj, t] = is_involved_in_cargo_op[obj, t] = (
% (exists (op in 1..n_operations where (not is_moving_operation[op]) /\ (main_obj_of_operation[op] = obj)) ( % (exists (op in 1..n_operations where (not is_moving_operation[op]) /\ (main_obj_of_operation[op] = obj)) (
(exists (op in related_cargo_op_using_obj_as_main[obj]) ( (exists (op in related_cargo_op[obj]) (op_status[op, t]))
op_status[op, t] \/
)) ((participation_as_resource[obj, t] != 0) /\ (not is_moving_operation[participation_as_resource[obj, t]]))
\/ )
((participation_as_resource[obj, t] != 0) /\ (not is_moving_operation[participation_as_resource[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) (
...@@ -226,35 +238,41 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -226,35 +238,41 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Требуемое положение конкретных типов объектов в момент начала операций. % Требуемое положение конкретных типов объектов в момент начала операций.
array [1..n_resources_counters] of 1..n_locations : operations_resources_start_loc; array [1..n_resources_counters] of 1..n_locations : operations_resources_start_loc;
% Требуемое положение главного объекта в момент начала операций. % Наличие на месте всех ресурсов.
array [1..n_operations] of 1..n_locations : main_obj_start_loc;
% Наличие и готовность всех ресурсов.
constraint forall ( constraint forall (
op in 1..n_operations, op in 1..n_operations,
t in 1..n_intervals, t in 1..n_intervals,
counter in counters_of_operation[op], counter in counters_of_operation[op],
obj in objects_of_type[counter_type[counter]]) ( obj in objects_of_type[counter_type[counter]]) (
((participation_as_resource[obj, t] = op) /\ (op_start[op, t]) ((participation_as_resource[obj, t] = op) /\ (op_start[op, t])
) -> ((m_obj_loc[obj, t] == operations_resources_start_loc[counter]) /\ ) -> (m_obj_loc[obj, t] == operations_resources_start_loc[counter])
(not is_m_obj_in_movement_before_start[obj, t]) /\ );
((not is_moving_operation[op]) -> (current_moving_operation[obj, t] = 0))
) % Требуемое положение главного объекта в момент начала операций.
array [0..n_operations] of 0..n_locations : main_obj_start_loc;
% Требуемое положение бункеровщика в момент начала операции.
array [0..n_operations] of 0..n_locations : bunker_start_loc;
% Бункеровщик, участвующий в операции погрузки (0, если такогого нет или это не погрузка).
array [0..n_operations] of 0..n_moving_obj : bunker_of_cargo_op;
% Наличие главных объектов на месте.
constraint forall (op in 1..n_operations,
t in 1..n_intervals,
obj = main_obj_of_operation[op]) (
op_start[op, t] -> (m_obj_loc[obj, t] == main_obj_start_loc[op])
); );
/* TODO узнать, как ((not is_moving_operation[op]) -> (current_moving_operation[obj, t] = 0)) влияет на производительность -
по идее это не нужно, но на v2-60 без неё гораздо лучше чем с ней. % Наличие бункеровщиков на месте.
*/ constraint forall (op in 1..n_operations,
t in 1..n_intervals,
% Наличие главных объектов (субъектов) на месте. obj = bunker_of_cargo_op[op] where obj != 0) (
constraint forall (op in 1..n_operations, t in 1..n_intervals, obj = main_obj_of_operation[op]) ( op_start[op, t] -> (m_obj_loc[obj, t] == bunker_start_loc[op])
op_start[op, t] -> ((m_obj_loc[obj, t] == main_obj_start_loc[op]) /\
(not is_m_obj_in_movement_before_start[obj, t])
)
); );
% Непрерывность перемещения и швартовки. % Непрерывность перемещения и швартовки.
array [1..n_operations] of int : operations_duration; array [0..n_operations] of int : operations_duration;
array [1..n_operations] of bool : is_continuous_operation; array [0..n_operations] of bool : is_continuous_operation;
constraint forall (i in 1..n_operations, len = operations_duration[i] where is_continuous_operation[i]) ( constraint forall (i in 1..n_operations, len = operations_duration[i] where is_continuous_operation[i]) (
(forall (j in 1..(n_intervals - len + 1)) ( (forall (j in 1..(n_intervals - len + 1)) (
...@@ -268,14 +286,14 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -268,14 +286,14 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
); );
% Конфликтующие операции. % Конфликтующие операции.
array [1..n_operations] of set of 1..n_operations : conflicting_operations; array [0..n_operations] of set of 1..n_operations : conflicting_operations;
constraint forall (op in 1..n_operations, t in 0..(n_intervals + 1), conf_op in conflicting_operations[op]) ( 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] op_status[op, t] -> not op_status[conf_op, t]
); );
% Окна непогоды. % Окна непогоды.
array [1..n_operations, 1..n_intervals] of bool : bad_weather; array [0..n_operations, 0..n_intervals] of bool : bad_weather;
constraint forall (op in 1..n_operations, t in 1..n_intervals) ( constraint forall (op in 1..n_operations, t in 1..n_intervals) (
bad_weather[op, t] -> (op_status[op, t] = false) bad_weather[op, t] -> (op_status[op, t] = false)
...@@ -284,10 +302,12 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -284,10 +302,12 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Грузообработка. % Грузообработка.
int : n_cargo_types; int : n_cargo_types;
int : n_obj_with_storage; int : n_obj_with_storage;
array [1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types] of var int : storage_used_volume; % Первые n_moving_obj соответствуют наполненности соответствующих движущихся объектов. array [0..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types] of var int : storage_used_volume; % Первые n_moving_obj соответствуют наполненности соответствующих движущихся объектов.
constraint forall (t in 0..(n_intervals + 1), cargo in 1..n_cargo_types) (storage_used_volume[0, t, cargo] = 0); % Фиктивный объект.
% Ограничения на вместимость. % Ограничения на вместимость.
array [1..n_obj_with_storage] of int : max_storage_vol; array [0..n_obj_with_storage] of int : max_storage_vol;
% Максимальный объём. % Максимальный объём.
constraint forall (storage in 1..n_obj_with_storage, t in 0..(n_intervals + 1)) ( constraint forall (storage in 1..n_obj_with_storage, t in 0..(n_intervals + 1)) (
sum (cargo in 1..n_cargo_types) (storage_used_volume[storage, t, cargo]) <= max_storage_vol[storage] sum (cargo in 1..n_cargo_types) (storage_used_volume[storage, t, cargo]) <= max_storage_vol[storage]
...@@ -298,8 +318,8 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -298,8 +318,8 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
); );
% Ограничения на граничные значения. % Ограничения на граничные значения.
array [1..n_obj_with_storage, 1..n_cargo_types] of int : initial_storage_vol; array [0..n_obj_with_storage, 0..n_cargo_types] of int : initial_storage_vol;
array [1..n_obj_with_storage, 1..n_cargo_types] of int : final_storage_vol; array [0..n_obj_with_storage, 0..n_cargo_types] of int : final_storage_vol;
constraint forall (storage in 1..n_obj_with_storage, cargo in 1..n_cargo_types) ( % Initial values. constraint forall (storage in 1..n_obj_with_storage, cargo in 1..n_cargo_types) ( % Initial values.
storage_used_volume[storage, 0, cargo] = initial_storage_vol[storage, cargo] storage_used_volume[storage, 0, cargo] = initial_storage_vol[storage, cargo]
...@@ -311,14 +331,14 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -311,14 +331,14 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
); );
% Изменение грузов в хранилищах. % Изменение грузов в хранилищах.
array [1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types] of int : cargo_flows; array [0..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types] of int : cargo_flows;
int : n_loading_op; int : n_loading_op;
array [1..n_operations] of int : loading_op_delta_of_main_obj; array [0..n_operations] of int : loading_op_delta_of_main_obj;
array [1..n_operations] of 1..n_obj_with_storage : operations_main_stor; array [0..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 [0..n_operations] of 1..n_obj_with_storage : operations_secondary_stor;
array [1..n_operations] of 1..n_cargo_types : operations_cargo_t; array [0..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 int : loading_op_delta;
array [1..n_loading_op] of 1..n_operations : loading_op_n; % Номера среди общего списка операций. array [1..n_loading_op] of 1..n_operations : loading_op_n; % Номера среди общего списка операций.
...@@ -343,7 +363,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -343,7 +363,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
array [1..n_fixed_op] of 1..n_intervals : fixed_op_start; array [1..n_fixed_op] of 1..n_intervals : fixed_op_start;
array [1..n_fixed_op] of 1..n_intervals : fixed_op_end; % Включительно. array [1..n_fixed_op] of 1..n_intervals : fixed_op_end; % Включительно.
array [1..n_operations, 1..n_intervals] of bool : is_fixed; array [0..n_operations, 0..n_intervals] of bool : is_fixed;
constraint forall (no in 1..n_fixed_op, op = fixed_op[no]) ( constraint forall (no in 1..n_fixed_op, op = fixed_op[no]) (
forall (t in fixed_op_start[no]..fixed_op_end[no]) ( forall (t in fixed_op_start[no]..fixed_op_end[no]) (
...@@ -356,7 +376,9 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -356,7 +376,9 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Оптимизация - сдвиг в начало. % Оптимизация - сдвиг в начало.
% Возможно ли начать операцию в данный интервал (если предположить, что операция длится 1 интервал). % Возможно ли начать операцию в данный интервал (если предположить, что операция длится 1 интервал).
array [1..n_operations, 1..n_intervals] of var bool : is_op_possible; array [0..n_operations, 1..n_intervals] of var bool : is_op_possible;
constraint forall (t in 1..n_intervals) (is_op_possible[0, t] = false); % Фиктивный объект.
% Счётчик ресурсов, которые могут быть потенциально задействованы в операции. % Счётчик ресурсов, которые могут быть потенциально задействованы в операции.
array [1..n_resources_counters , 1..n_intervals] of var int : possible_resources_counter; array [1..n_resources_counters , 1..n_intervals] of var int : possible_resources_counter;
...@@ -371,7 +393,9 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -371,7 +393,9 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
); );
% Достаточно ли свободных ресурсов для операции. % Достаточно ли свободных ресурсов для операции.
array [1..n_operations, 1..n_intervals] of var bool : is_enough_free_resources; array [0..n_operations, 1..n_intervals] of var bool : is_enough_free_resources;
constraint forall (t in 1..n_intervals) (is_enough_free_resources[0, t] = false); % Фиктивный объект.
constraint forall (op in 1..n_operations, t in 1..n_intervals) ( 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]) ( is_enough_free_resources[op, t] = forall (counter in counters_of_operation[op]) (
...@@ -379,12 +403,6 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -379,12 +403,6 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
) )
); );
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. % Определение is_op_possible.
constraint forall (op in 1..n_operations, t in 1..n_intervals) ( constraint forall (op in 1..n_operations, t in 1..n_intervals) (
is_op_possible[op, t] = ( is_op_possible[op, t] = (
...@@ -400,7 +418,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -400,7 +418,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
/\ % Если это операция перемещения, то главный объект /\ % Если это операция перемещения, то главный объект
% не участвует в операциях погрузки. % не участвует в операциях погрузки.
((is_mooring_op[op] /\ (operations_destination[op] mod 2 = 0)) -> ( ((is_mooring_op[op] /\ (operations_destination[op] mod 2 = 0)) -> (
obj_in_loc_counter[operations_destination[op], t] = 0) current_moored_obj[operations_destination[op], t] = 0)
) /\ % Если это операция пришвартовки, то в этот интервал ) /\ % Если это операция пришвартовки, то в этот интервал
% причал должен быть свободным. % причал должен быть свободным.
((not is_moving_operation[op]) -> ( ((not is_moving_operation[op]) -> (
...@@ -417,9 +435,16 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац ...@@ -417,9 +435,16 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% объём берегового хранилища и хранилища судна за % объём берегового хранилища и хранилища судна за
% границы дозволенного. % границы дозволенного.
(((not is_moving_operation[op]) /\ (main_obj_start_loc[op] mod 2 = 1)) -> (((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) ((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]))
% то причал должен быть свободен в этот интервал. ) /\ % Если это операция грузообработки без пришвартовки,
% то причал должен быть свободен в этот интервал, либо
% главный объект должен быть уже условно пришвартован.
(((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))
) % Бункеровщик (если есть) находится в нужной локации
% и не участвует в операциях перемещения.
) )
); );
...@@ -450,13 +475,16 @@ output [show(sum(is_not_terminated)), "\n", ...@@ -450,13 +475,16 @@ output [show(sum(is_not_terminated)), "\n",
"op_start = ", show(op_start), "\n\n", "op_start = ", show(op_start), "\n\n",
"is_not_terminated = ", show(is_not_terminated), "\n\n", "is_not_terminated = ", show(is_not_terminated), "\n\n",
"storage_used_volume = ", show(storage_used_volume), "\n\n", "storage_used_volume = ", show(storage_used_volume), "\n\n",
"is_m_obj_in_movement_before_start = ", show(is_m_obj_in_movement_before_start), "\n\n",
"obj_in_loc_counter = ", show(obj_in_loc_counter), "\n\n",
"m_obj_loc = ", show(m_obj_loc), "\n\n", "m_obj_loc = ", show(m_obj_loc), "\n\n",
"current_moving_operation = ", show(current_moving_operation), "\n\n", "current_moving_operation = ", show(current_moving_operation), "\n\n",
"resources_counter {", show(n_intervals), "} = ", show(resources_counter), "\n\n", "resources_counter {", show(n_intervals), "} = ", show(resources_counter), "\n\n",
"operation_of_counter {", show(n_resources_counters), "} = ", show(operation_of_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", "participation_as_resource = ", show(participation_as_resource), "\n\n",
"is_involved_in_cargo_op = {", show(n_intervals), "} ", show(is_involved_in_cargo_op), "\n\n",
"current_moored_obj = ", show(current_moored_obj), "\n\n",
/* /*
"is_op_possible {", show(n_intervals), "} = ", show(is_op_possible), "\n\n", "is_op_possible {", show(n_intervals), "} = ", show(is_op_possible), "\n\n",
"debug_1 {", show(n_intervals), "} = ", show(debug_1), "\n\n", "debug_1 {", show(n_intervals), "} = ", show(debug_1), "\n\n",
......
...@@ -8,26 +8,17 @@ package inport; ...@@ -8,26 +8,17 @@ package inport;
* *
* @author topazh_ag * @author topazh_ag
*/ */
public class Bunker extends MovingObject { public class Bunker extends TransportShip {
public Bunker(int id, String name) { public Bunker(int id, String name, double cargoMax) {
super(id, name); super(id, name, cargoMax);
} }
public Bunker() { public Bunker() {
super( ); super( );
} }
@Override
public String toString() {
return getId() + ";" + getName();
}
public Bunker(String s) { public Bunker(String s) {
super(s); super(s);
} }
} }
...@@ -19,10 +19,17 @@ public class ConversionUtil { ...@@ -19,10 +19,17 @@ public class ConversionUtil {
} }
} }
static private void write2DArrayOfInt(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations) throws IOException {
locWrite2DArray(writer, name, operations, Object::toString, false);
}
static private void write2DArrayOfInt(FileWriter writer, static private void write2DArrayOfInt(FileWriter writer,
String name, String name,
ArrayList<ArrayList<Integer>> operations) throws IOException { ArrayList<ArrayList<Integer>> operations,
locWrite2DArray(writer, name, operations, Object::toString); boolean isNumberedFromZero) throws IOException {
locWrite2DArray(writer, name, operations, Object::toString, isNumberedFromZero);
} }
static private void write2DArrayOfSet(FileWriter writer, static private void write2DArrayOfSet(FileWriter writer,
...@@ -47,39 +54,61 @@ public class ConversionUtil { ...@@ -47,39 +54,61 @@ public class ConversionUtil {
); );
} }
static private void write2DArrayOfSetAs3DArray(FileWriter writer, static private <T extends Collection<Integer>> void write2DArrayOfSetAs3DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations) throws IOException {
write2DArrayOfSetAs3DArray(writer, name, operations, false);
}
static private <T extends Collection<Integer>> void write2DArrayOfSetAs3DArray(FileWriter writer,
String name, String name,
ArrayList<ArrayList<ArrayList<Integer>>> operations) throws IOException { ArrayList<ArrayList<T>> operations,
boolean isNumberedFromZero) throws IOException {
int maxSize = 0; int maxSize = 0;
ArrayList<ArrayList<Integer>> sizes = new ArrayList<>(); ArrayList<ArrayList<Integer>> sizes = new ArrayList<>();
int dim1 = operations.size(); int dim1 = operations.size();
int dim2 = 0; int dim2 = 0;
for (ArrayList<ArrayList<Integer>> a1 : operations) { for (ArrayList<T> a1 : operations) {
dim2 = a1.size(); dim2 = a1.size();
ArrayList<Integer> locSizes = new ArrayList<>(); ArrayList<Integer> locSizes = new ArrayList<>();
for (ArrayList<Integer> a2 : a1) { for (T a2 : a1) {
maxSize = Math.max(maxSize, a2.size()); maxSize = Math.max(maxSize, a2.size());
locSizes.add(a2.size()); locSizes.add(a2.size());
} }
sizes.add(locSizes); sizes.add(locSizes);
} }
writer.write(name + "_max_size = " + maxSize + ";\n"); writer.write(name + "_max_size = " + maxSize + ";\n");
write2DArrayOfInt(writer, name + "_sizes", sizes); write2DArrayOfInt(writer, name + "_sizes", sizes, true);
{
String firstEl = Integer.toString(isNumberedFromZero ? 0 : 1);
int modifier = isNumberedFromZero ? -1 : 0;
writer.write(name + " = array3d(" + firstEl + ".." + (dim1 + modifier)
+ ", " + firstEl + ".." + (dim2 + modifier)
+ ", 1.." + name + "_max_size, [");
}
writer.write(name + " = array3d(1.." + dim1 + ", 1.." + dim2 + ", 1.." + name + "_max_size, [");
boolean isFirst = true; boolean isFirst = true;
for (ArrayList<ArrayList<Integer>> a1 : operations) { for (ArrayList<T> a1 : operations) {
for (ArrayList<Integer> a2 : a1) { for (T a2 : a1) {
for (int i = 0; i < maxSize; i++) { for (Integer val : a2) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write(Integer.toString(val));
}
for (int i = a2.size(); i < maxSize; i++) {
if (isFirst) { if (isFirst) {
isFirst = false; isFirst = false;
} else { } else {
writer.write(", "); writer.write(", ");
} }
writer.write(Integer.toString(i < a2.size() ? a2.get(i) : 1)); writer.write(Integer.toString(1));
} }
} }
} }
...@@ -139,31 +168,40 @@ public class ConversionUtil { ...@@ -139,31 +168,40 @@ public class ConversionUtil {
writer.write("]);\n"); writer.write("]);\n");
} }
static private <T> void locWrite2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations,
Function<T, String> toMZNFormat) throws IOException {
locWrite2DArray(writer, name, operations, toMZNFormat, false);
}
static int boolToInt(boolean b) {
return b ? 1 : 0;
}
static private <T> void locWrite2DArray(FileWriter writer, static private <T> void locWrite2DArray(FileWriter writer,
String name, String name,
ArrayList<ArrayList<T>> operations, ArrayList<ArrayList<T>> operations,
Function<T, String> toMZNFormat) throws IOException { Function<T, String> toMZNFormat,
writer.write(name + " = \n"); boolean isNumberedFromZero) throws IOException {
writer.write(name + " = array2d(" + (isNumberedFromZero ? 0 : 1) + ".." + (operations.size() - boolToInt(isNumberedFromZero))
+ ", " + (isNumberedFromZero ? 0 : 1) + ".." + (operations.get(0).size() - boolToInt(isNumberedFromZero))
+ ", [");
boolean isFirst0 = true; boolean isFirst0 = true;
for (ArrayList<T> a : operations) { for (ArrayList<T> a : operations) {
if (isFirst0) {
isFirst0 = false;
writer.write(" [| ");
} else {
writer.write(" | ");
}
boolean isFirst1 = true;
for (T val : a) { for (T val : a) {
if (isFirst1) { if (isFirst0) {
isFirst1 = false; isFirst0 = false;
} else { } else {
writer.write(", "); writer.write(", ");
} }
writer.write(toMZNFormat.apply(val)); writer.write(toMZNFormat.apply(val));
} }
writer.write("\n");
} }
writer.write(" |];\n"); writer.write("]);\n");
} }
static private <T, E> void writeArray(FileWriter writer, static private <T, E> void writeArray(FileWriter writer,
...@@ -362,6 +400,10 @@ public class ConversionUtil { ...@@ -362,6 +400,10 @@ public class ConversionUtil {
private ArrayList<Set<Integer>> objectsOfType; private ArrayList<Set<Integer>> objectsOfType;
public ArrayList<MovingObject> getMovingObjects() {
return movingObjects;
}
Task(TaskCase task, String fileName) { Task(TaskCase task, String fileName) {
this.fileName = fileName; this.fileName = fileName;
this.task = task; this.task = task;
...@@ -375,19 +417,11 @@ public class ConversionUtil { ...@@ -375,19 +417,11 @@ public class ConversionUtil {
locationNumberById.put(new Pair<>(berth.getId(), true), locationNumberById.size()); locationNumberById.put(new Pair<>(berth.getId(), true), locationNumberById.size());
} }
movingObjects = new ArrayList<>(); movingObjects = calcMovingObjects(task);
mObjNumberById = new TreeMap<>(); mObjNumberById = new TreeMap<>();
for (MovingObject obj : task.getShips()) {
mObjNumberById.put(obj.getId(), movingObjects.size()); for (int i = 0; i < movingObjects.size(); i++) {
movingObjects.add(obj); mObjNumberById.put(movingObjects.get(i).getId(), i);
}
for (MovingObject obj : task.getTows()) {
mObjNumberById.put(obj.getId(), movingObjects.size());
movingObjects.add(obj);
}
for (MovingObject obj : task.getEquipments()) {
mObjNumberById.put(obj.getId(), movingObjects.size());
movingObjects.add(obj);
} }
operationTemplates = new ArrayList<>(task.getTemplates()); operationTemplates = new ArrayList<>(task.getTemplates());
...@@ -417,6 +451,10 @@ public class ConversionUtil { ...@@ -417,6 +451,10 @@ public class ConversionUtil {
typeToN.put(type, next); typeToN.put(type, next);
next++; next++;
} }
for (Integer type : task.getBunkerTypes().keySet()) {
typeToN.put(type, next);
next++;
}
for (Integer type : task.getEquipmentsTypes().keySet()) { for (Integer type : task.getEquipmentsTypes().keySet()) {
typeToN.put(type, next); typeToN.put(type, next);
next++; next++;
...@@ -508,7 +546,7 @@ public class ConversionUtil { ...@@ -508,7 +546,7 @@ public class ConversionUtil {
for (MovingObjectState state : task.getVesselInitialState()) { for (MovingObjectState state : task.getVesselInitialState()) {
initialStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false)); initialStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false));
} }
writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1); writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1, Optional.of(-1));
writer.write("\n"); writer.write("\n");
} }
...@@ -538,23 +576,27 @@ public class ConversionUtil { ...@@ -538,23 +576,27 @@ public class ConversionUtil {
/* Окна погоды. Новый формат. */ /* Окна погоды. Новый формат. */
private void weatherWindowsNewFormat() throws IOException { private void weatherWindowsNewFormat() throws IOException {
ArrayList<ArrayList<Boolean>> badWeather = new ArrayList<>(); ArrayList<ArrayList<Boolean>> badWeather = new ArrayList<>();
badWeather.add(new ArrayList<>());
for (int j = 0; j <= n_intervals; j++) {
badWeather.get(0).add(false);
}
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i < operationTemplates.size(); i++) {
ArrayList<Boolean> curLine = new ArrayList<>(); ArrayList<Boolean> curLine = new ArrayList<>();
for (int j = 0; j < n_intervals; j++) { for (int j = 0; j <= n_intervals; j++) {
curLine.add(false); curLine.add(false);
} }
operationTemplates.get(i).getTimeWindows().forEach( operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> { (Double start, Double duration) -> {
for (int j = (int)Math.floor(start); j < (int)Math.ceil(start + duration); j++) { for (int j = (int)Math.floor(start); j < (int)Math.ceil(start + duration); j++) {
curLine.set(j, true); curLine.set(j + 1, true);
} }
} }
); );
badWeather.add(curLine); badWeather.add(curLine);
} }
locWrite2DArray(writer, "bad_weather", badWeather, Objects::toString); locWrite2DArray(writer, "bad_weather", badWeather, Objects::toString, true);
} }
/* Непрерывность перемещения и швартовки. */ /* Непрерывность перемещения и швартовки. */
...@@ -576,8 +618,8 @@ public class ConversionUtil { ...@@ -576,8 +618,8 @@ public class ConversionUtil {
isMovingObj.add(false); isMovingObj.add(false);
} }
} }
writeArray(writer, "operations_duration", operationsDuration); writeArray(writer, "operations_duration", operationsDuration, Optional.of(1));
writeArray(writer, "is_continuous_operation", isMovingObj); writeArray(writer, "is_continuous_operation", isMovingObj, Optional.of(false));
} }
/* Конечные положения объектов. */ /* Конечные положения объектов. */
...@@ -586,7 +628,7 @@ public class ConversionUtil { ...@@ -586,7 +628,7 @@ public class ConversionUtil {
for (MovingObjectState state : task.getVesselEndState()) { for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false)); finalStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false));
} }
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1); writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1, Optional.of(-1));
} }
/* Наличие всех ресурсов на месте, в том числе и самого корабля. */ /* Наличие всех ресурсов на месте, в том числе и самого корабля. */
...@@ -658,7 +700,7 @@ public class ConversionUtil { ...@@ -658,7 +700,7 @@ public class ConversionUtil {
for (Storage storage : storages) { for (Storage storage : storages) {
maxStorageVol.add((int)Math.ceil(storage.getVolume())); maxStorageVol.add((int)Math.ceil(storage.getVolume()));
} }
writeArray(writer, "max_storage_vol", maxStorageVol); writeArray(writer, "max_storage_vol", maxStorageVol, Optional.of(0));
writer.write("\n"); writer.write("\n");
} }
...@@ -668,9 +710,9 @@ public class ConversionUtil { ...@@ -668,9 +710,9 @@ public class ConversionUtil {
ArrayList<ArrayList<Integer>> initialStorageVol = new ArrayList<>(); ArrayList<ArrayList<Integer>> initialStorageVol = new ArrayList<>();
ArrayList<ArrayList<Integer>> finalStorageVol = new ArrayList<>(); ArrayList<ArrayList<Integer>> finalStorageVol = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) { for (int i = 0; i <= nObjWithStorage; i++) {
initialStorageVol.add(integerArray(cargoes.size(), 0)); initialStorageVol.add(integerArray(cargoes.size() + 1, 0));
finalStorageVol .add(integerArray(cargoes.size(), -1)); finalStorageVol .add(integerArray(cargoes.size() + 1, -1));
} }
for (StorageState st : task.getStorageInitialState()) { for (StorageState st : task.getStorageInitialState()) {
int cargoN = cargoNById.get(st.getCargo().getId()); int cargoN = cargoNById.get(st.getCargo().getId());
...@@ -679,10 +721,10 @@ public class ConversionUtil { ...@@ -679,10 +721,10 @@ public class ConversionUtil {
if (st.getStorage() instanceof Storage) { if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage(); Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId()); int stN = storNById.get(storage.getId());
initialStorageVol.get(movingObjects.size() + stN).set(cargoN, val); initialStorageVol.get(movingObjects.size() + stN + 1).set(cargoN + 1, val);
} else if (st.getStorage() instanceof TransportShip) { } else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage(); TransportShip ship = (TransportShip) st.getStorage();
initialStorageVol.get(mObjToN(ship)).set(cargoN, val); initialStorageVol.get(mObjToN(ship) + 1).set(cargoN + 1, val);
} }
} }
for (StorageState st : task.getStorageEndState()) { for (StorageState st : task.getStorageEndState()) {
...@@ -692,14 +734,14 @@ public class ConversionUtil { ...@@ -692,14 +734,14 @@ public class ConversionUtil {
if (st.getStorage() instanceof Storage) { if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage(); Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId()); int stN = storNById.get(storage.getId());
finalStorageVol.get(movingObjects.size() + stN).set(cargoN, val); finalStorageVol.get(movingObjects.size() + stN + 1).set(cargoN + 1, val);
} else if (st.getStorage() instanceof TransportShip) { } else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage(); TransportShip ship = (TransportShip) st.getStorage();
finalStorageVol.get(mObjToN(ship)).set(cargoN, val); finalStorageVol.get(mObjToN(ship) + 1).set(cargoN + 1, val);
} }
} }
write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol); write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol, true);
write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol); write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol, true);
} }
/* Потоки грузов. */ /* Потоки грузов. */
...@@ -721,8 +763,19 @@ public class ConversionUtil { ...@@ -721,8 +763,19 @@ public class ConversionUtil {
cargoFlows.get(storageN + movingObjects.size()).get(i).set(cargoN, (int)flow.getCurrentValue(i - 0.1)); cargoFlows.get(storageN + movingObjects.size()).get(i).set(cargoN, (int)flow.getCurrentValue(i - 0.1));
} }
} }
writer.write("cargo_flows = array3d(1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types, ["); writer.write("cargo_flows = array3d(0..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types, [");
boolean isFirst = true; boolean isFirst = true;
for (int j = 0; j < n_intervals + 2; j++) {
for (int k = 0; k < cargoes.size(); k++) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write("0");
}
}
for (int i = 0; i < nObjWithStorage; i++) { for (int i = 0; i < nObjWithStorage; i++) {
for (int j = 0; j < n_intervals + 2; j++) { for (int j = 0; j < n_intervals + 2; j++) {
for (int k = 0; k < cargoes.size(); k++) { for (int k = 0; k < cargoes.size(); k++) {
...@@ -749,6 +802,9 @@ public class ConversionUtil { ...@@ -749,6 +802,9 @@ public class ConversionUtil {
ArrayList<Integer> operations_secondary_stor = new ArrayList<>(); ArrayList<Integer> operations_secondary_stor = new ArrayList<>();
ArrayList<Integer> operations_cargo_t = new ArrayList<>(); ArrayList<Integer> operations_cargo_t = new ArrayList<>();
ArrayList<Integer> bunker_of_cargo_op = new ArrayList<>();
ArrayList<Boolean> is_bunker_required = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) { for (int i = 0; i < nObjWithStorage; i++) {
involvedOperations.add(new ArrayList<>()); involvedOperations.add(new ArrayList<>());
for (int j = 0; j < cargoes.size(); j++) { for (int j = 0; j < cargoes.size(); j++) {
...@@ -759,13 +815,19 @@ public class ConversionUtil { ...@@ -759,13 +815,19 @@ public class ConversionUtil {
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) { if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i); LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
int storageN = storNById.get(op.getStorage().getId());
int storageN;
if (op.getBunker().isPresent()) {
storageN = mObjToN(op.getBunker().get());
} else {
storageN = storNById.get(op.getStorage().getId()) + movingObjects.size();
}
int shipN = mObjToN(op.getLoader()); int shipN = mObjToN(op.getLoader());
int cargoN = cargoNById.get(op.getCargo().getId()); int cargoN = cargoNById.get(op.getCargo().getId());
loadingOpDelta.add(-(int)op.getIntensity()); loadingOpDelta.add(-(int)op.getIntensity());
loadingOpN.add(i); loadingOpN.add(i);
involvedOperations.get(storageN + movingObjects.size()).get(cargoN).add(loadingOpDelta.size()); involvedOperations.get(storageN).get(cargoN).add(loadingOpDelta.size());
loadingOpDelta.add((int)op.getIntensity()); loadingOpDelta.add((int)op.getIntensity());
loadingOpN.add(i); loadingOpN.add(i);
...@@ -773,13 +835,15 @@ public class ConversionUtil { ...@@ -773,13 +835,15 @@ public class ConversionUtil {
loading_op_delta_of_main_obj.add((int)op.getIntensity()); loading_op_delta_of_main_obj.add((int)op.getIntensity());
operations_main_stor.add(shipN + 1); operations_main_stor.add(shipN + 1);
operations_secondary_stor.add(storageN + movingObjects.size() + 1); operations_secondary_stor.add(storageN + 1);
operations_cargo_t.add(cargoN + 1); operations_cargo_t.add(cargoN + 1);
bunker_of_cargo_op.add(op.getBunker().isPresent() ? mObjToN(op.getBunker().get()) + 1 : 0);
} else { } else {
loading_op_delta_of_main_obj.add(0); loading_op_delta_of_main_obj.add(0);
operations_main_stor.add(1); operations_main_stor.add(1);
operations_secondary_stor.add(1); operations_secondary_stor.add(1);
operations_cargo_t.add(1); operations_cargo_t.add(1);
bunker_of_cargo_op.add(0);
} }
} }
writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n"); writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n");
...@@ -791,10 +855,11 @@ public class ConversionUtil { ...@@ -791,10 +855,11 @@ public class ConversionUtil {
writeArray(writer, "loading_op_delta", loadingOpDelta); writeArray(writer, "loading_op_delta", loadingOpDelta);
writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1); 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, "loading_op_delta_of_main_obj", loading_op_delta_of_main_obj, Optional.of(0));
writeArray(writer, "operations_main_stor", operations_main_stor); writeArray(writer, "operations_main_stor", operations_main_stor, Optional.of(1));
writeArray(writer, "operations_secondary_stor", operations_secondary_stor); writeArray(writer, "operations_secondary_stor", operations_secondary_stor, Optional.of(1));
writeArray(writer, "operations_cargo_t", operations_cargo_t); writeArray(writer, "operations_cargo_t", operations_cargo_t, Optional.of(1));
writeArray(writer, "bunker_of_cargo_op", bunker_of_cargo_op, Optional.of(0));
writer.write("\n"); writer.write("\n");
} }
...@@ -925,57 +990,48 @@ public class ConversionUtil { ...@@ -925,57 +990,48 @@ public class ConversionUtil {
} }
private void movingObjectLocationDefinition(boolean isV1) throws IOException { private void movingObjectLocationDefinition(boolean isV1) throws IOException {
if (! isV1) { writeArray(writer, "is_mooring_op", isMooringOp, Optional.of(false));
writeArray(writer, "is_mooring_op", isMooringOp, Optional.of(false)); writeArray(writer, "operations_destination", operationsDestination, (Integer val) -> val + 1,
writeArray(writer, "main_obj_of_operation", mainObjOfOperation, (Integer val) -> val + 1, Optional.of(1)); Optional.of(-1));
ArrayList<ArrayList<Boolean>> locMovingOpOfObj = new ArrayList<>();
for (ArrayList<Integer> operations : movingOpOfObj) {
ArrayList<Boolean> lOperations = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
lOperations.add(false);
}
for (Integer op : operations) {
lOperations.set(op - 1, true);
}
locMovingOpOfObj.add(lOperations);
}
locWrite2DArray(writer, "moving_op_of_obj", locMovingOpOfObj, Objects::toString);
} else {
writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj, true, false);
}
writeArray(writer, "operations_destination", operationsDestination, (Integer val) -> val + 1);
writer.write("\n"); writer.write("\n");
} }
private void unmooredCargoOp() throws IOException { private void cargoOpUsingObj() throws IOException {
ArrayList<Set<Integer>> relatedUnmooredCargoOp = new ArrayList<>(); ArrayList<Set<Integer>> relatedCargoOp = new ArrayList<>();
for (int i = 0; i < locationNumberById.size(); i++) { for (int i = 0; i < movingObjects.size(); i++) {
relatedUnmooredCargoOp.add(new TreeSet<>()); relatedCargoOp.add(new TreeSet<>());
} }
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) { if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i); LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
if (! op.getWithMooring()) { relatedCargoOp.get(mObjToN(op.getLoader())).add(i + 1);
relatedUnmooredCargoOp.get(getLocNById(op.getStartLocation().getId(), false)).add(i + 1); if (op.getBunker().isPresent()) {
relatedCargoOp.get(mObjToN(op.getBunker().get())).add(i + 1);
} }
} }
} }
writeArray(writer, "related_unmoored_cargo_op", relatedUnmooredCargoOp, ConversionUtil::setToString); writeArray(writer, "related_cargo_op", relatedCargoOp, ConversionUtil::setToString,
Optional.of(new TreeSet<>()));
} }
private void cargoOpUsingObjAsMain() throws IOException { private void addOpWithNominallyMooring() throws IOException {
ArrayList<Set<Integer>> relatedCargoOpUsingObjAsMain = new ArrayList<>(); ArrayList<ArrayList<Set<Integer>>> opWithNominallyMooring = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) { for (int loc = 0; loc <= locationNumberById.size(); loc++) {
relatedCargoOpUsingObjAsMain.add(new TreeSet<>()); opWithNominallyMooring.add(new ArrayList<>());
for (int obj = 0; obj <= movingObjects.size(); obj++) {
opWithNominallyMooring.get(loc).add(new TreeSet<>());
}
} }
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) { OperationTemplate t = operationTemplates.get(i);
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i); if ((t instanceof MooringTemplate) ||
relatedCargoOpUsingObjAsMain.get(getMObjNumberById().get(op.getLoader().getId())).add(i + 1); ((t instanceof LoadingTemplate) && (! ((LoadingTemplate)t).getWithMooring()))) {
opWithNominallyMooring.get(getLocNById(t.getStartLocation().getId(), true) + 1)
.get(mObjToN(getExecutor(t)) + 1)
.add(i + 1);
} }
} }
writeArray(writer, "related_cargo_op_using_obj_as_main", relatedCargoOpUsingObjAsMain, ConversionUtil::setToString); write2DArrayOfSetAs3DArray(writer, "op_with_nominally_mooring", opWithNominallyMooring, true);
} }
void portToMiniZinc_0() throws IOException { void portToMiniZinc_0() throws IOException {
...@@ -1054,22 +1110,29 @@ public class ConversionUtil { ...@@ -1054,22 +1110,29 @@ public class ConversionUtil {
} }
} }
public static ArrayList<MovingObject> calcMovingObjects(TaskCase taskCase) {
ArrayList<MovingObject> movingObjects = new ArrayList<>();
movingObjects.addAll(taskCase.getShips());
movingObjects.addAll(taskCase.getBunkers());
movingObjects.addAll(taskCase.getTows());
movingObjects.addAll(taskCase.getEquipments());
return movingObjects;
}
/* Каждую операцию лишает типизации по главному действующему лицу. */ /* Каждую операцию лишает типизации по главному действующему лицу. */
public static ArrayList<OperationTemplate> renumberOperations(TaskCase task) { public static ArrayList<OperationTemplate> renumberOperations(TaskCase task) {
TreeMap<Integer, ArrayList<MovingObject>> shipsByType = new TreeMap<>(); TreeMap<Integer, ArrayList<MovingObject>> shipsByType = new TreeMap<>();
for (Integer type : task.getVesselTypes().keySet()) { for (Integer type : task.getVesselTypes().keySet()) {
shipsByType.put(type, new ArrayList<>()); shipsByType.put(type, new ArrayList<>());
} }
for (Integer type : task.getBunkerTypes().keySet()) {
shipsByType.put(type, new ArrayList<>());
}
for (Integer type : task.getEquipmentsTypes().keySet()) { for (Integer type : task.getEquipmentsTypes().keySet()) {
shipsByType.put(type, new ArrayList<>()); shipsByType.put(type, new ArrayList<>());
} }
ArrayList<MovingObject> movingObjects = new ArrayList<>(); for (MovingObject obj : calcMovingObjects(task)) {
movingObjects.addAll(task.getTows());
movingObjects.addAll(task.getShips());
movingObjects.addAll(task.getEquipments());
for (MovingObject obj : movingObjects) {
if (obj.getType().isPresent()) { if (obj.getType().isPresent()) {
shipsByType.get(obj.getType().getAsInt()).add(obj); shipsByType.get(obj.getType().getAsInt()).add(obj);
} }
...@@ -1082,8 +1145,34 @@ public class ConversionUtil { ...@@ -1082,8 +1145,34 @@ public class ConversionUtil {
if (t.getLoaderType().isPresent()) { if (t.getLoaderType().isPresent()) {
for (MovingObject obj : shipsByType.get(t.getLoaderType().getAsInt())) { for (MovingObject obj : shipsByType.get(t.getLoaderType().getAsInt())) {
assert(obj instanceof TransportShip); assert(obj instanceof TransportShip);
result.add(new LoadingTemplate((TransportShip)obj, t.getStartLocation(), t.getStorage(), if (t.getBunkerType().isPresent()) {
t.getCargo(), t.getResourcesTypes(), t.getWithMooring(), t.getIntensity(), t.getId())); for (MovingObject bunker : shipsByType.get(t.getBunkerType().getAsInt())) {
assert(obj instanceof Bunker);
result.add(new LoadingTemplate(
(TransportShip)obj,
t.getStartLocation(),
t.getStorage(),
t.getCargo(),
Optional.of((Bunker)bunker),
t.getResourcesTypes(),
t.getWithMooring(),
t.getIntensity(),
t.getId()
));
}
} else {
result.add(new LoadingTemplate(
(TransportShip)obj,
t.getStartLocation(),
t.getStorage(),
t.getCargo(),
Optional.empty(),
t.getResourcesTypes(),
t.getWithMooring(),
t.getIntensity(),
t.getId()
));
}
} }
} }
} }
...@@ -1129,6 +1218,26 @@ public class ConversionUtil { ...@@ -1129,6 +1218,26 @@ public class ConversionUtil {
conflictingOperationsG.get(i).add(j + 1); conflictingOperationsG.get(i).add(j + 1);
} }
} }
{ // Взаимоисключение операций погрузки без швартовки на одном причале с разными субъектами.
// + операций бункеровки без швартовки на одном причалое
// TODO переделать
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.getWithMooring()) && (! op2.getWithMooring()) &&
(op1.getStartLocation() == op2.getStartLocation()) &&
(op1.getLoader() != op2.getLoader())) {
conflictingOperationsG.get(i).add(j + 1);
}
if ((! op1.getWithMooring()) && (! op2.getWithMooring()) &&
(op1.getStartLocation() == op2.getStartLocation()) &&
(op1.getBunker().isPresent()) && (op2.getBunker().isPresent())) {
conflictingOperationsG.get(i).add(j + 1);
}
}
}
{ // Взаимоисключение операций перемещения и грузообработки с общим деятелем. { // Взаимоисключение операций перемещения и грузообработки с общим деятелем.
// TODO вынести в отдельный constraint // TODO вынести в отдельный constraint
OperationTemplate t1 = operationTemplates.get(i); OperationTemplate t1 = operationTemplates.get(i);
...@@ -1147,7 +1256,8 @@ public class ConversionUtil { ...@@ -1147,7 +1256,8 @@ public class ConversionUtil {
} }
} }
} }
writeArray(writer, "conflicting_operations", conflictingOperationsG, ConversionUtil::setToString); writeArray(writer, "conflicting_operations", conflictingOperationsG, ConversionUtil::setToString,
Optional.of(new TreeSet<>()));
} }
public ArrayList<ArrayList<Boolean>> getIsFixedArray() { public ArrayList<ArrayList<Boolean>> getIsFixedArray() {
...@@ -1158,9 +1268,9 @@ public class ConversionUtil { ...@@ -1158,9 +1268,9 @@ public class ConversionUtil {
} }
ArrayList<ArrayList<Boolean>> isFixed = new ArrayList<>(); ArrayList<ArrayList<Boolean>> isFixed = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i <= operationTemplates.size(); i++) {
isFixed.add(new ArrayList<>()); isFixed.add(new ArrayList<>());
for (int j = 0; j < n_intervals; j++) { for (int j = 0; j <= n_intervals; j++) {
isFixed.get(i).add(false); isFixed.get(i).add(false);
} }
} }
...@@ -1169,7 +1279,7 @@ public class ConversionUtil { ...@@ -1169,7 +1279,7 @@ public class ConversionUtil {
int operation = opNoByOpIdAndExecutorNo.get(new Pair<>(op.getTemplate().getId(), op.getExecutor().getId())); int operation = opNoByOpIdAndExecutorNo.get(new Pair<>(op.getTemplate().getId(), op.getExecutor().getId()));
for (int i = (int)Math.floor(op.getStart()); i < (int)Math.ceil(op.getDuration() + op.getStart()); i++) { for (int i = (int)Math.floor(op.getStart()); i < (int)Math.ceil(op.getDuration() + op.getStart()); i++) {
isFixed.get(operation).set(i, true); isFixed.get(operation + 1).set(i + 1, true);
} }
} }
} }
...@@ -1206,7 +1316,36 @@ public class ConversionUtil { ...@@ -1206,7 +1316,36 @@ public class ConversionUtil {
writeArray(writer, "fixed_op_resources", fixedOpResources, ConversionUtil::setToString); writeArray(writer, "fixed_op_resources", fixedOpResources, ConversionUtil::setToString);
writeArray(writer, "fixed_op_start", fixedOpStart); writeArray(writer, "fixed_op_start", fixedOpStart);
writeArray(writer, "fixed_op_end", fixedOpEnd); writeArray(writer, "fixed_op_end", fixedOpEnd);
locWrite2DArray(writer, "is_fixed", getIsFixedArray(), Objects::toString); locWrite2DArray(writer, "is_fixed", getIsFixedArray(), Objects::toString, true);
}
void defDataForCurMovingOp() throws IOException {
ArrayList<Boolean> isMovingOp = new ArrayList<>();
for (OperationTemplate op : operationTemplates) {
isMovingOp.add((op instanceof MovingTemplate) || (op instanceof MooringTemplate));
}
writeArray(writer, "is_moving_operation", isMovingOp, Optional.of(false));
writer.write("\n");
writeArray(writer, "main_obj_of_operation", mainObjOfOperation, (Integer val) -> val + 1, Optional.of(-1));
ArrayList<ArrayList<Boolean>> locMovingOpOfObj = new ArrayList<>();
locMovingOpOfObj.add(new ArrayList<>());
for (int i = 0; i <= operationTemplates.size(); i++) {
locMovingOpOfObj.get(0).add(false);
}
for (ArrayList<Integer> operations : movingOpOfObj) {
ArrayList<Boolean> lOperations = new ArrayList<>();
lOperations.add(false);
for (int i = 0; i < operationTemplates.size(); i++) {
lOperations.add(false);
}
for (Integer op : operations) {
lOperations.set(op, true);
}
locMovingOpOfObj.add(lOperations);
}
locWrite2DArray(writer, "moving_op_of_obj", locMovingOpOfObj, Objects::toString, true);
} }
private void typifiedResourcesDefinition() throws IOException { private void typifiedResourcesDefinition() throws IOException {
...@@ -1223,26 +1362,8 @@ public class ConversionUtil { ...@@ -1223,26 +1362,8 @@ public class ConversionUtil {
} }
} }
} }
writeArray(writer, "operations_that_used_obj_as_resource", res, ConversionUtil::setToString); writeArray(writer, "operations_that_used_obj_as_resource", res, ConversionUtil::setToString,
writer.write("\n"); Optional.of(new TreeSet<>()));
}
{ // main_obj_start_loc, is_moving_operation
ArrayList<Integer> mainObjStartLoc = new ArrayList<>();
ArrayList<Boolean> isMovingOp = new ArrayList<>();
for (OperationTemplate op : operationTemplates) {
boolean isMoored = false;
if ((op instanceof LoadingTemplate) && (((LoadingTemplate) op).getWithMooring())) {
isMoored = true;
}
if ((op instanceof MooringTemplate) && (!((MooringTemplate)op).isDirect())) {
isMoored = true;
}
mainObjStartLoc.add(locationNumberById.get(new Pair<>(op.getStartLocation().getId(), isMoored)));
isMovingOp.add((op instanceof MovingTemplate) || (op instanceof MooringTemplate));
}
writeArray(writer, "main_obj_start_loc", mainObjStartLoc, (Integer val) -> val + 1);
writeArray(writer, "is_moving_operation", isMovingOp, Optional.of(false));
writer.write("\n"); writer.write("\n");
} }
{ // counters, operations_resources_start_loc { // counters, operations_resources_start_loc
...@@ -1274,10 +1395,29 @@ public class ConversionUtil { ...@@ -1274,10 +1395,29 @@ public class ConversionUtil {
writeArray(writer, "operation_of_counter", operationOfCounter, (Integer val) -> val + 1); writeArray(writer, "operation_of_counter", operationOfCounter, (Integer val) -> val + 1);
writeArray(writer, "required_counter_values", requiredCounterValues); writeArray(writer, "required_counter_values", requiredCounterValues);
writeArray(writer, "operations_resources_start_loc", operationsResourcesStartLoc, (Integer val) -> val + 1); writeArray(writer, "operations_resources_start_loc", operationsResourcesStartLoc, (Integer val) -> val + 1);
writeArray(writer, "counters_of_operation", countersOfOperation, ConversionUtil::setToString); writeArray(writer, "counters_of_operation", countersOfOperation, ConversionUtil::setToString,
Optional.of(new TreeSet<>()));
} }
} }
void requiredLocationsOnOpStart() throws IOException {
ArrayList<Integer> mainObjStartLoc = new ArrayList<>();
ArrayList<Integer> bunkerStartLoc = new ArrayList<>();
for (OperationTemplate op : operationTemplates) {
boolean isMoored = false;
if ((op instanceof LoadingTemplate) && (((LoadingTemplate) op).getWithMooring())) {
isMoored = true;
}
if ((op instanceof MooringTemplate) && (!((MooringTemplate)op).isDirect())) {
isMoored = true;
}
mainObjStartLoc.add(getLocNById(op.getStartLocation().getId(), isMoored));
bunkerStartLoc.add(getLocNById(op.getStartLocation().getId(), false));
}
writeArray(writer, "main_obj_start_loc", mainObjStartLoc, (Integer val) -> val + 1, Optional.of(-1));
writeArray(writer, "bunker_start_loc", bunkerStartLoc, (Integer val) -> val + 1, Optional.of(-1));
}
/* С типизацией. */ /* С типизацией. */
void portToMiniZinc_2() throws IOException { void portToMiniZinc_2() throws IOException {
if (!task.isTypified()) { if (!task.isTypified()) {
...@@ -1296,15 +1436,19 @@ public class ConversionUtil { ...@@ -1296,15 +1436,19 @@ public class ConversionUtil {
movingObjectLocationDefinition(false); movingObjectLocationDefinition(false);
initialLocations(); initialLocations();
finalLocations(); finalLocations();
defDataForCurMovingOp();
weatherWindowsNewFormat(); weatherWindowsNewFormat();
conflictingOperationsOnStorageAndOnTypeOnMainObject(); conflictingOperationsOnStorageAndOnTypeOnMainObject();
requiredLocationsOnOpStart();
operationsContinuity(); operationsContinuity();
typifiedResourcesDefinition(); typifiedResourcesDefinition();
unmooredCargoOp(); cargoOpUsingObj();
addOpWithNominallyMooring();
cargoOpUsingObjAsMain();
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n"); writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n"); writer.write("n_cargo_types = " + cargoes.size() + ";\n");
...@@ -1346,7 +1490,7 @@ public class ConversionUtil { ...@@ -1346,7 +1490,7 @@ public class ConversionUtil {
} }
} }
public static void resolveMiniZincResults(TaskCase task, String fileName) { public static void resolveMiniZincResults(TaskCase taskCase, String fileName) {
ArrayList<Operation> operations = null; ArrayList<Operation> operations = null;
Integer result = null; Integer result = null;
...@@ -1386,7 +1530,7 @@ public class ConversionUtil { ...@@ -1386,7 +1530,7 @@ public class ConversionUtil {
while ((pos < line.length()) && (line.charAt(pos) != '[') && (line.charAt(pos) != '{')) { while ((pos < line.length()) && (line.charAt(pos) != '[') && (line.charAt(pos) != '{')) {
pos++; pos++;
} }
int arrayFirstDim = ((int) task.getPlanningInterval()) + 2; int arrayFirstDim = ((int) taskCase.getPlanningInterval()) + 2;
if (line.charAt(pos) == '{') { if (line.charAt(pos) == '{') {
pos++; pos++;
...@@ -1429,78 +1573,87 @@ public class ConversionUtil { ...@@ -1429,78 +1573,87 @@ public class ConversionUtil {
if (result == null) { if (result == null) {
throw new ParserException("No result in input"); throw new ParserException("No result in input");
} }
if (!arrays.containsKey("op_status")) {
if (result == -1) { for (String keyArray : Arrays.asList("op_status", "participation_as_resource")) {
operations = new ArrayList<>(); if (! arrays.containsKey(keyArray)) {
} else { if (result == -1) {
throw new ParserException("No \"op_status\" in input"); operations = new ArrayList<>();
} else {
throw new ParserException("No \"" + keyArray + "\" in input");
}
} }
} }
if (result != -1) { if (result != -1) {
Task task = new Task(taskCase, "");
operations = new ArrayList<>(); operations = new ArrayList<>();
ArrayList<ArrayList<String>> opStatus = arrays.get("op_status"); ArrayList<ArrayList<String>> opStatus = arrays.get("op_status");
ArrayList<OperationTemplate> templates = new ArrayList<>(task.getTemplates()); ArrayList<OperationTemplate> templates = new ArrayList<>(taskCase.getTemplates());
if (task.isTypified()) { if (taskCase.isTypified()) {
templates = Task.renumberOperations(task); templates = Task.renumberOperations(taskCase);
} }
Map<Integer, OperationTemplate> operationById = new TreeMap<>(); Map<Integer, OperationTemplate> operationById = new TreeMap<>();
for (OperationTemplate operation : task.getTemplates()) { for (OperationTemplate operation : taskCase.getTemplates()) {
operationById.put(operation.getId(), operation); operationById.put(operation.getId(), operation);
} }
Map<Integer, MovingObject> objByNo = new TreeMap<>(); Map<Integer, MovingObject> objByNo = new TreeMap<>();
ArrayList<ArrayList<Boolean>> isFixed; ArrayList<ArrayList<Boolean>> isFixed;
{
Task t = new Task(task, "");
ArrayList<MovingObject> movingObjects = new ArrayList<>();
movingObjects.addAll(task.getShips());
movingObjects.addAll(task.getTows());
movingObjects.addAll(task.getEquipments());
for (MovingObject obj : movingObjects) {
objByNo.put(t.getMObjNumberById().get(obj.getId()), obj);
}
isFixed = t.getIsFixedArray(); for (MovingObject obj : task.getMovingObjects()) {
objByNo.put(task.getMObjNumberById().get(obj.getId()), obj);
} }
isFixed = task.getIsFixedArray();
Set<String> oldSolution = new TreeSet<>(); Set<String> oldSolution = new TreeSet<>();
for (Operation op : task.getSolution()) { for (Operation op : taskCase.getSolution()) {
if (op.getFixation()) { if (op.getFixation()) {
oldSolution.add(op.toString()); oldSolution.add(op.toString());
} }
} }
for (int opNo = 0; opNo < opStatus.size(); opNo++) { for (int opNo = 1; opNo < opStatus.size(); opNo++) {
int duration = 0; int duration = 0;
int t = 0; int t = 0;
boolean lastFixation = false; boolean lastFixation = false;
while (t < opStatus.get(opNo).size()) { while (t < opStatus.get(opNo).size()) {
if ((opStatus.get(opNo).get(t).equals("true") && (lastFixation != isFixed.get(opNo).get(t - 1))) if ((opStatus.get(opNo).get(t).equals("true") && (lastFixation != isFixed.get(opNo).get(t)) && (duration != 0))
|| (opStatus.get(opNo).get(t).equals("false") && (duration != 0))) { // Добавляем новую операцию. || (opStatus.get(opNo).get(t).equals("false") && (duration != 0))) { // Добавляем новую операцию.
Operation op = new Operation(); Operation op = new Operation();
op.setStart(t - duration - 1); op.setStart(t - duration - 1);
op.setDuration(duration); op.setDuration(duration);
op.setTemplate(operationById.get(templates.get(opNo).getId())); op.setTemplate(operationById.get(templates.get(opNo - 1).getId()));
if (task.isTypified()) { if (taskCase.isTypified()) {
op.setExecutor(ConversionUtil.getExecutor(templates.get(opNo))); op.setExecutor(ConversionUtil.getExecutor(templates.get(opNo - 1)));
ArrayList<MovingObject> resources = new ArrayList<>(); ArrayList<MovingObject> resources = new ArrayList<>();
// TODO ускорить. // TODO ускорить.
ArrayList<ArrayList<String>> opOfResource = arrays.get("participation_as_resource"); ArrayList<ArrayList<String>> opOfResource = arrays.get("participation_as_resource");
for (int obj = 0; obj < opOfResource.size(); obj++) { for (int obj = 1; obj < opOfResource.size(); obj++) {
if (opOfResource.get(obj).get(t - 1).equals(Integer.toString(opNo + 1))) { if (opOfResource.get(obj).get(t - 1).equals(Integer.toString(opNo))) {
resources.add(objByNo.get(obj)); resources.add(objByNo.get(obj - 1));
} }
} }
op.setResources(resources); op.setResources(resources);
} }
{
OperationTemplate template = templates.get(opNo - 1);
if (template instanceof LoadingTemplate) {
LoadingTemplate operation = (LoadingTemplate)template;
if (operation.getBunker().isPresent()) {
// TODO Доделать.
}
}
}
op.setFixation(true); op.setFixation(true);
if (! oldSolution.contains(op.toString())) { if (! oldSolution.contains(op.toString())) {
op.setFixation(false); op.setFixation(false);
...@@ -1509,22 +1662,24 @@ public class ConversionUtil { ...@@ -1509,22 +1662,24 @@ public class ConversionUtil {
operations.add(op); operations.add(op);
duration = 0; duration = 0;
} }
if (opStatus.get(opNo).get(t).equals("true") && (lastFixation != isFixed.get(opNo).get(t - 1))) { // Остаёмся на месте. if (opStatus.get(opNo).get(t).equals("true") && (lastFixation != isFixed.get(opNo).get(t))) { // Остаёмся на месте.
lastFixation = isFixed.get(opNo).get(t - 1); lastFixation = isFixed.get(opNo).get(t);
continue; continue;
} }
if (opStatus.get(opNo).get(t).equals("true")) { if (opStatus.get(opNo).get(t).equals("true")) {
duration++; duration++;
} else {
duration = 0;
} }
if ((0 <= t - 1) && (t - 1 < isFixed.get(opNo).size())) { if ((0 <= t) && (t < isFixed.get(opNo).size())) {
lastFixation = isFixed.get(opNo).get(t - 1); lastFixation = isFixed.get(opNo).get(t);
} }
t++; t++;
} }
} }
} }
task.setSolution(operations); taskCase.setSolution(operations);
task.setSolution_result(result); taskCase.setSolution_result(result);
} catch (IOException e) { } catch (IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }
......
...@@ -6,6 +6,7 @@ package inport; ...@@ -6,6 +6,7 @@ package inport;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.OptionalInt; import java.util.OptionalInt;
/** /**
...@@ -15,7 +16,9 @@ import java.util.OptionalInt; ...@@ -15,7 +16,9 @@ import java.util.OptionalInt;
public class LoadingTemplate extends OperationTemplate { public class LoadingTemplate extends OperationTemplate {
private TransportShip loader; private TransportShip loader;
private OptionalInt loaderType = OptionalInt.empty(); private OptionalInt loaderType = OptionalInt.empty();
private Optional<Bunker> bunker = Optional.empty();
private OptionalInt bunkerType = OptionalInt.empty();
private Storage storage; private Storage storage;
private List<LoadingEquipment> resources; private List<LoadingEquipment> resources;
private List<Integer> resourcesTypes; private List<Integer> resourcesTypes;
...@@ -23,6 +26,20 @@ public class LoadingTemplate extends OperationTemplate { ...@@ -23,6 +26,20 @@ public class LoadingTemplate extends OperationTemplate {
private boolean withMooring; private boolean withMooring;
private Cargo cargo; private Cargo cargo;
public OptionalInt getBunkerType() {
return bunkerType;
}
public void setBunkerType(OptionalInt bunkerType) {
this.bunkerType = bunkerType;
}
public Optional<Bunker> getBunker() {
return bunker;
}
public void setBunker(Optional<Bunker> bunker) {
this.bunker = bunker;
}
public OptionalInt getLoaderType() { public OptionalInt getLoaderType() {
return loaderType; return loaderType;
} }
...@@ -95,11 +112,19 @@ public class LoadingTemplate extends OperationTemplate { ...@@ -95,11 +112,19 @@ public class LoadingTemplate extends OperationTemplate {
return cargo; return cargo;
} }
public LoadingTemplate(TransportShip loader, Berth berth, Storage storage, Cargo cargo, public LoadingTemplate(TransportShip loader,
List<Integer> resourcesTypes, boolean withMooring, double intensity, int id) { Berth berth,
Storage storage,
Cargo cargo,
Optional<Bunker> bunker,
List<Integer> resourcesTypes,
boolean withMooring,
double intensity,
int id) {
super(id, berth); super(id, berth);
this.loader = loader; this.loader = loader;
this.storage = storage; this.storage = storage;
this.bunker = bunker;
this.resources = new ArrayList<>(); this.resources = new ArrayList<>();
this.resourcesTypes = new ArrayList<>(resourcesTypes); this.resourcesTypes = new ArrayList<>(resourcesTypes);
this.withMooring = withMooring; this.withMooring = withMooring;
...@@ -130,20 +155,20 @@ public class LoadingTemplate extends OperationTemplate { ...@@ -130,20 +155,20 @@ public class LoadingTemplate extends OperationTemplate {
res += t; res += t;
first = false; first = false;
} }
int startId;
if (loaderType.isPresent()) {
startId = loaderType.getAsInt();
} else {
startId = loader.getId();
}
int source = startId; int source = (loaderType.isPresent() ? loaderType.getAsInt() : loader.getId());
if (intensity>0) int target;
source = storage.getId(); if (bunkerType.isPresent()) {
int target = startId; target = bunkerType.getAsInt();
if (intensity<=0) } else target = bunker.map(MovingObject::getId).orElseGet(() -> storage.getId());
target = storage.getId();
if (intensity > 0) {
int temp = source;
source = target;
target = temp;
}
return getId() + "; " + "loa; " + twtoString() + "; " + source + "; " + cargo.getId() + "; " + target + "; " return getId() + "; " + "loa; " + twtoString() + "; " + source + "; " + cargo.getId() + "; " + target + "; "
+ getStartLocation().getId() + "; [" + res +"]; " + Math.abs(intensity) + "; " + (withMooring ? "M" : "U"); + getStartLocation().getId() + "; [" + res +"]; " + Math.abs(intensity) + "; "
} + (withMooring ? "M" : "U");
}
} }
...@@ -100,7 +100,6 @@ public class Main { ...@@ -100,7 +100,6 @@ public class Main {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
break; break;
} }
String error = solveTask_2(task); String error = solveTask_2(task);
if (!error.isEmpty()) { if (!error.isEmpty()) {
...@@ -148,10 +147,7 @@ public class Main { ...@@ -148,10 +147,7 @@ public class Main {
} }
Task t = new Task(task, ""); Task t = new Task(task, "");
{ {
ArrayList<MovingObject> movingObjects = new ArrayList<>(); ArrayList<MovingObject> movingObjects = Task.calcMovingObjects(task);
movingObjects.addAll(task.getShips());
movingObjects.addAll(task.getTows());
movingObjects.addAll(task.getEquipments());
Map<Integer, MovingObject> objByNo = new TreeMap<>(); Map<Integer, MovingObject> objByNo = new TreeMap<>();
for (MovingObject obj : movingObjects) { for (MovingObject obj : movingObjects) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package inport; package inport;
import java.util.List; import java.util.List;
import java.util.Optional;
/** /**
* *
...@@ -17,8 +18,16 @@ public class Operation { ...@@ -17,8 +18,16 @@ public class Operation {
private double start; private double start;
private double duration; private double duration;
private MovingObject executor; private MovingObject executor;
private Optional<Bunker> bunker = Optional.empty();
private List<MovingObject> resources; private List<MovingObject> resources;
public Optional<Bunker> getBunker() {
return bunker;
}
public void setBunker(Optional<Bunker> bunker) {
this.bunker = bunker;
}
public boolean getFixation() { public boolean getFixation() {
return fixation; return fixation;
} }
...@@ -110,7 +119,8 @@ public class Operation { ...@@ -110,7 +119,8 @@ public class Operation {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(template.getId()).append("; "); sb.append(template.getId()).append("; ");
sb.append(fixation ? "F" : "R").append("; ").append(start).append("; ").append(duration); sb.append(fixation ? "F" : "R").append("; ").append(start).append("; ").append(duration);
sb.append(" (").append(executor.getId()).append(" ["); sb.append(" (").append(executor.getId()).append(" ");
sb.append(bunker.map(b -> b.getId() + " ").orElse("")).append("[");
boolean isFirst = true; boolean isFirst = true;
for (MovingObject obj : resources) { for (MovingObject obj : resources) {
if (isFirst) { if (isFirst) {
......
...@@ -101,7 +101,7 @@ public class Storage { ...@@ -101,7 +101,7 @@ public class Storage {
@Override @Override
public String toString() { public String toString() {
return id + "; " + name + "; " + cargo.getId() + "; " +volume; return id + "; " + name + "; " + cargo.getId() + "; " + volume;
} }
public Storage(String s, Map<Integer, Cargo> cargoes) { public Storage(String s, Map<Integer, Cargo> cargoes) {
......
...@@ -82,15 +82,24 @@ public class StorageState { ...@@ -82,15 +82,24 @@ public class StorageState {
return ""; return "";
} }
public StorageState(String s, Map<Integer, Storage> mp, Map<Integer, MovingObject> vp, Map<Integer, Cargo> cp) { public StorageState(String s,
Map<Integer, Storage> mp,
Map<Integer, MovingObject> vp,
Map<Integer, Bunker> bunkers,
Map<Integer, Cargo> cp) {
String[] tokens = s.split(";"); String[] tokens = s.split(";");
int key = Integer.parseInt(tokens[0].trim()); int key = Integer.parseInt(tokens[0].trim());
cargo = cp.get(key); cargo = cp.get(key);
key = Integer.parseInt(tokens[1].trim()); key = Integer.parseInt(tokens[1].trim());
if (mp.containsKey(key)) if (mp.containsKey(key)) {
storage = mp.get(key); storage = mp.get(key);
if (vp.containsKey(key)) }
if (vp.containsKey(key)) {
storage = vp.get(key); storage = vp.get(key);
}
if (bunkers.containsKey(key)) {
storage = bunkers.get(key);
}
cargoState = Double.parseDouble(tokens[2].trim()); cargoState = Double.parseDouble(tokens[2].trim());
} }
......
...@@ -35,6 +35,9 @@ public class TaskCase { ...@@ -35,6 +35,9 @@ public class TaskCase {
// Обслуживаемые суда // Обслуживаемые суда
private List<TransportShip> ships; private List<TransportShip> ships;
// Типы бункеровщиков.
private Map<Integer, String> bunkerTypes;
// Типы обслуживаемых судов // Типы обслуживаемых судов
private Map<Integer, String> vesselTypes; private Map<Integer, String> vesselTypes;
...@@ -67,6 +70,13 @@ public class TaskCase { ...@@ -67,6 +70,13 @@ public class TaskCase {
// План - решение // План - решение
private List<Operation> solution; private List<Operation> solution;
public Map<Integer, String> getBunkerTypes() {
return bunkerTypes;
}
public void setBunkerTypes(Map<Integer, String> bunkerTypes) {
this.bunkerTypes = bunkerTypes;
}
/** /**
* Get the value of solution * Get the value of solution
* *
...@@ -385,6 +395,7 @@ public class TaskCase { ...@@ -385,6 +395,7 @@ public class TaskCase {
equipments = new ArrayList<>(); equipments = new ArrayList<>();
ships = new ArrayList<>(); ships = new ArrayList<>();
bunkerTypes = new TreeMap<>();
vesselTypes = new TreeMap<>(); vesselTypes = new TreeMap<>();
equipmentTypes = new TreeMap<>(); equipmentTypes = new TreeMap<>();
...@@ -401,12 +412,15 @@ public class TaskCase { ...@@ -401,12 +412,15 @@ public class TaskCase {
solution = new ArrayList<>(); solution = new ArrayList<>();
} }
private MovingObjectState fromString(String s, Map<Integer, Berth> m_berth, Map<Integer, MovingObject> m_vessel) private MovingObjectState fromString(String s,
Map<Integer, Berth> m_berth,
Map<Integer, MovingObject> m_vessel,
Map<Integer, Bunker> m_bunker)
{ {
String[] tkns1 = s.split(";"); String[] tkns1 = s.split(";");
MovingObjectState st = new MovingObjectState(); MovingObjectState st = new MovingObjectState();
int key = Integer.parseInt(tkns1[0].trim()); int key = Integer.parseInt(tkns1[0].trim());
MovingObject vs = m_vessel.get(key); MovingObject vs = m_vessel.containsKey(key) ? m_vessel.get(key) : m_bunker.get(key);
st.setVessel(vs); st.setVessel(vs);
key = Integer.parseInt(tkns1[1].trim()); key = Integer.parseInt(tkns1[1].trim());
st.setLocation(m_berth.get(key)); st.setLocation(m_berth.get(key));
...@@ -422,6 +436,7 @@ public class TaskCase { ...@@ -422,6 +436,7 @@ public class TaskCase {
Loading_Equipment_Types("Loading Equipment Types"), Loading_Equipment_Types("Loading Equipment Types"),
Vessel_Types ("Vessel Types"), Vessel_Types ("Vessel Types"),
Bunkers ("Bunkers"), Bunkers ("Bunkers"),
Bunker_Types ("Bunker Types"),
Tows ("Tows"), Tows ("Tows"),
Loading_Equipments ("Loading Equipments"), Loading_Equipments ("Loading Equipments"),
Transport_Ships ("Transport Ships"), Transport_Ships ("Transport Ships"),
...@@ -453,6 +468,7 @@ public class TaskCase { ...@@ -453,6 +468,7 @@ public class TaskCase {
{ {
cargoes.clear(); berths.clear(); storages.clear(); bunkers.clear(); tows.clear(); equipments.clear(); ships.clear(); templates.clear(); cargoes.clear(); berths.clear(); storages.clear(); bunkers.clear(); tows.clear(); equipments.clear(); ships.clear(); templates.clear();
cargoFlows.clear(); vesselInitialState.clear(); storageInitialState.clear(); vesselEndState.clear(); storageEndState.clear(); cargoFlows.clear(); vesselInitialState.clear(); storageInitialState.clear(); vesselEndState.clear(); storageEndState.clear();
bunkerTypes.clear();
solution.clear(); solution.clear();
// Open the file // Open the file
...@@ -467,6 +483,7 @@ public class TaskCase { ...@@ -467,6 +483,7 @@ public class TaskCase {
Map<Integer, Berth> m_berth = new HashMap<>(); Map<Integer, Berth> m_berth = new HashMap<>();
Map<Integer, Storage> m_storage = new HashMap<>(); Map<Integer, Storage> m_storage = new HashMap<>();
Map<Integer, MovingObject> m_vessel = new HashMap<>(); Map<Integer, MovingObject> m_vessel = new HashMap<>();
Map<Integer, Bunker> m_bunker = new HashMap<>();
Map<Integer, LoadingEquipment> m_equipment = new HashMap<>(); Map<Integer, LoadingEquipment> m_equipment = new HashMap<>();
Map<Integer, OperationTemplate> m_template = new HashMap<>(); Map<Integer, OperationTemplate> m_template = new HashMap<>();
//Read File Line By Line //Read File Line By Line
...@@ -494,7 +511,8 @@ public class TaskCase { ...@@ -494,7 +511,8 @@ public class TaskCase {
break; break;
case Berths: Berth b = new Berth(strLine); berths.add(b); m_berth.put(b.getId(), b); case Berths: Berth b = new Berth(strLine); berths.add(b); m_berth.put(b.getId(), b);
break; break;
case Storages: Storage s = new Storage(strLine, m_cargo); storages.add(s); m_storage.put(s.getId(), s); case Storages:
Storage s = new Storage(strLine, m_cargo); storages.add(s); m_storage.put(s.getId(), s);
break; break;
case Vessel_Types: case Vessel_Types:
tokens = strLine.split(";"); tokens = strLine.split(";");
...@@ -505,6 +523,13 @@ public class TaskCase { ...@@ -505,6 +523,13 @@ public class TaskCase {
equipmentTypes.put(Integer.parseInt(tokens[0].trim()), tokens[1].trim()); equipmentTypes.put(Integer.parseInt(tokens[0].trim()), tokens[1].trim());
break; break;
case Bunkers: case Bunkers:
Bunker bunker = new Bunker(strLine);
bunkers.add(bunker);
m_bunker.put(bunker.getId(), bunker);
break;
case Bunker_Types :
tokens = strLine.split(";");
bunkerTypes.put(Integer.parseInt(tokens[0].trim()), tokens[1].trim());
break; break;
case Tows: Tow t = new Tow(strLine); tows.add(t); m_vessel.put(t.getId(), t); case Tows: Tow t = new Tow(strLine); tows.add(t); m_vessel.put(t.getId(), t);
break; break;
...@@ -577,7 +602,8 @@ public class TaskCase { ...@@ -577,7 +602,8 @@ public class TaskCase {
LoadingTemplate mt = new LoadingTemplate(); LoadingTemplate mt = new LoadingTemplate();
mt.setId(Integer.parseInt(tokens[0].trim())); mt.setId(Integer.parseInt(tokens[0].trim()));
mt.setTimeWindow(tokens[2].trim()); mt.setTimeWindow(tokens[2].trim());
int direct = 1;
int direction = 1;
BiFunction<Integer, Integer, Integer> addLoaderOrStorage = (Integer key, Integer loaderDirection) -> { BiFunction<Integer, Integer, Integer> addLoaderOrStorage = (Integer key, Integer loaderDirection) -> {
int dir = 1; int dir = 1;
...@@ -588,17 +614,27 @@ public class TaskCase { ...@@ -588,17 +614,27 @@ public class TaskCase {
if (m_vessel.containsKey(key)) { if (m_vessel.containsKey(key)) {
mt.setLoader((TransportShip)m_vessel.get(key)); mt.setLoader((TransportShip)m_vessel.get(key));
dir = loaderDirection; dir = loaderDirection;
} } else
if (m_storage.containsKey(key)) { if (m_storage.containsKey(key)) {
mt.setStorage((Storage)m_storage.get(key)); mt.setStorage(m_storage.get(key));
dir = -loaderDirection;
} else
if (m_bunker.containsKey(key)) {
mt.setBunker(Optional.of(m_bunker.get(key)));
dir = -loaderDirection;
} else
if (bunkerTypes.containsKey(key)) {
mt.setBunkerType(OptionalInt.of(key));
dir = -loaderDirection; dir = -loaderDirection;
} }
return dir; return dir;
}; };
// Источник. Пока пара - это только хранилище-судно. С бункеровкой будем разбираться потом int key;
int key = Integer.parseInt(tokens[3].trim());
direct = addLoaderOrStorage.apply(key, -1); // Источник.
key = Integer.parseInt(tokens[3].trim());
direction = addLoaderOrStorage.apply(key, -1);
// Груз. // Груз.
key = Integer.parseInt(tokens[4].trim());; key = Integer.parseInt(tokens[4].trim());;
for (Cargo cargo : cargoes) { for (Cargo cargo : cargoes) {
...@@ -606,9 +642,9 @@ public class TaskCase { ...@@ -606,9 +642,9 @@ public class TaskCase {
mt.setCargo(cargo); mt.setCargo(cargo);
} }
} }
// Приемник. Пока пара - это только хранилище-судно. С бункеровкой будем разбираться потом // Приемник.
key = Integer.parseInt(tokens[5].trim()); key = Integer.parseInt(tokens[5].trim());
direct = addLoaderOrStorage.apply(key, 1); direction = addLoaderOrStorage.apply(key, 1);
key = Integer.parseInt(tokens[6].trim()); key = Integer.parseInt(tokens[6].trim());
mt.setStartLocation(m_berth.get(key)); mt.setStartLocation(m_berth.get(key));
String[] rs = tokens[7].trim().replace("[", "").replace("]", "").split(","); String[] rs = tokens[7].trim().replace("[", "").replace("]", "").split(",");
...@@ -621,7 +657,7 @@ public class TaskCase { ...@@ -621,7 +657,7 @@ public class TaskCase {
mt.getResources().add(m_equipment.get(key)); mt.getResources().add(m_equipment.get(key));
} }
} }
mt.setIntensity(direct*Double.parseDouble(tokens[8].trim())); mt.setIntensity(direction*Double.parseDouble(tokens[8].trim()));
mt.setWithMooring(tokens[9].trim().equals("M")); mt.setWithMooring(tokens[9].trim().equals("M"));
templates.add(mt); templates.add(mt);
...@@ -632,13 +668,13 @@ public class TaskCase { ...@@ -632,13 +668,13 @@ public class TaskCase {
break; break;
case Cargo_Flows: cargoFlows.add(new CargoFlow(strLine, m_storage, m_cargo)); case Cargo_Flows: cargoFlows.add(new CargoFlow(strLine, m_storage, m_cargo));
break; break;
case Initial_Vessel_State: vesselInitialState.add(fromString(strLine, m_berth, m_vessel)); case Initial_Vessel_State: vesselInitialState.add(fromString(strLine, m_berth, m_vessel, m_bunker));
break; break;
case Initial_Storage_State: storageInitialState.add(new StorageState(strLine, m_storage, m_vessel, m_cargo)); case Initial_Storage_State: storageInitialState.add(new StorageState(strLine, m_storage, m_vessel, m_bunker, m_cargo));
break; break;
case Final_Vessel_State: vesselEndState.add(fromString(strLine, m_berth, m_vessel)); case Final_Vessel_State: vesselEndState.add(fromString(strLine, m_berth, m_vessel, m_bunker));
break; break;
case Final_Storage_State: storageEndState.add(new StorageState(strLine, m_storage, m_vessel, m_cargo)); case Final_Storage_State: storageEndState.add(new StorageState(strLine, m_storage, m_vessel, m_bunker, m_cargo));
break; break;
case Task_Properties: case Task_Properties:
{ {
...@@ -719,7 +755,13 @@ public class TaskCase { ...@@ -719,7 +755,13 @@ public class TaskCase {
for (Map.Entry<Integer, String> e : vesselTypes.entrySet()) { for (Map.Entry<Integer, String> e : vesselTypes.entrySet()) {
writer.write(e.getKey() + "; " + e.getValue() + "\n"); writer.write(e.getKey() + "; " + e.getValue() + "\n");
} }
writer.write("\n" + Tag.Bunker_Types.text + "\n");
for (Map.Entry<Integer, String> e : bunkerTypes.entrySet()) {
writer.write(e.getKey() + "; " + e.getValue() + "\n");
}
} }
writer.write("\nBunkers"+"\n"); writer.write("\nBunkers"+"\n");
for (Bunker c : bunkers) for (Bunker c : bunkers)
writer.write(c.toString()+"\n"); writer.write(c.toString()+"\n");
......
Typified
1
Cargoes
10001; Нечто; 0.0
10002; Топливо; 0.0
Berths
1; Raid
2; Pier 1
3; Pier 2
Storages
4; Storage 1; 10001; 10000.0
Vessel Types
1001; Тип судна 1
Bunker Types
2001; Тип бункировщика 1
Bunkers
201; Bunker 1; 2000.0; 2001
202; Bunker 2; 2000.0; 2001
Tows
Loading Equipment Types
Loading Equipments
Transport Ships
101; Ship 1; 2000.0; 1001
102; Ship 2; 2000.0; 1001
Templates
7; mov; []; 1001; 1; 2; []; 1.0
8; mov; []; 1001; 2; 1; []; 1.0
9; mov; []; 1001; 1; 3; []; 1.0
10; mov; []; 1001; 3; 1; []; 1.0
11; mov; []; 1001; 2; 3; []; 1.0
12; mov; []; 1001; 3; 2; []; 1.0
13; mov; []; 2001; 3; 2; []; 1.0
14; mov; []; 2001; 3; 2; []; 1.0
19; loa; []; 4; 10001; 1001; 2; []; 100.0; U
20; loa; []; 2001; 10002; 1001; 2; []; 10.0; U
Cargo Flows
Initial Vessel State
101; 1
102; 1
201; 2
202; 2
Initial Storage State
10001; 101; 0.0
10002; 101; 0.0
10001; 102; 0.0
10002; 102; 0.0
10002; 201; 20.0
10002; 202; 20.0
10001; 4; 10000.0
Final Vessel State
101; 1
102; 1
Final Storage State
10001; 101; 300.0
10002; 101; 20.0
10001; 102; 300.0
10002; 102; 20.0
Task Properties
30.0; 0
Solution
8.0
7; R; 0.0; 1.0 (101 [])
9; R; 0.0; 1.0 (102 [])
19; R; 1.0; 3.0 (101 [])
20; R; 1.0; 1.0 (101 [])
10; R; 2.0; 1.0 (102 [])
7; R; 3.0; 1.0 (102 [])
20; R; 3.0; 1.0 (101 [])
11; R; 4.0; 1.0 (101 [])
19; R; 4.0; 3.0 (102 [])
20; R; 4.0; 1.0 (102 [])
20; R; 5.0; 1.0 (102 [])
8; R; 7.0; 1.0 (102 [])
10; R; 7.0; 1.0 (101 [])
...@@ -69,7 +69,7 @@ Final Storage State ...@@ -69,7 +69,7 @@ Final Storage State
Task Properties Task Properties
30.0; 0 22.0; 0
Solution Solution
......
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