Commit 00fb0844 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Refactoring.

parent d233ebf1
...@@ -3,7 +3,11 @@ ...@@ -3,7 +3,11 @@
rm -f raw_result.txt rm -f raw_result.txt
rm -f result.txt rm -f result.txt
java -classpath "../out/production/Conversion" inport.Main to_MiniZinc in.ipp conversion_0.dzn java -classpath "../out/production/Conversion" inport.Main to_MiniZinc_0 in.ipp conversion_0.dzn
mzn2fzn -o model.fzn "../constraints/conversion_0.mzn" conversion_0.dzn
N_LINES=$(wc -l model.fzn)
echo "Model size : $N_LINES"
START=$(date +%s.%N) START=$(date +%s.%N)
...@@ -12,6 +16,6 @@ minizinc --solver Gecode "../constraints/conversion_0.mzn" conversion_0.dzn >> r ...@@ -12,6 +16,6 @@ minizinc --solver Gecode "../constraints/conversion_0.mzn" conversion_0.dzn >> r
END=$(date +%s.%N) END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc) DIFF=$(echo "$END - $START" | bc)
echo $(DIFF) echo $DIFF
java -classpath "../out/production/Conversion" inport.Main resolve_result in.ipp raw_result.txt result.txt java -classpath "../out/production/Conversion" inport.Main resolve_result in.ipp raw_result.txt result.txt
...@@ -257,24 +257,46 @@ public class ConversionUtil { ...@@ -257,24 +257,46 @@ public class ConversionUtil {
return true; return true;
} }
static public void portToMiniZinc(TaskCase task, String fileName) throws IOException { private static class Task {
try(FileWriter writer = new FileWriter(fileName, false)) { private FileWriter writer = null;
int n_intervals = (int)task.getPlanningInterval(); private final String fileName;
writer.write("n_intervals = " + n_intervals + ";\n"); private final TaskCase task;
writer.write("n_operations = " + task.getTemplates().size() + ";\n");
private final int n_intervals;
ArrayList<Berth> berths = new ArrayList<>(task.getBerths()); private final ArrayList<Berth> berths;
Map<Pair<Integer, Boolean>, Integer> locationNumberById = new TreeMap<>(new PairComparator());
private final Map<Pair<Integer, Boolean>, Integer> locationNumberById;
private final BiFunction<Integer, Boolean, Integer> getLocNById;
private final ArrayList<MovingObject> movingObjects;
private final Function<MovingObject, Integer> mObjToN;
private final ArrayList<OperationTemplate> operationTemplates;
private final ArrayList<Storage> storages;
private final ArrayList<Cargo> cargoes;
private final int nObjWithStorage;
private final Map<Integer, Integer> storNById;
private final Map<Integer, Integer> cargoNById;
Task(TaskCase task, String fileName) {
this.fileName = fileName;
this.task = task;
n_intervals = (int)task.getPlanningInterval();
berths = new ArrayList<>(task.getBerths());
locationNumberById = new TreeMap<>(new PairComparator());
for (Berth berth : berths) { for (Berth berth : berths) {
locationNumberById.put(new Pair<>(berth.getId(), false), locationNumberById.size()); locationNumberById.put(new Pair<>(berth.getId(), false), locationNumberById.size());
locationNumberById.put(new Pair<>(berth.getId(), true), locationNumberById.size()); locationNumberById.put(new Pair<>(berth.getId(), true), locationNumberById.size());
} }
writer.write("n_locations = " + locationNumberById.size() + ";\n");
BiFunction<Integer, Boolean, Integer> getLocNById = getLocNById = (Integer id, Boolean isMoored) -> locationNumberById.get(new Pair<>(id, isMoored));
(Integer id, Boolean isMoored) -> locationNumberById.get(new Pair<>(id, isMoored));
ArrayList<MovingObject> movingObjects = new ArrayList<>(); movingObjects = new ArrayList<>();
Map<Integer, Integer> mObjNumberById = new TreeMap<>(); Map<Integer, Integer> mObjNumberById = new TreeMap<>();
for (MovingObject obj : task.getShips()) { for (MovingObject obj : task.getShips()) {
mObjNumberById.put(obj.getId(), movingObjects.size()); mObjNumberById.put(obj.getId(), movingObjects.size());
...@@ -288,365 +310,421 @@ public class ConversionUtil { ...@@ -288,365 +310,421 @@ public class ConversionUtil {
mObjNumberById.put(obj.getId(), movingObjects.size()); mObjNumberById.put(obj.getId(), movingObjects.size());
movingObjects.add(obj); movingObjects.add(obj);
} }
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
writer.write("\n");
Function<MovingObject, Integer> mObjToN = (MovingObject obj) -> mObjNumberById.get(obj.getId()); mObjToN = (MovingObject obj) -> mObjNumberById.get(obj.getId());
operationTemplates = new ArrayList<>(task.getTemplates());
ArrayList<OperationTemplate> operationTemplates = new ArrayList<>(task.getTemplates());
{ // Операции прибытия/отбытия в локацию. (В том числе и швартовка.)
ArrayList<ArrayList<ArrayList<Integer>>> arrivalOp = new ArrayList<>();
ArrayList<ArrayList<ArrayList<Integer>>> departureOp = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) {
arrivalOp.add(new ArrayList<>());
departureOp.add(new ArrayList<>());
for (int j = 0; j < locationNumberById.size(); j++) {
arrivalOp.get(i).add(new ArrayList<>());
departureOp.get(i).add(new ArrayList<>());
}
}
for (int i = 0; i < operationTemplates.size(); i++) { storages = new ArrayList<>(task.getStorages());
if (operationTemplates.get(i) instanceof MovingTemplate) { cargoes = new ArrayList<>(task.getCargoes());
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
ArrayList<Integer> movingObjN = new ArrayList<>(); storNById = new TreeMap<>();
for (MovingObject obj : op.getResources()) { for (int i = 0; i < storages.size(); i++) {
movingObjN.add(mObjToN.apply(obj)); storNById.put(storages.get(i).getId(), i);
} }
movingObjN.add(mObjToN.apply(op.getMover()));
for (Integer n : movingObjN) { cargoNById = new TreeMap<>();
arrivalOp .get(n).get(getLocNById.apply(op.getDestination().getId(), false)).add(i + 1); for (int i = 0; i < task.getCargoes().size(); i++) {
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), false)).add(i + 1); cargoNById.put(cargoes.get(i).getId(), i);
} }
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
ArrayList<Integer> movingObjN = new ArrayList<>(); nObjWithStorage = movingObjects.size() + storages.size();
for (MovingObject obj : op.getResources()) { }
movingObjN.add(mObjToN.apply(obj));
}
movingObjN.add(mObjToN.apply(op.getMoorer()));
for (Integer n : movingObjN) { /* Операции прибытия/отбытия в локацию. (В том числе и швартовка.) */
arrivalOp .get(n).get(getLocNById.apply(op.getStartLocation().getId(), op.isDirect())).add(i + 1); private void arrivalAndDepartureOperations() throws IOException {
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), !op.isDirect())).add(i + 1); ArrayList<ArrayList<ArrayList<Integer>>> arrivalOp = new ArrayList<>();
} ArrayList<ArrayList<ArrayList<Integer>>> departureOp = new ArrayList<>();
} for (int i = 0; i < movingObjects.size(); i++) {
} arrivalOp.add(new ArrayList<>());
write2DArrayOfSetAs3DArray(writer, "arrival_op", arrivalOp); departureOp.add(new ArrayList<>());
write2DArrayOfSetAs3DArray(writer, "departure_op", departureOp); for (int j = 0; j < locationNumberById.size(); j++) {
writer.write("\n"); arrivalOp.get(i).add(new ArrayList<>());
} departureOp.get(i).add(new ArrayList<>());
{ // Начальные положения объектов.
ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
for (MovingObjectState state : task.getVesselInitialState()) {
initialStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
}
writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1);
writer.write("\n");
}
{ // Окна погоды.
ArrayList<Integer> bw_op = new ArrayList<>();
ArrayList<Integer> bw_start = new ArrayList<>();
ArrayList<Integer> bw_fin = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
final int id = i;
operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> {
bw_op.add(id + 1);
bw_start.add((int)Math.floor(start));
bw_fin.add((int)Math.ceil(start + duration));
}
);
} }
writer.write("n_bad_weather_windows = " + bw_op.size() + ";\n");
writeArray(writer, "bw_op", bw_op);
writeArray(writer, "bw_start", bw_start);
writeArray(writer, "bw_fin", bw_fin);
writer.write("\n");
} }
{ // Непрерывность перемещения и швартовки.
ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0);
ArrayList<Boolean> isMovingObj = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration())); for (int i = 0; i < operationTemplates.size(); i++) {
isMovingObj.add(true); if (operationTemplates.get(i) instanceof MovingTemplate) {
} else if (operationTemplates.get(i) instanceof MooringTemplate) { MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
MooringTemplate op = (MooringTemplate) operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration())); ArrayList<Integer> movingObjN = new ArrayList<>();
isMovingObj.add(true); for (MovingObject obj : op.getResources()) {
} else { movingObjN.add(mObjToN.apply(obj));
isMovingObj.add(false);
} }
} movingObjN.add(mObjToN.apply(op.getMover()));
writeArray(writer, "operations_duration", operationsDuration);
writeArray(writer, "is_continuous_operation", isMovingObj);
}
{ // Конечные положения объектов.
ArrayList<Integer> finalStates = integerArray(movingObjects.size(), -1);
for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
}
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1);
}
{ // Наличие всех ресурсов на месте, в том числе и самого корабля.
// TODO ресурсы покрываются "Конфликтующими операциями" (кроме наличия корабля на месте).
ArrayList<Set<Integer>> operationsResources = new ArrayList<>();
ArrayList<Integer> operationsStartLoc = integerArray(operationTemplates.size(), 0);
for (int i = 0; i < operationTemplates.size(); i++) {
operationsResources.add(new TreeSet<>());
if (operationTemplates.get(i) instanceof MovingTemplate) { // Перемещение.
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMover()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), false) + 1);
} else if (operationTemplates.get(i) instanceof MooringTemplate) { // Швартовка.
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMoorer()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), !op.isDirect()) + 1);
} else if (operationTemplates.get(i) instanceof LoadingTemplate) { // Погрузка.
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
Set<Integer> s = new TreeSet<>(); for (Integer n : movingObjN) {
s.add(mObjToN.apply(op.getLoader()) + 1); arrivalOp .get(n).get(getLocNById.apply(op.getDestination().getId(), false)).add(i + 1);
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), false)).add(i + 1);
}
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
// TODO ресурсы у операции погрузки. ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN.apply(obj));
}
movingObjN.add(mObjToN.apply(op.getMoorer()));
operationsResources.set(i, s); for (Integer n : movingObjN) {
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1); arrivalOp .get(n).get(getLocNById.apply(op.getStartLocation().getId(), op.isDirect())).add(i + 1);
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), !op.isDirect())).add(i + 1);
} }
// TODO швартовка, погрузка.
} }
writeArray(writer, "operations_start_loc", operationsStartLoc);
//writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString);
writeArrayOfSetAs2DArray(writer, "operations_resources", operationsResources);
writer.write("\n");
} }
{ // Конфликтующие операции. write2DArrayOfSetAs3DArray(writer, "arrival_op", arrivalOp);
ArrayList<Pair<Integer, Integer>> conflictingPairs = new ArrayList<>(); write2DArrayOfSetAs3DArray(writer, "departure_op", departureOp);
for (int i = 0; i < operationTemplates.size(); i++) { writer.write("\n");
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)); /* Начальные положения объектов. */
} private void initialLocations() throws IOException {
} ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
} for (MovingObjectState state : task.getVesselInitialState()) {
writer.write("n_conflicting_op = " + conflictingPairs.size() + ";\n"); initialStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
writeArray(writer, "confl_op_1", conflictingPairs, Pair::getKey);
writeArray(writer, "confl_op_2", conflictingPairs, Pair::getValue);
writer.write("\n");
} }
// Грузоообработка. writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1);
writer.write("\n");
}
ArrayList<Storage> storages = new ArrayList<>(task.getStorages()); /* Окна погоды. */
ArrayList<Cargo> cargoes = new ArrayList<>(task.getCargoes()); private void weatherWindows() throws IOException {
ArrayList<Integer> bw_op = new ArrayList<>();
ArrayList<Integer> bw_start = new ArrayList<>();
ArrayList<Integer> bw_fin = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
final int id = i;
operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> {
bw_op.add(id + 1);
bw_start.add((int)Math.floor(start));
bw_fin.add((int)Math.ceil(start + duration));
}
);
}
writer.write("n_bad_weather_windows = " + bw_op.size() + ";\n");
writeArray(writer, "bw_op", bw_op);
writeArray(writer, "bw_start", bw_start);
writeArray(writer, "bw_fin", bw_fin);
writer.write("\n");
}
Map<Integer, Integer> storNById = new TreeMap<>(); /* Непрерывность перемещения и швартовки. */
for (int i = 0; i < storages.size(); i++) { private void operationsContinuity() throws IOException {
storNById.put(storages.get(i).getId(), i); ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0);
ArrayList<Boolean> isMovingObj = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate) operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else {
isMovingObj.add(false);
}
} }
writeArray(writer, "operations_duration", operationsDuration);
writeArray(writer, "is_continuous_operation", isMovingObj);
}
Map<Integer, Integer> cargoNById = new TreeMap<>(); /* Конечные положения объектов. */
for (int i = 0; i < task.getCargoes().size(); i++) { private void finalLocations() throws IOException {
cargoNById.put(cargoes.get(i).getId(), i); ArrayList<Integer> finalStates = integerArray(movingObjects.size(), -1);
for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
} }
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1);
}
int nObjWithStorage = movingObjects.size() + storages.size(); /* Наличие всех ресурсов на месте, в том числе и самого корабля. */
private void presenceOfResourcesInLocation() throws IOException {
// TODO ресурсы покрываются "Конфликтующими операциями" (кроме наличия корабля на месте).
ArrayList<Set<Integer>> operationsResources = new ArrayList<>();
ArrayList<Integer> operationsStartLoc = integerArray(operationTemplates.size(), 0);
for (int i = 0; i < operationTemplates.size(); i++) {
operationsResources.add(new TreeSet<>());
if (operationTemplates.get(i) instanceof MovingTemplate) { // Перемещение.
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMover()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), false) + 1);
} else if (operationTemplates.get(i) instanceof MooringTemplate) { // Швартовка.
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMoorer()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), !op.isDirect()) + 1);
} else if (operationTemplates.get(i) instanceof LoadingTemplate) { // Погрузка.
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n"); Set<Integer> s = new TreeSet<>();
writer.write("n_cargo_types = " + cargoes.size() + ";\n"); s.add(mObjToN.apply(op.getLoader()) + 1);
{ // Ограничения на вместимость. // TODO ресурсы у операции погрузки.
ArrayList<Integer> maxStorageVol = new ArrayList<>();
for (MovingObject obj : movingObjects) { operationsResources.set(i, s);
if (obj instanceof TransportShip) { operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1);
maxStorageVol.add((int)Math.ceil(((TransportShip) obj).getCargoMax()));
} else {
maxStorageVol.add(0);
}
} }
for (Storage storage : storages) { // TODO швартовка, погрузка.
maxStorageVol.add((int)Math.ceil(storage.getVolume())); }
writeArray(writer, "operations_start_loc", operationsStartLoc);
//writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString);
writeArrayOfSetAs2DArray(writer, "operations_resources", operationsResources);
writer.write("\n");
}
/* Конфликтующие операции. */
private void conflictingOperations() 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 (!isCompatible(operationTemplates.get(i), operationTemplates.get(j))) {
conflictingPairs.add(new Pair<>(i + 1, j + 1));
}
} }
writeArray(writer, "max_storage_vol", maxStorageVol);
writer.write("\n");
} }
{ // Граничные условия хранилищ. writer.write("n_conflicting_op = " + conflictingPairs.size() + ";\n");
// TODO выделить отдельно общий код. writeArray(writer, "confl_op_1", conflictingPairs, Pair::getKey);
ArrayList<ArrayList<Integer>> initialStorageVol = new ArrayList<>(); writeArray(writer, "confl_op_2", conflictingPairs, Pair::getValue);
ArrayList<ArrayList<Integer>> finalStorageVol = new ArrayList<>(); writer.write("\n");
}
/* Ограничения на вместимость. */
private void maxStorageVolume() throws IOException {
ArrayList<Integer> maxStorageVol = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) { for (MovingObject obj : movingObjects) {
initialStorageVol.add(integerArray(cargoes.size(), 0)); if (obj instanceof TransportShip) {
finalStorageVol .add(integerArray(cargoes.size(), -1)); maxStorageVol.add((int)Math.ceil(((TransportShip) obj).getCargoMax()));
} else {
maxStorageVol.add(0);
} }
for (StorageState st : task.getStorageInitialState()) { }
int cargoN = cargoNById.get(st.getCargo().getId()); for (Storage storage : storages) {
int val = (int)st.getCargoState(); maxStorageVol.add((int)Math.ceil(storage.getVolume()));
}
if (st.getStorage() instanceof Storage) { writeArray(writer, "max_storage_vol", maxStorageVol);
Storage storage = (Storage) st.getStorage(); writer.write("\n");
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(); private void boundaryStorageStates() throws IOException {
initialStorageVol.get(mObjToN.apply(ship)).set(cargoN, val); // 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()); for (StorageState st : task.getStorageEndState()) {
int val = (int)st.getCargoState(); int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage(); if (st.getStorage() instanceof Storage) {
int stN = storNById.get(storage.getId()); Storage storage = (Storage) st.getStorage();
finalStorageVol.get(movingObjects.size() + stN).set(cargoN, val); int stN = storNById.get(storage.getId());
} else if (st.getStorage() instanceof TransportShip) { finalStorageVol.get(movingObjects.size() + stN).set(cargoN, val);
TransportShip ship = (TransportShip) st.getStorage(); } else if (st.getStorage() instanceof TransportShip) {
finalStorageVol.get(mObjToN.apply(ship)).set(cargoN, val); 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); write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol);
} write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol);
{ // Потоки грузов. }
ArrayList<ArrayList<ArrayList<Integer>>> cargoFlows = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) { /* Потоки грузов. */
cargoFlows.add(new ArrayList<>()); private void cargoFlows() throws IOException {
for (int j = 0; j < n_intervals + 2; j++) { ArrayList<ArrayList<ArrayList<Integer>>> cargoFlows = new ArrayList<>();
cargoFlows.get(i).add(new ArrayList<>()); for (int i = 0; i < nObjWithStorage; i++) {
for (int k = 0; k < cargoes.size(); k++) { cargoFlows.add(new ArrayList<>());
cargoFlows.get(i).get(j).add(0); for (int j = 0; j < n_intervals + 2; j++) {
} cargoFlows.get(i).add(new ArrayList<>());
for (int k = 0; k < cargoes.size(); k++) {
cargoFlows.get(i).get(j).add(0);
} }
} }
for (CargoFlow flow : task.getCargoFlows()) { }
int storageN = storNById.get(flow.getStorage().getId()); for (CargoFlow flow : task.getCargoFlows()) {
int cargoN = cargoNById.get(flow.getCargo().getId()); int storageN = storNById.get(flow.getStorage().getId());
for (int i = 1; i < n_intervals + 2; i++) { int cargoN = cargoNById.get(flow.getCargo().getId());
cargoFlows.get(storageN + movingObjects.size()).get(i).set(cargoN, (int)flow.getCurrentValue(i - 0.1)); for (int i = 1; i < n_intervals + 2; i++) {
} cargoFlows.get(storageN + movingObjects.size()).get(i).set(cargoN, (int)flow.getCurrentValue(i - 0.1));
} }
writer.write("cargo_flows = array3d(1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types, ["); }
boolean isFirst = true; writer.write("cargo_flows = array3d(1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types, [");
for (int i = 0; i < nObjWithStorage; i++) { boolean isFirst = true;
for (int j = 0; j < n_intervals + 2; j++) { for (int i = 0; i < nObjWithStorage; i++) {
for (int k = 0; k < cargoes.size(); k++) { for (int j = 0; j < n_intervals + 2; j++) {
if (isFirst) { for (int k = 0; k < cargoes.size(); k++) {
isFirst = false; if (isFirst) {
} else { isFirst = false;
writer.write(", "); } else {
} writer.write(", ");
writer.write(cargoFlows.get(i).get(j).get(k).toString());
} }
writer.write(cargoFlows.get(i).get(j).get(k).toString());
} }
} }
writer.write("]);\n\n");
} }
{ // Грузовые операции со всеми хранилищами. writer.write("]);\n\n");
ArrayList<ArrayList<ArrayList<Integer>>> involvedOperations = new ArrayList<>(); }
ArrayList<Integer> loadingOpDelta = new ArrayList<>();
ArrayList<Integer> loadingOpN = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) { /* Грузовые операции со всеми хранилищами. */
involvedOperations.add(new ArrayList<>()); private void cargoOperations() throws IOException {
for (int j = 0; j < cargoes.size(); j++) { ArrayList<ArrayList<ArrayList<Integer>>> involvedOperations = new ArrayList<>();
involvedOperations.get(i).add(new ArrayList<>()); ArrayList<Integer> loadingOpDelta = new ArrayList<>();
} ArrayList<Integer> loadingOpN = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) {
involvedOperations.add(new ArrayList<>());
for (int j = 0; j < cargoes.size(); j++) {
involvedOperations.get(i).add(new ArrayList<>());
} }
}
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) { if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i); LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
int storageN = storNById.get(op.getStorage().getId()); int storageN = storNById.get(op.getStorage().getId());
int shipN = mObjToN.apply(op.getLoader()); int shipN = mObjToN.apply(op.getLoader());
int cargoN = cargoNById.get(op.getStorage().getCargo().getId());// TODO в TaskCase пока не реализовано, пересмотреть. int cargoN = cargoNById.get(op.getStorage().getCargo().getId());// TODO в TaskCase пока не реализовано, пересмотреть.
loadingOpDelta.add(-(int)op.getIntensity()); loadingOpDelta.add(-(int)op.getIntensity());
loadingOpN.add(i); loadingOpN.add(i);
involvedOperations.get(storageN + movingObjects.size()).get(cargoN).add(loadingOpDelta.size()); involvedOperations.get(storageN + movingObjects.size()).get(cargoN).add(loadingOpDelta.size());
loadingOpDelta.add((int)op.getIntensity()); loadingOpDelta.add((int)op.getIntensity());
loadingOpN.add(i); loadingOpN.add(i);
involvedOperations.get(shipN).get(cargoN).add(loadingOpDelta.size()); involvedOperations.get(shipN).get(cargoN).add(loadingOpDelta.size());
}
} }
writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n");
// write2DArrayOfSet(writer, "involved_operations", involvedOperations);
write2DArrayOfSetAs3DArray(writer, "involved_operations", involvedOperations);
writeArray(writer, "loading_op_delta", loadingOpDelta);
writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1);
writer.write("\n");
} }
{ // Ограничение на необходимость полезной операции между движениями к одному пункту назначения. writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n");
ArrayList<Set<Integer>> objUsefulOperations = new ArrayList<>(); // write2DArrayOfSet(writer, "involved_operations", involvedOperations);
write2DArrayOfSetAs3DArray(writer, "involved_operations", involvedOperations);
writeArray(writer, "loading_op_delta", loadingOpDelta);
writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1);
writer.write("\n");
}
/* Ограничение на необходимость полезной операции между движениями к одному пункту назначения. */
private void constraintOnUsefulOperationBetweenMovements() throws IOException {
ArrayList<Set<Integer>> objUsefulOperations = new ArrayList<>();
ArrayList<Set<Integer>> movingOpOfObj = new ArrayList<>(); ArrayList<Set<Integer>> movingOpOfObj = new ArrayList<>();
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) -> BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) ->
objUsefulOperations.get(mObjToN.apply(obj)).add(op + 1); objUsefulOperations.get(mObjToN.apply(obj)).add(op + 1);
for (int i = 0; i < movingObjects.size(); i++) { for (int i = 0; i < movingObjects.size(); i++) {
movingOpOfObj.add(new TreeSet<>()); movingOpOfObj.add(new TreeSet<>());
objUsefulOperations.add(new TreeSet<>()); objUsefulOperations.add(new TreeSet<>());
} }
for (int i = 0; i < operationTemplates.size(); i++) { for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i); OperationTemplate t = operationTemplates.get(i);
if (t instanceof MovingTemplate) { if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t; MovingTemplate op = (MovingTemplate)t;
int id = mObjToN.apply(op.getMover()); int id = mObjToN.apply(op.getMover());
movingOpOfObj.get(id).add(i + 1); movingOpOfObj.get(id).add(i + 1);
for (MovingObject obj : op.getResources()) { for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i); addUsOp.accept(obj, i);
} }
} else if (t instanceof MooringTemplate) { } else if (t instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)t; MooringTemplate op = (MooringTemplate)t;
int id = mObjToN.apply(op.getMoorer()); int id = mObjToN.apply(op.getMoorer());
movingOpOfObj.get(id).add(i + 1); movingOpOfObj.get(id).add(i + 1);
for (MovingObject obj : op.getResources()) { for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i); addUsOp.accept(obj, i);
} }
if (!op.isDirect()) { // Отшвартовка. if (!op.isDirect()) { // Отшвартовка.
addUsOp.accept(op.getMoorer(), i); addUsOp.accept(op.getMoorer(), i);
}
} else if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate)t;
addUsOp.accept(op.getLoader(), i);
} }
} else if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate)t;
addUsOp.accept(op.getLoader(), i);
} }
}
writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations); writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations);
writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj); writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj);
writer.write("\n");
}
void portToMiniZinc_0() throws IOException {
try {
writer = new FileWriter(fileName, false);
writer.write("n_intervals = " + n_intervals + ";\n");
writer.write("n_operations = " + task.getTemplates().size() + ";\n");
writer.write("n_locations = " + locationNumberById.size() + ";\n");
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
writer.write("\n"); writer.write("\n");
arrivalAndDepartureOperations();
initialLocations();
weatherWindows();
operationsContinuity();
finalLocations();
presenceOfResourcesInLocation();
conflictingOperations();
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
maxStorageVolume();
boundaryStorageStates();
cargoFlows();
cargoOperations();
constraintOnUsefulOperationBetweenMovements();
} finally {
if (writer != null) {
writer.close();
}
} }
} }
} }
static public void portToMiniZinc_0(TaskCase task, String fileName) throws IOException {
Task taskData = new Task(task, fileName);
taskData.portToMiniZinc_0();
}
static public void resolveMiniZincResults(TaskCase task, String fileName) throws IOException, ParserException { static public void resolveMiniZincResults(TaskCase task, String fileName) throws IOException, ParserException {
List<Operation> operations = null; List<Operation> operations = null;
Integer result = null; Integer result = null;
......
...@@ -11,13 +11,13 @@ public class Main { ...@@ -11,13 +11,13 @@ public class Main {
String type = args[0]; String type = args[0];
switch (type) { switch (type) {
case "to_MiniZinc" : { case "to_MiniZinc_0" : {
String input = args[1]; String input = args[1];
String output = args[2]; String output = args[2];
TaskCase task = new TaskCase(); TaskCase task = new TaskCase();
try { try {
task.deserialize(input); task.deserialize(input);
ConversionUtil.portToMiniZinc(task, output); ConversionUtil.portToMiniZinc_0(task, output);
} catch (IOException ex) { } catch (IOException ex) {
System.out.println(ex.getMessage()); System.out.println(ex.getMessage());
} }
......
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