Commit c8542a5d authored by Vladislav Kiselev's avatar Vladislav Kiselev

Типизация.

parent 7098b577
......@@ -11,7 +11,7 @@ array [1..n_operations, 0..(n_intervals + 1)] of var bool : op_fin;
int : moving_op_of_obj_max_size;
array [1..n_moving_obj] of 0..moving_op_of_obj_max_size : moving_op_of_obj_sizes;
array [1..n_moving_obj, 1..moving_op_of_obj_max_size] of 1..n_operations : moving_op_of_obj; % Операции перемещения затрагивающие данный объект.
array [1..n_moving_obj, 0..moving_op_of_obj_max_size] of 1..n_operations : moving_op_of_obj; % Операции перемещения затрагивающие данный объект.
% Определение current_moving_operation.
% Текущая операция операция перемещения, в которой задействован данный объект.
......@@ -21,16 +21,34 @@ array [1..n_moving_obj, 1..moving_op_of_obj_max_size] of 1..n_operations : movin
constraint forall (obj in 1..n_moving_obj, t in 0..(n_intervals + 1)) (
current_moving_operation[obj, t] <= moving_op_of_obj_sizes[obj]
);
% Если операция, затрагивающая данный объект в качестве главного, выполняется - то именно она текущая операция перемещения для этого объекта.
constraint forall (op in 1..n_operations, t in 0..(n_intervals + 1), obj = main_obj_of_operation[op]
where is_moving_operation[op]) (
op_status[op, t] -> ((current_moving_operation[obj, t] != 0) /\
(moving_op_of_obj[obj, current_moving_operation[obj, t]] = op))
);
% Если операция, затрагивающая данный объект в качестве ресурса
% TODO упростить в conversion_1
% Связь current_moving_operation c op_status.
constraint forall (obj in 1..n_moving_obj,
t in 0..(n_intervals + 1)) (
(current_moving_operation[obj, t] != 0)
-> (op_status[moving_op_of_obj[obj, current_moving_operation[obj, t]], t])
);
% Ограничение на количество пришвартованных кораблей.
% Счётчик объектов в локации (только в чётных - в состоянии пришвартованности).
array [1..n_locations, 0..(n_intervals + 1)] of var int : obj_in_loc_counter;
% Если операция, затрагивающая данный объект, выполняется - то именно она текущая операция перемещения для этого объекта.
constraint forall (obj in 1..n_moving_obj, op_no in 1..moving_op_of_obj_sizes[obj], t in 0..(n_intervals + 1)) (
(op_status[moving_op_of_obj[obj, op_no], t]) -> (current_moving_operation[obj, t] = op_no)
% Определение obj_in_loc_counter.
constraint forall (loc in 1..n_locations, t in 0..(n_intervals + 1)) (
obj_in_loc_counter[loc, t] = sum (obj in 1..n_moving_obj) (m_obj_loc[obj, t] = loc)
);
% Если объект движется, то выполняется какая-то операция перемещения, касаящаяся этого объекта.
constraint forall (obj in 1..n_moving_obj, t in 0..(n_intervals + 1)) (
(current_moving_operation[obj, t] > 0) ->
(exists (op_no in 1..moving_op_of_obj_sizes[obj]) (op_status[moving_op_of_obj[obj, op_no], t]))
% Само ограничение.
constraint forall (loc in 1..n_locations, t in 0..(n_intervals + 1) where (loc mod 2) = 0) (
obj_in_loc_counter[loc, t] <= 1
);
% Определение is_m_obj_in_movement_before_start.
......@@ -44,11 +62,12 @@ array [1..n_moving_obj, 1..moving_op_of_obj_max_size] of 1..n_operations : movin
% Если в предыдущем интервале объект не движется - то в начале этого он не движется, иначе он движется если предыдущая операция не закончилась.
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
if (current_moving_operation[obj, t - 1] = 0) then
is_m_obj_in_movement_before_start[obj, t] = false
else
is_m_obj_in_movement_before_start[obj, t] = (current_moving_operation[obj, t - 1] == current_moving_operation[obj, t])
endif
(current_moving_operation[obj, t - 1] = 0)
-> is_m_obj_in_movement_before_start[obj, t] = false
);
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals + 1)) (
(current_moving_operation[obj, t - 1] != 0)
-> is_m_obj_in_movement_before_start[obj, t] = (current_moving_operation[obj, t - 1] == current_moving_operation[obj, t])
);
array [1..n_operations] of 1..n_locations : operations_destination; % Локация в которой окажется объект после завершения операции.
......@@ -56,27 +75,49 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Определение m_obj_loc.
% Местоположение объекта или пункт назначения (если объект движется) перед началом определённого интервала.
array [1..n_moving_obj, 0..(n_intervals + 1)] of var 1..n_locations : m_obj_loc;
% Главный объект (субъект) операции.
array [1..n_operations] of 1..n_moving_obj : main_obj_of_operation;
% Является ли операция швартовкой/отшвартовкой.
array [1..n_operations] of bool : is_mooring_op;
% За фиктивный нулевой интервал объект не успевает ничего сделать с начальным положением.
constraint forall (obj in 1..n_moving_obj) (
m_obj_loc[obj, 1] = m_obj_loc[obj, 0]
);
% TODO исправить в conversion_1.mzn
% Направление движения/местоположение объекта может измениться только если перед этим началась операция перемещения.
constraint forall (obj in 1..n_moving_obj, t in 2..(n_intervals + 1)) (
if ((current_moving_operation[obj, t - 1] != current_moving_operation[obj, t - 2]) /\
(current_moving_operation[obj, t - 1] != 0)) then
m_obj_loc[obj, t] = operations_destination[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]]
else
m_obj_loc[obj, t] = m_obj_loc[obj, t - 1]
endif
((current_moving_operation[obj, t - 1] != current_moving_operation[obj, t - 2]) /\
(current_moving_operation[obj, t - 1] != 0) /\
((obj = main_obj_of_operation[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]])
\/
(not is_mooring_op[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]])
)
) -> (m_obj_loc[obj, t] = operations_destination[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]])
);
constraint forall (obj in 1..n_moving_obj, t in 2..(n_intervals + 1)) (
((current_moving_operation[obj, t - 1] != current_moving_operation[obj, t - 2]) /\
(current_moving_operation[obj, t - 1] != 0) /\
((obj != main_obj_of_operation[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]])
/\
(is_mooring_op[moving_op_of_obj[obj, current_moving_operation[obj, t - 1]]])
)
) -> (m_obj_loc[obj, t] = m_obj_loc[obj, t - 1])
);
constraint forall (obj in 1..n_moving_obj, t in 2..(n_intervals + 1)) (
((current_moving_operation[obj, t - 1] = current_moving_operation[obj, t - 2]) \/
(current_moving_operation[obj, t - 1] = 0)
) -> (m_obj_loc[obj, t] = m_obj_loc[obj, t - 1])
);
% Начальное состояние.
array [1..n_moving_obj] of var 0..n_locations : initial_m_obj_loc;
array [1..n_moving_obj] of 0..n_locations : initial_m_obj_loc;
constraint forall (i in 1..n_moving_obj) (m_obj_loc[i, 0] = initial_m_obj_loc[i]);
% Конечное состояние.
array [1..n_moving_obj] of var 0..n_locations : final_m_obj_loc;
array [1..n_moving_obj] of 0..n_locations : final_m_obj_loc;
constraint forall (i in 1..n_moving_obj) (
(final_m_obj_loc[i] != 0) ->
(m_obj_loc[i, n_intervals + 1] = final_m_obj_loc[i])
......@@ -94,9 +135,6 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Операции, которые могут задействовать данный объект как ресурс.
array [1..n_moving_obj] of set of 1..n_operations : operations_that_used_obj_as_resource;
% Главный объект (субъект) операции.
array [1..n_operations] of 1..n_moving_obj : main_obj_of_operation;
% Является ли данная операция операцией перемещения.
array [1..n_operations] of bool : is_moving_operation;
......@@ -109,7 +147,8 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Только те операции, которые затрагивают данный объект.
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
participation_as_resource[obj, t] in operations_that_used_obj_as_resource[obj]
(participation_as_resource[obj, t] != 0)
-> participation_as_resource[obj, t] in operations_that_used_obj_as_resource[obj]
);
% Связь с текущими операциями перемещения.
......@@ -123,29 +162,37 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
(participation_as_resource[obj, t] = moving_op_of_obj[obj, current_moving_operation[obj, t]])
)
);
% { Если объект участвует как ресурс в операции перемещения, то это согласованно с current_moving_operation,
% иначе (как ресурс в погрузке) - он должен стоять на месте. }
% { Если объект участвует как ресурс в операции перемещения (не швартовки), то это согласованно с current_moving_operation,
% иначе (как ресурс в погрузке или швартове) - он должен стоять на месте. }
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
(participation_as_resource[obj, t] != 0) -> (
if (is_moving_operation[participation_as_resource[obj, t]]) then
( (is_moving_operation[participation_as_resource[obj, t]] /\
(not is_mooring_op[participation_as_resource[obj, t]])
) -> (
(current_moving_operation[obj, t] != 0)
/\
(participation_as_resource[obj, t] = moving_op_of_obj[obj, current_moving_operation[obj, t]])
else
current_moving_operation[obj, t] = 0
end
)
)
/\
(not (is_moving_operation[participation_as_resource[obj, t]] /\
(not is_mooring_op[participation_as_resource[obj, t]])
) -> current_moving_operation[obj, t] = 0)
)
);
% { Объект участвует где-то в качестве ресурса - соответствующая операция обязана быть активной. }
constraint forall (obj in n_moving_obj, t in 1..n_intervals) (
constraint forall (obj in 1..n_moving_obj, t in 1..n_intervals) (
(participation_as_resource[obj, t] != 0) -> op_status[participation_as_resource[obj, t], t]
);
% От начала операции и до конца её ресурсы не могут измениться (в том числе и для погрузки).
constraint forall (obj in 1..n_moving_obj, t in 1..(n_intervals - 1)) (
if participation_as_resource[obj, t] != 0 then
op_status[participation_as_resource[obj, t], t + 1] -> (
participation_as_resource[obj, t + 1] = participation_as_resource[obj, t]
(participation_as_resource[obj, t] != 0) ->
(op_status[participation_as_resource[obj, t], t + 1]
-> participation_as_resource[obj, t + 1] = participation_as_resource[obj, t]
)
else true
end
);
int : n_resources_types; % Количество различных типов ресурсов.
......@@ -167,7 +214,7 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
% Определение resources_counter.
constraint forall (counter in 1..n_resources_counters, t in 1..n_intervals) (
resources_counter[counter, t] = sum (obj in objects_of_type[counter_type[counter]]) (
participation_as_resource[obj] = operation_of_counter[counter]
participation_as_resource[obj, t] = operation_of_counter[counter]
)
);
......@@ -183,24 +230,27 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
op in 1..n_operations,
t in 1..n_intervals,
counter in counters_of_operation[op],
obj in objects_of_type[counter_type[counter]]
where (participation_as_resource[obj, t] = op)) (
op_start[op, t] -> ((m_obj_loc[obj, t] == operations_resources_start_loc[counter]) /\
(not is_m_obj_in_movement_before_start[obj, t]))
obj in objects_of_type[counter_type[counter]]) (
((participation_as_resource[obj, t] = op) /\ (op_start[op, t])
) -> ((m_obj_loc[obj, t] == operations_resources_start_loc[counter]) /\
(not is_m_obj_in_movement_before_start[obj, t]) /\
((not is_moving_operation[op]) -> (current_moving_operation[obj, t] = 0))
)
);
% Наличие и готовность главных объектов (субъектов).
constraint forall (op in 1..n_operations, t in 1..n_intervals) (
op_start[op, t] -> ((m_obj_loc[main_obj_of_operation[op], t] == main_obj_start_loc[op]) /\
(not is_m_obj_in_movement_before_start[main_obj_of_operation[op], t]))
constraint forall (op in 1..n_operations, t in 1..n_intervals, obj = main_obj_of_operation[op]) (
op_start[op, t] -> ((m_obj_loc[obj, t] == main_obj_start_loc[op]) /\
(not is_m_obj_in_movement_before_start[obj, t]) /\
((not is_moving_operation[op]) -> (current_moving_operation[obj, t] = 0))
)
);
% Непрерывность перемещения и швартовки.
array [1..n_operations] of int : operations_duration;
array [1..n_operations] of bool : is_continuous_operation;
constraint forall (i in 1..n_operations where is_continuous_operation[i]) (
let {var int : len = operations_duration[i]} in
constraint forall (i in 1..n_operations, len = operations_duration[i] where is_continuous_operation[i]) (
(forall (j in 1..(n_intervals - len + 1)) (
(op_start[i, j] == 1) -> (
(forall (k in 1..(len - 1)) (op_status[i, j + k]))
......@@ -300,12 +350,20 @@ array [1..n_operations] of 1..n_locations : operations_destination; % Локац
solve minimize sum(is_not_terminated);
output [show(sum(is_not_terminated)), "\n",
show(op_status), "\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",
"is_not_terminated = ", show(is_not_terminated), "\n\n",
"storage_used_volume = ", show(storage_used_volume), "\n\n",
"is_m_obj_in_movement_before_start = ", show(is_m_obj_in_movement_before_start), "\n\n",
"current_moving_operation = ", show(current_moving_operation), "\n\n"
];
"obj_in_loc_counter = ", show(obj_in_loc_counter), "\n\n",
"m_obj_loc = ", show(m_obj_loc), "\n\n",
"current_moving_operation = ", show(current_moving_operation), "\n\n",
"resources_counter {", show(n_intervals), "} = ", show(resources_counter), "\n\n",
"operation_of_counter {", show(n_resources_counters), "} = ", show(operation_of_counter), "\n\n",
"participation_as_resource = ", show(participation_as_resource), "\n\n",
"real_current_moving_operation = ", show(current_moving_operation), "\n\n",
"moving_op_of_obj {", show(moving_op_of_obj_max_size + 1), "}= ", show(moving_op_of_obj), "\n\n",
""];
......@@ -5,7 +5,6 @@ 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;
public class ConversionUtil {
......@@ -90,13 +89,14 @@ public class ConversionUtil {
static private void writeArrayOfSetAs2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations) throws IOException {
writeArrayOfSetAs2DArray(writer, name, operations, true);
writeArrayOfSetAs2DArray(writer, name, operations, true, false);
}
static private void writeArrayOfSetAs2DArray(FileWriter writer,
String name,
ArrayList<ArrayList<Integer>> operations,
boolean addAdditionalInfo) throws IOException {
boolean addAdditionalInfo,
boolean addDummyZeroElement) throws IOException {
int maxSize = 0;
ArrayList<Integer> sizes = new ArrayList<>();
for (ArrayList<Integer> s : operations) {
......@@ -107,10 +107,18 @@ public class ConversionUtil {
writer.write(name + "_max_size = " + maxSize + ";\n");
writeArray(writer, name + "_sizes", sizes);
}
writer.write(name + " = array2d(1.." + operations.size() + ", 1.." + maxSize + ", [");
writer.write(name + " = array2d(1.." + operations.size() + ", " + (addDummyZeroElement ? "0" : "1") + ".." + maxSize + ", [");
boolean isFirst = true;
for (ArrayList<Integer> s : operations) {
if (addDummyZeroElement) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write("1");
}
for (Integer val : s) {
if (isFirst) {
isFirst = false;
......@@ -197,7 +205,23 @@ public class ConversionUtil {
return res;
}
static private MovingObject getExecutor(OperationTemplate t) {
static private ArrayList<ArrayList<Integer>> arrayOfIntegerArrays(int size) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
for (int i = 0; i < size; i++) {
res.add(new ArrayList<>());
}
return res;
}
static private ArrayList<Set<Integer>> arrayOfIntegerSet(int size) {
ArrayList<Set<Integer>> res = new ArrayList<>();
for (int i = 0; i < size; i++) {
res.add(new TreeSet<>());
}
return res;
}
static MovingObject getExecutor(OperationTemplate t) {
if (t instanceof LoadingTemplate) {
return ((LoadingTemplate) t).getLoader();
}
......@@ -210,7 +234,7 @@ public class ConversionUtil {
return null;
}
static private List<MovingObject> getResources(OperationTemplate t) {
static List<MovingObject> getResources(OperationTemplate t) {
List<MovingObject> res = new ArrayList<>();
if (t instanceof LoadingTemplate) {
res.addAll(((LoadingTemplate) t).getResources());
......@@ -266,7 +290,7 @@ public class ConversionUtil {
return true;
}
private static class Task {
static class Task {
private FileWriter writer = null;
private final String fileName;
private final TaskCase task;
......@@ -280,9 +304,17 @@ public class ConversionUtil {
}
private final ArrayList<MovingObject> movingObjects;
private final Function<MovingObject, Integer> mObjToN;
private final ArrayList<OperationTemplate> operationTemplates;
public Map<Integer, Integer> getMObjNumberById() {
return mObjNumberById;
}
private final Map<Integer, Integer> mObjNumberById;
private int mObjToN(MovingObject obj) {
return mObjNumberById.get(obj.getId());
}
private ArrayList<OperationTemplate> operationTemplates;
private final ArrayList<Storage> storages;
private final ArrayList<Cargo> cargoes;
......@@ -292,6 +324,19 @@ public class ConversionUtil {
private final Map<Integer, Integer> storNById;
private final Map<Integer, Integer> cargoNById;
private final Map<Integer, Integer> typeToN;
private ArrayList<ArrayList<Integer>> movingOpOfObj;
private ArrayList<Integer> operationsDestination;
private ArrayList<Integer> mainObjOfOperation;
private ArrayList<Boolean> isMooringOp;
public ArrayList<ArrayList<Integer>> getMovingOpOfObj() {
return movingOpOfObj;
}
private ArrayList<Set<Integer>> objectsOfType;
Task(TaskCase task, String fileName) {
this.fileName = fileName;
this.task = task;
......@@ -306,7 +351,7 @@ public class ConversionUtil {
}
movingObjects = new ArrayList<>();
Map<Integer, Integer> mObjNumberById = new TreeMap<>();
mObjNumberById = new TreeMap<>();
for (MovingObject obj : task.getShips()) {
mObjNumberById.put(obj.getId(), movingObjects.size());
movingObjects.add(obj);
......@@ -320,8 +365,10 @@ public class ConversionUtil {
movingObjects.add(obj);
}
mObjToN = (MovingObject obj) -> mObjNumberById.get(obj.getId());
operationTemplates = new ArrayList<>(task.getTemplates());
if (task.isTypified()) {
operationTemplates = renumberOperations(task);
}
storages = new ArrayList<>(task.getStorages());
cargoes = new ArrayList<>(task.getCargoes());
......@@ -337,6 +384,50 @@ public class ConversionUtil {
}
nObjWithStorage = movingObjects.size() + storages.size();
{
typeToN = new TreeMap<>();
int next = 0;
for (Integer type : task.getVesselTypes().keySet()) {
typeToN.put(type, next);
next++;
}
for (Integer type : task.getEquipmentsTypes().keySet()) {
typeToN.put(type, next);
next++;
}
}
{
objectsOfType = arrayOfIntegerSet(typeToN.size());
for (MovingObject obj : movingObjects) {
if (obj.getType().isPresent()) {
objectsOfType.get(typeToN.get(obj.getType().getAsInt())).add(mObjToN(obj) + 1);
}
}
}
{
movingOpOfObj = arrayOfIntegerArrays(movingObjects.size());
operationsDestination = new ArrayList<>();
mainObjOfOperation = new ArrayList<>();
isMooringOp = new ArrayList<>();
initMovingObjectLocationDefinition();
}
}
private ArrayList<Integer> getNumbersOfResourcesTypes(OperationTemplate t) {
ArrayList<Integer> res = new ArrayList<>();
if (t instanceof LoadingTemplate) {
res.addAll(((LoadingTemplate) t).getResourcesTypes());
}
if (t instanceof MooringTemplate) {
res.addAll(((MooringTemplate) t).getResourcesTypes());
}
if (t instanceof MovingTemplate) {
res.addAll(((MovingTemplate) t).getResourcesTypes());
}
res.replaceAll(typeToN::get);
return res;
}
/* Операции прибытия/отбытия в локацию. (В том числе и швартовка.) */
......@@ -358,9 +449,9 @@ public class ConversionUtil {
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN.apply(obj));
movingObjN.add(mObjToN(obj));
}
movingObjN.add(mObjToN.apply(op.getMover()));
movingObjN.add(mObjToN(op.getMover()));
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById(op.getDestination().getId(), false)).add(i + 1);
......@@ -371,9 +462,9 @@ public class ConversionUtil {
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN.apply(obj));
movingObjN.add(mObjToN(obj));
}
movingObjN.add(mObjToN.apply(op.getMoorer()));
movingObjN.add(mObjToN(op.getMoorer()));
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById(op.getStartLocation().getId(), op.isDirect())).add(i + 1);
......@@ -390,7 +481,7 @@ public class ConversionUtil {
private void initialLocations() throws IOException {
ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
for (MovingObjectState state : task.getVesselInitialState()) {
initialStates.set(mObjToN.apply(state.getVessel()), getLocNById(state.getLocation().getId(), false));
initialStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false));
}
writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1);
writer.write("\n");
......@@ -446,7 +537,7 @@ public class ConversionUtil {
private void finalLocations() throws IOException {
ArrayList<Integer> finalStates = integerArray(movingObjects.size(), -1);
for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN.apply(state.getVessel()), getLocNById(state.getLocation().getId(), false));
finalStates.set(mObjToN(state.getVessel()), getLocNById(state.getLocation().getId(), false));
}
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1);
}
......@@ -457,7 +548,7 @@ public class ConversionUtil {
ArrayList<ArrayList<Integer>> operationsResourcesStartLoc = new ArrayList<>();
BiConsumer<MovingObject, Integer> addResource = (MovingObject r, Integer stLoc) -> {
operationsResources.get(operationsResources.size() - 1).add(mObjToN.apply(r) + 1);
operationsResources.get(operationsResources.size() - 1).add(mObjToN(r) + 1);
operationsResourcesStartLoc.get(operationsResourcesStartLoc.size() - 1).add(stLoc + 1);
};
......@@ -486,7 +577,7 @@ public class ConversionUtil {
}
}
writeArrayOfSetAs2DArray(writer, "operations_resources", operationsResources);
writeArrayOfSetAs2DArray(writer, "operations_resources_start_loc", operationsResourcesStartLoc, false);
writeArrayOfSetAs2DArray(writer, "operations_resources_start_loc", operationsResourcesStartLoc, false, false);
writer.write("\n");
}
......@@ -544,7 +635,7 @@ public class ConversionUtil {
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);
initialStorageVol.get(mObjToN(ship)).set(cargoN, val);
}
}
for (StorageState st : task.getStorageEndState()) {
......@@ -557,7 +648,7 @@ public class ConversionUtil {
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);
finalStorageVol.get(mObjToN(ship)).set(cargoN, val);
}
}
write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol);
......@@ -617,7 +708,7 @@ public class ConversionUtil {
if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
int storageN = storNById.get(op.getStorage().getId());
int shipN = mObjToN.apply(op.getLoader());
int shipN = mObjToN(op.getLoader());
int cargoN = cargoNById.get(op.getCargo().getId());
loadingOpDelta.add(-(int)op.getIntensity());
......@@ -644,9 +735,9 @@ public class ConversionUtil {
ArrayList<ArrayList<Integer>> movingOpOfObj = new ArrayList<>();
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) ->
objUsefulOperations.get(mObjToN.apply(obj)).add(op + 1);
objUsefulOperations.get(mObjToN(obj)).add(op + 1);
BiConsumer<MovingObject, Integer> addMovingOp = (MovingObject obj, Integer op) ->
movingOpOfObj.get(mObjToN.apply(obj)).add(op + 1);
movingOpOfObj.get(mObjToN(obj)).add(op + 1);
for (int i = 0; i < movingObjects.size(); i++) {
movingOpOfObj.add(new ArrayList<>());
......@@ -692,7 +783,7 @@ public class ConversionUtil {
ArrayList<ArrayList<Integer>> objUsefulOperations = new ArrayList<>();
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) ->
objUsefulOperations.get(mObjToN.apply(obj)).add(op + 1);
objUsefulOperations.get(mObjToN(obj)).add(op + 1);
for (int i = 0; i < movingObjects.size(); i++) {
objUsefulOperations.add(new ArrayList<>());
......@@ -726,25 +817,29 @@ public class ConversionUtil {
writer.write("\n");
}
private void movingObjectLocationDefinition() throws IOException {
ArrayList<ArrayList<Integer>> movingOpOfObj = new ArrayList<>();
ArrayList<Integer> operationsDestination = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) {
movingOpOfObj.add(new ArrayList<>());
}
private void initMovingObjectLocationDefinition() {
BiConsumer<MovingObject, Integer> addMovingOp = (MovingObject obj, Integer op) ->
movingOpOfObj.get(mObjToN.apply(obj)).add(op + 1);
movingOpOfObj.get(mObjToN(obj)).add(op + 1);
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i);
mainObjOfOperation.add(mObjToN(getExecutor(t)));
isMooringOp.add(t instanceof MooringTemplate);
if ((t instanceof MovingTemplate) || (t instanceof MooringTemplate)) {
addMovingOp.accept(getExecutor(t), i);
if (!task.isTypified()) {
for (MovingObject obj : getResources(t)) {
addMovingOp.accept(obj, i);
}
} else {
for (Integer typeId : new TreeSet<>(getNumbersOfResourcesTypes(t))) {
for (Integer objId : objectsOfType.get(typeId)) {
movingOpOfObj.get(objId - 1).add(i + 1);
}
}
}
}
if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t;
......@@ -756,8 +851,12 @@ public class ConversionUtil {
operationsDestination.add(getLocNById(t.getStartLocation().getId(), false));
}
}
}
writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj);
private void movingObjectLocationDefinition() throws IOException {
writeArray(writer, "is_mooring_op", isMooringOp);
writeArray(writer, "main_obj_of_operation", mainObjOfOperation, (Integer val) -> val + 1);
writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj, true, true);
writeArray(writer, "operations_destination", operationsDestination, (Integer val) -> val + 1);
writer.write("\n");
}
......@@ -838,6 +937,181 @@ public class ConversionUtil {
}
}
/* Каждую операцию лишает типизации по главному действующему лицу. */
public static ArrayList<OperationTemplate> renumberOperations(TaskCase task) {
TreeMap<Integer, ArrayList<MovingObject>> shipsByType = new TreeMap<>();
for (Integer type : task.getVesselTypes().keySet()) {
shipsByType.put(type, new ArrayList<>());
}
for (Integer type : task.getEquipmentsTypes().keySet()) {
shipsByType.put(type, new ArrayList<>());
}
ArrayList<MovingObject> movingObjects = new ArrayList<>();
movingObjects.addAll(task.getTows());
movingObjects.addAll(task.getShips());
movingObjects.addAll(task.getEquipments());
for (MovingObject obj : movingObjects) {
if (obj.getType().isPresent()) {
shipsByType.get(obj.getType().getAsInt()).add(obj);
}
}
ArrayList<OperationTemplate> result = new ArrayList<>();
for (OperationTemplate op : task.getTemplates()) {
if (op instanceof LoadingTemplate) {
LoadingTemplate t = (LoadingTemplate)op;
if (t.getLoaderType().isPresent()) {
for (MovingObject obj : shipsByType.get(t.getLoaderType().getAsInt())) {
assert(obj instanceof TransportShip);
result.add(new LoadingTemplate((TransportShip)obj, t.getStartLocation(), t.getStorage(),
t.getCargo(), t.getResourcesTypes(), t.getWithMooring(), t.getIntensity(), t.getId()));
}
}
}
if (op instanceof MooringTemplate) {
MooringTemplate t = (MooringTemplate)op;
if (t.getMoorerType().isPresent()) {
for (MovingObject obj : shipsByType.get(t.getMoorerType().getAsInt())) {
assert(obj instanceof TransportShip);
result.add(new MooringTemplate((TransportShip)obj, t.getStartLocation(), t.getResourcesTypes(),
t.getDuration(), t.isDirect(), t.getId()));
}
}
}
if (op instanceof MovingTemplate) {
MovingTemplate t = (MovingTemplate)op;
if (t.getMoverType().isPresent()) {
for (MovingObject obj : shipsByType.get(t.getMoverType().getAsInt())) {
result.add(new MovingTemplate(obj, t.getStartLocation(), t.getDestination(), t.getResourcesTypes(),
t.getDuration(), t.getId()));
}
}
}
}
return result;
}
private void conflictingOperationsOnStorageAndOnTypeOnMainObject() throws IOException {
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 ((operationTemplates.get(i) instanceof LoadingTemplate) &&
(operationTemplates.get(j) instanceof LoadingTemplate)) {
LoadingTemplate op1 = (LoadingTemplate) operationTemplates.get(i);
LoadingTemplate op2 = (LoadingTemplate) operationTemplates.get(j);
if ((op1.getLoader() == op2.getLoader()) &&
(op1.getStorage() == op2.getStorage()) &&
(op1.getStartLocation() == op2.getStartLocation())) {
conflictingPairs.add(new Pair<>(i + 1, j + 1));
}
}
{ // Взаимоисключение операций перемещения и грузообработки с общим деятелем.
// TODO вынести в отдельный constraint
OperationTemplate t1 = operationTemplates.get(i);
OperationTemplate t2 = operationTemplates.get(j);
if (t1 instanceof LoadingTemplate) {
OperationTemplate t3 = t1;
t1 = t2;
t2 = t3;
}
if (((t1 instanceof MovingTemplate) || (t1 instanceof MooringTemplate))
&& (t2 instanceof LoadingTemplate)) {
if (getExecutor(t1) == getExecutor(t2)) {
conflictingPairs.add(new Pair<>(i + 1, j + 1));
}
}
}
{ // Взаимоисключение операций швартовки/отшвартовки с одним причалом.
// TODO выделить в отдельный constraint
if ((operationTemplates.get(i) instanceof MooringTemplate) &&
(operationTemplates.get(j) instanceof MooringTemplate)) {
MooringTemplate op1 = (MooringTemplate) operationTemplates.get(i);
MooringTemplate op2 = (MooringTemplate) operationTemplates.get(j);
if (op1.getStartLocation() == op2.getStartLocation()) {
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);
writer.write("\n");
}
private void typifiedResourcesDefinition() throws IOException {
{ // objects_of_type и operations_that_used_obj_as_resource
writer.write("n_resources_types = " + typeToN.size() + ";\n");
writeArray(writer, "objects_of_type", objectsOfType, ConversionUtil::setToString);
ArrayList<Set<Integer>> res = arrayOfIntegerSet(movingObjects.size());
for (int i = 0; i < operationTemplates.size(); i++) {
for (Integer typeNo : getNumbersOfResourcesTypes(operationTemplates.get(i))) {
for (int obj : objectsOfType.get(typeNo)) {
res.get(obj - 1).add(i + 1);
}
}
}
writeArray(writer, "operations_that_used_obj_as_resource", res, ConversionUtil::setToString);
writer.write("\n");
}
{ // main_obj_start_loc, is_moving_operation
ArrayList<Integer> mainObjStartLoc = new ArrayList<>();
ArrayList<Boolean> isMovingOp = new ArrayList<>();
for (OperationTemplate op : operationTemplates) {
boolean isMoored = false;
if ((op instanceof LoadingTemplate) && (((LoadingTemplate) op).getWithMooring())) {
isMoored = true;
}
if ((op instanceof MooringTemplate) && (!((MooringTemplate)op).isDirect())) {
isMoored = true;
}
mainObjStartLoc.add(locationNumberById.get(new Pair<>(op.getStartLocation().getId(), isMoored)));
isMovingOp.add((op instanceof MovingTemplate) || (op instanceof MooringTemplate));
}
writeArray(writer, "main_obj_start_loc", mainObjStartLoc, (Integer val) -> val + 1);
writeArray(writer, "is_moving_operation", isMovingOp);
writer.write("\n");
}
{ // counters, operations_resources_start_loc
ArrayList<Integer> counterType = new ArrayList<>();
ArrayList<Integer> operationOfCounter = new ArrayList<>();
ArrayList<Integer> requiredCounterValues = new ArrayList<>();
ArrayList<Set<Integer>> countersOfOperation = arrayOfIntegerSet(operationTemplates.size());
ArrayList<Integer> operationsResourcesStartLoc = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
Map<Integer, Integer> numberOfTypes = new TreeMap<>();
for (int type : getNumbersOfResourcesTypes(operationTemplates.get(i))) {
if (!numberOfTypes.containsKey(type)) {
numberOfTypes.put(type, 1);
} else {
numberOfTypes.put(type, numberOfTypes.get(type) + 1);
}
}
for (Map.Entry<Integer, Integer> p : numberOfTypes.entrySet()) {
counterType.add(p.getKey());
operationOfCounter.add(i);
requiredCounterValues.add(p.getValue());
countersOfOperation.get(i).add(counterType.size());
operationsResourcesStartLoc.add(locationNumberById.get(new Pair<>(operationTemplates.get(i).getStartLocation().getId(), false)));
}
}
writer.write("n_resources_counters = " + counterType.size() + ";\n");
writeArray(writer, "counter_type", counterType, (Integer val) -> val + 1);
writeArray(writer, "operation_of_counter", operationOfCounter, (Integer val) -> val + 1);
writeArray(writer, "required_counter_values", requiredCounterValues);
writeArray(writer, "operations_resources_start_loc", operationsResourcesStartLoc, (Integer val) -> val + 1);
writeArray(writer, "counters_of_operation", countersOfOperation, ConversionUtil::setToString);
}
}
/* С типизацией. */
void portToMiniZinc_2() throws IOException {
......@@ -848,7 +1122,7 @@ public class ConversionUtil {
writer = new FileWriter(fileName, false);
writer.write("n_intervals = " + n_intervals + ";\n");
writer.write("n_operations = " + task.getTemplates().size() + ";\n");
writer.write("n_operations = " + operationTemplates.size() + ";\n");
writer.write("n_locations = " + locationNumberById.size() + ";\n");
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
......@@ -856,11 +1130,12 @@ public class ConversionUtil {
movingObjectLocationDefinition();
initialLocations();
finalLocations();
weatherWindows();
conflictingOperationsOnStorageAndOnTypeOnMainObject();
operationsContinuity();
finalLocations();
presenceOfResourcesInLocation();
conflictingOperations();
typifiedResourcesDefinition();
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
......@@ -891,13 +1166,22 @@ public class ConversionUtil {
}
}
static public void portToMiniZinc_2(TaskCase task, String fileName) {
try {
Task taskData = new Task(task, fileName);
taskData.portToMiniZinc_2();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private static class OperationsComparator implements Comparator<Operation> {
public int compare(Operation op1, Operation op2) {
return Double.compare(op1.getStart(), op2.getStart());
}
}
static public void resolveMiniZincResults(TaskCase task, String fileName) {
public static void resolveMiniZincResults(TaskCase task, String fileName) {
ArrayList<Operation> operations = null;
Integer result = null;
......@@ -906,72 +1190,147 @@ public class ConversionUtil {
String line;
Map<String, ArrayList<ArrayList<String>>> arrays = new TreeMap<>();
while (((line = br.readLine()) != null)) {
line = line.trim();
if (line.equals("")) {
continue;
}
String regexpr = "^\\[.*]\\z";
if (line.matches(regexpr)) {
if (operations != null) {
continue;
int pos = 0;
while ((pos < line.length()) && (line.charAt(pos) != ' ')) {
pos++;
}
String []rawTokens = line.split("[\\s\\[\\],]");
ArrayList<String> tokens = new ArrayList<>();
for (String str : rawTokens) {
if (!str.isEmpty()) {
tokens.add(str);
String name = line.substring(0, pos);
if (name.equals("=====UNSATISFIABLE=====")) {
result = -1;
break;
}
if (name.equals("----------")) {
break;
}
final int n_intervals = (int)task.getPlanningInterval();
if (tokens.size() != (n_intervals + 2) * task.getTemplates().size()) {
throw new ParserException("Invalid length of \"op_status\"");
if (name.matches("\\d+")) {
if (result != null) {
continue;
}
result = Integer.parseInt(name);
continue;
}
operations = new ArrayList<>();
for (int i = 0; i < task.getTemplates().size(); i++) {
int duration = 0;
for (int j = 0; j < n_intervals + 2; j++) {
if (tokens.get(i * (n_intervals + 2) + j).equals("true")) {
duration++;
} else if (duration != 0) {
Operation op = new Operation();
op.setStart(j - duration - 1);
op.setDuration(duration);
op.setTemplate(task.getTemplates().get(i));
operations.add(op);
while ((pos < line.length()) && (line.charAt(pos) != '[') && (line.charAt(pos) != '{')) {
pos++;
}
int arrayFirstDim = ((int) task.getPlanningInterval()) + 2;
duration = 0;
if (line.charAt(pos) == '{') {
pos++;
int nextPos = pos;
while (line.charAt(nextPos) != '}') {
nextPos++;
}
arrayFirstDim = Integer.valueOf(line.substring(pos, nextPos).trim());
pos = nextPos + 1;
while (line.charAt(pos) != '[') {
pos++;
}
}
continue;
int pos2 = pos;
while ((pos2 < line.length()) && (line.charAt(pos2) != ']')) {
pos2++;
}
if (line.matches("\\d+")) {
if (result != null) {
continue;
String values = line.substring(pos + 1, pos2);
ArrayList<String> elements = new ArrayList<>();
for (String val : values.split(",")) {
elements.add(val.trim());
}
result = Integer.parseInt(line);
continue;
if ((arrayFirstDim != 0) && (elements.size() % arrayFirstDim == 0)) {
ArrayList<ArrayList<String>> res = new ArrayList<>();
for (int i = 0; i < elements.size(); i += arrayFirstDim) {
ArrayList<String> subRes = new ArrayList<>();
for (int j = 0; j < arrayFirstDim; j++) {
subRes.add(elements.get(i + j));
}
if (line.equals("=====UNSATISFIABLE=====")) {
result = -1;
res.add(subRes);
}
break;
arrays.put(name, res);
}
}
if (result == null) {
throw new ParserException("No result in input");
}
if (operations == null) {
if (!arrays.containsKey("op_status")) {
if (result == -1) {
operations = new ArrayList<>();
} else {
throw new ParserException("No \"op_status\" in input");
}
}
if (result != -1) {
operations = new ArrayList<>();
ArrayList<ArrayList<String>> opStatus = arrays.get("op_status");
ArrayList<OperationTemplate> templates = new ArrayList<>(task.getTemplates());
if (task.isTypified()) {
templates = Task.renumberOperations(task);
}
Map<Integer, OperationTemplate> operationById = new TreeMap<>();
for (OperationTemplate operation : task.getTemplates()) {
operationById.put(operation.getId(), operation);
}
Map<Integer, MovingObject> objByNo = new TreeMap<>();
{
Task t = new Task(task, "");
ArrayList<MovingObject> movingObjects = new ArrayList<>();
movingObjects.addAll(task.getShips());
movingObjects.addAll(task.getTows());
movingObjects.addAll(task.getEquipments());
for (MovingObject obj : movingObjects) {
objByNo.put(t.getMObjNumberById().get(obj.getId()), obj);
}
}
for (int opNo = 0; opNo < opStatus.size(); opNo++) {
int duration = 0;
for (int t = 0; t < opStatus.get(opNo).size(); t++) {
if (opStatus.get(opNo).get(t).equals("true")) {
duration++;
} else if (duration != 0) {
Operation op = new Operation();
op.setStart(t - duration - 1);
op.setDuration(duration);
op.setTemplate(operationById.get(templates.get(opNo).getId()));
if (task.isTypified()) {
op.setExecutor(ConversionUtil.getExecutor(templates.get(opNo)));
ArrayList<MovingObject> resources = new ArrayList<>();
// TODO ускорить.
ArrayList<ArrayList<String>> opOfResource = arrays.get("participation_as_resource");
for (int obj = 0; obj < opOfResource.size(); obj++) {
if (opOfResource.get(obj).get(t - 1).equals(Integer.toString(opNo + 1))) {
resources.add(objByNo.get(obj));
}
}
op.setResources(resources);
}
operations.add(op);
duration = 0;
}
}
}
}
operations.sort(new OperationsComparator());
task.setSolution(operations);
task.setSolution_result(result);
......
......@@ -22,9 +22,9 @@ public class LoadingEquipment extends MovingObject{
@Override
public String toString() {
String res = getId() + ";" + getName();
String res = getId() + "; " + getName();
if (getType().isPresent()) {
res += ";" + getType().getAsInt();
res += "; " + getType().getAsInt();
}
return res;
}
......
......@@ -95,13 +95,16 @@ public class LoadingTemplate extends OperationTemplate {
return cargo;
}
public LoadingTemplate(TransportShip loader, Berth berth, Storage storage, double intensity, int id) {
public LoadingTemplate(TransportShip loader, Berth berth, Storage storage, Cargo cargo,
List<Integer> resourcesTypes, boolean withMooring, double intensity, int id) {
super(id, berth);
this.loader = loader;
this.storage = storage;
this.resources = new ArrayList<>();
this.resourcesTypes = new ArrayList<>();
this.resourcesTypes = new ArrayList<>(resourcesTypes);
this.withMooring = withMooring;
this.intensity = intensity;
this.cargo = cargo;
}
public LoadingTemplate() {
......
package inport;
import java.io.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import static inport.Testing.solveTask_1;
import static inport.Testing.solveTask_2;
import static inport.Testing.test_1;
import inport.ConversionUtil.*;
public class Main {
......@@ -27,7 +32,12 @@ public class Main {
break;
}
String error = solveTask_1(task);
String error;
if (!task.isTypified()) {
error = solveTask_1(task);
} else {
error = solveTask_2(task);
}
long finish = System.currentTimeMillis();
System.out.println((finish - start) + " milliseconds");
......@@ -81,16 +91,29 @@ public class Main {
break;
}
case "debug" : {
String fileName = args[1];
String output = args[2];
String fileName = "experiment/in.ipp";
String solverResults = "temp_data/solver_results.txt";
String output = "experiment/debug_info.txt";
TaskCase task = new TaskCase();
try {
task.deserialize(fileName);
task.serialize(output);
} catch (IOException e) {
System.out.println(e.getMessage());
break;
}
String error = solveTask_2(task);
if (!error.isEmpty()) {
System.out.println("Error : " + error);
break;
} else {
task.serialize(fileName);
}
debugInfo(task, solverResults, output);
break;
}
case "testing" :
......@@ -100,4 +123,145 @@ public class Main {
System.out.println("Unknown type \"" + type + "\"");
}
}
private static void debugInfo(TaskCase task, String solverResults, String output) {
try (FileInputStream fstream = new FileInputStream(solverResults)) {
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
FileWriter writer = new FileWriter(output, false);
{
ArrayList<OperationTemplate> operations = new ArrayList<>(task.getTemplates());
if (task.isTypified()) {
operations = Task.renumberOperations(task);
}
writer.write("operations :\n");
int no = 1;
for (OperationTemplate op : operations) {
writer.write(" " + no + " " + op.toString() + "\n");
no++;
}
writer.write("\n");
}
Task t = new Task(task, "");
{
ArrayList<MovingObject> movingObjects = new ArrayList<>();
movingObjects.addAll(task.getShips());
movingObjects.addAll(task.getTows());
movingObjects.addAll(task.getEquipments());
Map<Integer, MovingObject> objByNo = new TreeMap<>();
for (MovingObject obj : movingObjects) {
objByNo.put(t.getMObjNumberById().get(obj.getId()), obj);
}
writer.write("moving_objects : \n");
for (int i = 0; i < movingObjects.size(); i++) {
writer.write(" " + (i + 1) + " " + objByNo.get(i).toString() + "\n");
}
writer.write("\n");
}
String line;
int linesNumber = 0;
while (((line = br.readLine()) != null)) {
line = line.trim();
if (line.equals("")) {
continue;
}
linesNumber++;
if (linesNumber <= 1) {
continue;
}
int pos = 0;
while ((pos < line.length()) && (line.charAt(pos) != ' ')) {
pos++;
}
String name = line.substring(0, pos);
if (name.equals("----------")) {
break;
}
while ((pos < line.length()) && (line.charAt(pos) != '[') && (line.charAt(pos) != '{')) {
pos++;
}
int arrayFirstDim = ((int) task.getPlanningInterval()) + 2;
if (line.charAt(pos) == '{') {
pos++;
int nextPos = pos;
while (line.charAt(nextPos) != '}') {
nextPos++;
}
arrayFirstDim = Integer.valueOf(line.substring(pos, nextPos).trim());
pos = nextPos + 1;
while (line.charAt(pos) != '[') {
pos++;
}
}
int pos2 = pos;
while ((pos2 < line.length()) && (line.charAt(pos2) != ']')) {
pos2++;
}
String values = line.substring(pos + 1, pos2);
ArrayList<String> elements = new ArrayList<>();
for (String val : values.split(",")) {
elements.add(val.trim());
}
if (name.equals("current_moving_operation")) {
ArrayList<ArrayList<Integer>> movingOpOfObj = t.getMovingOpOfObj();
for (int i = 0; i < elements.size(); i += arrayFirstDim) {
for (int j = 0; j < arrayFirstDim; j++) {
int val = Integer.valueOf(elements.get(i + j));
if (val != 0) {
elements.set(i + j, Integer.toString(movingOpOfObj.get(i / arrayFirstDim).get(val - 1)));
}
}
}
name = name + " *";
}
{ // bool to int
for (int i = 0; i < elements.size(); i++) {
if (elements.get(i).equals("true")) {
elements.set(i, "1");
}
if (elements.get(i).equals("false")) {
elements.set(i, "0");
}
}
}
int maxLength = 0;
for (String val : elements) {
maxLength = Math.max(maxLength, val.length());
}
if ((arrayFirstDim != 0) && (elements.size() % arrayFirstDim == 0)) {
writer.write(name + " :\n");
for (int i = 0; i < elements.size(); i += arrayFirstDim) {
writer.write(" ");
for (int j = 0; j < arrayFirstDim; j++) {
String val = elements.get(i + j);
for (int k = val.length(); k < maxLength; k++) {
writer.write(" ");
}
writer.write(val + " ");
}
writer.write("\n");
}
writer.write("\n");
}
}
writer.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
......@@ -4,6 +4,7 @@
*/
package inport;
import java.util.List;
import java.util.OptionalInt;
/**
......@@ -59,10 +60,11 @@ public class MooringTemplate extends TowUsingTemplate {
this.moorer = moorer;
}
public MooringTemplate(TransportShip moorer, Berth berth, double duration, boolean direct, int id) {
public MooringTemplate(TransportShip moorer, Berth berth, List<Integer> resourcesTypes, double duration, boolean direct, int id) {
super(duration, id, berth);
this.moorer = moorer;
this.direct = direct;
this.setResourcesTypes(resourcesTypes);
}
public MooringTemplate() {
......
......@@ -4,6 +4,7 @@
*/
package inport;
import java.util.List;
import java.util.OptionalInt;
/**
......@@ -60,10 +61,11 @@ public class MovingTemplate extends TowUsingTemplate {
this.moverType = moverType;
}
public MovingTemplate(MovingObject mover, Berth source, Berth destination, double duration, int id) {
public MovingTemplate(MovingObject mover, Berth source, Berth destination, List<Integer> resourcesTypes, double duration, int id) {
super(duration, id, source);
this.mover = mover;
this.destination = destination;
this.setResourcesTypes(resourcesTypes);
}
public MovingTemplate() {
......
......@@ -4,6 +4,8 @@
*/
package inport;
import java.util.List;
/**
*
* @author topazh_ag
......@@ -13,6 +15,22 @@ public class Operation {
private OperationTemplate template;
private double start;
private double duration;
private MovingObject executor;
private List<MovingObject> resources;
public List<MovingObject> getResources() {
return resources;
}
public void setResources(List<MovingObject> resources) {
this.resources = resources;
}
public MovingObject getExecutor() {
return executor;
}
public void setExecutor(MovingObject executor) {
this.executor = executor;
}
/**
* Get the value of duration
......@@ -75,8 +93,25 @@ public class Operation {
@Override
public String toString() {
return template.getId() + "; R; " + start + "; " + duration;
if (executor == null) {
executor = ConversionUtil.getExecutor(template);
}
if (resources == null) {
resources = ConversionUtil.getResources(template);
}
StringBuilder sb = new StringBuilder();
sb.append(template.getId()).append("; R; ").append(start).append("; ").append(duration);
sb.append(" (").append(executor.getId()).append(" [");
boolean isFirst = true;
for (MovingObject obj : resources) {
if (isFirst) {
isFirst = false;
} else {
sb.append(", ");
}
sb.append(obj.getId());
}
sb.append("])");
return sb.toString();
}
}
......@@ -26,6 +26,14 @@ public class Testing {
ConversionUtil::resolveMiniZincResults);
}
public static String solveTask_2(TaskCase task) {
return solveTask(
task,
"conversion_2.mzn",
ConversionUtil::portToMiniZinc_2,
ConversionUtil::resolveMiniZincResults);
}
/* Возвращает описание ошибки, если ошибки не было, то пустую строку. */
public static String solveTask(TaskCase task,
String constraintName,
......@@ -63,6 +71,13 @@ public class Testing {
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = br.lines().collect(Collectors.joining("\n"));
BufferedReader br2 = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String errors = br.lines().collect(Collectors.joining("\n"));
System.out.println("output : " + output);
System.out.println("errors : " + errors);
if (output.trim().equals("=====UNSATISFIABLE=====")) {
task.setSolution(new ArrayList<>());
task.setSolution_result(-1);
......@@ -72,7 +87,7 @@ public class Testing {
} catch (UncheckedIOException | IOException | InterruptedException | ParserException ex) {
return ex.getMessage();
} finally {
removeDirectory(directory);
// removeDirectory(directory);
}
return "";
}
......
......@@ -21,9 +21,9 @@ public class Tow extends MovingObject {
@Override
public String toString() {
String res = getId() + ";" + getName() + ";1000000";
String res = getId() + "; " + getName() + "; 1000000";
if (getType().isPresent()) {
res += ";" + getType().getAsInt();
res += "; " + getType().getAsInt();
}
return res;
}
......
......@@ -32,9 +32,9 @@ public class TransportShip extends MovingObject {
@Override
public String toString() {
String res = getId() + ";" + getName() + ";" + cargoMax;
String res = getId() + "; " + getName() + "; " + cargoMax;
if (getType().isPresent()) {
res += ";" + getType().getAsInt();
res += "; " + getType().getAsInt();
}
return res;
}
......
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