Commit aee5e993 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Refactoring.

parent 6f4e16e6
......@@ -218,6 +218,9 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
% Операции погрузки, которые используют этот объект в качестве главного или в качестве бункеровщика.
array [0..n_moving_obj] of set of 0..n_operations : related_cargo_op;
% Операции отшвартовки, которые используют объект в качестве главного.
array [0..n_moving_obj] of set of 1..n_operations : related_unmooring_op;
% Определение is_involved_in_cargo_op.
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
is_involved_in_cargo_op[obj, t] = (
......@@ -698,6 +701,11 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
);
*/
% Для оптимизаций.
array [1..n_all_storage_sections, 1..n_locations] of int : min_positive_cargo_val; % Объём максимальной положительной операции, которая может быть произведена с этой секцией в этом хранилище. Если в локации таковой нет, то это значение объёма хранилища + 1.
array [1..n_all_storage_sections, 1..n_locations] of int : max_negative_cargo_val;
array [1..n_moving_obj, 1..n_locations] of bool : can_obj_leave_loc_only_alone;
array [1..n_moving_obj, 1..n_locations, 1..n_intervals] of bool : is_fixed_op_planned_in_future;
% Критерий оптимизации
......
......@@ -218,6 +218,9 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
% Операции погрузки, которые используют этот объект в качестве главного или в качестве бункеровщика.
array [0..n_moving_obj] of set of 0..n_operations : related_cargo_op;
% Операции отшвартовки, которые используют объект в качестве главного.
array [0..n_moving_obj] of set of 1..n_operations : related_unmooring_op;
% Определение is_involved_in_cargo_op.
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
is_involved_in_cargo_op[obj, t] = (
......@@ -356,11 +359,30 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
0..n_all_storage_sections : max_number_of_connected_sections;
array [0..n_sections_of_real_storage_and_bunkers, 0..max_number_of_connected_sections, 1..(n_intervals + 1)] of var int : nominal_cargo_value;
array [0..n_sections_of_real_storage_and_bunkers, 0..(max_number_of_connected_sections + 1), 1..(n_intervals + 1)] of var int : cargo_overflow_remains;
array [0..n_sections_of_real_storage_and_bunkers, 0..max_number_of_connected_sections, 1..(n_intervals + 1)] of var int : real_cargo_value;
array [0..n_operations, 1..(n_intervals + 1)] of var int : nominal_cargo_value;
array [0..n_sections_of_real_storage_and_bunkers, 1..(n_intervals + 1)] of var int : nominal_incoming_sum;
array [0..n_operations, 1..(n_intervals + 1)] of var int : real_cargo_value;
array [0..n_sections_of_real_storage_and_bunkers, 1..(n_intervals + 1)] of var int : total_sum;
% Использует ли эта операция секцию как хранилище при погрузке или как бункеровщик при бункеровке.
array [0..n_sections_of_real_storage_and_bunkers, 0..n_operations] of bool : is_op_used_stor_as_secondary;
array [0..n_sections_of_real_storage_and_bunkers, 1..(n_intervals + 1)] of var 0..n_operations : current_partial_cargo_op;
% Определение current_partial_cargo_op
% current_partial_cargo_op только из множества допустимых операций.
constraint forall (section in 1..n_sections_of_real_storage_and_bunkers, t in 1..(n_intervals + 1)) (
(current_partial_cargo_op[section, t] != 0) -> (is_op_used_stor_as_secondary[section, current_partial_cargo_op[section, t]])
);
% current_partial_cargo_op активна.
constraint forall (section in 1..n_sections_of_real_storage_and_bunkers, t in 1..(n_intervals + 1)) (
(current_partial_cargo_op[section, t] != 0) -> op_status[current_partial_cargo_op[section, t], t]
);
% Определение nominal_incoming_sum - номинальный объём груза, который суда вливают в хранилище.
constraint forall (section in 0..n_sections_of_real_storage_and_bunkers, t in 1..(n_intervals + 1)) (
nominal_incoming_sum[section, t] = sum (op in involved_operations[section]) (nominal_cargo_value[op, t])
);
% Определение real_cargo_value
array [0..n_operations] of 0..n_all_storage_sections : operations_main_stor_no_in_secondary;
array [0..n_operations] of 0..n_all_storage_sections : operations_secondary_stor_no_in_main;
......@@ -377,7 +399,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
where pos != 0) (
let {var int : total_vol = storage_used_volume[section_1, t - 1] + loading_op_delta_of_main_obj[op];} in
(op_status[op, t] /\ total_vol > storage_greedy_upper_limit[section_1]) -> (
nominal_cargo_value[section_2, pos, t] = -(loading_op_delta_of_main_obj[op] - (total_vol - storage_greedy_upper_limit[section_1]))
nominal_cargo_value[op, t] = -(loading_op_delta_of_main_obj[op] - (total_vol - storage_greedy_upper_limit[section_1]))
)
);
constraint forall (op in 1..n_operations,
......@@ -388,7 +410,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
where pos != 0) (
let {var int : total_vol = storage_used_volume[section_1, t - 1] + loading_op_delta_of_main_obj[op];} in
(op_status[op, t] /\ total_vol < storage_greedy_lower_limit[section_1]) -> (
nominal_cargo_value[section_2, pos, t] = -(loading_op_delta_of_main_obj[op] - (total_vol - storage_greedy_lower_limit[section_1]))
nominal_cargo_value[op, t] = -(loading_op_delta_of_main_obj[op] - (total_vol - storage_greedy_lower_limit[section_1]))
)
);
constraint forall (op in 1..n_operations,
......@@ -400,134 +422,87 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
let {var int : total_vol = storage_used_volume[section_1, t - 1] + loading_op_delta_of_main_obj[op];} in
(op_status[op, t] /\ (total_vol >= storage_greedy_lower_limit[section_1])
/\ (total_vol <= storage_greedy_upper_limit[section_1])) -> (
nominal_cargo_value[section_2, pos, t] = -loading_op_delta_of_main_obj[op]
nominal_cargo_value[op, t] = -loading_op_delta_of_main_obj[op]
)
);
% Если нет активной операции, влияющей на эту пару секций, то nominal_cargo_value = 0.
constraint forall (section_1 in 1..n_sections_of_real_storage_and_bunkers,
section_2 in 1..number_of_connected_sections[section_1],
t in 1..(n_intervals + 1)) (
(forall (op in connected_op_to_pair_of_sections[section_1, section_2]) (not op_status[op, t]))
->
(nominal_cargo_value[section_1, section_2, t] = 0)
% Если опреация не активна, то nominal_cargo_value = 0.
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1)) (
(not op_status[op, t]) -> (nominal_cargo_value[op, t] = 0)
);
% Крайние значения.
constraint forall (section_1 in 1..n_sections_of_real_storage_and_bunkers,
section_2 in (number_of_connected_sections[section_1] + 1)..max_number_of_connected_sections,
t in 1..(n_intervals + 1)) (
nominal_cargo_value[section_1, section_2, t] = 0
);
constraint forall (section_1 in 1..n_sections_of_real_storage_and_bunkers,
t in 1..(n_intervals + 1)) (
nominal_cargo_value[section_1, 0, t] = 0
);
constraint forall (section_2 in 0..max_number_of_connected_sections,
t in 1..(n_intervals + 1)) (
nominal_cargo_value[0, section_2, t] = 0
);
constraint forall (op in 1..n_operations) (nominal_cargo_value[op, 0] = 0);
constraint forall (t in 1..(n_intervals + 1)) (nominal_cargo_value[0, t] = 0);
% Определение cargo_overflow_remains.
% array [0..n_sections_of_real_storage_and_bunkers, 1..(n_intervals + 1)] of var int : total_sum;
constraint forall (t in 1..(n_intervals + 1), section in 1..n_sections_of_real_storage_and_bunkers) (
total_sum[section, t] = sum (i in 1..number_of_connected_sections[section]) (nominal_cargo_value[section, i, t])
% Определение real_cargo_value
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1)) ( % Целая операция.
(current_partial_cargo_op[operations_secondary_stor[op], t] != op) ->
(real_cargo_value[op, t] = nominal_cargo_value[op, t])
);
constraint forall (t in 1..(n_intervals + 1)) (total_sum[0, t] = 0);
% Переполнение.
constraint forall (t in 1..(n_intervals + 1), section in 1..n_sections_of_real_storage_and_bunkers) (
(total_sum[section, t] + storage_used_volume[section, t - 1] > storage_greedy_upper_limit[section])
->
(cargo_overflow_remains[section, number_of_connected_sections[section] + 1, t] =
total_sum[section, t] + storage_used_volume[section, t - 1] - storage_greedy_upper_limit[section]
% Нецелая операция.
% Переполнение за нижнюю границу.
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1),
section = operations_secondary_stor[op]) ( % Нецелая операция.
( (current_partial_cargo_op[section, t] == op)
/\ (nominal_cargo_value[op, t] < 0)
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] < storage_greedy_lower_limit[section])
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1]
- nominal_cargo_value[op, t] >= storage_greedy_lower_limit[section])
) -> (
real_cargo_value[op, t] = storage_greedy_lower_limit[section] - (
nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] - nominal_cargo_value[op, t])
)
);
constraint forall (t in 1..(n_intervals + 1), section in 1..n_sections_of_real_storage_and_bunkers) (
(total_sum[section, t] + storage_used_volume[section, t - 1] < storage_greedy_lower_limit[section])
->
(cargo_overflow_remains[section, number_of_connected_sections[section] + 1, t] =
total_sum[section, t] + storage_used_volume[section, t - 1] - storage_greedy_lower_limit[section]
% Переполнение за верхнюю границу.
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1),
section = operations_secondary_stor[op]) ( % Нецелая операция.
( (current_partial_cargo_op[section, t] == op)
/\ (nominal_cargo_value[op, t] > 0)
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] > storage_greedy_upper_limit[section])
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1]
- nominal_cargo_value[op, t] <= storage_greedy_upper_limit[section])
) -> (
real_cargo_value[op, t] = storage_greedy_upper_limit[section] - (
nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] - nominal_cargo_value[op, t])
)
);
constraint forall (t in 1..(n_intervals + 1), section in 1..n_sections_of_real_storage_and_bunkers) (
let {var int : total = total_sum[section, t] + storage_used_volume[section, t - 1]} in
((storage_greedy_lower_limit[section] <= total) /\ (total <= storage_greedy_upper_limit[section]))
->
(cargo_overflow_remains[section, number_of_connected_sections[section] + 1, t] = 0)
% Переполнения нет.
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1),
section = operations_secondary_stor[op]) ( % Нецелая операция.
( (current_partial_cargo_op[section, t] == op)
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] <= storage_greedy_upper_limit[section])
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] >= storage_greedy_lower_limit[section])
) -> (real_cargo_value[op, t] = nominal_cargo_value[op, t])
);
% Избавляемся от лишнего.
% Если остаток переполнения и номналное значение одного знака, то полностью отменяем это номинальное значение.
constraint forall (t in 1..(n_intervals + 1),
section in 1..n_sections_of_real_storage_and_bunkers,
i in 1..number_of_connected_sections[section]) (
((((cargo_overflow_remains[section, i + 1, t] < 0) /\ (nominal_cargo_value[section, i, t] < 0))
\/
((cargo_overflow_remains[section, i + 1, t] > 0) /\ (nominal_cargo_value[section, i, t] > 0))
) /\ (abs(cargo_overflow_remains[section, i + 1, t]) >= abs(nominal_cargo_value[section, i, t]))
) -> (
cargo_overflow_remains[section, i, t] =
cargo_overflow_remains[section, i + 1, t] -
nominal_cargo_value[section, i, t]
)
% Неустранимое переполнение за нижнюю границу.
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1),
section = operations_secondary_stor[op]) ( % Нецелая операция.
( (current_partial_cargo_op[section, t] == op)
/\ (nominal_cargo_value[op, t] <= 0)
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] < storage_greedy_lower_limit[section])
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1]
- nominal_cargo_value[op, t] < storage_greedy_lower_limit[section])
) -> (real_cargo_value[op, t] = 0)
);
% Иначе оно полностью перекрыло переполнение.
constraint forall (t in 1..(n_intervals + 1),
section in 1..n_sections_of_real_storage_and_bunkers,
i in 1..number_of_connected_sections[section]) (
(((cargo_overflow_remains[section, i + 1, t] <= 0) /\ (nominal_cargo_value[section, i, t] >= 0))
\/
((cargo_overflow_remains[section, i + 1, t] >= 0) /\ (nominal_cargo_value[section, i, t] <= 0))
\/
(abs(cargo_overflow_remains[section, i + 1, t]) < abs(nominal_cargo_value[section, i, t]))
) -> (
cargo_overflow_remains[section, i, t] = 0
)
% Неустранимое переполнение за верхнюю границу.
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1),
section = operations_secondary_stor[op]) ( % Нецелая операция.
( (current_partial_cargo_op[section, t] == op)
/\ (nominal_cargo_value[op, t] >= 0)
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1] > storage_greedy_upper_limit[section])
/\ (nominal_incoming_sum[section, t] + storage_used_volume[section, t - 1]
- nominal_cargo_value[op, t] > storage_greedy_upper_limit[section])
) -> (real_cargo_value[op, t] = 0)
);
% Крайние значения.
constraint forall (t in 1..(n_intervals + 1), section in 1..n_sections_of_real_storage_and_bunkers) (
cargo_overflow_remains[section, 0, t] = 0
);
constraint forall (t in 1..(n_intervals + 1),
section in 1..n_sections_of_real_storage_and_bunkers,
i in (number_of_connected_sections[section] + 2)..max_number_of_connected_sections) (
cargo_overflow_remains[section, i, t] = 0
);
constraint forall (section_2 in 0..(max_number_of_connected_sections + 1),
t in 1..(n_intervals + 1)) (
cargo_overflow_remains[0, section_2, t] = 0
);
% Определение real_cargo_value
constraint forall (t in 1..(n_intervals + 1),
section in 1..n_sections_of_real_storage_and_bunkers,
i in 1..number_of_connected_sections[section]) (
real_cargo_value[section, i, t] = nominal_cargo_value[section, i, t]
- cargo_overflow_remains[section, i + 1, t]
+ cargo_overflow_remains[section, i, t]
);
% Крайние значения.
constraint forall (t in 1..(n_intervals + 1), section in 1..n_sections_of_real_storage_and_bunkers) (
real_cargo_value[section, 0, t] = 0
);
constraint forall (t in 1..(n_intervals + 1),
section in 1..n_sections_of_real_storage_and_bunkers,
i in (number_of_connected_sections[section] + 1)..max_number_of_connected_sections) (
real_cargo_value[section, i, t] = 0
);
constraint forall (section_2 in 0..max_number_of_connected_sections,
t in 1..(n_intervals + 1)) (
real_cargo_value[0, section_2, t] = 0
);
constraint forall (t in 1..(n_intervals + 1)) (real_cargo_value[0, t] = 0);
array [0..n_all_storage_sections] of set of 1..n_all_storage_sections : all_used_positions_in_real_cargo_value;
array [1..n_all_storage_sections, 1..n_all_storage_sections] of 0..max_number_of_connected_sections : positions_of_connected_sections;
/*
constraint forall (storage in 1..n_sections_of_real_storage_and_bunkers, t in 1..(n_intervals + 1)) (
storage_used_volume[storage, t] = (
storage_used_volume[storage, t - 1] +
......@@ -544,7 +519,6 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
)
);
/*
constraint forall (storage in 1..n_sections_of_real_storage_and_bunkers, t in 1..(n_intervals + 1)) (
debug_storage_used_volume[storage, t] = (
debug_storage_used_volume[storage, t - 1] +
......@@ -570,7 +544,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
debug_storage_used_volume[storage, 0] = initial_storage_vol[storage]
);
/*
constraint forall (storage in 1..n_all_storage_sections, t in 1..(n_intervals + 1)) (
storage_used_volume[storage, t] = (
storage_used_volume[storage, t - 1] +
......@@ -581,7 +555,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
)
)
);
*/
% Фиксированные операции.
int : n_fixed_op;
array [1..n_fixed_op] of 1..n_operations : fixed_op;
......@@ -602,6 +576,11 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
)
);
% Для оптимизаций.
array [1..n_all_storage_sections, 1..n_locations] of int : min_positive_cargo_val; % Объём максимальной положительной операции, которая может быть произведена с этой секцией в этом хранилище. Если в локации таковой нет, то это значение объёма хранилища + 1.
array [1..n_all_storage_sections, 1..n_locations] of int : max_negative_cargo_val;
array [1..n_moving_obj, 1..n_locations] of bool : can_obj_leave_loc_only_alone;
array [1..n_moving_obj, 1..n_locations, 1..n_intervals] of bool : is_fixed_op_planned_in_future;
% Критерий оптимизации
......@@ -637,7 +616,6 @@ output [show(sum(is_not_terminated)), "\n",
"current_moored_obj = ", show(current_moored_obj), "\n\n",
"nominal_cargo_value {", show(max_number_of_connected_sections + 1), " ", show(n_intervals + 1), "} = ", show(nominal_cargo_value), "\n\n",
"cargo_overflow_remains {", show(max_number_of_connected_sections + 2), " ", show(n_intervals + 1), "} = ", show(cargo_overflow_remains), "\n\n",
"real_cargo_value {", show(max_number_of_connected_sections + 1), " ", show(n_intervals + 1), "} = ", show(real_cargo_value), "\n\n",
% "debug_1 {", show(max_number_of_connected_sections + 1), " ", show(n_intervals + 1), "} = ", show(debug_1), "\n\n",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
package inport.ConversionUtils;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
public class MZnFormat {
static public void write2DArrayOfInt(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations) throws IOException {
locWrite2DArray(writer, name, operations, Object::toString, false);
}
static public void write2DArrayOfInt(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations,
boolean isNumberedFromZero) throws IOException {
locWrite2DArray(writer, name, operations, Object::toString, isNumberedFromZero);
}
static public void write2DArrayOfSet(FileWriter writer,
String name,
ArrayList<ArrayList<ArrayList<Integer>>> operations) throws IOException {
locWrite2DArray(writer, name, operations,
(ArrayList<Integer> a) -> {
StringBuilder s = new StringBuilder();
s.append('{');
boolean isFirst2 = true;
for (Integer val : a) {
if (isFirst2) {
isFirst2 = false;
} else {
s.append(", ");
}
s.append(val);
}
s.append('}');
return s.toString();
}
);
}
static public <T> void locWrite2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations,
Function<T, String> toMZNFormat) throws IOException {
locWrite2DArray(writer, name, operations, toMZNFormat, false);
}
static public int boolToInt(boolean b) {
return b ? 1 : 0;
}
static public <T> void locWrite2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations,
Function<T, String> toMZNFormat,
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;
for (ArrayList<T> a : operations) {
for (T val : a) {
if (isFirst0) {
isFirst0 = false;
} else {
writer.write(", ");
}
writer.write(toMZNFormat.apply(val));
}
}
writer.write("]);\n");
}
static public <T extends Collection<Integer>> void write2DArrayOfSetAs3DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations) throws IOException {
write2DArrayOfSetAs3DArray(writer, name, operations, false);
}
static public <T extends Collection<Integer>> void write2DArrayOfSetAs3DArray(FileWriter writer,
String name,
ArrayList<ArrayList<T>> operations,
boolean isNumberedFromZero) throws IOException {
int maxSize = 0;
ArrayList<ArrayList<Integer>> sizes = new ArrayList<>();
int dim1 = operations.size();
int dim2 = 0;
for (ArrayList<T> a1 : operations) {
dim2 = a1.size();
ArrayList<Integer> locSizes = new ArrayList<>();
for (T a2 : a1) {
maxSize = Math.max(maxSize, a2.size());
locSizes.add(a2.size());
}
sizes.add(locSizes);
}
writer.write(name + "_max_size = " + maxSize + ";\n");
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, [");
}
boolean isFirst = true;
for (ArrayList<T> a1 : operations) {
for (T a2 : a1) {
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) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write(Integer.toString(1));
}
}
}
writer.write("]);\n");
}
static public <T> void write3dArray(FileWriter writer,
String name,
ArrayList<ArrayList<ArrayList<T>>> array,
Function<T, String> toString) throws IOException {
int dim1 = array.size();
int dim2 = (dim1 > 0) ? array.get(0).size() : 0;
int dim3 = (dim2 > 0) ? array.get(0).get(0).size() : 0;
writer.write(name + " = array3d(1.." + dim1 + ", 1.." + dim2 + ", 1.." + dim3 + ", ");
ArrayList<String> values = new ArrayList<>();
for (ArrayList<ArrayList<T>> a2 : array) {
for (ArrayList<T> a1 : a2) {
for (T val : a1) {
values.add(toString.apply(val));
}
}
}
writer.write("[" + String.join(", ", values) + "]);\n");
}
static public void writeArrayOfSetAs2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations) throws IOException {
writeArrayOfSetAs2DArray(writer, name, operations, true, false);
}
static public void writeArrayOfSetAs2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations,
boolean addAdditionalInfo,
boolean addDummyZeroElement) throws IOException {
int maxSize = 0;
ArrayList<Integer> sizes = new ArrayList<>();
for (ArrayList<Integer> s : operations) {
maxSize = Math.max(maxSize, s.size());
sizes.add(s.size());
}
if (addAdditionalInfo) {
writer.write(name + "_max_size = " + maxSize + ";\n");
writeArray(writer, name + "_sizes", sizes);
}
writer.write(name + " = array2d(1.." + operations.size() + ", " + (addDummyZeroElement ? "0" : "1") + ".." + maxSize + ", [");
boolean isFirst = true;
for (ArrayList<Integer> s : operations) {
if (addDummyZeroElement) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write("1");
}
for (Integer val : s) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write(Integer.toString(val));
}
for (int i = s.size(); i < maxSize; i++) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write("1");
}
}
writer.write("]);\n");
}
static public <T, E> void writeArray(FileWriter writer,
String name,
ArrayList<T> data,
Function<T, E> f,
Optional<T> dummyZeroElement) throws IOException {
writer.write(name + " = array1d(" + (dummyZeroElement.isPresent() ? 0 : 1) + ".." + data.size() + ", [");
boolean isFirst = true;
if (dummyZeroElement.isPresent()) {
isFirst = false;
writer.write(f.apply(dummyZeroElement.get()).toString());
}
for (int i = 0; i < data.size(); i++) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write(f.apply(data.get(i)).toString());
}
writer.write("]);\n");
}
static public <T> void writeArray(FileWriter writer, String name, ArrayList<T> data) throws IOException {
writeArray(writer, name, data, (T val) -> val, Optional.empty());
}
static public <T, E> void writeArray(FileWriter writer,
String name,
ArrayList<T> data,
Function<T, E> f) throws IOException {
writeArray(writer, name, data, f, Optional.empty());
}
static public <T, E> void writeArray(FileWriter writer,
String name,
ArrayList<T> data,
Optional<T> dummyZeroElement) throws IOException {
writeArray(writer, name, data, (T val) -> val, dummyZeroElement);
}
static public <T> String setToString(Set<T> s) {
StringBuilder res = new StringBuilder();
res.append("{");
boolean isFirst = true;
for (T t : s) {
if (isFirst) {
isFirst = false;
} else {
res.append(", ");
}
res.append(t.toString());
}
res.append("}");
return res.toString();
}
static public <T> String arrayToStringAsSet(ArrayList<T> a) {
return setToString(new TreeSet<>(a));
}
}
package inport.ConversionUtils;
import inport.*;
import java.io.*;
import java.util.*;
public class MZnResultsResolver {
public static void resolveMiniZincResults(TaskCase taskCase, String fileName) {
ArrayList<Operation> operations = null;
Integer result = null;
try (FileInputStream fstream = new FileInputStream(fileName)) {
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String line;
Map<String, ArrayList<ArrayList<String>>> arrays = new TreeMap<>();
while (((line = br.readLine()) != null)) {
line = line.trim();
if (line.equals("")) {
continue;
}
int pos = 0;
while ((pos < line.length()) && (line.charAt(pos) != ' ')) {
pos++;
}
String name = line.substring(0, pos);
if (name.equals("=====UNSATISFIABLE=====")) {
result = -1;
break;
}
if (name.equals("----------")) {
break;
}
if (name.matches("\\d+")) {
if (result != null) {
continue;
}
result = Integer.parseInt(name);
continue;
}
while ((pos < line.length()) && (line.charAt(pos) != '[') && (line.charAt(pos) != '{')) {
pos++;
}
int arrayFirstDim = ((int) taskCase.getPlanningInterval()) + 2;
if (line.charAt(pos) == '{') {
pos++;
int nextPos = pos;
while (line.charAt(nextPos) != '}') {
nextPos++;
}
String []dimensions = line.substring(pos, nextPos).trim().split(" ");
if (dimensions.length > 0) {
arrayFirstDim = Integer.valueOf(dimensions[0].trim());
}
pos = nextPos + 1;
while (line.charAt(pos) != '[') {
pos++;
}
}
int pos2 = pos;
while ((pos2 < line.length()) && (line.charAt(pos2) != ']')) {
pos2++;
}
String values = line.substring(pos + 1, pos2);
ArrayList<String> elements = new ArrayList<>();
for (String val : values.split(",")) {
elements.add(val.trim());
}
if ((arrayFirstDim != 0) && (elements.size() % arrayFirstDim == 0)) {
ArrayList<ArrayList<String>> res = new ArrayList<>();
for (int i = 0; i < elements.size(); i += arrayFirstDim) {
ArrayList<String> subRes = new ArrayList<>();
for (int j = 0; j < arrayFirstDim; j++) {
subRes.add(elements.get(i + j));
}
res.add(subRes);
}
arrays.put(name, res);
}
}
if (result == null) {
throw new ParserException("No result in input");
}
for (String keyArray : Arrays.asList("op_status", "participation_as_resource")) {
if (! arrays.containsKey(keyArray)) {
if (result == -1) {
operations = new ArrayList<>();
} else {
throw new ParserException("No \"" + keyArray + "\" in input");
}
}
}
if (result != -1) {
Task task = new Task(taskCase, "");
operations = new ArrayList<>();
ArrayList<ArrayList<String>> opStatus = arrays.get("op_status");
ArrayList<OperationTemplate> templates = new ArrayList<>(taskCase.getTemplates());
if (taskCase.isTypified()) {
templates = Task.renumberOperations(taskCase);
}
ArrayList<ArrayList<String>> cargoOpIntensity;
if (arrays.containsKey("cargo_op_intensity")) {
cargoOpIntensity = arrays.get("cargo_op_intensity");
} else {
cargoOpIntensity = new ArrayList<>();
for (int opNo = 0; opNo < opStatus.size(); opNo++) {
cargoOpIntensity.add(new ArrayList<>());
for (String val : opStatus.get(opNo)) {
if (val.equals("true") && (templates.get(opNo - 1) instanceof LoadingTemplate)) {
LoadingTemplate op = (LoadingTemplate)templates.get(opNo - 1);
cargoOpIntensity.get(opNo).add(Integer.toString((int)Math.ceil(Math.abs(op.getIntensity()))));
} else {
cargoOpIntensity.get(opNo).add("0");
}
}
}
}
Map<Integer, OperationTemplate> operationById = new TreeMap<>();
for (OperationTemplate operation : taskCase.getTemplates()) {
operationById.put(operation.getId(), operation);
}
Map<Integer, MovingObject> objByNo = new TreeMap<>();
ArrayList<ArrayList<Boolean>> isFixed;
for (MovingObject obj : task.getMovingObjects()) {
objByNo.put(task.getMObjNumberById().get(obj.getId()), obj);
}
isFixed = task.getIsFixedArray();
Set<String> oldSolution = new TreeSet<>();
for (Operation op : taskCase.getFixedOperations()) {
if (op.getFixation()) {
oldSolution.add(op.toString());
}
}
for (int opNo = 1; opNo < opStatus.size(); opNo++) {
int duration = 0;
int t = 1;
boolean lastFixation = false;
while (t < opStatus.get(opNo).size()) {
boolean isOpLogicallyInterrupted = false;
if (opStatus.get(opNo).get(t).equals("true") &&
(lastFixation != isFixed.get(opNo).get(t)) &&
(duration != 0)) { // У операции изменилась фиксация.
isOpLogicallyInterrupted = true;
}
if (opStatus.get(opNo).get(t).equals("false") && (duration != 0)) { // Операция просто закончилась.
isOpLogicallyInterrupted = true;
}
if ((! cargoOpIntensity.get(opNo).get(t - 1).equals(cargoOpIntensity.get(opNo).get(t))) &&
(duration != 0)) { // Изменилась интенсивность погрузки.
isOpLogicallyInterrupted = true;
}
if (isOpLogicallyInterrupted) { // Добавляем новую операцию.
Operation op = new Operation();
op.setStart(t - duration - 1);
op.setDuration(duration);
op.setTemplate(operationById.get(templates.get(opNo - 1).getId()));
if (taskCase.isTypified()) {
op.setExecutor(Utils.getExecutor(templates.get(opNo - 1)));
ArrayList<MovingObject> resources = new ArrayList<>();
// TODO ускорить.
ArrayList<ArrayList<String>> opOfResource = arrays.get("participation_as_resource");
for (int obj = 1; obj < opOfResource.size(); obj++) {
if (opOfResource.get(obj).get(t - 1).equals(Integer.toString(opNo))) {
resources.add(objByNo.get(obj - 1));
}
}
op.setResources(resources);
}
{ // Установка бункеровщика.
OperationTemplate template = templates.get(opNo - 1);
if (template instanceof LoadingTemplate) {
LoadingTemplate operation = (LoadingTemplate)template;
if (operation.getBunker().isPresent()) {
op.setBunker(operation.getBunker());
}
}
}
if (! cargoOpIntensity.get(opNo).get(t - 1).equals("0")) {
op.setIntensity(Optional.of(Integer.valueOf(cargoOpIntensity.get(opNo).get(t - 1))));
}
op.setFixation(true);
if (! oldSolution.contains(op.toString())) {
op.setFixation(false);
}
operations.add(op);
duration = 0;
}
if (opStatus.get(opNo).get(t).equals("true") && (lastFixation != isFixed.get(opNo).get(t))) { // Остаёмся на месте.
lastFixation = isFixed.get(opNo).get(t);
continue;
}
if (opStatus.get(opNo).get(t).equals("true")) {
duration++;
} else {
duration = 0;
}
if ((0 <= t) && (t < isFixed.get(opNo).size())) {
lastFixation = isFixed.get(opNo).get(t);
}
t++;
}
}
}
taskCase.setSolution(operations);
taskCase.setSolution_result(result);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
package inport;
package inport.ConversionUtils;
public class ParserException extends RuntimeException {
ParserException(String mess) {
......
package inport.ConversionUtils;
import inport.*;
import javafx.util.Pair;
import org.jetbrains.annotations.NotNull;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import static inport.ConversionUtils.MZnFormat.*;
import static inport.ConversionUtils.Utils.*;
public class Task {
private FileWriter writer = null;
private final String fileName;
private final TaskCase task;
private final int n_intervals;
private final ArrayList<Berth> berths;
private final Map<Pair<Integer, Boolean>, Integer> locationNumberById;
private int getLocNById(int id, boolean isMoored) {
return locationNumberById.get(new Pair<>(id, isMoored));
}
private final ArrayList<MovingObject> movingObjects;
public Map<Integer, Integer> getMObjNumberById() {
return mObjNumberById;
}
private final Map<Integer, Integer> mObjNumberById;
private int mObjToN(MovingObject obj) {
return mObjNumberById.get(obj.getId());
}
private ArrayList<OperationTemplate> operationTemplates;
private final ArrayList<Storage> storages;
private final ArrayList<Cargo> cargoes;
private final int nObjWithStorage;
class StorageSectionId implements Comparable<StorageSectionId> {
boolean isRealStorage; // Not transport ship.
Integer localN;
Integer typeN;
StorageSectionId(boolean isRealStorage, Integer localN, Integer typeN) {
this.isRealStorage = isRealStorage;
this.localN = localN;
this.typeN = typeN;
}
@Override
public int compareTo(@NotNull StorageSectionId id) {
if (isRealStorage != id.isRealStorage) {
return (isRealStorage ? 1 : -1);
}
if (! localN.equals(id.localN)) {
return localN.compareTo(id.localN);
}
if (! typeN.equals(id.typeN)) {
return typeN.compareTo(id.typeN);
}
return 0;
}
}
private final Map<StorageSectionId, Integer> sectionNById;
private int sectionIdToN(Storage storage, Cargo cargo) {
return sectionNById.get(new StorageSectionId(
true,
storageNById.get(storage.getId()),
cargoNById.get(cargo.getId())));
}
private int sectionIdToN(TransportShip transportShip, Cargo cargo) {
return sectionNById.get(new StorageSectionId(
false,
mObjToN(transportShip),
cargoNById.get(cargo.getId())));
}
private final Map<Integer, Integer> storageNById;
private final Map<Integer, Integer> cargoNById;
private final Map<Integer, Integer> typeToN;
private ArrayList<ArrayList<Integer>> movingOpOfObj;
private ArrayList<Integer> operationsDestination;
private ArrayList<Integer> mainObjOfOperation;
private ArrayList<Boolean> isMooringOp;
private ArrayList<Set<Integer>> objectsOfType;
public ArrayList<MovingObject> getMovingObjects() {
return movingObjects;
}
private final int nSectionsOfRealStorageAndBunkers;
private final ArrayList<Integer> initialStorageVol;
private final ArrayList<Integer> finalStorageVol;
private final ArrayList<Integer> maxStorageVol;
public Task(TaskCase task, String fileName) {
this.fileName = fileName;
this.task = task;
n_intervals = (int)task.getPlanningInterval();
berths = new ArrayList<>(task.getBerths());
locationNumberById = new TreeMap<>(new PairComparator<>());
for (Berth berth : berths) {
locationNumberById.put(new Pair<>(berth.getId(), false), locationNumberById.size());
locationNumberById.put(new Pair<>(berth.getId(), true), locationNumberById.size());
}
movingObjects = calcMovingObjects(task);
mObjNumberById = new TreeMap<>();
for (int i = 0; i < movingObjects.size(); i++) {
mObjNumberById.put(movingObjects.get(i).getId(), i);
}
operationTemplates = new ArrayList<>(task.getTemplates());
if (task.isTypified()) {
operationTemplates = renumberOperations(task);
}
storages = new ArrayList<>(task.getStorages());
cargoes = new ArrayList<>(task.getCargoes());
cargoNById = new TreeMap<>();
for (int i = 0; i < task.getCargoes().size(); i++) {
cargoNById.put(cargoes.get(i).getId(), i);
}
int nextStorageNo = 0;
storageNById = new TreeMap<>();
sectionNById = new TreeMap<>();
for (int i = 0; i < storages.size(); i++) { // Сначала реальные хранилища.
storageNById.put(storages.get(i).getId(), i);
for (Pair<Cargo, Double> p : storages.get(i).getStorageSections()) {
sectionNById.put(new StorageSectionId(true, i, cargoNById.get(p.getKey().getId())), nextStorageNo++);
}
}
for (MovingObject obj : movingObjects) { // Затем бункеровщики.
if (obj instanceof Bunker) {
for (Pair<Cargo, Double> p : ((TransportShip) obj).getStorageSections()) {
sectionNById.put(new StorageSectionId(false, mObjToN(obj), cargoNById.get(p.getKey().getId())), nextStorageNo++);
}
}
}
nSectionsOfRealStorageAndBunkers = sectionNById.size();
for (MovingObject obj : movingObjects) { // Дальше - все остальные.
if ((obj instanceof TransportShip) && (!(obj instanceof Bunker))) {
for (Pair<Cargo, Double> p : ((TransportShip) obj).getStorageSections()) {
sectionNById.put(new StorageSectionId(false, mObjToN(obj), cargoNById.get(p.getKey().getId())), nextStorageNo++);
}
}
}
nObjWithStorage = movingObjects.size() + storages.size();
{
typeToN = new TreeMap<>();
int next = 0;
for (Integer type : task.getVesselTypes().keySet()) {
typeToN.put(type, next);
next++;
}
for (Integer type : task.getBunkerTypes().keySet()) {
typeToN.put(type, next);
next++;
}
for (Integer type : task.getEquipmentsTypes().keySet()) {
typeToN.put(type, next);
next++;
}
}
{
objectsOfType = arrayOfIntegerSet(typeToN.size());
for (MovingObject obj : movingObjects) {
if (obj.getType().isPresent()) {
objectsOfType.get(typeToN.get(obj.getType().getAsInt())).add(mObjToN(obj) + 1);
}
}
}
{
movingOpOfObj = arrayOfIntegerArrays(movingObjects.size());
operationsDestination = new ArrayList<>();
mainObjOfOperation = new ArrayList<>();
isMooringOp = new ArrayList<>();
initMovingObjectLocationDefinition();
}
{
initialStorageVol = integerArray(sectionNById.size(), 0);
finalStorageVol = integerArray(sectionNById.size(), -1);
BiConsumer<ArrayList<Integer>, StorageState> f = (ArrayList<Integer> a, StorageState st) -> {
int val = (int)st.getCargoState();
int sectionN;
if (st.getStorage() instanceof Storage) {
sectionN = sectionIdToN((Storage) st.getStorage(), st.getCargo());
} else {
assert st.getStorage() instanceof TransportShip;
sectionN = sectionIdToN((TransportShip) st.getStorage(), st.getCargo());
}
a.set(sectionN, val);
};
for (StorageState st : task.getStorageInitialState()) {
f.accept(initialStorageVol, st);
}
for (StorageState st : task.getStorageEndState()) {
f.accept(finalStorageVol, st);
}
}
{ // maxStorageVol
maxStorageVol = integerArray(sectionNById.size(), 0);
for (MovingObject obj : movingObjects) {
if (obj instanceof TransportShip) {
for (Pair<Cargo, Double> p : ((TransportShip) obj).getStorageSections()) {
maxStorageVol.set(sectionIdToN((TransportShip) obj, p.getKey()),
(int)Math.ceil(p.getValue()));
}
}
}
for (Storage storage : storages) {
for (Pair<Cargo, Double> p : storage.getStorageSections()) {
maxStorageVol.set(sectionIdToN(storage, p.getKey()),
(int)Math.ceil(p.getValue()));
}
}
}
}
private ArrayList<Integer> getNumbersOfResourcesTypes(OperationTemplate t) {
ArrayList<Integer> res = new ArrayList<>();
if (t instanceof LoadingTemplate) {
res.addAll(((LoadingTemplate) t).getResourcesTypes());
}
if (t instanceof MooringTemplate) {
res.addAll(((MooringTemplate) t).getResourcesTypes());
}
if (t instanceof MovingTemplate) {
res.addAll(((MovingTemplate) t).getResourcesTypes());
}
res.replaceAll(typeToN::get);
return res;
}
/* Операции прибытия/отбытия в локацию. (В том числе и швартовка.) */
private void arrivalAndDepartureOperations() throws IOException {
ArrayList<ArrayList<ArrayList<Integer>>> arrivalOp = new ArrayList<>();
ArrayList<ArrayList<ArrayList<Integer>>> departureOp = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) {
arrivalOp.add(new ArrayList<>());
departureOp.add(new ArrayList<>());
for (int j = 0; j < locationNumberById.size(); j++) {
arrivalOp.get(i).add(new ArrayList<>());
departureOp.get(i).add(new ArrayList<>());
}
}
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN(obj));
}
movingObjN.add(mObjToN(op.getMover()));
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById(op.getDestination().getId(), false)).add(i + 1);
departureOp.get(n).get(getLocNById(op.getStartLocation().getId(), false)).add(i + 1);
}
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN(obj));
}
movingObjN.add(mObjToN(op.getMoorer()));
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById(op.getStartLocation().getId(), op.isDirect())).add(i + 1);
departureOp.get(n).get(getLocNById(op.getStartLocation().getId(), !op.isDirect())).add(i + 1);
}
}
}
write2DArrayOfSetAs3DArray(writer, "arrival_op", arrivalOp);
write2DArrayOfSetAs3DArray(writer, "departure_op", departureOp);
writer.write("\n");
}
/* Начальные положения объектов. */
private void initialLocations() throws IOException {
ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
for (MovingObjectState state : task.getVesselInitialState()) {
initialStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false));
}
writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1, Optional.of(-1));
writer.write("\n");
}
/* Окна погоды. */
private void weatherWindows() throws IOException {
ArrayList<Integer> bw_op = new ArrayList<>();
ArrayList<Integer> bw_start = new ArrayList<>();
ArrayList<Integer> bw_fin = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
final int id = i;
operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> {
bw_op.add(id + 1);
bw_start.add((int)Math.floor(start));
bw_fin.add((int)Math.ceil(start + duration));
}
);
}
writer.write("n_bad_weather_windows = " + bw_op.size() + ";\n");
writeArray(writer, "bw_op", bw_op);
writeArray(writer, "bw_start", bw_start);
writeArray(writer, "bw_fin", bw_fin);
writer.write("\n");
}
/* Окна погоды. Новый формат. */
private void weatherWindowsNewFormat() throws IOException {
ArrayList<ArrayList<Boolean>> badWeather = new ArrayList<>();
badWeather.add(new ArrayList<>());
for (int j = 0; j <= n_intervals; j++) {
badWeather.get(0).add(false);
}
for (OperationTemplate operationTemplate : operationTemplates) {
ArrayList<Boolean> curLine = new ArrayList<>();
for (int j = 0; j <= n_intervals; j++) {
curLine.add(false);
}
operationTemplate.getTimeWindows().forEach(
(Double start, Double duration) -> {
for (int j = (int) Math.floor(start); j < (int) Math.ceil(start + duration); j++) {
curLine.set(j + 1, true);
}
}
);
badWeather.add(curLine);
}
locWrite2DArray(writer, "bad_weather", badWeather, Objects::toString, true);
}
/* Непрерывность перемещения и швартовки. */
private void operationsContinuity() throws IOException {
ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0);
ArrayList<Boolean> isMovingObj = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate) operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else {
isMovingObj.add(false);
}
}
writeArray(writer, "operations_duration", operationsDuration, Optional.of(1));
writeArray(writer, "is_continuous_operation", isMovingObj, Optional.of(false));
}
/* Конечные положения объектов. */
private void finalLocations() throws IOException {
ArrayList<Integer> finalStates = integerArray(movingObjects.size(), -1);
for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false));
}
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1, Optional.of(-1));
}
/* Наличие всех ресурсов на месте, в том числе и самого корабля. */
private void presenceOfResourcesInLocation() throws IOException {
ArrayList<ArrayList<Integer>> operationsResources = new ArrayList<>();
ArrayList<ArrayList<Integer>> operationsResourcesStartLoc = new ArrayList<>();
BiConsumer<MovingObject, Integer> addResource = (MovingObject r, Integer stLoc) -> {
operationsResources.get(operationsResources.size() - 1).add(mObjToN(r) + 1);
operationsResourcesStartLoc.get(operationsResourcesStartLoc.size() - 1).add(stLoc + 1);
};
for (OperationTemplate operationTemplate : operationTemplates) {
operationsResources.add(new ArrayList<>());
operationsResourcesStartLoc.add(new ArrayList<>());
if (operationTemplate instanceof MovingTemplate) { // Перемещение.
MovingTemplate op = (MovingTemplate) operationTemplate;
addResource.accept(op.getMover(), getLocNById(op.getStartLocation().getId(), false));
for (MovingObject obj : op.getResources()) {
addResource.accept(obj, getLocNById(op.getStartLocation().getId(), false));
}
} else if (operationTemplate instanceof MooringTemplate) { // Швартовка.
MooringTemplate op = (MooringTemplate) operationTemplate;
addResource.accept(op.getMoorer(), getLocNById(op.getStartLocation().getId(), !op.isDirect()));
for (MovingObject obj : op.getResources()) {
addResource.accept(obj, getLocNById(op.getStartLocation().getId(), false));
}
} else if (operationTemplate instanceof LoadingTemplate) { // Погрузка.
LoadingTemplate op = (LoadingTemplate) operationTemplate;
addResource.accept(op.getLoader(), getLocNById(op.getStartLocation().getId(), op.getWithMooring()));
for (MovingObject obj : op.getResources()) {
addResource.accept(obj, getLocNById(op.getStartLocation().getId(), false));
}
}
}
writeArrayOfSetAs2DArray(writer, "operations_resources", operationsResources);
writeArrayOfSetAs2DArray(writer, "operations_resources_start_loc", operationsResourcesStartLoc, false, false);
writer.write("\n");
}
/* Конфликтующие операции. */
private void conflictingOperations() throws IOException {
ArrayList<Pair<Integer, Integer>> conflictingPairs = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
for (int j = i + 1; j < operationTemplates.size(); j++) {
if (!isCompatible(operationTemplates.get(i), operationTemplates.get(j))) {
conflictingPairs.add(new Pair<>(i + 1, j + 1));
}
}
}
writer.write("n_conflicting_op = " + conflictingPairs.size() + ";\n");
writeArray(writer, "confl_op_1", conflictingPairs, Pair::getKey);
writeArray(writer, "confl_op_2", conflictingPairs, Pair::getValue);
writer.write("\n");
}
/* Ограничения на вместимость. */
private void maxStorageVolume() throws IOException {
writeArray(writer, "max_storage_vol", maxStorageVol, Optional.of(0));
writer.write("\n");
}
/* Граничные состояния хранилищ. */
private void boundaryStorageStates() throws IOException {
writeArray(writer, "initial_storage_vol", initialStorageVol, Optional.of(0));
writeArray(writer, "final_storage_vol", finalStorageVol, Optional.of(-1));
}
/* Потоки грузов. */
private void cargoFlows() throws IOException {
ArrayList<ArrayList<Integer>> cargoFlows = new ArrayList<>();
for (int i = 0; i <= sectionNById.size(); i++) {
cargoFlows.add(integerArray(n_intervals + 2, 0));
}
for (CargoFlow flow : task.getCargoFlows()) {
int storageN = sectionIdToN(flow.getStorage(), flow.getCargo());
for (int i = 1; i < n_intervals + 2; i++) {
cargoFlows.get(storageN + 1).set(i, (int)flow.getCurrentValue(i - 0.1));
}
}
write2DArrayOfInt(writer,"cargo_flows", cargoFlows, true);
}
/* Грузовые операции со всеми хранилищами. */
private void cargoOperations() throws IOException {
ArrayList<ArrayList<Integer>> involvedOperations = new ArrayList<>();
ArrayList<Integer> loadingOpDelta = new ArrayList<>();
ArrayList<Integer> loading_op_local_direction = new ArrayList<>();
ArrayList<Integer> loadingOpN = new ArrayList<>();
ArrayList<Integer> loading_op_delta_of_main_obj = new ArrayList<>();
ArrayList<Integer> loading_op_abs_delta = new ArrayList<>();
ArrayList<Integer> loading_op_direction = new ArrayList<>();
ArrayList<Integer> operations_main_stor = new ArrayList<>();
ArrayList<Integer> operations_secondary_stor = new ArrayList<>();
ArrayList<Integer> operations_cargo_t = new ArrayList<>();
ArrayList<Integer> bunker_of_cargo_op = new ArrayList<>();
for (int i = 0; i < sectionNById.size(); i++) {
involvedOperations.add(new ArrayList<>());
}
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
int cargoN = cargoNById.get(op.getCargo().getId());
int storageN;
if (op.getBunker().isPresent()) {
storageN = sectionIdToN(op.getBunker().get(), op.getCargo());
} else {
storageN = sectionIdToN(op.getStorage(), op.getCargo());
}
int shipStorageN = sectionIdToN(op.getLoader(), op.getCargo());
loadingOpDelta.add(-(int)op.getIntensity());
loading_op_local_direction.add(-(int)op.getIntensity() > 0 ? 1 : -1);
loadingOpN.add(i);
involvedOperations.get(storageN).add(loadingOpDelta.size());
loadingOpDelta.add((int)op.getIntensity());
loading_op_local_direction.add( (int)op.getIntensity() > 0 ? 1 : -1);
loadingOpN.add(i);
involvedOperations.get(shipStorageN).add(loadingOpDelta.size());
loading_op_delta_of_main_obj.add((int)op.getIntensity());
loading_op_abs_delta.add(Math.abs((int)op.getIntensity()));
loading_op_direction.add((int)op.getIntensity() > 0 ? 1 : -1);
operations_main_stor.add(shipStorageN + 1);
operations_secondary_stor.add(storageN + 1);
operations_cargo_t.add(cargoN + 1);
bunker_of_cargo_op.add(op.getBunker().isPresent() ? mObjToN(op.getBunker().get()) + 1 : 0);
} else {
loading_op_delta_of_main_obj.add(0);
loading_op_abs_delta.add(0);
loading_op_direction.add(1);
operations_main_stor.add(1);
operations_secondary_stor.add(1);
operations_cargo_t.add(1);
bunker_of_cargo_op.add(0);
}
}
ArrayList<ArrayList<Integer>> sections_of_moving_obj = arrayOfIntegerArrays(movingObjects.size());
for (int i = 0; i < movingObjects.size(); i++) {
if (movingObjects.get(i) instanceof TransportShip) {
TransportShip ship = ((TransportShip) movingObjects.get(i));
for (Pair<Cargo, Double> p : ship.getStorageSections()) {
sections_of_moving_obj.get(i).add(sectionIdToN(ship, p.getKey()) + 1);
}
}
}
ArrayList<Boolean> is_sections_of_moving_obj_empty = new ArrayList<>();
for (ArrayList<Integer> sections : sections_of_moving_obj) {
is_sections_of_moving_obj_empty.add(sections.isEmpty());
}
writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n");
writeArray(writer, "involved_operations", involvedOperations, MZnFormat::arrayToStringAsSet);
writeArray(writer, "loading_op_delta", loadingOpDelta);
writeArray(writer, "loading_op_local_direction", loading_op_local_direction);
writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1);
writeArray(writer, "loading_op_delta_of_main_obj", loading_op_delta_of_main_obj, Optional.of(0));
writeArray(writer, "loading_op_abs_delta", loading_op_abs_delta, Optional.of(0));
writeArray(writer, "loading_op_direction", loading_op_direction, Optional.of(1));
writeArray(writer, "operations_main_stor", operations_main_stor, Optional.of(1));
writeArray(writer, "operations_secondary_stor", operations_secondary_stor, Optional.of(1));
writeArray(writer, "operations_cargo_t", operations_cargo_t, Optional.of(1));
writeArray(writer, "bunker_of_cargo_op", bunker_of_cargo_op, Optional.of(0));
writeArray(writer, "sections_of_moving_obj", sections_of_moving_obj, MZnFormat::arrayToStringAsSet);
writeArray(writer, "is_sections_of_moving_obj_empty", is_sections_of_moving_obj_empty);
writer.write("\n");
}
/* Ограничение на необходимость полезной операции между движениями к одному пункту назначения. */
private void constraintOnUsefulOperationBetweenMovements_0() throws IOException {
ArrayList<ArrayList<Integer>> objUsefulOperations = new ArrayList<>();
ArrayList<ArrayList<Integer>> movingOpOfObj = new ArrayList<>();
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) ->
objUsefulOperations.get(mObjToN(obj)).add(op + 1);
BiConsumer<MovingObject, Integer> addMovingOp = (MovingObject obj, Integer op) ->
movingOpOfObj.get(mObjToN(obj)).add(op + 1);
for (int i = 0; i < movingObjects.size(); i++) {
movingOpOfObj.add(new ArrayList<>());
objUsefulOperations.add(new ArrayList<>());
}
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i);
if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t;
addMovingOp.accept(op.getMover(), i);
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
addMovingOp.accept(obj, i);
}
} else if (t instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)t;
addMovingOp.accept(op.getMoorer(), i);
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
addMovingOp.accept(obj, i);
}
if (!op.isDirect()) { // Отшвартовка.
addUsOp.accept(op.getMoorer(), i);
}
} else if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate)t;
addUsOp.accept(op.getLoader(), i);
}
}
writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations);
writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj);
writer.write("\n");
}
private void constraintOnUsefulOperationBetweenMovements_1() throws IOException {
ArrayList<ArrayList<Integer>> objUsefulOperations = new ArrayList<>();
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) ->
objUsefulOperations.get(mObjToN(obj)).add(op + 1);
for (int i = 0; i < movingObjects.size(); i++) {
objUsefulOperations.add(new ArrayList<>());
}
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i);
if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t;
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
}
} else if (t instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)t;
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
}
if (!op.isDirect()) { // Отшвартовка.
addUsOp.accept(op.getMoorer(), i);
}
} else if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate)t;
addUsOp.accept(op.getLoader(), i);
}
}
writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations);
writer.write("\n");
}
private void initMovingObjectLocationDefinition() {
BiConsumer<MovingObject, Integer> addMovingOp = (MovingObject obj, Integer op) ->
movingOpOfObj.get(mObjToN(obj)).add(op + 1);
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i);
mainObjOfOperation.add(mObjToN(getExecutor(t)));
isMooringOp.add(t instanceof MooringTemplate);
if ((t instanceof MovingTemplate) || (t instanceof MooringTemplate)) {
addMovingOp.accept(getExecutor(t), i);
if (!task.isTypified()) {
for (MovingObject obj : getResources(t)) {
addMovingOp.accept(obj, i);
}
} else {
for (Integer typeId : new TreeSet<>(getNumbersOfResourcesTypes(t))) {
for (Integer objId : objectsOfType.get(typeId)) {
movingOpOfObj.get(objId - 1).add(i + 1);
}
}
}
}
if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t;
operationsDestination.add(getLocNById(op.getDestination().getId(), false));
} else if (t instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)t;
operationsDestination.add(getLocNById(op.getStartLocation().getId(), op.isDirect()));
} else {
operationsDestination.add(getLocNById(t.getStartLocation().getId(), false));
}
}
}
private void movingObjectLocationDefinition(boolean isV1) throws IOException {
writeArray(writer, "is_mooring_op", isMooringOp, Optional.of(false));
writeArray(writer, "operations_destination", operationsDestination, (Integer val) -> val + 1,
Optional.of(-1));
writer.write("\n");
}
private void cargoOpUsingObj() throws IOException {
ArrayList<Set<Integer>> relatedCargoOp = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) {
relatedCargoOp.add(new TreeSet<>());
}
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
relatedCargoOp.get(mObjToN(op.getLoader())).add(i + 1);
if (op.getBunker().isPresent()) {
relatedCargoOp.get(mObjToN(op.getBunker().get())).add(i + 1);
}
}
}
writeArray(writer, "related_cargo_op", relatedCargoOp, MZnFormat::setToString,
Optional.of(new TreeSet<>()));
}
private void unmooringOpUsingObj() throws IOException {
ArrayList<Set<Integer>> relatedUnmooringOp = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) {
relatedUnmooringOp.add(new TreeSet<>());
}
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate) operationTemplates.get(i);
if (! op.isDirect()) {
relatedUnmooringOp.get(mObjToN(op.getMoorer())).add(i + 1);
}
}
}
writeArray(writer, "related_unmooring_op", relatedUnmooringOp, MZnFormat::setToString,
Optional.of(new TreeSet<>()));
}
// related_unmooring_op
private void addOpWithNominallyMooring() throws IOException {
ArrayList<ArrayList<Set<Integer>>> opWithNominallyMooring = new ArrayList<>();
for (int loc = 0; loc <= locationNumberById.size(); loc++) {
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++) {
OperationTemplate t = operationTemplates.get(i);
if ((t instanceof MooringTemplate) ||
((t instanceof LoadingTemplate) && (! ((LoadingTemplate)t).getWithMooring()))) {
opWithNominallyMooring.get(getLocNById(t.getStartLocation().getId(), true) + 1)
.get(mObjToN(getExecutor(t)) + 1)
.add(i + 1);
}
}
write2DArrayOfSetAs3DArray(writer, "op_with_nominally_mooring", opWithNominallyMooring, true);
}
void portToMiniZinc_0() {
if (task.isTypified()) {
throw new ParserException("Attempt to convert typified task as untyped.");
}
try {
writer.write("n_intervals = " + n_intervals + ";\n");
writer.write("n_operations = " + task.getTemplates().size() + ";\n");
writer.write("n_locations = " + locationNumberById.size() + ";\n");
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
writer.write("\n");
arrivalAndDepartureOperations();
initialLocations();
weatherWindows();
operationsContinuity();
finalLocations();
presenceOfResourcesInLocation();
conflictingOperations();
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
maxStorageVolume();
boundaryStorageStates();
cargoFlows();
cargoOperations();
constraintOnUsefulOperationBetweenMovements_0();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
void portToMiniZinc_1() {
if (task.isTypified()) {
throw new ParserException("Attempt to convert typified task as untyped.");
}
try {
writer.write("n_intervals = " + n_intervals + ";\n");
writer.write("n_operations = " + task.getTemplates().size() + ";\n");
writer.write("n_locations = " + locationNumberById.size() + ";\n");
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
writer.write("\n");
movingObjectLocationDefinition(true);
initialLocations();
weatherWindows();
operationsContinuity();
finalLocations();
presenceOfResourcesInLocation();
conflictingOperations();
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
maxStorageVolume();
boundaryStorageStates();
cargoFlows();
cargoOperations();
// constraintOnUsefulOperationBetweenMovements_1();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
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) {
TreeMap<Integer, ArrayList<MovingObject>> shipsByType = new TreeMap<>();
for (Integer type : task.getVesselTypes().keySet()) {
shipsByType.put(type, new ArrayList<>());
}
for (Integer type : task.getBunkerTypes().keySet()) {
shipsByType.put(type, new ArrayList<>());
}
for (Integer type : task.getEquipmentsTypes().keySet()) {
shipsByType.put(type, new ArrayList<>());
}
for (MovingObject obj : calcMovingObjects(task)) {
if (obj.getType().isPresent()) {
shipsByType.get(obj.getType().getAsInt()).add(obj);
}
}
ArrayList<OperationTemplate> result = new ArrayList<>();
for (OperationTemplate op : task.getTemplates()) {
if (op instanceof LoadingTemplate) {
LoadingTemplate t = (LoadingTemplate)op;
if (t.getLoaderType().isPresent()) {
for (MovingObject obj : shipsByType.get(t.getLoaderType().getAsInt())) {
assert(obj instanceof TransportShip);
if (t.getBunkerType().isPresent()) {
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()
));
}
}
}
}
if (op instanceof MooringTemplate) {
MooringTemplate t = (MooringTemplate)op;
if (t.getMoorerType().isPresent()) {
for (MovingObject obj : shipsByType.get(t.getMoorerType().getAsInt())) {
assert(obj instanceof TransportShip);
result.add(new MooringTemplate((TransportShip)obj, t.getStartLocation(), t.getResourcesTypes(),
t.getDuration(), t.isDirect(), t.getId()));
}
}
}
if (op instanceof MovingTemplate) {
MovingTemplate t = (MovingTemplate)op;
if (t.getMoverType().isPresent()) {
for (MovingObject obj : shipsByType.get(t.getMoverType().getAsInt())) {
result.add(new MovingTemplate(obj, t.getStartLocation(), t.getDestination(), t.getResourcesTypes(),
t.getDuration(), t.getId()));
}
}
}
}
return result;
}
private void conflictingOperationsOnStorageAndOnTypeOnMainObject() throws IOException {
ArrayList<Set<Integer>> conflictingOperationsG = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
conflictingOperationsG.add(new TreeSet<>());
for (int j = 0; j < operationTemplates.size(); j++) {
if (i == j) {
continue;
}
if ((operationTemplates.get(i) instanceof LoadingTemplate) &&
(operationTemplates.get(j) instanceof LoadingTemplate)) {
LoadingTemplate op1 = (LoadingTemplate) operationTemplates.get(i);
LoadingTemplate op2 = (LoadingTemplate) operationTemplates.get(j);
if ((op1.getStorage() == op2.getStorage()) &&
(op1.getStartLocation() == op2.getStartLocation()) &&
(op1.getLoader() == op2.getLoader())) {
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.getBunker().isPresent()) && (op2.getBunker().isPresent())) {
conflictingOperationsG.get(i).add(j + 1);
}
}
}
{ // Взаимоисключение операций перемещения и грузообработки с общим деятелем.
// TODO вынести в отдельный constraint
OperationTemplate t1 = operationTemplates.get(i);
OperationTemplate t2 = operationTemplates.get(j);
if (t1 instanceof LoadingTemplate) {
OperationTemplate t3 = t1;
t1 = t2;
t2 = t3;
}
if (((t1 instanceof MovingTemplate) || (t1 instanceof MooringTemplate))
&& (t2 instanceof LoadingTemplate)) {
if (getExecutor(t1) == getExecutor(t2)) {
conflictingOperationsG.get(i).add(j + 1);
}
}
}
{ // Взаимоисключение всех возможных пар операций перемещения с одним деятелем и пунктом отправления.
if ((operationTemplates.get(i) instanceof MovingTemplate) &&
(operationTemplates.get(j) instanceof MovingTemplate)) {
MovingTemplate op1 = (MovingTemplate) operationTemplates.get(i);
MovingTemplate op2 = (MovingTemplate) operationTemplates.get(j);
if ((op1.getMover() == op2.getMover()) && (op1.getStartLocation() == op2.getStartLocation())) {
conflictingOperationsG.get(i).add(j + 1);
}
}
}
}
}
writeArray(writer, "conflicting_operations", conflictingOperationsG, MZnFormat::setToString,
Optional.of(new TreeSet<>()));
}
public ArrayList<ArrayList<Boolean>> getIsFixedArray() {
Map<Pair<Integer, Integer>, Integer> opNoByOpIdAndExecutorNo = new TreeMap<>(new PairComparator<>());
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate op = operationTemplates.get(i);
opNoByOpIdAndExecutorNo.put(new Pair<>(op.getId(), getExecutor(op).getId()), i);
}
ArrayList<ArrayList<Boolean>> isFixed = new ArrayList<>();
for (int i = 0; i <= operationTemplates.size(); i++) {
isFixed.add(new ArrayList<>());
for (int j = 0; j <= n_intervals; j++) {
isFixed.get(i).add(false);
}
}
for (Operation op : task.getFixedOperations()) {
if (op.getFixation()) {
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++) {
isFixed.get(operation + 1).set(i + 1, true);
}
}
}
return isFixed;
}
private void fixedOperations() throws IOException {
ArrayList<Integer> fixedOp = new ArrayList<>();
ArrayList<Set<Integer>> fixedOpResources = new ArrayList<>();
ArrayList<Integer> fixedOpStart = new ArrayList<>();
ArrayList<Integer> fixedOpEnd = new ArrayList<>();
ArrayList<Integer> fixedOpIntensity = new ArrayList<>();
ArrayList<ArrayList<ArrayList<Boolean>>> is_fixed_op_planned_in_future = new ArrayList<>();
class OperationData implements Comparable<OperationData> {
private int opId, executorId;
private OptionalInt bunkerId;
OperationData(int opId, int executorId, OptionalInt bunkerId) {
this.opId = opId;
this.executorId = executorId;
this.bunkerId = bunkerId;
}
@Override
public int compareTo(@NotNull OperationData o) {
if (opId != o.opId) {
return Integer.compare(opId, o.opId);
}
if (executorId != o.executorId) {
return Integer.compare(executorId, o.executorId);
}
if (! bunkerId.isPresent()) {
return (! o.bunkerId.isPresent()) ? 0 : -1;
}
if (! o.bunkerId.isPresent()) {
return 1;
}
return Integer.compare(bunkerId.getAsInt(), o.bunkerId.getAsInt());
}
};
Map<OperationData, Integer> opNoByOpData = new TreeMap<>();
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate op = operationTemplates.get(i);
OptionalInt bunkerId = OptionalInt.empty();
if ((op instanceof LoadingTemplate) && (((LoadingTemplate)op).getBunker().isPresent())) {
bunkerId = OptionalInt.of(((LoadingTemplate)op).getBunker().get().getId());
}
opNoByOpData.put(new OperationData(op.getId(), getExecutor(op).getId(), bunkerId), i);
}
ArrayList<ArrayList<Boolean>> is_obj_involved_in_fixed_op = new ArrayList<>();
for (int i = 0; i <= movingObjects.size(); i++) {
is_obj_involved_in_fixed_op.add(new ArrayList<>());
for (int j = 0; j < n_intervals + 2; j++) {
is_obj_involved_in_fixed_op.get(i).add(false);
}
}
for (int i = 0; i < movingObjects.size(); i++) {
is_fixed_op_planned_in_future.add(new ArrayList<>());
for (int j = 0; j < locationNumberById.size(); j++) {
is_fixed_op_planned_in_future.get(i).add(new ArrayList<>());
for (int k = 0; k < n_intervals; k++) {
is_fixed_op_planned_in_future.get(i).get(j).add(false);
}
}
}
for (Operation op : task.getFixedOperations()) {
if (op.getFixation()) {
OptionalInt bunkerId = op.getBunker().map(b -> OptionalInt.of(b.getId())).orElse(OptionalInt.empty());
int opNo = opNoByOpData.get(new OperationData(op.getTemplate().getId(), op.getExecutor().getId(), bunkerId));
int start = (int)Math.floor(op.getStart());
int end = (int)Math.ceil(op.getDuration() + op.getStart());
{
ArrayList<Integer> involvedMovingObj = new ArrayList<>();
involvedMovingObj.add(mObjToN(op.getExecutor()));
if (op.getBunker().isPresent()) {
involvedMovingObj.add(mObjToN(op.getBunker().get()));
}
for (MovingObject obj : op.getResources()) {
involvedMovingObj.add(mObjToN(obj));
}
for (int t = start; t < end; t++) {
for (Integer obj : involvedMovingObj) {
is_obj_involved_in_fixed_op.get(obj + 1).set(t + 1, true);
}
}
}
int loc = getLocNById(op.getTemplate().getStartLocation().getId(), false);
int executor = mObjToN(op.getExecutor());
for (int i = 0; i < end; i++) {
is_fixed_op_planned_in_future.get(executor).get(loc).set(i, true);
}
fixedOp.add(opNo + 1);
TreeSet<Integer> resources = new TreeSet<>();
for (MovingObject obj : op.getResources()) {
resources.add(mObjToN(obj));
}
fixedOpResources.add(resources);
fixedOpStart.add(start + 1);
fixedOpEnd.add(end);
fixedOpIntensity.add((int)Math.ceil(op.getIntensity().orElse(0)));
}
}
writer.write("n_fixed_op = " + fixedOp.size() + ";\n");
writeArray(writer, "fixed_op", fixedOp);
writeArray(writer, "fixed_op_resources", fixedOpResources, MZnFormat::setToString);
writeArray(writer, "fixed_op_start", fixedOpStart);
writeArray(writer, "fixed_op_end", fixedOpEnd);
writeArray(writer, "fixed_op_intensity", fixedOpIntensity);
locWrite2DArray(writer, "is_fixed", getIsFixedArray(), Objects::toString, true);
locWrite2DArray(writer, "is_obj_involved_in_fixed_op", is_obj_involved_in_fixed_op, Objects::toString, true);
write3dArray(writer, "is_fixed_op_planned_in_future", is_fixed_op_planned_in_future, Objects::toString);
}
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 {
{ // objects_of_type и operations_that_used_obj_as_resource
writer.write("n_resources_types = " + typeToN.size() + ";\n");
writeArray(writer, "objects_of_type", objectsOfType, MZnFormat::setToString);
ArrayList<Set<Integer>> res = arrayOfIntegerSet(movingObjects.size());
for (int i = 0; i < operationTemplates.size(); i++) {
for (Integer typeNo : getNumbersOfResourcesTypes(operationTemplates.get(i))) {
for (int obj : objectsOfType.get(typeNo)) {
res.get(obj - 1).add(i + 1);
}
}
}
writeArray(writer, "operations_that_used_obj_as_resource", res, MZnFormat::setToString,
Optional.of(new TreeSet<>()));
writer.write("\n");
}
{ // counters, operations_resources_start_loc
ArrayList<Integer> counterType = new ArrayList<>();
ArrayList<Integer> operationOfCounter = new ArrayList<>();
ArrayList<Integer> requiredCounterValues = new ArrayList<>();
ArrayList<Set<Integer>> countersOfOperation = arrayOfIntegerSet(operationTemplates.size());
ArrayList<Integer> operationsResourcesStartLoc = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
Map<Integer, Integer> numberOfTypes = new TreeMap<>();
for (int type : getNumbersOfResourcesTypes(operationTemplates.get(i))) {
if (!numberOfTypes.containsKey(type)) {
numberOfTypes.put(type, 1);
} else {
numberOfTypes.put(type, numberOfTypes.get(type) + 1);
}
}
for (Map.Entry<Integer, Integer> p : numberOfTypes.entrySet()) {
counterType.add(p.getKey());
operationOfCounter.add(i);
requiredCounterValues.add(p.getValue());
countersOfOperation.get(i).add(counterType.size());
operationsResourcesStartLoc.add(locationNumberById.get(new Pair<>(operationTemplates.get(i).getStartLocation().getId(), false)));
}
}
writer.write("n_resources_counters = " + counterType.size() + ";\n");
writeArray(writer, "counter_type", counterType, (Integer val) -> val + 1);
writeArray(writer, "operation_of_counter", operationOfCounter, (Integer val) -> val + 1);
writeArray(writer, "required_counter_values", requiredCounterValues);
writeArray(writer, "operations_resources_start_loc", operationsResourcesStartLoc, (Integer val) -> val + 1);
writeArray(writer, "counters_of_operation", countersOfOperation, MZnFormat::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 dataForOptimization3() throws IOException {
ArrayList<ArrayList<Integer>> min_positive_cargo_val = arrayOfIntegerArrays(sectionNById.size());
ArrayList<ArrayList<Integer>> max_negative_cargo_val = arrayOfIntegerArrays(sectionNById.size());
ArrayList<ArrayList<Boolean>> can_obj_leave_loc_only_alone = new ArrayList<>();
for (int i = 0; i < sectionNById.size(); i++) {
for (int j = 0; j < locationNumberById.size(); j++) {
min_positive_cargo_val.get(i).add(maxStorageVol.get(i) + 1);
max_negative_cargo_val.get(i).add(-maxStorageVol.get(i) - 1);
}
}
for (int i = 0; i < movingObjects.size(); i++) {
can_obj_leave_loc_only_alone.add(new ArrayList<>());
for (int j = 0; j < locationNumberById.size(); j++) {
can_obj_leave_loc_only_alone.get(i).add((j + 1) % 2 == 1);
}
}
for (OperationTemplate t : operationTemplates) {
if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) t;
int val = (int) op.getIntensity();
int loc = getLocNById(op.getStartLocation().getId(), false) ;
ArrayList<Pair<Integer, Integer>> sections = new ArrayList<>();
sections.add(new Pair<>(sectionIdToN(op.getLoader(), op.getCargo()), val));
if (op.getBunker().isPresent()) {
sections.add(new Pair<>(sectionIdToN(op.getBunker().get(), op.getCargo()), -val));
} else {
sections.add(new Pair<>(sectionIdToN(op.getStorage(), op.getCargo()), -val));
}
for (Pair<Integer, Integer> p : sections) {
if (p.getValue() > 0) {
min_positive_cargo_val.get(p.getKey()).set(loc, Math.min(p.getValue(), min_positive_cargo_val.get(p.getKey()).get(loc)));
} else {
max_negative_cargo_val.get(p.getKey()).set(loc, Math.max(p.getValue(), max_negative_cargo_val.get(p.getKey()).get(loc)));
}
}
} else if (t instanceof MovingTemplate) {
int loc = getLocNById(t.getStartLocation().getId(), false);
int obj = mObjToN(getExecutor(t));
if (! ((MovingTemplate) t).getResourcesTypes().isEmpty()) {
can_obj_leave_loc_only_alone.get(obj).set(loc, false);
}
}
}
write2DArrayOfInt(writer, "min_positive_cargo_val", min_positive_cargo_val, false);
write2DArrayOfInt(writer, "max_negative_cargo_val", max_negative_cargo_val, false);
locWrite2DArray(writer, "can_obj_leave_loc_only_alone", can_obj_leave_loc_only_alone, Objects::toString);
writer.write("\n");
}
/* С типизацией. */
void portToMiniZinc_2() {
if (!task.isTypified()) {
throw new ParserException("Attempt to convert untyped task as typified.");
}
try {
writer.write("n_intervals = " + n_intervals + ";\n");
writer.write("n_operations = " + operationTemplates.size() + ";\n");
writer.write("n_locations = " + locationNumberById.size() + ";\n");
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
writer.write("\n");
movingObjectLocationDefinition(false);
initialLocations();
finalLocations();
defDataForCurMovingOp();
weatherWindowsNewFormat();
conflictingOperationsOnStorageAndOnTypeOnMainObject();
requiredLocationsOnOpStart();
operationsContinuity();
typifiedResourcesDefinition();
cargoOpUsingObj();
unmooringOpUsingObj();
addOpWithNominallyMooring();
writer.write("n_all_storage_sections = " + sectionNById.size() + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
maxStorageVolume();
boundaryStorageStates();
cargoFlows();
cargoOperations();
dataForOptimization3();
fixedOperations();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
void dataForGreediness() throws IOException {
ArrayList<ArrayList<Integer>> connectedSections = arrayOfIntegerArrays(sectionNById.size());
ArrayList<Set<Integer>> connectedSectionsSet = arrayOfIntegerSet(sectionNById.size());
for (OperationTemplate t : operationTemplates) {
if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) t;
int section1 = sectionIdToN(op.getLoader(), op.getCargo());
int section2;
if (op.getBunker().isPresent()) {
section2 = sectionIdToN(op.getBunker().get(), op.getCargo());
} else {
section2 = sectionIdToN(op.getStorage(), op.getCargo());
}
connectedSectionsSet.get(section2).add(section1);
}
}
ArrayList<ArrayList<Integer>> positionsOfConnectedSections = arrayOfIntegerArrays(sectionNById.size());
for (int i = 0; i < sectionNById.size(); i++) {
positionsOfConnectedSections.set(i, integerArray(sectionNById.size(), 0));
}
for (int i = 0; i < sectionNById.size(); i++) {
connectedSections.set(i, new ArrayList<>(connectedSectionsSet.get(i)));
for (int j = 0; j < connectedSections.get(i).size(); j++) {
positionsOfConnectedSections.get(connectedSections.get(i).get(j)).set(i, j);
}
}
ArrayList<Integer> operationsMainStorNoInSecondary = new ArrayList<>();
ArrayList<Integer> operationsSecondaryStorNoInMain = new ArrayList<>();
for (OperationTemplate t : operationTemplates) {
if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) t;
int section1 = sectionIdToN(op.getLoader(), op.getCargo());
int section2;
if (op.getBunker().isPresent()) {
section2 = sectionIdToN(op.getBunker().get(), op.getCargo());
} else {
section2 = sectionIdToN(op.getStorage(), op.getCargo());
}
operationsMainStorNoInSecondary.add(positionsOfConnectedSections.get(section1).get(section2));
operationsSecondaryStorNoInMain.add(positionsOfConnectedSections.get(section2).get(section1));
} else {
operationsMainStorNoInSecondary.add(-1);
operationsSecondaryStorNoInMain.add(-1);
}
}
int max_number_of_connected_sections = 0;
ArrayList<Integer> number_of_connected_sections = new ArrayList<>();
for (int i = 0; i < nSectionsOfRealStorageAndBunkers; i++) {
number_of_connected_sections.add(connectedSections.get(i).size());
max_number_of_connected_sections = Math.max(max_number_of_connected_sections, connectedSections.get(i).size());
}
writer.write("n_sections_of_real_storage_and_bunkers = " + nSectionsOfRealStorageAndBunkers + ";\n");
writer.write("max_number_of_connected_sections = " + max_number_of_connected_sections + ";\n");
writeArray(writer, "number_of_connected_sections", number_of_connected_sections, Optional.of(0));
writeArray(writer, "operations_main_stor_no_in_secondary", operationsMainStorNoInSecondary, (Integer i) -> i + 1, Optional.of(-1));
writeArray(writer, "operations_secondary_stor_no_in_main", operationsSecondaryStorNoInMain, (Integer i) -> i + 1, Optional.of(-1));
ArrayList<ArrayList<ArrayList<Integer>>> connected_op_to_pair_of_sections = new ArrayList<>();
for (int i = 0; i <= nSectionsOfRealStorageAndBunkers; i++) {
connected_op_to_pair_of_sections.add(new ArrayList<>());
for (int j = 0; j <= max_number_of_connected_sections; j++) {
connected_op_to_pair_of_sections.get(i).add(new ArrayList<>());
}
}
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
int section1 = sectionIdToN(op.getLoader(), op.getCargo());
int section2;
if (op.getBunker().isPresent()) {
section2 = sectionIdToN(op.getBunker().get(), op.getCargo());
} else {
section2 = sectionIdToN(op.getStorage(), op.getCargo());
}
connected_op_to_pair_of_sections.get(section2 + 1).get(operationsMainStorNoInSecondary.get(i) + 1).add(i + 1);
}
}
locWrite2DArray(writer, "connected_op_to_pair_of_sections", connected_op_to_pair_of_sections, MZnFormat::arrayToStringAsSet, true);
{
ArrayList<Integer> storage_greedy_upper_limit = new ArrayList<>(maxStorageVol);
ArrayList<Integer> storage_greedy_lower_limit = integerArray(sectionNById.size(), 0);
for (int i = 0; i < sectionNById.size(); i++) {
if (finalStorageVol.get(i) >= 0) {
if (finalStorageVol.get(i) <= initialStorageVol.get(i)) {
storage_greedy_lower_limit.set(i, finalStorageVol.get(i));
} else {
storage_greedy_upper_limit.set(i, Math.min(storage_greedy_upper_limit.get(i), finalStorageVol.get(i)));
}
}
}
writeArray(writer, "storage_greedy_upper_limit", storage_greedy_upper_limit, Optional.of(0));
writeArray(writer, "storage_greedy_lower_limit", storage_greedy_lower_limit, Optional.of(0));
}
{
ArrayList<ArrayList<Integer>> all_used_positions_in_real_cargo_value = arrayOfIntegerArrays(sectionNById.size());
for (int i = 0; i < sectionNById.size(); i++) {
for (int j = 0; j < connectedSections.get(i).size(); j++) {
all_used_positions_in_real_cargo_value.get(connectedSections.get(i).get(j)).add(i + 1);
}
}
locWrite2DArray(writer, "positions_of_connected_sections", positionsOfConnectedSections, (Integer i) -> Integer.toString(i + 1), false);
writeArray(writer, "all_used_positions_in_real_cargo_value", all_used_positions_in_real_cargo_value, MZnFormat::arrayToStringAsSet, Optional.of(new ArrayList<>()));
}
}
void portToMiniZinc_2_greedy() {
if (!task.isTypified()) {
throw new ParserException("Attempt to convert untyped task as typified.");
}
try {
portToMiniZinc_2();
dataForGreediness();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
static public void portToMiniZinc_0(TaskCase task, String fileName) {
startConversion(task, fileName, Task::portToMiniZinc_0);
}
static public void portToMiniZinc_1(TaskCase task, String fileName) {
startConversion(task, fileName, Task::portToMiniZinc_1);
}
static public void portToMiniZinc_2(TaskCase task, String fileName) {
startConversion(task, fileName, Task::portToMiniZinc_2);
}
static public void portToMiniZincGreedy(TaskCase task, String fileName) {
startConversion(task, fileName, Task::portToMiniZinc_2_greedy);
}
static private void startConversion(TaskCase task, String fileName, Consumer<Task> conversion) {
try {
Task taskData = new Task(task, fileName);
try {
taskData.writer = new FileWriter(fileName, false);
conversion.accept(taskData);
} finally {
if (taskData.writer != null) {
taskData.writer.close();
}
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
package inport.ConversionUtils;
import inport.*;
import javafx.util.Pair;
import java.util.*;
public class Utils {
static class PairComparator<T extends Comparable<T>, U extends Comparable<U>> implements Comparator<Pair<T, U>> {
public int compare(Pair<T, U> p1, Pair<T, U> p2) {
int res = p1.getKey().compareTo(p2.getKey());
if (res != 0) {
return res;
} else {
return p1.getValue().compareTo(p2.getValue());
}
}
}
static public ArrayList<Integer> integerArray(int size, int initVal) {
ArrayList<Integer> res = new ArrayList<>();
for (int i = 0; i < size; i++) {
res.add(initVal);
}
return res;
}
static public ArrayList<ArrayList<Integer>> arrayOfIntegerArrays(int size) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
for (int i = 0; i < size; i++) {
res.add(new ArrayList<>());
}
return res;
}
static public ArrayList<Set<Integer>> arrayOfIntegerSet(int size) {
ArrayList<Set<Integer>> res = new ArrayList<>();
for (int i = 0; i < size; i++) {
res.add(new TreeSet<>());
}
return res;
}
static public MovingObject getExecutor(OperationTemplate t) {
if (t instanceof LoadingTemplate) {
return ((LoadingTemplate) t).getLoader();
}
if (t instanceof MooringTemplate) {
return ((MooringTemplate) t).getMoorer();
}
if (t instanceof MovingTemplate) {
return ((MovingTemplate) t).getMover();
}
return null;
}
static public List<MovingObject> getResources(OperationTemplate t) {
List<MovingObject> res = new ArrayList<>();
if (t instanceof LoadingTemplate) {
res.addAll(((LoadingTemplate) t).getResources());
}
if (t instanceof MooringTemplate) {
res.addAll(((MooringTemplate) t).getResources());
}
if (t instanceof MovingTemplate) {
res.addAll(((MovingTemplate) t).getResources());
}
return res;
}
static public boolean isCompatible(OperationTemplate t1, OperationTemplate t2) {
MovingObject exec1 = getExecutor(t1);
Berth place1 = t1.getStartLocation();
List<MovingObject> resources1 = getResources(t1);
MovingObject exec2 = getExecutor(t2);
Berth place2 = t2.getStartLocation();
List<MovingObject> resources2 = getResources(t2);
// Пересекаемость ресурсов
for (Object res2 : resources2)
if (resources1.contains(res2))
return false;
// Выполнитель = ресурс
if (resources1.contains(exec2))
return false;
// Ресурс = выполнитель
if (resources2.contains(exec1))
return false;
// Выполнитель = выполнитель
if (exec1.equals(exec2))
{
// Это не погрузка
if (!(t1 instanceof LoadingTemplate) || (!(t2 instanceof LoadingTemplate)))
return false;
// Разные причалы
if (!place1.equals(place2))
return false;
Storage s1 = ((LoadingTemplate)t1).getStorage();
Storage s2 = ((LoadingTemplate)t2).getStorage();
// В одно хранилище
if (s1.equals(s2))
return false;
}
else
// На одном причале и это не перемещения
if (place1.equals(place2) && (!(t1 instanceof MovingTemplate)) && (!(t2 instanceof MovingTemplate)))
return false;
return true;
}
}
......@@ -8,7 +8,9 @@ import java.util.function.BiFunction;
import static inport.Testing.*;
import inport.ConversionUtil.*;
import inport.ConversionUtils.MZnResultsResolver;
import inport.ConversionUtils.ParserException;
import inport.ConversionUtils.Task;
public class Main {
......@@ -85,8 +87,8 @@ public class Main {
error = solveTask(
task,
constraintName,
ConversionUtil::portToMiniZinc_2,
ConversionUtil::resolveMiniZincResults,
Task::portToMiniZinc_2,
MZnResultsResolver::resolveMiniZincResults,
DEFAULT_TIME_LIMIT_S);
}
......@@ -106,7 +108,7 @@ public class Main {
TaskCase task = new TaskCase();
try {
task.deserialize(input);
ConversionUtil.portToMiniZinc_0(task, output);
Task.portToMiniZinc_0(task, output);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
......@@ -118,7 +120,7 @@ public class Main {
TaskCase task = new TaskCase();
try {
task.deserialize(input);
ConversionUtil.portToMiniZinc_1(task, output);
Task.portToMiniZinc_1(task, output);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
......@@ -133,7 +135,7 @@ public class Main {
TaskCase task = new TaskCase();
task.deserialize(input);
ConversionUtil.resolveMiniZincResults(task, fileWIthResult);
MZnResultsResolver.resolveMiniZincResults(task, fileWIthResult);
task.serialize(output);
} catch (IOException | ParserException ex) {
......@@ -153,6 +155,10 @@ public class Main {
debug(Testing::solveTaskWithGreedyConstraints, DEFAULT_TIME_LIMIT_S);
break;
}
case "debug greedy v2" : {
debug(Testing::solveTaskWithGreedyConstraintsV2, DEFAULT_TIME_LIMIT_S);
break;
}
case "debug read-write" : {
debugReadWrite();
break;
......
......@@ -4,6 +4,8 @@
*/
package inport;
import inport.ConversionUtils.Utils;
import java.util.*;
/**
......@@ -118,10 +120,10 @@ public class Operation {
@Override
public String toString() {
if (executor == null) {
executor = ConversionUtil.getExecutor(template);
executor = Utils.getExecutor(template);
}
if (resources == null) {
resources = ConversionUtil.getResources(template);
resources = Utils.getResources(template);
}
StringBuilder sb = new StringBuilder();
sb.append(template.getId()).append("; ");
......
package inport;
import inport.ConversionUtils.MZnResultsResolver;
import inport.ConversionUtils.ParserException;
import inport.ConversionUtils.Task;
import javafx.util.Pair;
import java.io.*;
......@@ -29,8 +32,8 @@ public class Testing {
return solveTask(
task,
"conversion_1.mzn",
ConversionUtil::portToMiniZinc_1,
ConversionUtil::resolveMiniZincResults,
Task::portToMiniZinc_1,
MZnResultsResolver::resolveMiniZincResults,
timeLimitS);
}
......@@ -38,8 +41,8 @@ public class Testing {
return solveTask(
task,
"conversion_2.mzn",
ConversionUtil::portToMiniZinc_2,
ConversionUtil::resolveMiniZincResults,
Task::portToMiniZinc_2,
MZnResultsResolver::resolveMiniZincResults,
timeLimitS);
}
......@@ -47,8 +50,8 @@ public class Testing {
return solveTask(
task,
"conversion_2_with_partial_cargo_operations.mzn",
ConversionUtil::portToMiniZinc_2,
ConversionUtil::resolveMiniZincResults,
Task::portToMiniZinc_2,
MZnResultsResolver::resolveMiniZincResults,
timeLimitS);
}
......@@ -56,8 +59,17 @@ public class Testing {
return solveTask(
task,
"conversion_2_greedy.mzn",
ConversionUtil::portToMiniZincGreedy,
ConversionUtil::resolveMiniZincResults,
Task::portToMiniZincGreedy,
MZnResultsResolver::resolveMiniZincResults,
timeLimitS);
}
public static String solveTaskWithGreedyConstraintsV2(TaskCase task, int timeLimitS) {
return solveTask(
task,
"conversion_2_greedy_v2.mzn",
Task::portToMiniZincGreedy,
MZnResultsResolver::resolveMiniZincResults,
timeLimitS);
}
......@@ -65,8 +77,8 @@ public class Testing {
return solveTask(
task,
"conversion_2.0.mzn",
ConversionUtil::portToMiniZinc_2,
ConversionUtil::resolveMiniZincResults,
Task::portToMiniZinc_2,
MZnResultsResolver::resolveMiniZincResults,
"temp_data_2",
timeLimitS);
}
......
......@@ -223,10 +223,10 @@ Initial Vessel State
38; 6
/* Бункеровщики.
11; 4
12; 4
13; 5
14; 5
11; 1
12; 1
13; 2
14; 2
/* Буксиры.
21; 3
......@@ -292,7 +292,7 @@ Final Storage State
10002; 38; 4500
Task Properties
20.0; 0
16.0; 0
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