Commit 2f3980f4 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Баги

parent 93ff4528
...@@ -221,7 +221,6 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац ...@@ -221,7 +221,6 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
% Определение 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 related_cargo_op[obj]) (op_status[op, t])) (exists (op in related_cargo_op[obj]) (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]]))
...@@ -347,6 +346,206 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац ...@@ -347,6 +346,206 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
array [1..n_all_storage_sections] of set of 1..n_loading_op : involved_operations; array [1..n_all_storage_sections] of set of 1..n_loading_op : involved_operations;
array [0..n_all_storage_sections] of int : storage_greedy_upper_limit;
array [0..n_all_storage_sections] of int : storage_greedy_lower_limit;
0..n_all_storage_sections : n_sections_of_real_storage_and_bunkers;
array [0..n_sections_of_real_storage_and_bunkers] of 0..n_all_storage_sections : number_of_connected_sections;
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;
% Определение 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;
array [0..n_sections_of_real_storage_and_bunkers, 0..max_number_of_connected_sections] of set of 1..n_operations : connected_op_to_pair_of_sections;
array [0..n_sections_of_real_storage_and_bunkers, 0..max_number_of_connected_sections, 1..(n_intervals + 1)] of var int : debug_1;
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1) where operations_main_stor_no_in_secondary[op] != 0) (
op_status[op, t] -> (
debug_1[operations_secondary_stor[op], operations_main_stor_no_in_secondary[op], t] =
min(storage_greedy_upper_limit[operations_main_stor[op]] - storage_used_volume[operations_main_stor[op], t - 1],
loading_op_delta_of_main_obj[op])
)
);
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]))
->
(debug_1[section_1, section_2, t] = 0)
);
% Определение nominal_cargo_value
% Операция грузообработки активна -> нужные номинальные значения согласованы с ней.
constraint forall (op in 1..n_operations, t in 1..(n_intervals + 1) where operations_main_stor_no_in_secondary[op] != 0) (
op_status[op, t] -> (
nominal_cargo_value[operations_secondary_stor[op], operations_main_stor_no_in_secondary[op], t] =
-max(
min(storage_greedy_upper_limit[operations_main_stor[op]] - storage_used_volume[operations_main_stor[op], t - 1],
loading_op_delta_of_main_obj[op]),
storage_greedy_lower_limit[operations_main_stor[op]] - storage_used_volume[operations_main_stor[op], t - 1])
)
);
% Если нет активной операции, влияющей на эту пару секций, то 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)
);
% Крайние значения.
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
);
% Определение cargo_overflow_remains.
% Переполнение.
constraint forall (t in 1..(n_intervals + 1), section in 1..n_sections_of_real_storage_and_bunkers) (
let {var int : delta = sum (i in 1..number_of_connected_sections[section]) (nominal_cargo_value[section, i, t]);
var int : real_delta = min(max(delta,
storage_greedy_lower_limit[section] - storage_used_volume[section, t - 1]),
storage_greedy_upper_limit[section] - storage_used_volume[section, t - 1]);
} in (
cargo_overflow_remains[section, number_of_connected_sections[section] + 1, t] = (delta - real_delta)
)
);
% Избавляемся от лишнего.
% Если остаток переполнения и номналное значение одного знака, то полностью отменяем это номинальное значение.
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 (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 (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
);
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] +
cargo_flows[storage, t] +
(sum (i in 1..number_of_connected_sections[storage]) (real_cargo_value[storage, i, t])) +
(sum (i in all_used_positions_in_real_cargo_value[storage]) (-real_cargo_value[i, positions_of_connected_sections[storage, i], t]))
)
);
constraint forall (storage in (n_sections_of_real_storage_and_bunkers + 1)..n_all_storage_sections, t in 1..(n_intervals + 1)) (
storage_used_volume[storage, t] = (
storage_used_volume[storage, t - 1] +
cargo_flows[storage, t] +
(sum (i in all_used_positions_in_real_cargo_value[storage]) (-real_cargo_value[i, positions_of_connected_sections[storage, i], t]))
)
);
/*
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] +
cargo_flows[storage, t] +
(sum (i in 1..number_of_connected_sections[storage]) (real_cargo_value[storage, i, t])) +
(sum (i in all_used_positions_in_real_cargo_value[storage]) (-real_cargo_value[i, positions_of_connected_sections[storage, i], t]))
)
);
constraint forall (storage in (n_sections_of_real_storage_and_bunkers + 1)..n_all_storage_sections, t in 1..(n_intervals + 1)) (
debug_storage_used_volume[storage, t] = (
debug_storage_used_volume[storage, t - 1] +
cargo_flows[storage, t] +
(sum (i in all_used_positions_in_real_cargo_value[storage]) (-real_cargo_value[i, positions_of_connected_sections[storage, i], t]))
)
);
*/
array [0..n_all_storage_sections, 0..(n_intervals + 1)] of var int : debug_storage_used_volume;
constraint forall (t in 0..(n_intervals + 1)) (debug_storage_used_volume[0, t] = 0); % Фиктивный объект.
constraint forall (storage in 1..n_all_storage_sections) ( % Initial values.
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)) ( 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] = (
storage_used_volume[storage, t - 1] + storage_used_volume[storage, t - 1] +
...@@ -357,7 +556,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац ...@@ -357,7 +556,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
) )
) )
); );
*/
% Фиксированные операции. % Фиксированные операции.
int : n_fixed_op; int : n_fixed_op;
array [1..n_fixed_op] of 1..n_operations : fixed_op; array [1..n_fixed_op] of 1..n_operations : fixed_op;
...@@ -376,7 +575,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац ...@@ -376,7 +575,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
) )
) )
); );
/*
% Оптимизация - сдвиг в начало. % Оптимизация - сдвиг в начало.
% Возможно ли начать операцию в данный интервал (если предположить, что операция длится 1 интервал). % Возможно ли начать операцию в данный интервал (если предположить, что операция длится 1 интервал).
array [0..n_operations, 1..n_intervals] of var bool : is_op_possible; array [0..n_operations, 1..n_intervals] of var bool : is_op_possible;
...@@ -454,7 +653,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац ...@@ -454,7 +653,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
constraint forall (op in 1..n_operations, t in 2..n_intervals) ( constraint forall (op in 1..n_operations, t in 2..n_intervals) (
(op_start[op, t] /\ (not is_fixed[op, t])) -> not is_op_possible[op, t - 1] (op_start[op, t] /\ (not is_fixed[op, t])) -> not is_op_possible[op, t - 1]
); );
*/
% Критерий оптимизации % Критерий оптимизации
array [1..(n_intervals + 1)] of var bool : is_not_terminated; array [1..(n_intervals + 1)] of var bool : is_not_terminated;
% В конце всё остановится. % В конце всё остановится.
...@@ -487,6 +686,15 @@ output [show(sum(is_not_terminated)), "\n", ...@@ -487,6 +686,15 @@ output [show(sum(is_not_terminated)), "\n",
"current_moored_obj = ", show(current_moored_obj), "\n\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",
"debug_storage_used_volume = ", show(debug_storage_used_volume), "\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",
......
...@@ -416,6 +416,19 @@ public class ConversionUtil { ...@@ -416,6 +416,19 @@ public class ConversionUtil {
} }
private final Map<StorageSectionId, Integer> sectionNById; 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> storageNById;
private final Map<Integer, Integer> cargoNById; private final Map<Integer, Integer> cargoNById;
...@@ -432,6 +445,12 @@ public class ConversionUtil { ...@@ -432,6 +445,12 @@ public class ConversionUtil {
return movingObjects; return movingObjects;
} }
private final int nSectionsOfRealStorageAndBunkers;
private final ArrayList<Integer> initialStorageVol;
private final ArrayList<Integer> finalStorageVol;
private final ArrayList<Integer> maxStorageVol;
Task(TaskCase task, String fileName) { Task(TaskCase task, String fileName) {
this.fileName = fileName; this.fileName = fileName;
this.task = task; this.task = task;
...@@ -471,22 +490,28 @@ public class ConversionUtil { ...@@ -471,22 +490,28 @@ public class ConversionUtil {
storageNById = new TreeMap<>(); storageNById = new TreeMap<>();
sectionNById = new TreeMap<>(); sectionNById = new TreeMap<>();
for (int i = 0; i < storages.size(); i++) { for (int i = 0; i < storages.size(); i++) { // Сначала реальные хранилища.
storageNById.put(storages.get(i).getId(), 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) { for (MovingObject obj : movingObjects) { // Затем бункеровщики.
if (obj instanceof TransportShip) { if (obj instanceof Bunker) {
for (Pair<Cargo, Double> p : ((TransportShip) obj).getStorageSections()) { for (Pair<Cargo, Double> p : ((TransportShip) obj).getStorageSections()) {
sectionNById.put(new StorageSectionId(false, mObjToN(obj), cargoNById.get(p.getKey().getId())), nextStorageNo++); sectionNById.put(new StorageSectionId(false, mObjToN(obj), cargoNById.get(p.getKey().getId())), nextStorageNo++);
} }
} }
} }
for (int i = 0; i < storages.size(); i++) { nSectionsOfRealStorageAndBunkers = sectionNById.size();
storageNById.put(storages.get(i).getId(), i);
for (Pair<Cargo, Double> p : storages.get(i).getStorageSections()) { for (MovingObject obj : movingObjects) { // Дальше - все остальные.
sectionNById.put(new StorageSectionId(true, i, cargoNById.get(p.getKey().getId())), nextStorageNo++); 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++);
}
} }
} }
...@@ -524,6 +549,48 @@ public class ConversionUtil { ...@@ -524,6 +549,48 @@ public class ConversionUtil {
initMovingObjectLocationDefinition(); 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) { private ArrayList<Integer> getNumbersOfResourcesTypes(OperationTemplate t) {
...@@ -736,26 +803,6 @@ public class ConversionUtil { ...@@ -736,26 +803,6 @@ public class ConversionUtil {
/* Ограничения на вместимость. */ /* Ограничения на вместимость. */
private void maxStorageVolume() throws IOException { private void maxStorageVolume() throws IOException {
ArrayList<Integer> maxStorageVol = integerArray(sectionNById.size(), 0);
for (MovingObject obj : movingObjects) {
if (obj instanceof TransportShip) {
for (Pair<Cargo, Double> p : ((TransportShip) obj).getStorageSections()) {
maxStorageVol.set(sectionNById.get(new StorageSectionId(false,
mObjToN(obj),
cargoNById.get(p.getKey().getId()))),
(int)Math.ceil(p.getValue()));
}
}
}
for (Storage storage : storages) {
for (Pair<Cargo, Double> p : storage.getStorageSections()) {
maxStorageVol.set(sectionNById.get(new StorageSectionId(true,
storageNById.get(storage.getId()),
cargoNById.get(p.getKey().getId()))),
(int)Math.ceil(p.getValue()));
}
}
writeArray(writer, "max_storage_vol", maxStorageVol, Optional.of(0)); writeArray(writer, "max_storage_vol", maxStorageVol, Optional.of(0));
writer.write("\n"); writer.write("\n");
...@@ -763,38 +810,6 @@ public class ConversionUtil { ...@@ -763,38 +810,6 @@ public class ConversionUtil {
/* Граничные состояния хранилищ. */ /* Граничные состояния хранилищ. */
private void boundaryStorageStates() throws IOException { private void boundaryStorageStates() throws IOException {
// TODO выделить отдельно общий код.
ArrayList<Integer> initialStorageVol = integerArray(sectionNById.size(), 0);
ArrayList<Integer> finalStorageVol = integerArray(sectionNById.size(), -1);
BiConsumer<ArrayList<Integer>, StorageState> f = (ArrayList<Integer> a, StorageState st) -> {
int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
boolean isRealStorage;
int localN;
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage();
isRealStorage = true;
localN = storageNById.get(storage.getId());
} else {
assert st.getStorage() instanceof TransportShip;
isRealStorage = false;
TransportShip ship = (TransportShip) st.getStorage();
localN = mObjToN(ship);
}
int sectionN = sectionNById.get(new StorageSectionId(isRealStorage, localN, cargoN));
a.set(sectionN, val);
};
for (StorageState st : task.getStorageInitialState()) {
f.accept(initialStorageVol, st);
}
for (StorageState st : task.getStorageEndState()) {
f.accept(finalStorageVol, st);
}
writeArray(writer, "initial_storage_vol", initialStorageVol, Optional.of(0)); writeArray(writer, "initial_storage_vol", initialStorageVol, Optional.of(0));
writeArray(writer, "final_storage_vol", finalStorageVol, Optional.of(-1)); writeArray(writer, "final_storage_vol", finalStorageVol, Optional.of(-1));
} }
...@@ -806,9 +821,7 @@ public class ConversionUtil { ...@@ -806,9 +821,7 @@ public class ConversionUtil {
cargoFlows.add(integerArray(n_intervals + 2, 0)); cargoFlows.add(integerArray(n_intervals + 2, 0));
} }
for (CargoFlow flow : task.getCargoFlows()) { for (CargoFlow flow : task.getCargoFlows()) {
int storageN = sectionNById.get(new StorageSectionId(true, int storageN = sectionIdToN(flow.getStorage(), flow.getCargo());
storageNById.get(flow.getStorage().getId()),
cargoNById.get(flow.getCargo().getId())));
for (int i = 1; i < n_intervals + 2; i++) { for (int i = 1; i < n_intervals + 2; i++) {
cargoFlows.get(storageN + 1).set(i, (int)flow.getCurrentValue(i - 0.1)); cargoFlows.get(storageN + 1).set(i, (int)flow.getCurrentValue(i - 0.1));
} }
...@@ -847,12 +860,12 @@ public class ConversionUtil { ...@@ -847,12 +860,12 @@ public class ConversionUtil {
int storageN; int storageN;
if (op.getBunker().isPresent()) { if (op.getBunker().isPresent()) {
storageN = sectionNById.get(new StorageSectionId(false, mObjToN(op.getBunker().get()), cargoN)); storageN = sectionIdToN(op.getBunker().get(), op.getCargo());
} else { } else {
storageN = sectionNById.get(new StorageSectionId(true, storageNById.get(op.getStorage().getId()), cargoN)); storageN = sectionIdToN(op.getStorage(), op.getCargo());
} }
int shipStorageN = sectionNById.get(new StorageSectionId(false, shipN, cargoN)); int shipStorageN = sectionIdToN(op.getLoader(), op.getCargo());
loadingOpDelta.add(-(int)op.getIntensity()); loadingOpDelta.add(-(int)op.getIntensity());
loading_op_local_direction.add(-(int)op.getIntensity() > 0 ? 1 : -1); loading_op_local_direction.add(-(int)op.getIntensity() > 0 ? 1 : -1);
...@@ -868,7 +881,7 @@ public class ConversionUtil { ...@@ -868,7 +881,7 @@ public class ConversionUtil {
loading_op_abs_delta.add(Math.abs((int)op.getIntensity())); loading_op_abs_delta.add(Math.abs((int)op.getIntensity()));
loading_op_direction.add((int)op.getIntensity() > 0 ? 1 : -1); loading_op_direction.add((int)op.getIntensity() > 0 ? 1 : -1);
operations_main_stor.add(shipN + 1); operations_main_stor.add(shipStorageN + 1);
operations_secondary_stor.add(storageN + 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); bunker_of_cargo_op.add(op.getBunker().isPresent() ? mObjToN(op.getBunker().get()) + 1 : 0);
...@@ -1536,6 +1549,183 @@ public class ConversionUtil { ...@@ -1536,6 +1549,183 @@ public class ConversionUtil {
} }
} }
} }
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);
}
}
// System.out.print("#######\n");
// for (int i = 0; i < sectionNById.size(); i++) {
// for (Integer val : positionsOfConnectedSections.get(i)) {
// System.out.print(val + " ");
// }
// System.out.print("\n");
// }
// System.out.print("---\n");
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, ConversionUtil::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, ConversionUtil::arrayToStringAsSet, Optional.of(new ArrayList<>()));
}
}
void portToMiniZinc_2_greedy() throws IOException {
if (!task.isTypified()) {
throw new ParserException("Attempt to convert untyped task as typified.");
}
try {
writer = new FileWriter(fileName, false);
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();
addOpWithNominallyMooring();
writer.write("n_all_storage_sections = " + sectionNById.size() + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
maxStorageVolume();
boundaryStorageStates();
cargoFlows();
cargoOperations();
fixedOperations();
dataForGreediness();
} finally {
if (writer != null) {
writer.close();
}
}
}
} }
static public void portToMiniZinc_0(TaskCase task, String fileName) throws IOException { static public void portToMiniZinc_0(TaskCase task, String fileName) throws IOException {
...@@ -1561,6 +1751,15 @@ public class ConversionUtil { ...@@ -1561,6 +1751,15 @@ public class ConversionUtil {
} }
} }
static public void portToMiniZincGreedy(TaskCase task, String fileName) {
try {
Task taskData = new Task(task, fileName);
taskData.portToMiniZinc_2_greedy();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public static void resolveMiniZincResults(TaskCase taskCase, String fileName) { public static void resolveMiniZincResults(TaskCase taskCase, String fileName) {
ArrayList<Operation> operations = null; ArrayList<Operation> operations = null;
Integer result = null; Integer result = null;
...@@ -1609,7 +1808,10 @@ public class ConversionUtil { ...@@ -1609,7 +1808,10 @@ public class ConversionUtil {
while (line.charAt(nextPos) != '}') { while (line.charAt(nextPos) != '}') {
nextPos++; nextPos++;
} }
arrayFirstDim = Integer.valueOf(line.substring(pos, nextPos).trim()); String []dimensions = line.substring(pos, nextPos).trim().split(" ");
if (dimensions.length > 0) {
arrayFirstDim = Integer.valueOf(dimensions[0].trim());
}
pos = nextPos + 1; pos = nextPos + 1;
while (line.charAt(pos) != '[') { while (line.charAt(pos) != '[') {
pos++; pos++;
......
...@@ -149,6 +149,10 @@ public class Main { ...@@ -149,6 +149,10 @@ public class Main {
debug(Testing::solveTaskWithPartialCargoOp, DEFAULT_TIME_LIMIT_S); debug(Testing::solveTaskWithPartialCargoOp, DEFAULT_TIME_LIMIT_S);
break; break;
} }
case "debug greedy" : {
debug(Testing::solveTaskWithGreedyConstraints, DEFAULT_TIME_LIMIT_S);
break;
}
case "debug read-write" : { case "debug read-write" : {
debugReadWrite(); debugReadWrite();
break; break;
...@@ -289,6 +293,7 @@ public class Main { ...@@ -289,6 +293,7 @@ public class Main {
} }
int arrayFirstDim = ((int) task.getPlanningInterval()) + 2; int arrayFirstDim = ((int) task.getPlanningInterval()) + 2;
int arraySecondDim = 0;
if (line.charAt(pos) == '{') { if (line.charAt(pos) == '{') {
pos++; pos++;
...@@ -296,7 +301,14 @@ public class Main { ...@@ -296,7 +301,14 @@ public class Main {
while (line.charAt(nextPos) != '}') { while (line.charAt(nextPos) != '}') {
nextPos++; nextPos++;
} }
arrayFirstDim = Integer.valueOf(line.substring(pos, nextPos).trim()); String []dimensions = line.substring(pos, nextPos).trim().split(" ");
if (dimensions.length > 0) {
arrayFirstDim = Integer.valueOf(dimensions[0].trim());
}
if (dimensions.length > 1) {
arraySecondDim = Integer.valueOf(dimensions[1].trim());
}
pos = nextPos + 1; pos = nextPos + 1;
while (line.charAt(pos) != '[') { while (line.charAt(pos) != '[') {
pos++; pos++;
...@@ -330,7 +342,7 @@ public class Main { ...@@ -330,7 +342,7 @@ public class Main {
maxLength = Math.max(maxLength, val.length()); maxLength = Math.max(maxLength, val.length());
} }
if ((arrayFirstDim != 0) && (elements.size() % arrayFirstDim == 0)) { if ((arrayFirstDim != 0) && (elements.size() % arrayFirstDim == 0) && ((arraySecondDim == 0) || (elements.size() % (arrayFirstDim * arraySecondDim) != 0))) {
writer.write(name + " :\n"); writer.write(name + " :\n");
for (int i = 0; i < elements.size(); i += arrayFirstDim) { for (int i = 0; i < elements.size(); i += arrayFirstDim) {
writer.write(" "); writer.write(" ");
...@@ -344,6 +356,23 @@ public class Main { ...@@ -344,6 +356,23 @@ public class Main {
writer.write("\n"); writer.write("\n");
} }
writer.write("\n"); writer.write("\n");
} else if ((arrayFirstDim != 0) && (arraySecondDim != 0) && (elements.size() % (arrayFirstDim * arraySecondDim) == 0)) {
writer.write(name + " :\n");
for (int i = 0; i < elements.size(); i += arrayFirstDim * arraySecondDim) {
for (int j = 0; j < arrayFirstDim; j++) {
writer.write(" ");
for (int k = 0; k < arraySecondDim; k++) {
String val = elements.get(i + j * arraySecondDim + k);
for (int l = val.length(); l < maxLength; l++) {
writer.write(" ");
}
writer.write(val + " ");
}
writer.write("\n");
}
writer.write("\n");
}
writer.write("\n");
} }
} }
......
...@@ -52,6 +52,15 @@ public class Testing { ...@@ -52,6 +52,15 @@ public class Testing {
timeLimitS); timeLimitS);
} }
public static String solveTaskWithGreedyConstraints(TaskCase task, int timeLimitS) {
return solveTask(
task,
"conversion_2_greedy.mzn",
ConversionUtil::portToMiniZincGreedy,
ConversionUtil::resolveMiniZincResults,
timeLimitS);
}
public static String solveTask_2_0(TaskCase task, int timeLimitS) { public static String solveTask_2_0(TaskCase task, int timeLimitS) {
return solveTask( return solveTask(
task, task,
......
...@@ -292,7 +292,7 @@ Final Storage State ...@@ -292,7 +292,7 @@ Final Storage State
10002; 38; 4500 10002; 38; 4500
Task Properties Task Properties
100.0; 0 20.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