Commit 3c72d73d authored by Vladislav Kiselev's avatar Vladislav Kiselev

Полезная операция между движениями.

parent 1710470c
......@@ -112,6 +112,8 @@ constraint forall (storage in 1..n_obj_with_storage, cargo in 1..n_cargo_types)
/\
(if final_storage_vol[storage, cargo] >= 0 then
(storage_used_volume[storage, (n_intervals + 1), cargo] == final_storage_vol[storage, cargo])
else
true
endif)
);
......@@ -145,6 +147,78 @@ constraint forall (t in 1..n_intervals) (
)
);
% Ограничение на совершение полезной операции при движении назад (окончание отшвартовки - "полезная операция").
array [1..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_locations : next_m_obj_loc; % Позиция движущегося объекта на ближайшей остановке.
constraint forall (obj in 1..n_moving_obj) (next_m_obj_loc[obj, n_intervals + 1] = m_obj_loc[obj, n_intervals + 1]);
constraint forall (obj in 1..n_moving_obj, t in 0..n_intervals) (
next_m_obj_loc[obj, t] =
if (m_obj_loc[obj, t] = 0) then
next_m_obj_loc[obj, t + 1]
else
m_obj_loc[obj, t]
endif
);
array [1..n_moving_obj, 0..(n_intervals + 1)] of var 0..n_locations : prev_m_obj_loc; % Строго предыдущая позиция объекта.
constraint forall (obj in 1..n_moving_obj) (prev_m_obj_loc[obj, 0] = 0);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
prev_m_obj_loc[obj, t] =
if ((m_obj_loc[obj, t - 1] != 0) /\ (m_obj_loc[obj, t] != m_obj_loc[obj, t - 1])) then
m_obj_loc[obj, t - 1]
else
prev_m_obj_loc[obj, t - 1]
endif
);
int : n_useful_op;
array [1..n_useful_op] of 1..n_moving_obj : useful_op_obj;
array [1..n_useful_op] of 1..n_operations : useful_op_id;
array [1..n_moving_obj] of set of 1..n_operations : obj_useful_operations; % Все полезные операции касающиеся данного объекта.
array [1..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_m_obj_useful; % Был ли объект задействован в "полезной" операции (не движении в качестве главного объекта).
constraint forall (i in 1..n_useful_op, t in 0..(n_intervals + 1)) (
op_status[useful_op_id[i], t] -> is_m_obj_useful[useful_op_obj[i], t]
);
constraint forall (obj in 1..n_moving_obj, t in 0..(n_intervals + 1)) ( % Недопущение "ложного срабатывания" is_m_obj_useful.
is_m_obj_useful[obj, t] -> exists (useful_op in obj_useful_operations[obj]) (
op_status[useful_op, t] == true
)
);
array [1..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_in_moving;
array [1..n_moving_obj] of set of 1..n_operations : moving_op_of_obj; % Операции перемещения затрагивающие данный объект.
constraint forall (obj in 1..n_moving_obj, t in 0..(n_intervals + 1)) (
is_obj_in_moving[obj, t] = exists (moving_op in moving_op_of_obj[obj]) (op_status[moving_op, t] = true)
);
array [1..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_interval_useful; % Была ли на текущем интервале полезная операция.
% Ось времени нарежим по моментам начал свершившихся операций перемещения соответствующего движущегося объекта. Речь идёт о интервале который включает в себя данный атомарный промежуток времени.
% !!! Важен только самый правый элемент интервала!!! (Значения на времени покрывающимся операцией движения могут быть 0 если они не с правого края интервала.)
% И в фиктивном нуле false.
constraint forall (obj in 1..n_moving_obj) (is_interval_useful[obj, 0] = false);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
is_interval_useful[obj, t] =
if (is_obj_in_moving[obj, t]) then
is_m_obj_useful[obj, t]
else
is_m_obj_useful[obj, t] \/ is_interval_useful[obj, t - 1]
endif
);
constraint forall (obj in 1..n_moving_obj, t in 0..n_intervals) ( % Само ограничение.
if ((m_obj_loc[obj, t] != 0) /\ (next_m_obj_loc[obj, t + 1] != 0) /\ (m_obj_loc[obj, t + 1] == 0)) then
if (next_m_obj_loc[obj, t + 1] == prev_m_obj_loc[obj, t]) then
is_interval_useful[obj, t] == true
endif
endif
);
solve minimize sum(is_not_terminated);
output [show(sum(is_not_terminated)), "\n",
......@@ -155,5 +229,8 @@ output [show(sum(is_not_terminated)), "\n",
"arrival_op = ", show(arrival_op), "\n\n",
"departure_op = ", show(departure_op), "\n\n",
"is_not_terminated = ", show(is_not_terminated), "\n\n",
"storage_used_volume = ", show(storage_used_volume), "\n\n"
"storage_used_volume = ", show(storage_used_volume), "\n\n",
"prev_m_obj_loc = ", show(prev_m_obj_loc), "\n\n",
"next_m_obj_loc = ", show(next_m_obj_loc), "\n\n",
"is_interval_useful = ", show(is_interval_useful), "\n\n"
];
......@@ -4,6 +4,7 @@ import javafx.util.Pair;
import java.io.*;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
......@@ -516,6 +517,64 @@ public class ConversionUtil {
write2DArrayOfSet(writer, "involved_operations", involvedOperations);
writeArray(writer, "loading_op_delta", loadingOpDelta);
writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1);
writer.write("\n");
}
{ // Ограничение на необходимость полезной операции между движениями к одному пункту назначения.
ArrayList<Integer> usefulOpObj = new ArrayList<>();
ArrayList<Integer> usefulOpId = new ArrayList<>();
ArrayList<Set<Integer>> objUsefulOperations = new ArrayList<>();
ArrayList<Set<Integer>> movingOpOfObj = new ArrayList<>();
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) -> {
usefulOpObj.add(mObjToN.apply(obj));
usefulOpId.add(op);
objUsefulOperations.get(mObjToN.apply(obj)).add(op + 1);
};
for (int i = 0; i < movingObjects.size(); i++) {
movingOpOfObj.add(new TreeSet<>());
objUsefulOperations.add(new TreeSet<>());
}
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i);
if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t;
int id = mObjToN.apply(op.getMover());
movingOpOfObj.get(id).add(i + 1);
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
}
} else if (t instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)t;
int id = mObjToN.apply(op.getMoorer());
movingOpOfObj.get(id).add(i + 1);
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);
}
}
writer.write("n_useful_op = " + usefulOpObj.size() + ";\n");
writeArray(writer, "useful_op_obj", usefulOpObj, (Integer i) -> i + 1);
writeArray(writer, "useful_op_id", usefulOpId, (Integer i) -> i + 1);
writeArray(writer, "obj_useful_operations", objUsefulOperations, ConversionUtil::setToString);
writeArray(writer, "moving_op_of_obj", movingOpOfObj, ConversionUtil::setToString);
writer.write("\n");
}
}
}
......
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