Commit dbe1706c authored by Vladislav Kiselev's avatar Vladislav Kiselev

Добавлена оптимизация - прежде чем возвращаться в предыдущую локацию судно...

Добавлена оптимизация - прежде чем возвращаться в предыдущую локацию судно должно сделать что-то полезное.
parent 6d484cf5
......@@ -219,6 +219,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;
% TODO узнать про where
% Определение is_involved_in_cargo_op.
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
......@@ -369,6 +372,7 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
array [1..n_fixed_op] of int : fixed_op_intensity;
array [0..n_operations, 0..n_intervals] of bool : is_fixed;
array [0..n_moving_obj, 0..(n_intervals + 1)] of bool : is_obj_involved_in_fixed_op;
constraint forall (no in 1..n_fixed_op, op = fixed_op[no]) (
forall (t in fixed_op_start[no]..fixed_op_end[no]) (
......@@ -457,6 +461,55 @@ array [0..n_operations] of 0..n_locations : operations_destination; % Локац
(op_start[op, t] /\ (not is_fixed[op, t])) -> not is_op_possible[op, t - 1]
);
% Оптимизация - судно возвращается откуда перед этим пришло -> оно сделало или делает что-то "полезное".
array [0..n_moving_obj, 0..(n_intervals + 1)] of var 1..n_locations : prev_m_obj_loc;
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_obj_involved_in_useful_operation;
constraint forall (t in 0..(n_intervals + 1)) (prev_m_obj_loc[0, t] = 1);
constraint forall (t in 0..(n_intervals + 1)) (is_obj_involved_in_useful_operation[0, t] = false);
% Определение prev_m_obj_loc
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
(m_obj_loc[obj, t - 1] != m_obj_loc[obj, t]) -> (prev_m_obj_loc[obj, t] = m_obj_loc[obj, t - 1])
);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
(m_obj_loc[obj, t - 1] == m_obj_loc[obj, t]) -> (prev_m_obj_loc[obj, t] = prev_m_obj_loc[obj, t - 1])
);
constraint forall (obj in 1..n_moving_obj) (prev_m_obj_loc[obj, 0] = m_obj_loc[obj, 0]);
% Определение is_obj_involved_in_useful_operation
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
is_obj_involved_in_useful_operation[obj, t] = (
(participation_as_resource[obj, t] != 0)
\/ (exists (op in related_cargo_op[obj]) (op_status[op, t]))
\/ (is_obj_involved_in_fixed_op[obj, t])
\/ (exists (op in related_unmooring_op[obj]) (op_status[op, t]))
)
);
constraint forall (obj in 1..n_moving_obj) (is_obj_involved_in_useful_operation[obj, 0] = false);
% Успел ли объект поучаствовать в полезной операции к концу данного интервала.
array [0..n_moving_obj, 0..(n_intervals + 1)] of var bool : is_attended_useful_op_in_cur_loc;
% Определение is_attended_useful_op_in_cur_loc
constraint forall (t in 0..(n_intervals + 1)) (is_attended_useful_op_in_cur_loc[0, t] = false);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
is_attended_useful_op_in_cur_loc[obj, t] = (
(is_attended_useful_op_in_cur_loc[obj, t - 1] /\ (m_obj_loc[obj, t - 1] == m_obj_loc[obj, t])) % Предыдущее значение в текущей локации.
\/
is_obj_involved_in_useful_operation[obj, t]
\/
is_obj_involved_in_useful_operation[obj, t - 1] % Учитывает случай когда операция перемещения, из-за которой объект попал в локацию была нужна.
)
);
% Сама оптимизация - если объект
constraint forall (obj in 1..n_moving_obj, t in 2..(n_intervals + 1)) (
((m_obj_loc[obj, t - 1] != m_obj_loc[obj, t]) /\ (prev_m_obj_loc[obj, t - 1] == m_obj_loc[obj, t])
) -> is_attended_useful_op_in_cur_loc[obj, t - 1]
);
% Критерий оптимизации
array [1..(n_intervals + 1)] of var bool : is_not_terminated;
% В конце всё остановится.
......@@ -487,7 +540,11 @@ output [show(sum(is_not_terminated)), "\n",
"is_involved_in_cargo_op = {", show(n_intervals), "} ", show(is_involved_in_cargo_op), "\n\n",
"current_moored_obj = ", show(current_moored_obj), "\n\n",
"m_obj_loc = ", show(m_obj_loc), "\n\n",
"prev_m_obj_loc = {", show(n_intervals + 2), "} ", show(prev_m_obj_loc), "\n\n",
"is_obj_involved_in_useful_operation = {", show(n_intervals + 2), "} ", show(is_obj_involved_in_useful_operation), "\n\n",
"is_attended_useful_op_in_cur_loc = {", show(n_intervals + 2), "} ", show(is_attended_useful_op_in_cur_loc), "\n\n",
/*
"is_op_possible {", show(n_intervals), "} = ", show(is_op_possible), "\n\n",
......
......@@ -1066,6 +1066,24 @@ public class ConversionUtil {
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, ConversionUtil::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++) {
......@@ -1378,18 +1396,45 @@ public class ConversionUtil {
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 (Operation op : task.getFixedOperations()) {
if (op.getFixation()) {
OptionalInt bunkerId = op.getBunker().map(b -> OptionalInt.of(b.getId())).orElse(OptionalInt.empty());
fixedOp.add(opNoByOpData.get(new OperationData(op.getTemplate().getId(), op.getExecutor().getId(), bunkerId)) + 1);
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);
}
}
}
fixedOp.add(opNo + 1);
TreeSet<Integer> resources = new TreeSet<>();
for (MovingObject obj : op.getResources()) {
resources.add(mObjToN(obj));
}
fixedOpResources.add(resources);
fixedOpStart.add((int)Math.floor(op.getStart()) + 1);
fixedOpEnd.add((int)Math.ceil(op.getDuration() + op.getStart()));
fixedOpStart.add(start + 1);
fixedOpEnd.add(end);
fixedOpIntensity.add((int)Math.ceil(op.getIntensity().orElse(0)));
}
}
......@@ -1401,6 +1446,7 @@ public class ConversionUtil {
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);
}
void defDataForCurMovingOp() throws IOException {
......@@ -1532,6 +1578,7 @@ public class ConversionUtil {
typifiedResourcesDefinition();
cargoOpUsingObj();
unmooringOpUsingObj();
addOpWithNominallyMooring();
writer.write("n_all_storage_sections = " + sectionNById.size() + ";\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