From 10add7b3cce4778ac5ff95cba6720fbe45c6b5d9 Mon Sep 17 00:00:00 2001 From: Vlad_kv Date: Mon, 3 Dec 2018 16:13:11 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D1=91?= =?UTF-8?q?=D0=BD=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=B2,=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BF=D0=B0=D1=80=D1=83=20?= =?UTF-8?q?=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/inport/CargoFlow.java | 17 +- src/inport/ConversionUtil.java | 4 +- src/inport/LoadingTemplate.java | 19 +- src/inport/TaskCase.java | 296 +++++++--------------------- tests/cargo_handling_and_moving.ipp | 2 +- tests/simple_cargo_flow.ipp | 2 +- 6 files changed, 103 insertions(+), 237 deletions(-) diff --git a/src/inport/CargoFlow.java b/src/inport/CargoFlow.java index b266584..f3cd6d0 100644 --- a/src/inport/CargoFlow.java +++ b/src/inport/CargoFlow.java @@ -4,10 +4,7 @@ */ package inport; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; +import java.util.*; /** * @@ -17,14 +14,14 @@ public class CargoFlow { private Storage storage; private Cargo cargo; - Map flow; + SortedMap flow; public Map getFlow() { return flow; } public void setFlow(Map flow) { - this.flow = flow; + this.flow = new TreeMap<>(flow); } /** @@ -54,7 +51,7 @@ public class CargoFlow { } public CargoFlow() { - this.flow = new HashMap<>(); + this.flow = new TreeMap<>(); } public CargoFlow(Storage storage, Cargo cargo) { @@ -71,7 +68,7 @@ public class CargoFlow { double prevKey = -1.0; for (Double keyTime : keyTimes) { - if (forTime>=prevKey && forTime= prevKey && forTimeprevKey && forTime= prevKey && forTimeprevKey) + if (!isFound && forTime >= prevKey) res += flow.get(prevKey)*(forTime-prevKey); return res; } diff --git a/src/inport/ConversionUtil.java b/src/inport/ConversionUtil.java index 38d9c30..a73e48f 100644 --- a/src/inport/ConversionUtil.java +++ b/src/inport/ConversionUtil.java @@ -478,7 +478,7 @@ public class ConversionUtil { // TODO ресурсы у операции погрузки. operationsResources.set(i, s); - operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1); + operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), op.getWithMooring()) + 1); } // TODO швартовка, погрузка. } @@ -616,7 +616,7 @@ public class ConversionUtil { 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 пока не реализовано, пересмотреть. + int cargoN = cargoNById.get(op.getCargo().getId()); loadingOpDelta.add(-(int)op.getIntensity()); loadingOpN.add(i); diff --git a/src/inport/LoadingTemplate.java b/src/inport/LoadingTemplate.java index add3278..f8a9d34 100644 --- a/src/inport/LoadingTemplate.java +++ b/src/inport/LoadingTemplate.java @@ -17,7 +17,8 @@ public class LoadingTemplate extends OperationTemplate { private Storage storage; private List resources; private double intensity; - + private boolean withMooring; + private Cargo cargo; /** * Get the value of resources @@ -61,6 +62,22 @@ public class LoadingTemplate extends OperationTemplate { this.storage = storage; } + public void setWithMooring(boolean withMooring) { + this.withMooring = withMooring; + } + + public boolean getWithMooring() { + return withMooring; + } + + public void setCargo(Cargo cargo) { + this.cargo = cargo; + } + + public Cargo getCargo() { + return cargo; + } + public LoadingTemplate(TransportShip loader, Berth berth, Storage storage, double intensity, int id) { super(id, berth); this.loader = loader; diff --git a/src/inport/TaskCase.java b/src/inport/TaskCase.java index 3c5f288..0da26c7 100644 --- a/src/inport/TaskCase.java +++ b/src/inport/TaskCase.java @@ -4,8 +4,6 @@ */ package inport; -import javafx.util.Pair; - import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -13,7 +11,11 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -500,7 +502,13 @@ public class TaskCase { mt.setStorage((Storage)m_storage.get(key)); direct = 1; } - // Груз. Пока не нужен + // Груз. + key = Integer.parseInt(tokens[4].trim());; + for (Cargo cargo : cargoes) { + if (cargo.getId() == key) { + mt.setCargo(cargo); + } + } // Приемник. Пока пара - это только хранилище-судно. С бункеровкой будем разбираться потом key = Integer.parseInt(tokens[5].trim()); if (m_vessel.containsKey(key)) @@ -522,9 +530,11 @@ public class TaskCase { key = Integer.parseInt(crs.trim()); mt.getResources().add(m_equiopment.get(key)); } - mt.setIntensity(direct*Double.parseDouble(tokens[8].trim())); - templates.add(mt); - m_template.put(mt.getId(), mt); + mt.setIntensity(direct*Double.parseDouble(tokens[8].trim())); + mt.setWithMooring(tokens[9].trim().equals("M")); + + templates.add(mt); + m_template.put(mt.getId(), mt); } break; case 9: @@ -651,7 +661,7 @@ public class TaskCase { // Это начало блока operation = new Operation(); operation.setTemplate(template); - operation.setStart(i+1); + operation.setStart(i); inBlock = true; } } else @@ -1484,24 +1494,18 @@ public class TaskCase { // Состояние загрузки судов writer.write("* Ship Loading States \n"); - // Тут пок огшраничение только на местонахождение транспортных судов + // Тут пока ограничение только на местонахождение транспортных судов for (TransportShip s : ships) { - StorageState state1 = null; - StorageState state2 = null; + List state1List = new ArrayList(); + List state2List = new ArrayList(); MovingObjectState eState = null; for (StorageState state : storageInitialState) - if (state.getStorage().equals(s)) - { - state1 = (StorageState)state; - break; - } + if (state.getStorage().equals(s)) + state1List.add((StorageState)state); for (StorageState state : storageEndState) - if (state.getStorage().equals(s)) - { - state2 = (StorageState)state; - break; - } + if (state.getStorage().equals(s)) + state2List.add((StorageState)state); for (MovingObjectState state : vesselEndState) if (state.getVessel().equals(s)) { @@ -1512,12 +1516,25 @@ public class TaskCase { { int start = 0; int finish = 0; - if (state1!=null && state1.getCargo().equals(c)) - start = (int)state1.getCargoState(); - if (state2!=null && state2.getCargo().equals(c)) - finish = (int)state2.getCargoState(); + for (StorageState state1 : state1List) + { + if (state1!=null && state1.getCargo().equals(c)) + { + start = (int)state1.getCargoState(); + break; + } + } + for (StorageState state2 : state2List) + { + if (state2!=null && state2.getCargo().equals(c)) + { + finish = (int)state2.getCargoState(); + break; + } + } List vc = new ArrayList(); List intens = new ArrayList(); + int epsilon = 0; // Точность оценки остатка в судовом хранилище for (OperationTemplate tp : templates) if (tp instanceof LoadingTemplate) { @@ -1526,9 +1543,15 @@ public class TaskCase { if (ltp.getLoader().equals(s) && ltp.getStorage().getCargo().equals(c)) { vc.add(i); - intens.add((int)ltp.getIntensity()); + int itsv = (int)ltp.getIntensity(); + intens.add(itsv); + // Пока забъем.... + //if (Math.abs(itsv)>epsilon) + // epsilon = Math.abs(itsv); } } + if (epsilon>1) + epsilon--; for (int j=0; j= -" + start + " ;\n"); + writer.write(clause + " >= -" + (start + epsilon) + " ;\n"); nCons++; } // Ограничение на грузоподъемность судна int maxLoad = (int)(s.getCargoMax()+1.0); if (sumplus > (maxLoad - start)) { - writer.write(clause + " <= " + (maxLoad - start) + " ;\n"); + writer.write(clause + " <= " + (maxLoad - start + epsilon) + " ;\n"); nCons++; } } else { // Конечное состояние судна - writer.write(clause + " = " + (finish - start) + " ;\n"); + // writer.write(clause + " = " + (finish - start) + " ;\n"); + // nCons++; + writer.write(clause + " >= " + (finish - start - epsilon) + " ;\n"); + nCons++; + writer.write(clause + " <= " + (finish - start + epsilon) + " ;\n"); nCons++; } } @@ -1600,28 +1627,31 @@ public class TaskCase { } - // Невозможность одновременного нахождения двух пришвартованных судов у одного причала + // Невозможность одновременного нахождения двух пришвартованных судов у одного причала writer.write("* No more than 1 vessel moored to berth \n"); - if (isMooring) + if (ships.size()>1) { - for (Berth b : berths) + if (isMooring) { - if (b.getIsRaid()) - continue; - int bdx = berths.indexOf(b); - for (int j=1; j makeList(String... strings) { - return Arrays.asList(strings); - } - - private static ArrayList> initArray(int size) { - ArrayList> res = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - res.add(new TreeSet<>()); - } - return res; - } - - public void simpleMiniZincConversion(String fileName) throws IOException, ConversionException { - try(FileWriter writer = new FileWriter(fileName, false)) { - writer.write("include \"globals.mzn\";\n"); - int n_intervals = (int)getPlanningInterval(); - - writer.write("int: n_intervals = " + n_intervals + ";\n"); - - ArrayList ships = new ArrayList<>(getShips()); - Map shipNumberById = new TreeMap<>(); - for (int i = 0; i < ships.size(); i++) { - shipNumberById.put(ships.get(i).getId(), i); - } - writer.write("int: n_transports = " + ships.size() + ";\n"); - - ArrayList berths = new ArrayList<>(getBerths()); - Map berthNumberById = new TreeMap<>(); - for (int i = 0; i < berths.size(); i++) { - berthNumberById.put(berths.get(i).getId(), i); - } - writer.write("int: n_berths = " + berths.size() + ";\n"); - - ArrayList tows = new ArrayList<>(getTows()); - Map towNumberById = new TreeMap<>(); - for (int i = 0; i < tows.size(); i++) { - towNumberById.put(tows.get(i).getId(), i); - } - writer.write("int: n_tows = " + tows.size() + ";\n"); - - writer.write("\n"); - - writer.write("set of int: Operations_identifiers = {-2, -1"); - for(OperationTemplate operation : getTemplates()) { - writer.write(", " + operation.getId()); - } - writer.write("};\n"); - - writer.write("enum Berth_status = {free, moored, berthing, de_berthing};\n"); - - writer.write("array [1..n_berths, 0..n_intervals] of var 0..n_transports : transport_in_berthing;\n"); - writer.write("array [1..n_berths, 0..n_intervals] of var Berth_status : berths_status;\n"); - // -2 - занят, -1 - свободен, i - начало i-той операции. - writer.write("array [1..n_berths, 0..n_intervals] of var Operations_identifiers : berths_operations;\n\n"); - - writer.write("enum Moving_obj_status = {in_the_way, in_place};\n"); - - writer.write("array [1..n_transports, 0..n_intervals] of var 1..n_berths : transports_destination;\n"); - writer.write("array [1..n_transports, 0..n_intervals] of var Moving_obj_status : transports_status;\n"); - writer.write("array [1..n_transports, 0..n_intervals] of var Operations_identifiers : transports_operations;\n\n"); - - writer.write("array [1..n_tows, 0..n_intervals] of var 1..n_berths : tows_destination;\n"); - writer.write("array [1..n_tows, 0..n_intervals] of var Moving_obj_status : tows_status;\n"); - writer.write("array [1..n_tows, 0..n_intervals] of var Operations_identifiers : tows_operations;\n\n"); - - { // Пункт назначения может измениться только в начале новой реальной операции. - for (String name : makeList("transports", "tows")) { - writer.write("constraint forall (i in 1..n_" + name + ", j in 1..n_intervals)" + - "((" + name + "_operations[i, j] in {-2, -1}) -> " + - "(" + name + "_destination[i, j] == " + name + "_destination[i, j - 1]));\n"); - } - // Из свободного состояния нельзя перейти в "занято". - for (String name : makeList("berths", "transports", "tows")) { - writer.write("constraint forall (i in 1..n_" + name + ", j in 1..n_intervals) " + - "((" + name + "_operations[i, j] == -2) -> (" + name + "_operations[i, j - 1] != -1));\n"); - } - writer.write("\n"); - } - - { // Начальные состояния. - // Все объекты на своих местах. - for (MovingObjectState state : getVesselInitialState()) { - int dest_n = berthNumberById.get(state.getLocation().getId()); - int obj_id = state.getVessel().getId(); - if (shipNumberById.containsKey(obj_id)) { - writer.write("constraint (transports_destination[" + (shipNumberById.get(obj_id) + 1) + ", 0] == " + (dest_n + 1) + ");\n"); - continue; - } - if (towNumberById.containsKey(obj_id)) { - writer.write("constraint (tows_destination[" + (towNumberById.get(obj_id) + 1) + ", 0] == " + (dest_n + 1) + ");\n"); - continue; - } - throw new ConversionException("Unknown id " + obj_id + " - not transport and not tow."); - } - writer.write("\n"); - // Никто ничего не делает. - for (String name : makeList("berths", "transports", "tows")) { - writer.write("constraint forall (i in 1..n_" + name + ") (" + name + "_operations[i, 0] == -1);\n"); - } - writer.write("\n"); - - // Все на месте. - for (String name : makeList("transports", "tows")) { - writer.write("constraint forall (i in 1..n_" + name + ") (" + name + "_status[i, 0] == in_place);\n"); - } - writer.write("\n"); - // Все причалы изначально пусты. - // TODO учесть операции в процессе. - writer.write("constraint forall (i in 1..n_berths) (transport_in_berthing[i, 0] == 0);\n\n"); - } - - { // Конечные состояния. - // TODO - } - - // Причал свободен <=> его не занимает ни один корабль (фиктивный корабль с индексом 0). - writer.write("constraint forall (i in 1..n_berths, j in 1..n_intervals)" + - "((berths_status[i, j] == free) == (transport_in_berthing[i, j] == 0));\n"); - - // Причал занят кораблём -> пункт назначения корабля - данный причал, и он на месте. - writer.write("constraint forall (i in 1..n_berths, j in 1..n_intervals)" + - "(transport_in_berthing[i, j] > 0 -> " + - "((transports_destination[transport_in_berthing[i, j], j] == i)) /\\ (transports_status[transport_in_berthing[i, j], j] == in_place));\n"); - - ArrayList> usingOperationsWithThisBerth = initArray(getBerths().size()); - ArrayList> usingOperationsWithThisTransport = initArray(getShips().size()); - ArrayList> usingOperationsWithThisTow = initArray(getTows().size()); - - { // Операции перемещения. - for (OperationTemplate t : getTemplates()) { - if (t instanceof MovingTemplate) { - MovingTemplate operation = (MovingTemplate)t; - // TODO рассмотреть общий случай, ввести отдельный движущийся объект. - int transportNo = shipNumberById.get(operation.getMover().getId()); - int destNo = berthNumberById.get(operation.getDestination().getId()); - - usingOperationsWithThisBerth.get(destNo).add(operation.getId()); - usingOperationsWithThisTransport.get(transportNo).add(operation.getId()); - - { // Если операция началась - то началась у всех. - // TODO - } - -// operation.getResources(); - } - } - writer.write("\n"); - } - - { // Запрещаем все операции, которые не используют данный объект. - ArrayList>, String>> classesOfObjects = new ArrayList<>(); - classesOfObjects.add(new Pair<>(usingOperationsWithThisBerth, "berths")); - classesOfObjects.add(new Pair<>(usingOperationsWithThisTransport, "transports")); - classesOfObjects.add(new Pair<>(usingOperationsWithThisTow, "tows")); - - for (Pair>, String> p : classesOfObjects) { - for (int key = 0; key < p.getKey().size(); key++) { - writer.write("constraint forall (j in 0..n_intervals) (" + p.getValue() + "_operations[" + (key + 1) + ", j] in {-2, -1"); - - for (Integer usedOperation : p.getKey().get(key)) { - writer.write(", " + usedOperation); - } - writer.write("});\n"); - } - } - writer.write("\n"); - } - - writer.write("\nsolve satisfy;\n\n"); - writer.write("output ["); - for (String name : makeList("transport_in_berthing", "berths_status", "berths_operations", - "transports_destination", "transports_status", "transports_operations", - "tows_destination", "tows_status", "tows_operations")) { - writer.write("\"" + name + " = \", show(" + name + "), \"\\n\",\n "); - } - writer.write("];\n"); - } - } + } diff --git a/tests/cargo_handling_and_moving.ipp b/tests/cargo_handling_and_moving.ipp index 2b013c8..f344fc2 100644 --- a/tests/cargo_handling_and_moving.ipp +++ b/tests/cargo_handling_and_moving.ipp @@ -31,7 +31,7 @@ Templates 201; mrn; []; 11; 5; []; 1 202; unm; []; 11; 5; []; 1 -301; loa; []; 1001; 0; 11; 5; []; 2 +301; loa; []; 1001; 0; 11; 5; []; 2; M Cargo Flows Initial Vessel State diff --git a/tests/simple_cargo_flow.ipp b/tests/simple_cargo_flow.ipp index 04ec58f..a4aa976 100644 --- a/tests/simple_cargo_flow.ipp +++ b/tests/simple_cargo_flow.ipp @@ -16,7 +16,7 @@ Templates 103; mov; []; 11; 1; 2;[]; 1 201; mrn; []; 11; 2; []; 1 202; unm; []; 11; 2; []; 1 -301; loa; []; 1001; 0; 11; 2; []; 1 +301; loa; []; 1001; 0; 11; 2; []; 1; M Cargo Flows 1001; 0; [0:0, 5:1, 8:0] -- GitLab