Commit c5d0db0a authored by Vladislav Kiselev's avatar Vladislav Kiselev

Хранилища - общие условия

parent e50ce3df
......@@ -19,12 +19,41 @@ public class ConversionUtil {
}
}
static private void write2DArray(FileWriter writer,
static private void write2DArrayOfInt(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations) throws IOException {
locWrite2DArray(writer, name, operations, Object::toString);
}
static private 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 + 1));
}
s.append('}');
return s.toString();
}
);
}
static private <T> void locWrite2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<ArrayList<Integer>>> operations) throws IOException {
ArrayList<ArrayList<T>> operations,
Function<T, String> toMZNFormat) throws IOException {
writer.write(name + " = \n");
boolean isFirst0 = true;
for (ArrayList<ArrayList<Integer>> m1 : operations) {
for (ArrayList<T> a : operations) {
if (isFirst0) {
isFirst0 = false;
writer.write(" [| ");
......@@ -32,23 +61,13 @@ public class ConversionUtil {
writer.write(" | ");
}
boolean isFirst1 = true;
for (ArrayList<Integer> m2 : m1) {
for (T val : a) {
if (isFirst1) {
isFirst1 = false;
} else {
writer.write(", ");
}
writer.write("{");
boolean isFirst2 = true;
for (Integer val : m2) {
if (isFirst2) {
isFirst2 = false;
} else {
writer.write(", ");
}
writer.write((val + 1) + "");
}
writer.write("}");
writer.write(toMZNFormat.apply(val));
}
writer.write("\n");
}
......@@ -237,8 +256,8 @@ public class ConversionUtil {
}
}
}
write2DArray(writer, "arrival_op", arrivalOp);
write2DArray(writer, "departure_op", departureOp);
write2DArrayOfSet(writer, "arrival_op", arrivalOp);
write2DArrayOfSet(writer, "departure_op", departureOp);
}
{ // Начальные положения объектов.
ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
......@@ -258,8 +277,8 @@ public class ConversionUtil {
operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> {
bw_op.add(id + 1);
bw_start.add((int)Math.ceil(start));
bw_fin.add((int)Math.floor(start + duration));
bw_start.add((int)Math.floor(start));
bw_fin.add((int)Math.ceil(start + duration));
}
);
}
......@@ -331,6 +350,81 @@ public class ConversionUtil {
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");
}
// Грузоообработка.
ArrayList<Storage> storages = new ArrayList<>(task.getStorages());
ArrayList<Cargo> cargoes = new ArrayList<>(task.getCargoes());
Map<Integer, Integer> storNById = new TreeMap<>();
for (int i = 0; i < storages.size(); i++) {
storNById.put(storages.get(i).getId(), i);
}
Map<Integer, Integer> cargoNById = new TreeMap<>();
for (int i = 0; i < task.getCargoes().size(); i++) {
cargoNById.put(cargoes.get(i).getId(), i);
}
int nObjWithStorage = movingObjects.size() + storages.size();
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
{ // Ограничения на вместимость.
ArrayList<Integer> maxStorageVol = new ArrayList<>();
for (MovingObject obj : movingObjects) {
if (obj instanceof TransportShip) {
maxStorageVol.add((int)Math.ceil(((TransportShip) obj).getCargoMax()));
} else {
maxStorageVol.add(0);
}
}
for (Storage storage : storages) {
maxStorageVol.add((int)Math.ceil(storage.getVolume()));
}
writeArray(writer, "max_storage_vol", maxStorageVol);
writer.write("\n");
}
{ // Граничные условия хранилищ.
// TODO выделить отдельно общий код.
ArrayList<ArrayList<Integer>> initialStorageVol = new ArrayList<>();
ArrayList<ArrayList<Integer>> finalStorageVol = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) {
initialStorageVol.add(integerArray(cargoes.size(), 0));
finalStorageVol .add(integerArray(cargoes.size(), -1));
}
for (StorageState st : task.getStorageInitialState()) {
int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId());
initialStorageVol.get(movingObjects.size() + stN).set(cargoN, val);
} else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage();
initialStorageVol.get(mObjToN.apply(ship)).set(cargoN, val);
}
}
for (StorageState st : task.getStorageEndState()) {
int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId());
finalStorageVol.get(movingObjects.size() + stN).set(cargoN, val);
} else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage();
finalStorageVol.get(mObjToN.apply(ship)).set(cargoN, val);
}
}
write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol);
write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol);
}
}
}
......
......@@ -118,6 +118,32 @@ constraint forall (i in 1..n_bad_weather_windows) (
forall (t in bw_start[i]..bw_fin[i]) (op_status[bw_op[i], t] == 0)
);
% Грузоообработка.
int : n_cargo_types;
int : n_obj_with_storage;
array [1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types] of var int : storage_used_volume; % Первые n_moving_obj соответствуют наполненности соответствующих движущихся объектов.
% Ограничения на вместимость.
array [1..n_obj_with_storage] of int : max_storage_vol;
constraint forall (storage in 1..n_obj_with_storage, t in 0..(n_intervals + 1)) (
(sum (cargo in 1..n_cargo_types) (storage_used_volume[storage, t, cargo]) <= max_storage_vol[storage])
/\
(forall (cargo in 1..n_cargo_types) (0 <= storage_used_volume[storage, t, cargo]))
);
% Ограничения на граничные значения.
array [1..n_obj_with_storage, 1..n_cargo_types] of int : initial_storage_vol;
array [1..n_obj_with_storage, 1..n_cargo_types] of int : final_storage_vol;
constraint forall (storage in 1..n_obj_with_storage, cargo in 1..n_cargo_types) (
(storage_used_volume[storage, 0, cargo] == initial_storage_vol[storage, cargo])
/\
if final_storage_vol[storage, cargo] >= 0 then
(storage_used_volume[storage, (n_intervals + 1), cargo] == final_storage_vol[storage, cargo])
else true
endif
);
% Критерий оптимизации
array [0..(n_intervals + 1)] of var bool : is_not_terminated;
constraint (is_not_terminated[0] == 0 /\ is_not_terminated[n_intervals + 1] == 0);
......
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