Commit e43ed078 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Передвижение в порту без швартовок

parent 800d72ee
......@@ -94,6 +94,75 @@ public class ConversionUtil {
return res;
}
static private 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 private List<Object> getResources(OperationTemplate t) {
List<Object> 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 private boolean isCompatible(OperationTemplate t1, OperationTemplate t2) {
MovingObject exec1 = getExecutor(t1);
Berth place1 = t1.getStartLocation();
List<Object> resources1 = getResources(t1);
MovingObject exec2 = getExecutor(t2);
Berth place2 = t2.getStartLocation();
List<Object> 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;
}
static public void portToMiniZinc(TaskCase task, String fileName) throws IOException {
try(FileWriter writer = new FileWriter(fileName, false)) {
int n_intervals = (int)task.getPlanningInterval();
......@@ -159,9 +228,9 @@ public class ConversionUtil {
{ // Начальные положения объектов.
ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
for (MovingObjectState state : task.getVesselInitialState()) {
initialStates.set(mObjToN.apply(state.getVessel()), locationNumberById.get(new Pair<>(state.getLocation().getId(), false)) + 1);
initialStates.set(mObjToN.apply(state.getVessel()), locationNumberById.get(new Pair<>(state.getLocation().getId(), false)));
}
writeArray(writer, "initial_m_obj_loc", initialStates);
writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1);
}
// TODO окна погоды.
......@@ -188,7 +257,7 @@ public class ConversionUtil {
for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN.apply(state.getVessel()), locationNumberById.get(new Pair<>(state.getLocation().getId(), false)));
}
writeArray(writer, "final_m_obj_loc", finalStates);
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1);
}
{ // Наличие всех ресурсов на месте.
ArrayList<Set<Integer>> operationsResources = new ArrayList<>();
......@@ -204,14 +273,26 @@ public class ConversionUtil {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, locationNumberById.get(new Pair<>(op.getStartLocation().getId(), false)));
operationsStartLoc.set(i, locationNumberById.get(new Pair<>(op.getStartLocation().getId(), false)) + 1);
}
// TODO швартовка, погрузка.
}
writeArray(writer, "operations_start_loc", operationsStartLoc);
writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString);
}
{ // Конфликтующие операции.
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);
}
}
}
}
......@@ -16,11 +16,11 @@ array [1..n_moving_obj, 1..n_locations] of set of 1..n_operations : arrival_op;
array [1..n_moving_obj, 1..n_locations] of set of 1..n_operations : departure_op;
% Определение m_obj_loc.
constraint forall (i in 1..n_moving_obj, j in 1..(n_intervals + 1))
((m_obj_loc[i, j] != 0) -> (
(m_obj_loc[i, j] == m_obj_loc[i, j - 1] /\ (forall (k in departure_op[i, m_obj_loc[i, j]]) (op_status[k, j - 1] == 0)))
constraint forall (obj in 1..n_moving_obj, j in 1..(n_intervals + 1))
((m_obj_loc[obj, j] != 0) -> (
(m_obj_loc[obj, j] == m_obj_loc[obj, j - 1] /\ (forall (k in departure_op[obj, m_obj_loc[obj, j]]) (op_status[k, j - 1] == 0)))
\/
(not (forall (k in arrival_op[i, m_obj_loc[i, j]]) (op_fin[i, j - 1] == 0)))
(not (forall (k in arrival_op[obj, m_obj_loc[obj, j]]) (op_fin[k, j - 1] == 0)))
));
% Начальное состояние.
......@@ -37,34 +37,56 @@ constraint forall (i in 1..n_moving_obj) (
constraint forall (i in 1..n_operations, j in {0, n_intervals + 1}) (op_status[i, j] == 0); % Краевые значения.
% Определение op_start и op_fin.
constraint forall (i in 1..n_operations) (op_start[i, 0] == 0 /\ op_fin[i, n_intervals + 1] == 0);
constraint forall (i in 1..n_operations, j in 1..(n_intervals + 1)) (op_start[i, j] = op_status[i, j] /\ not op_status[i, j - 1]);
constraint forall (i in 1..n_operations, j in 1..n_intervals ) (op_fin [i, j] = op_status[i, j] /\ not op_status[i, j + 1]);
constraint forall (op in 1..n_operations, j in {0, n_intervals + 1})
(op_start[op, j] == 0 /\ op_fin[op, j] == 0);
constraint forall (i in 1..n_operations, j in 1..(n_intervals + 1)) (op_start[i, j] = (op_status[i, j] /\ not op_status[i, j - 1]));
constraint forall (i in 1..n_operations, j in 1..n_intervals ) (op_fin [i, j] = (op_status[i, j] /\ not op_status[i, j + 1]));
% Непрерывность перемещения.
array [1..n_operations] of var int : operations_duration;
array [1..n_operations] of var bool : is_moving_operation;
% TODO
%constraint forall (i in 1..n_operations) (
% if (is_moving_operation[i]) then (
% forall (j in 1..n_intervals) (
% let {var int : len = operations_duration[i]} in
% if (j + len > n_intervals + 1) then
% op_start[i, j] == 0
% else (
% (op_start[i, j] == 1) -> (
% (forall (k in 1..(len - 1))
% (op_status[i, j + k] == 1)
% ) /\
% (op_status[i, j + len] == 0)
% )
% )
% endif
% )
% ) else true
% endif
%);
constraint forall (i in 1..n_operations) (
if (is_moving_operation[i]) then (
forall (j in 1..n_intervals) (
if (j + operations_duration[i] > n_intervals + 1) then
op_start[i, j] = 0
else (
(op_start[i, j] == 1) -> (
(forall (k in 1..(operations_duration[i] - 1))
(op_status[i, j + k] == 1)
) /\
(op_status[i, j + operations_duration[i]] == 0)
)
let {var int : len = operations_duration[i]} in
(forall (j in 1..(n_intervals - len + 1)) (
(op_start[i, j] == 1) -> (
(forall (k in 1..(len - 1))
(op_status[i, j + k] == 1)
) /\
(op_status[i, j + len] == 0)
)
endif
)) /\
(forall (j in (n_intervals - len + 2)..(n_intervals + 1))
(op_start[i, j] == 0)
)
) else true
endif
);
% Наличие всех ресурсов на месте.
% Наличие всех ресурсов на месте во время начала операции перемещения.
array [1..n_operations] of set of 1..n_moving_obj : operations_resources;
array [1..n_operations] of 0..n_locations : operations_start_loc;
......@@ -74,6 +96,37 @@ constraint forall (op in 1..n_operations, j in 1..n_intervals) (
)
);
solve satisfy;
% Конфликтующие операции.
int : n_conflicting_op;
array [1..n_conflicting_op] of 1..n_operations : confl_op_1;
array [1..n_conflicting_op] of 1..n_operations : confl_op_2;
constraint forall (t in 0..(n_intervals + 1), i in 1..n_conflicting_op) (
(op_status[confl_op_1[i], t] -> not op_status[confl_op_2[i], t])
/\
(op_status[confl_op_2[i], t] -> not op_status[confl_op_1[i], t])
);
% Критерий оптимизации
array [0..(n_intervals + 1)] of var bool : is_not_terminated;
constraint (is_not_terminated[0] == 0 /\ is_not_terminated[n_intervals + 1] == 0);
constraint forall (t in 1..n_intervals) (
is_not_terminated[t] == (
(not (forall (op in 1..n_operations) (op_status[op, t] == 0)))
\/
is_not_terminated[t + 1]
)
);
solve minimize sum(is_not_terminated);
output ["op_status = ", show(op_status), "\n"];
output ["res = ", show(sum(is_not_terminated)), "\n\n",
"op_status = ", show(op_status), "\n\n",
"m_obj_loc = ", show(m_obj_loc), "\n\n",
"op_fin = ", show(op_fin), "\n\n",
"op_start = ", show(op_start), "\n\n",
"arrival_op = ", show(arrival_op), "\n\n",
"departure_op = ", show(departure_op), "\n\n",
"is_not_terminated = ", show(is_not_terminated), "\n\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