From 00fb084498aa505604b3e7aec8860851c29a6e6c Mon Sep 17 00:00:00 2001 From: Vlad_kv Date: Mon, 3 Dec 2018 08:29:24 +0300 Subject: [PATCH] Refactoring. --- experiment/run.sh | 8 +- src/inport/ConversionUtil.java | 688 ++++++++++++++++++--------------- src/inport/Main.java | 4 +- 3 files changed, 391 insertions(+), 309 deletions(-) diff --git a/experiment/run.sh b/experiment/run.sh index 162fa86..ebbfd9b 100755 --- a/experiment/run.sh +++ b/experiment/run.sh @@ -3,7 +3,11 @@ rm -f raw_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) @@ -12,6 +16,6 @@ minizinc --solver Gecode "../constraints/conversion_0.mzn" conversion_0.dzn >> r END=$(date +%s.%N) 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 diff --git a/src/inport/ConversionUtil.java b/src/inport/ConversionUtil.java index 61eb49e..c0aa9de 100644 --- a/src/inport/ConversionUtil.java +++ b/src/inport/ConversionUtil.java @@ -257,24 +257,46 @@ public class ConversionUtil { 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(); - writer.write("n_intervals = " + n_intervals + ";\n"); - writer.write("n_operations = " + task.getTemplates().size() + ";\n"); - - ArrayList berths = new ArrayList<>(task.getBerths()); - Map, Integer> locationNumberById = new TreeMap<>(new PairComparator()); + private static class Task { + private FileWriter writer = null; + private final String fileName; + private final TaskCase task; + + private final int n_intervals; + private final ArrayList berths; + + private final Map, Integer> locationNumberById; + private final BiFunction getLocNById; + + private final ArrayList movingObjects; + private final Function mObjToN; + + private final ArrayList operationTemplates; + + private final ArrayList storages; + private final ArrayList cargoes; + + private final int nObjWithStorage; + + private final Map storNById; + private final Map 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) { locationNumberById.put(new Pair<>(berth.getId(), false), locationNumberById.size()); locationNumberById.put(new Pair<>(berth.getId(), true), locationNumberById.size()); } - writer.write("n_locations = " + locationNumberById.size() + ";\n"); - BiFunction getLocNById = - (Integer id, Boolean isMoored) -> locationNumberById.get(new Pair<>(id, isMoored)); + getLocNById = (Integer id, Boolean isMoored) -> locationNumberById.get(new Pair<>(id, isMoored)); - ArrayList movingObjects = new ArrayList<>(); + movingObjects = new ArrayList<>(); Map mObjNumberById = new TreeMap<>(); for (MovingObject obj : task.getShips()) { mObjNumberById.put(obj.getId(), movingObjects.size()); @@ -288,365 +310,421 @@ public class ConversionUtil { mObjNumberById.put(obj.getId(), movingObjects.size()); movingObjects.add(obj); } - writer.write("n_moving_obj = " + movingObjects.size() + ";\n"); - writer.write("\n"); - Function mObjToN = (MovingObject obj) -> mObjNumberById.get(obj.getId()); - - ArrayList operationTemplates = new ArrayList<>(task.getTemplates()); - { // Операции прибытия/отбытия в локацию. (В том числе и швартовка.) - ArrayList>> arrivalOp = new ArrayList<>(); - ArrayList>> 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<>()); - } - } + mObjToN = (MovingObject obj) -> mObjNumberById.get(obj.getId()); + operationTemplates = new ArrayList<>(task.getTemplates()); - for (int i = 0; i < operationTemplates.size(); i++) { - if (operationTemplates.get(i) instanceof MovingTemplate) { - MovingTemplate op = (MovingTemplate)operationTemplates.get(i); + storages = new ArrayList<>(task.getStorages()); + cargoes = new ArrayList<>(task.getCargoes()); - ArrayList movingObjN = new ArrayList<>(); - for (MovingObject obj : op.getResources()) { - movingObjN.add(mObjToN.apply(obj)); - } - movingObjN.add(mObjToN.apply(op.getMover())); + storNById = new TreeMap<>(); + for (int i = 0; i < storages.size(); i++) { + storNById.put(storages.get(i).getId(), i); + } - for (Integer n : movingObjN) { - 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); + cargoNById = new TreeMap<>(); + for (int i = 0; i < task.getCargoes().size(); i++) { + cargoNById.put(cargoes.get(i).getId(), i); + } - ArrayList movingObjN = new ArrayList<>(); - for (MovingObject obj : op.getResources()) { - movingObjN.add(mObjToN.apply(obj)); - } - movingObjN.add(mObjToN.apply(op.getMoorer())); + nObjWithStorage = movingObjects.size() + storages.size(); + } - for (Integer n : movingObjN) { - 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); - } - } - } - write2DArrayOfSetAs3DArray(writer, "arrival_op", arrivalOp); - write2DArrayOfSetAs3DArray(writer, "departure_op", departureOp); - writer.write("\n"); - } - { // Начальные положения объектов. - ArrayList 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 bw_op = new ArrayList<>(); - ArrayList bw_start = new ArrayList<>(); - ArrayList 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)); - } - ); + /* Операции прибытия/отбытия в локацию. (В том числе и швартовка.) */ + private void arrivalAndDepartureOperations() throws IOException { + ArrayList>> arrivalOp = new ArrayList<>(); + ArrayList>> 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<>()); } - 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 operationsDuration = integerArray(operationTemplates.size(), 0); - ArrayList 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); + 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 { - isMovingObj.add(false); + ArrayList movingObjN = new ArrayList<>(); + for (MovingObject obj : op.getResources()) { + movingObjN.add(mObjToN.apply(obj)); } - } - writeArray(writer, "operations_duration", operationsDuration); - writeArray(writer, "is_continuous_operation", isMovingObj); - } - { // Конечные положения объектов. - ArrayList 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> operationsResources = new ArrayList<>(); - ArrayList 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 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 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); + movingObjN.add(mObjToN.apply(op.getMover())); - Set s = new TreeSet<>(); - s.add(mObjToN.apply(op.getLoader()) + 1); + for (Integer n : movingObjN) { + 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 movingObjN = new ArrayList<>(); + for (MovingObject obj : op.getResources()) { + movingObjN.add(mObjToN.apply(obj)); + } + movingObjN.add(mObjToN.apply(op.getMoorer())); - operationsResources.set(i, s); - operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1); + for (Integer n : movingObjN) { + 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"); } - { // Конфликтующие операции. - ArrayList> 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); - writer.write("\n"); + write2DArrayOfSetAs3DArray(writer, "arrival_op", arrivalOp); + write2DArrayOfSetAs3DArray(writer, "departure_op", departureOp); + writer.write("\n"); + } + + /* Начальные положения объектов. */ + private void initialLocations() throws IOException { + ArrayList 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 storages = new ArrayList<>(task.getStorages()); - ArrayList cargoes = new ArrayList<>(task.getCargoes()); + /* Окна погоды. */ + private void weatherWindows() throws IOException { + ArrayList bw_op = new ArrayList<>(); + ArrayList bw_start = new ArrayList<>(); + ArrayList 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 storNById = new TreeMap<>(); - for (int i = 0; i < storages.size(); i++) { - storNById.put(storages.get(i).getId(), i); + /* Непрерывность перемещения и швартовки. */ + private void operationsContinuity() throws IOException { + ArrayList operationsDuration = integerArray(operationTemplates.size(), 0); + ArrayList 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 cargoNById = new TreeMap<>(); - for (int i = 0; i < task.getCargoes().size(); i++) { - cargoNById.put(cargoes.get(i).getId(), i); + /* Конечные положения объектов. */ + private void finalLocations() throws IOException { + ArrayList 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> operationsResources = new ArrayList<>(); + ArrayList 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 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 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"); - writer.write("n_cargo_types = " + cargoes.size() + ";\n"); + Set s = new TreeSet<>(); + s.add(mObjToN.apply(op.getLoader()) + 1); - { // Ограничения на вместимость. - ArrayList maxStorageVol = new ArrayList<>(); + // TODO ресурсы у операции погрузки. - for (MovingObject obj : movingObjects) { - if (obj instanceof TransportShip) { - maxStorageVol.add((int)Math.ceil(((TransportShip) obj).getCargoMax())); - } else { - maxStorageVol.add(0); - } + operationsResources.set(i, s); + operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1); } - for (Storage storage : storages) { - maxStorageVol.add((int)Math.ceil(storage.getVolume())); + // TODO швартовка, погрузка. + } + 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> 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"); } - { // Граничные условия хранилищ. - // TODO выделить отдельно общий код. - ArrayList> initialStorageVol = new ArrayList<>(); - ArrayList> finalStorageVol = new ArrayList<>(); + 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 maxStorageVolume() throws IOException { + ArrayList maxStorageVol = new ArrayList<>(); - for (int i = 0; i < nObjWithStorage; i++) { - initialStorageVol.add(integerArray(cargoes.size(), 0)); - finalStorageVol .add(integerArray(cargoes.size(), -1)); + for (MovingObject obj : movingObjects) { + if (obj instanceof TransportShip) { + maxStorageVol.add((int)Math.ceil(((TransportShip) obj).getCargoMax())); + } else { + maxStorageVol.add(0); } - 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 (Storage storage : storages) { + maxStorageVol.add((int)Math.ceil(storage.getVolume())); + } + writeArray(writer, "max_storage_vol", maxStorageVol); + writer.write("\n"); + } + + /* Граничные состояния хранилищ. */ + private void boundaryStorageStates() throws IOException { + // TODO выделить отдельно общий код. + ArrayList> initialStorageVol = new ArrayList<>(); + ArrayList> 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()); - int val = (int)st.getCargoState(); - - if (st.getStorage() instanceof Storage) { - Storage storage = (Storage) st.getStorage(); - int stN = storNById.get(storage.getId()); - 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); - } + } + for (StorageState st : task.getStorageEndState()) { + 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()); + 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); } - write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol); - write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol); - } - { // Потоки грузов. - ArrayList>> cargoFlows = new ArrayList<>(); - for (int i = 0; i < nObjWithStorage; i++) { - cargoFlows.add(new ArrayList<>()); - 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); - } + } + write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol); + write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol); + } + + /* Потоки грузов. */ + private void cargoFlows() throws IOException { + ArrayList>> cargoFlows = new ArrayList<>(); + for (int i = 0; i < nObjWithStorage; i++) { + cargoFlows.add(new ArrayList<>()); + 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()); - int cargoN = cargoNById.get(flow.getCargo().getId()); - for (int i = 1; i < n_intervals + 2; i++) { - cargoFlows.get(storageN + movingObjects.size()).get(i).set(cargoN, (int)flow.getCurrentValue(i - 0.1)); - } + } + for (CargoFlow flow : task.getCargoFlows()) { + int storageN = storNById.get(flow.getStorage().getId()); + int cargoN = cargoNById.get(flow.getCargo().getId()); + 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; - for (int i = 0; i < nObjWithStorage; i++) { - for (int j = 0; j < n_intervals + 2; j++) { - for (int k = 0; k < cargoes.size(); k++) { - if (isFirst) { - isFirst = false; - } else { - writer.write(", "); - } - writer.write(cargoFlows.get(i).get(j).get(k).toString()); + } + writer.write("cargo_flows = array3d(1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types, ["); + boolean isFirst = true; + for (int i = 0; i < nObjWithStorage; i++) { + for (int j = 0; j < n_intervals + 2; j++) { + for (int k = 0; k < cargoes.size(); k++) { + if (isFirst) { + isFirst = false; + } else { + writer.write(", "); } + writer.write(cargoFlows.get(i).get(j).get(k).toString()); } } - writer.write("]);\n\n"); } - { // Грузовые операции со всеми хранилищами. - ArrayList>> involvedOperations = new ArrayList<>(); - ArrayList loadingOpDelta = new ArrayList<>(); - ArrayList loadingOpN = new ArrayList<>(); + writer.write("]);\n\n"); + } - 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<>()); - } + /* Грузовые операции со всеми хранилищами. */ + private void cargoOperations() throws IOException { + ArrayList>> involvedOperations = new ArrayList<>(); + ArrayList loadingOpDelta = new ArrayList<>(); + ArrayList 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++) { - 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 cargoN = cargoNById.get(op.getStorage().getCargo().getId());// TODO в TaskCase пока не реализовано, пересмотреть. + for (int i = 0; i < operationTemplates.size(); i++) { + 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 cargoN = cargoNById.get(op.getStorage().getCargo().getId());// TODO в TaskCase пока не реализовано, пересмотреть. - loadingOpDelta.add(-(int)op.getIntensity()); - loadingOpN.add(i); - involvedOperations.get(storageN + movingObjects.size()).get(cargoN).add(loadingOpDelta.size()); + loadingOpDelta.add(-(int)op.getIntensity()); + loadingOpN.add(i); + involvedOperations.get(storageN + movingObjects.size()).get(cargoN).add(loadingOpDelta.size()); - loadingOpDelta.add((int)op.getIntensity()); - loadingOpN.add(i); - involvedOperations.get(shipN).get(cargoN).add(loadingOpDelta.size()); - } + loadingOpDelta.add((int)op.getIntensity()); + loadingOpN.add(i); + 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"); } - { // Ограничение на необходимость полезной операции между движениями к одному пункту назначения. - ArrayList> objUsefulOperations = new ArrayList<>(); + 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"); + } + + /* Ограничение на необходимость полезной операции между движениями к одному пункту назначения. */ + private void constraintOnUsefulOperationBetweenMovements() throws IOException { + ArrayList> objUsefulOperations = new ArrayList<>(); - ArrayList> movingOpOfObj = new ArrayList<>(); + ArrayList> movingOpOfObj = new ArrayList<>(); - BiConsumer addUsOp = (MovingObject obj, Integer op) -> + BiConsumer addUsOp = (MovingObject obj, Integer op) -> objUsefulOperations.get(mObjToN.apply(obj)).add(op + 1); - for (int i = 0; i < movingObjects.size(); i++) { - movingOpOfObj.add(new TreeSet<>()); - objUsefulOperations.add(new TreeSet<>()); - } + for (int i = 0; i < movingObjects.size(); i++) { + movingOpOfObj.add(new TreeSet<>()); + objUsefulOperations.add(new TreeSet<>()); + } - for (int i = 0; i < operationTemplates.size(); i++) { - OperationTemplate t = operationTemplates.get(i); - if (t instanceof MovingTemplate) { - MovingTemplate op = (MovingTemplate)t; + for (int i = 0; i < operationTemplates.size(); i++) { + OperationTemplate t = operationTemplates.get(i); + if (t instanceof MovingTemplate) { + MovingTemplate op = (MovingTemplate)t; - int id = mObjToN.apply(op.getMover()); - movingOpOfObj.get(id).add(i + 1); + int id = mObjToN.apply(op.getMover()); + movingOpOfObj.get(id).add(i + 1); - for (MovingObject obj : op.getResources()) { - addUsOp.accept(obj, i); - } - } else if (t instanceof MooringTemplate) { - MooringTemplate op = (MooringTemplate)t; + for (MovingObject obj : op.getResources()) { + addUsOp.accept(obj, i); + } + } else if (t instanceof MooringTemplate) { + MooringTemplate op = (MooringTemplate)t; - int id = mObjToN.apply(op.getMoorer()); - movingOpOfObj.get(id).add(i + 1); + int id = mObjToN.apply(op.getMoorer()); + movingOpOfObj.get(id).add(i + 1); - for (MovingObject obj : op.getResources()) { - addUsOp.accept(obj, i); - } + for (MovingObject obj : op.getResources()) { + addUsOp.accept(obj, i); + } - if (!op.isDirect()) { // Отшвартовка. - addUsOp.accept(op.getMoorer(), i); - } - } else if (t instanceof LoadingTemplate) { - LoadingTemplate op = (LoadingTemplate)t; - addUsOp.accept(op.getLoader(), i); + if (!op.isDirect()) { // Отшвартовка. + addUsOp.accept(op.getMoorer(), i); } + } else if (t instanceof LoadingTemplate) { + LoadingTemplate op = (LoadingTemplate)t; + addUsOp.accept(op.getLoader(), i); } + } - writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations); - writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj); + writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations); + 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"); + + 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 { List operations = null; Integer result = null; diff --git a/src/inport/Main.java b/src/inport/Main.java index ff9fdef..2daad48 100644 --- a/src/inport/Main.java +++ b/src/inport/Main.java @@ -11,13 +11,13 @@ public class Main { String type = args[0]; switch (type) { - case "to_MiniZinc" : { + case "to_MiniZinc_0" : { String input = args[1]; String output = args[2]; TaskCase task = new TaskCase(); try { task.deserialize(input); - ConversionUtil.portToMiniZinc(task, output); + ConversionUtil.portToMiniZinc_0(task, output); } catch (IOException ex) { System.out.println(ex.getMessage()); } -- GitLab