/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package inport; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; 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; /** * * @author topazh_ag */ public class TaskCase { // Статическая структура порта private List cargoes; private List berths; private List storages; private List bunkers; private List tows; private List equipments; // Обслуживаемые суда private List ships; // Шаблоны операций private List templates; // Внешние грузопотоки private List cargoFlows; // Начальное состояние private List vesselInitialState; private List storageInitialState; // Конечное состояние private List vesselEndState; private List storageEndState; // Горизонт планирования private double planningInterval; // Тип критерия оптимизации private int criterionType; // План - критерий private double solution_result; // План - решение private List solution; /** * Get the value of solution * * @return the value of solution */ public List getSolution() { return solution; } /** * Set the value of solution * * @param solution new value of solution */ public void setSolution(List solution) { this.solution = solution; } /** * Get the value of planningInterval * * @return the value of planningInterval */ public double getPlanningInterval() { return planningInterval; } /** * Set the value of planningInterval * * @param planningInterval new value of planningInterval */ public void setPlanningInterval(double planningInterval) { this.planningInterval = planningInterval; } public int getCriterionType() { return criterionType; } public void setCriterionType(int criterionType) { this.criterionType = criterionType; } public double getSolution_result() { return solution_result; } public void setSolution_result(double solution_result) { this.solution_result = solution_result; } /** * Get the value of cargoFlows * * @return the value of cargoFlows */ public List getCargoFlows() { return cargoFlows; } /** * Set the value of cargoFlows * * @param cargoFlows new value of cargoFlows */ public void setCargoFlows(List cargoFlows) { this.cargoFlows = cargoFlows; } /** * Get the value of vesselEndState * * @return the value of vesselEndState */ public List getVesselEndState() { return vesselEndState; } /** * Set the value of vesselEndState * * @param vesselEndState new value of vesselEndState */ public void setVesselEndState(List vesselEndState) { this.vesselEndState = vesselEndState; } public List getStorageEndState() { return storageEndState; } public void setStorageEndState(List storageEndState) { this.storageEndState = storageEndState; } /** * Get the value of storageInitialState * * @return the value of storageInitialState */ public List getStorageInitialState() { return storageInitialState; } /** * Set the value of storageInitialState * * @param storageInitialState new value of storageInitialState */ public void setStorageInitialState(List storageInitialState) { this.storageInitialState = storageInitialState; } /** * Get the value of vesselInitialState * * @return the value of vesselInitialState */ public List getVesselInitialState() { return vesselInitialState; } /** * Set the value of vesselInitialState * * @param vesselInitialState new value of vesselInitialState */ public void setVesselInitialState(List vesselInitialState) { this.vesselInitialState = vesselInitialState; } /** * Get the value of templates * * @return the value of templates */ public List getTemplates() { return templates; } /** * Set the value of templates * * @param templates new value of templates */ public void setTemplates(List templates) { this.templates = templates; } /** * Get the value of ships * * @return the value of ships */ public List getShips() { return ships; } /** * Set the value of ships * * @param ships new value of ships */ public void setShips(List ships) { this.ships = ships; } /** * Get the value of equipments * * @return the value of equipments */ public List getEquipments() { return equipments; } /** * Set the value of equipments * * @param equipments new value of equipments */ public void setEquipments(List equipments) { this.equipments = equipments; } /** * Get the value of tows * * @return the value of tows */ public List getTows() { return tows; } /** * Set the value of tows * * @param tows new value of tows */ public void setTows(List tows) { this.tows = tows; } /** * Get the value of bunkers * * @return the value of bunkers */ public List getBunkers() { return bunkers; } /** * Set the value of bunkers * * @param bunkers new value of bunkers */ public void setBunkers(List bunkers) { this.bunkers = bunkers; } /** * Get the value of storages * * @return the value of storages */ public List getStorages() { return storages; } /** * Set the value of storages * * @param storages new value of storages */ public void setStorages(List storages) { this.storages = storages; } /** * Get the value of cargoes * * @return the value of cargoes */ public List getCargoes() { return cargoes; } /** * Set the value of cargoes * * @param cargoes new value of cargoes */ public void setCargoes(List cargoes) { this.cargoes = cargoes; } /** * Get the value of berths * * @return the value of berths */ public List getBerths() { return berths; } /** * Set the value of berths * * @param berths new value of berths */ public void setBerths(List berths) { this.berths = berths; } public TaskCase() { cargoes = new ArrayList<>(); berths = new ArrayList<>(); storages = new ArrayList<>(); bunkers = new ArrayList<>(); tows = new ArrayList<>(); equipments = new ArrayList<>(); ships = new ArrayList<>(); templates = new ArrayList<>(); cargoFlows = new ArrayList<>(); vesselInitialState = new ArrayList<>(); storageInitialState = new ArrayList<>() ; vesselEndState = new ArrayList<>(); storageEndState = new ArrayList<>(); solution = new ArrayList<>(); } private MovingObjectState fromString(String s, Map m_berth, Map m_vessel) { String[] tkns1 = s.split(";"); MovingObjectState st = new MovingObjectState(); int key = Integer.parseInt(tkns1[0].trim()); MovingObject vs = m_vessel.get(key); st.setVessel(vs); key = Integer.parseInt(tkns1[1].trim()); st.setLocation(m_berth.get(key)); return st; } public void deserialize(String fileName) throws IOException { cargoes.clear(); berths.clear(); storages.clear(); bunkers.clear(); tows.clear(); equipments.clear(); ships.clear(); templates.clear(); cargoFlows.clear(); vesselInitialState.clear(); storageInitialState.clear(); vesselEndState.clear(); storageEndState.clear(); solution.clear(); String[] tags = {"Cargoes", "Berths", "Storages", "Bunkers", "Tows", "Loading Equipments", "Transport Ships", "Templates", "Time Windows", "Cargo Flows", "Initial Vessel State", "Initial Storage State", "Final Vessel State", "Final Storage State", "Task Properties", "Solution"}; // Open the file FileInputStream fstream; try { fstream = new FileInputStream(fileName); BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); String strLine; int index = 0; Map m_cargo = new HashMap<>(); Map m_berth = new HashMap<>(); Map m_storage = new HashMap<>(); Map m_vessel = new HashMap<>(); Map m_equiopment = new HashMap<>(); Map m_template = new HashMap<>(); //Read File Line By Line int numInside = 0; while ((strLine = br.readLine()) != null) { numInside ++; boolean serviceString = false; for (int i = 0; i0) { key = Integer.parseInt(crs.trim()); mt.getResources().add((Tow)m_vessel.get(key)); } mt.setDuration(Double.parseDouble(tokens[7].trim())); templates.add(mt); m_template.put(mt.getId(), mt); } if (tokens[1].trim().equals("mrn") || tokens[1].trim().equals("unm")) { MooringTemplate mt = new MooringTemplate(); mt.setId(Integer.parseInt(tokens[0].trim())); mt.setDirect(true); if (tokens[1].trim().equals("unm")) mt.setDirect(false); mt.setTimeWindow(tokens[2].trim()); int key = Integer.parseInt(tokens[3].trim()); mt.setMoorer((TransportShip)m_vessel.get(key)); key = Integer.parseInt(tokens[4].trim()); mt.setStartLocation(m_berth.get(key)); String[] rs = tokens[5].trim().replace("[", "").replace("]", "").split(","); for (String crs : rs) if (crs.length()>0) { key = Integer.parseInt(crs.trim()); mt.getResources().add((Tow)m_vessel.get(key)); } mt.setDuration(Double.parseDouble(tokens[6].trim())); templates.add(mt); m_template.put(mt.getId(), mt); } if (tokens[1].trim().equals("loa")) { LoadingTemplate mt = new LoadingTemplate(); mt.setId(Integer.parseInt(tokens[0].trim())); mt.setTimeWindow(tokens[2].trim()); int direct = 1; // Источник. Пока пара - это только хранилище-судно. С бункеровкой будем разбираться потом int key = Integer.parseInt(tokens[3].trim()); if (m_vessel.containsKey(key)) { mt.setLoader((TransportShip)m_vessel.get(key)); direct = -1; } if (m_storage.containsKey(key)) { mt.setStorage((Storage)m_storage.get(key)); direct = 1; } // Груз. Пока не нужен // Приемник. Пока пара - это только хранилище-судно. С бункеровкой будем разбираться потом key = Integer.parseInt(tokens[5].trim()); if (m_vessel.containsKey(key)) { mt.setLoader((TransportShip)m_vessel.get(key)); direct = 1; } if (m_storage.containsKey(key)) { mt.setStorage((Storage)m_storage.get(key)); direct = - 1; } key = Integer.parseInt(tokens[6].trim()); mt.setStartLocation(m_berth.get(key)); String[] rs = tokens[7].trim().replace("[", "").replace("]", "").split(","); for (String crs : rs) if (crs.length()>0) { 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); } break; case 9: break; case 10: cargoFlows.add(new CargoFlow(strLine, m_storage, m_cargo)); break; case 11: vesselInitialState.add(fromString(strLine, m_berth, m_vessel)); break; case 12: storageInitialState.add(new StorageState(strLine, m_storage, m_vessel, m_cargo)); break; case 13: vesselEndState.add(fromString(strLine, m_berth, m_vessel)); break; case 14: storageEndState.add(new StorageState(strLine, m_storage, m_vessel, m_cargo)); break; case 15: { String[] rs = strLine.split(";"); planningInterval = Double.parseDouble(rs[0].trim()); criterionType = Integer.parseInt(rs[1].trim()); } break; case 16: // Тут чтение операций если надо. Потом подумаем break; default: break; } } //Close the input stream br.close(); } catch (FileNotFoundException ex) { Logger.getLogger(TaskCase.class.getName()).log(Level.SEVERE, null, ex); } } public void serialize(String fileName) { try(FileWriter writer = new FileWriter(fileName, false)) { // запись всего writer.write("Cargoes"+"\n"); for (Cargo c : cargoes) writer.write(c.toString()+"\n"); writer.write("Berths"+"\n"); for (Berth c : berths) writer.write(c.toString()+"\n"); writer.write("Storages"+"\n"); for (Storage c : storages) writer.write(c.toString()+"\n"); writer.write("Bunkers"+"\n"); for (Bunker c : bunkers) writer.write(c.toString()+"\n"); writer.write("Tows"+"\n"); for (Tow c : tows) writer.write(c.toString()+"\n"); writer.write("Loading Equipments"+"\n"); for (LoadingEquipment c : equipments) writer.write(c.toString()+"\n"); writer.write("Transport Ships"+"\n"); for (TransportShip c : ships) writer.write(c.toString()+"\n"); writer.write("\n"); writer.write("Templates"+"\n"); for (OperationTemplate c : templates) writer.write(c.toString()+"\n"); writer.write("\n"); writer.write("Cargo Flows"+"\n"); for (CargoFlow c : cargoFlows) writer.write(c.toString()+"\n"); writer.write("Initial Vessel State"+"\n"); for (MovingObjectState c : vesselInitialState) writer.write(c.toString()+"\n"); writer.write("Initial Storage State"+"\n"); for (StorageState c : storageInitialState) writer.write(c.toString()+"\n"); writer.write("Final Vessel State"+"\n"); for (MovingObjectState c : vesselEndState) writer.write(c.toString()+"\n"); writer.write("Final Storage State"+"\n"); for (StorageState c : storageEndState) writer.write(c.toString()+"\n"); writer.write("\n"); writer.write("Task Properties"+"\n"); writer.write(planningInterval+";"+criterionType+"\n"); writer.write("\n"); writer.write("Solution"+"\n"); writer.write(solution_result+"\n"); for (Operation c : solution) writer.write(c.toString()+"\n"); writer.flush(); } catch(IOException ex){ System.out.println(ex.getMessage()); } } public void formSolutionFromPB(int res[]) { int nTimes = (int) (planningInterval + 1.0 - 1e-7); int rLength = res.length; solution_result = 0.0; for (int k=1; k<=nTimes; k++) if (res[rLength-k]>0) { solution_result = nTimes - k + 1; break; } int cIndex = -1; for (OperationTemplate template : templates) { boolean inBlock = false; int duration = 0; Operation operation = null; for (int i=0; i0) { if (inBlock) duration++; else { // Это начало блока operation = new Operation(); operation.setTemplate(template); operation.setStart(i+1); inBlock = true; } } else { if (inBlock) { // Это окончание блока operation.setDuration(duration+1.0); duration = 0; solution.add(operation); inBlock = false; } } } if (inBlock) { // Это окончание блока operation.setDuration(duration+1.0); solution.add(operation); } } } private boolean isCompatible(OperationTemplate t1, OperationTemplate t2) { MovingObject doer1 = getDoer(t1); Berth place1 = t1.getStartLocation(); List resources1 = getResources(t1); MovingObject doer2 = getDoer(t2); Berth place2 = t2.getStartLocation(); List resources2 = getResources(t2); // Пересекаемость ресурсов for (Object res2 : resources2) if (resources1.contains(res2)) return false; // Выполнитель = ресурс if (resources1.contains(doer2)) return false; // Ресурс = выполнитель if (resources2.contains(doer1)) return false; // Выполнитель = выполнитель if (doer1.equals(doer2)) { // Это не погрузка if (!(t1 instanceof LoadingTemplate) || (!(t2 instanceof LoadingTemplate))) return false; // Разные причалы if (!place1.equals(place2)) return false; Storage s1 = ((LoadingTemplate)t1).getStorage(); Storage s2 = ((LoadingTemplate)t2).getStorage(); // В одно хранилище if (s1.equals(s2)) return false; } else // На одном причале и это не перемещения if (place1.equals(place2) && (!(t1 instanceof MovingTemplate)) && (!(t2 instanceof MovingTemplate))) return false; return true; } MovingObject getDoer(OperationTemplate t) { if (t instanceof LoadingTemplate) return ((LoadingTemplate)t).getLoader(); if (t instanceof MooringTemplate) return ((MooringTemplate)t).getMoorer(); if (t instanceof MovingTemplate) return ((MovingTemplate)t).getMover(); return null; } List getResources(OperationTemplate t) { List res = new ArrayList<>(); if (t instanceof LoadingTemplate) res.addAll(((LoadingTemplate)t).getResources()); if (t instanceof MooringTemplate) res.addAll(((MooringTemplate)t).getResources()); if (t instanceof MovingTemplate) res.addAll(((MovingTemplate)t).getResources()); return res; } private String xij(int i, int j, int nJ, boolean plus) { int number = i*nJ + j + 1; String prefix = ""; if (!plus) prefix ="~"; return prefix+"x"+number; } private String wrbj(int r, int b, int j, int nB, int nJ, int nIni, boolean isMooring, boolean moored, boolean plus) { int number = nIni + r*nJ*nB + b*nJ + j + 1; if (isMooring) { if (moored) number = nIni + r*nJ*nB*2 + b*nJ*2 + nJ + j + 1; else number = nIni + r*nJ*nB*2 + b*nJ*2 + j + 1; } String prefix = ""; if (!plus) prefix ="~"; return prefix+"x"+number; } private String sum1(List iks, int j, int nJ, int weight) { String res = ""; for (Integer ik : iks) res += " +" + weight + " "+xij(ik, j, nJ, true); return res; } private String fj(int j, int nBefore, boolean plus) { int number = nBefore + j + 1; String prefix = ""; if (!plus) prefix ="~"; return prefix+"x"+number; } public int pb_formalize(String fileName/*, int indent*/) throws IOException { FileWriter writer = new FileWriter("temp", false); int nCons = 0; List vss = new ArrayList(); vss.addAll(ships); vss.addAll(bunkers); vss.addAll(tows); vss.addAll(equipments); // Выяснение вопроса с наличием швартовки boolean isMooring = false; for (OperationTemplate tp : templates) if (tp instanceof MooringTemplate) { isMooring = true; break; } int nTimes = (int) (planningInterval + 1.0 - 1e-7); int nOperations = templates.size(); int nVars = nTimes*nOperations; int nBerths = berths.size(); int nVessels = vss.size(); int mult =1; if (isMooring) mult = 2; int nSuppVars = nVessels*nBerths*mult*nTimes; int nBefore = nVars + nSuppVars; int nAfter = nTimes; // String s1 = wrbj(0, 1, 17, 6, 18, 756, true, true, true); // String s2 = wrbj(0, 2, 0, 6, 18, 756, true, false, true); // String s23 = s1+s2; // Критерий оптимизации старый /* nAfter = 0; String crit = ""; int degree = 1; for (int j=nTimes - indent; j starts = tp.timeWindows.keySet(); for (Double start : starts) { // Определяем стартовый индекс int jstart = (int)(start.doubleValue()); Double duration = tp.timeWindows.get(start); int jend = (int)(start.doubleValue()+duration.doubleValue()); for (int j=jstart; j<=jend; j++) { writer.write(" +1 "+xij(i,j,nTimes,true)+" = 0 ;\n"); nCons++; } } } //!!!! Неразделимость ресурсов для операций. writer.write("* Resource Unsharedness \n"); // Новая байда for (int i1 = 0; i1 excluders = new ArrayList(); for (int i2 = i1+1; i20) { for (int j=0; j= 1 ;\n"); nCons++; } } } /* // Старая байда // Буксиры writer.write("* For Tows \n"); for (Tow tow : tows) { List iks = new ArrayList(); for (OperationTemplate tpl : templates) { int ik = templates.indexOf(tpl); if (tpl instanceof MovingTemplate) { MovingTemplate mt = (MovingTemplate)tpl; if (mt.getMover().equals(tow)) iks.add(ik); if (mt.getResources().contains(tow)) iks.add(ik); } if (tpl instanceof MooringTemplate) { MooringTemplate mt = (MooringTemplate)tpl; if (mt.getResources().contains(tow)) iks.add(ik); } } if (!iks.isEmpty()) for (int j=0; j iks = new ArrayList(); for (OperationTemplate tpl : templates) { int ik = templates.indexOf(tpl); if (tpl instanceof LoadingTemplate) { LoadingTemplate mt = (LoadingTemplate)tpl; if (mt.getResources().contains(le)) iks.add(ik); } if (tpl instanceof BunkeringTemplate) { BunkeringTemplate bt = (BunkeringTemplate)tpl; if (bt.getResources().contains(le)) iks.add(ik); } } if (!iks.isEmpty()) for (int j=0; j iks = new ArrayList(); for (OperationTemplate tpl : templates) { int ik = templates.indexOf(tpl); if (tpl instanceof BunkeringTemplate) { BunkeringTemplate bt = (BunkeringTemplate)tpl; if (bt.getBunker().equals(bk)) iks.add(ik); } } if (!iks.isEmpty()) for (int j=0; j mrks = new ArrayList(); List> opbs = new ArrayList>(); for (TransportShip ship : ships) opbs.add(new ArrayList()); boolean filled = false; for (OperationTemplate tpl : templates) { int ik = templates.indexOf(tpl); if (tpl instanceof MooringTemplate) { MooringTemplate mt = (MooringTemplate)tpl; if (mt.getBerth().equals(bt)) { mrks.add(ik); int ind = ships.indexOf(mt.getMoorer()); if (ind>=0) { opbs.get(ind).add(ik); filled = true; } } } if (tpl instanceof LoadingTemplate) { LoadingTemplate lt = (LoadingTemplate)tpl; if (lt.getBerth().equals(bt)) { int ind = ships.indexOf(lt.getLoader()); if (ind>=0) { opbs.get(ind).add(ik); filled = true; } } } if (tpl instanceof BunkeringTemplate) { BunkeringTemplate bkt = (BunkeringTemplate)tpl; if (bkt.getBerth().equals(bt)) { int ind = ships.indexOf(bkt.getLoader()); if (ind>=0) { opbs.get(ind).add(ik); filled = true; } } } } // На причале одновременно выполняется только одна операция швартовки if (!mrks.isEmpty()) for (int j=0; j vsops : opbs) { if (!vsops.isEmpty()) { nVess ++; String vsop = " +1 "; for (Integer i : vsops) vsop += xij(i,j,nTimes,false) + " "; clause += vsop; } } writer.write(clause + " >= " + (nVess-1) + " ; \n"); nCons++; } } // Суда writer.write("* For Vessels \n"); for (MovingObject vs : vss) { List mvks = new ArrayList(); List loks = new ArrayList(); List mrks = new ArrayList(); for (OperationTemplate tpl : templates) { int ik = templates.indexOf(tpl); // Перемещения if (tpl instanceof MovingTemplate) { MovingTemplate mt = (MovingTemplate)tpl; if (mt.getMover().equals(vs)) mvks.add(ik); } // Погрузка if (tpl instanceof LoadingTemplate) { LoadingTemplate lt = (LoadingTemplate)tpl; if (lt.getLoader().equals(vs)) loks.add(ik); } // Швартовка if (tpl instanceof MooringTemplate) { MooringTemplate rt = (MooringTemplate)tpl; if (rt.getMoorer().equals(vs)) mrks.add(ik); } // Бункеровка if (tpl instanceof BunkeringTemplate) { BunkeringTemplate bt = (BunkeringTemplate)tpl; if (bt.getLoader().equals(vs)) loks.add(ik); } } // Судно только в одном перемещении и при этом не может быть ни под погрузкой, ни под швартовкой if (!mvks.isEmpty()) { int nLM = loks.size()+mrks.size()+1; for (int j=0; j0) { String res = "+1 " + xij(ik,0,nTimes,false) + " +1 "+xij(ik,0,nTimes,true); for (int k=0; k= 1 ;\n"); nCons++; for (int j=1; j= 0 ;\n"); nCons++; } } } // Ограничения на объем хранилищ. Проверить!!! writer.write("* Current Storage Volume Constraints \n"); for (Storage st : storages) { int V = (int)st.getVolume(); double V0 = 0; for (StorageState sst : storageInitialState) if (sst.getStorage().equals(st)) { V0 = (int)sst.getCargoState(); break; } CargoFlow ccf = null; for (CargoFlow cf : cargoFlows) if (cf.getStorage().equals(st)) { ccf = cf; break; } List lts = new ArrayList(); for (OperationTemplate tpl : templates) { if (tpl instanceof LoadingTemplate) { LoadingTemplate lt = (LoadingTemplate)tpl; if (lt.getStorage().equals(st)) lts.add(lt); } } if (lts.size()>0) { for (int j=0; j= " + (int)(-sumV) + " ;\n"; writer.write(cl1); nCons++; String cl2 = clause + " <= " + (int)(V-sumV) + " ;\n"; writer.write(cl2); nCons++; } } } // Определение локационных переменных writer.write("* Location Variables \n"); for (MovingObject v : vss) { // Нахождение начального состояния для судна. Потом читать из незавершенных операций MovingObjectState iniState = null; int iniTime = 0; boolean iniMoored = false; for (MovingObjectState state : vesselInitialState) if (state.getVessel().equals(v)) { iniState = state; break; } int r = vss.indexOf(v); for (Berth berth : berths) { int b = berths.indexOf(berth); // Сперва ограничения на начальное состояние if (iniState!=null && iniState.getLocation().equals(berth)) { // До прибытия for(int j=0; j rb_plus = new ArrayList(); List rb_minus = new ArrayList(); List rm_plus = new ArrayList(); List rm_minus = new ArrayList(); for (OperationTemplate tp : templates) { if (tp instanceof MovingTemplate) { int idx = templates.indexOf(tp); MovingTemplate mtp = (MovingTemplate)tp; // Перемещение основного судна if (mtp.getMover().equals(v)) { if (mtp.getDestination().equals(berth)) rb_plus.add(idx); if (mtp.getStartLocation().equals(berth)) rb_minus.add(idx); } // Перемещение его помоганцев for (Tow tow : mtp.getResources()) if (tow.equals(v)) { if (mtp.getDestination().equals(berth)) rb_plus.add(idx); if (mtp.getStartLocation().equals(berth)) rb_minus.add(idx); } } // TODO: отработка швартовки if (tp instanceof MooringTemplate) { int idx = templates.indexOf(tp); MooringTemplate mtp = (MooringTemplate)tp; // Перемещение основного судна if (mtp.getMoorer().equals(v)) { if (mtp.getStartLocation().equals(berth) && mtp.isDirect()) // Пришвартовка { rm_plus.add(idx); rb_minus.add(idx); } if (mtp.getStartLocation().equals(berth) && (!mtp.isDirect())) // Отшвартовка { rm_minus.add(idx); rb_plus.add(idx); } } } } if (true) //(rb_plus.size()>0 && rb_minus.size()>0) { for (int j=1; j0 && rm_minus.size()>0) { for (int j=1; j resources_f = new ArrayList(); // Свободные List resources_m = new ArrayList(); // Пришвартованные Berth b = tp.getStartLocation(); boolean isAlways = true; if (tp instanceof LoadingTemplate) { int idx = vss.indexOf(((LoadingTemplate)tp).getLoader()); if (b.getIsRaid() || (!isMooring)) resources_f.add(idx); else resources_m.add(idx); for (MovingObject mo : ((LoadingTemplate)tp).getResources()) resources_f.add(vss.indexOf(mo)); } if (tp instanceof MooringTemplate) { int idx = vss.indexOf(((MooringTemplate)tp).getMoorer()); if (((MooringTemplate)tp).isDirect()) resources_f.add(idx); else resources_m.add(idx); for (Tow tow : ((MooringTemplate)tp).getResources()) resources_f.add(vss.indexOf(tow)); isAlways = false; } if (tp instanceof MovingTemplate) { int idx = vss.indexOf(((MovingTemplate)tp).getMover()); resources_f.add(idx); for (Tow tow : ((MovingTemplate)tp).getResources()) resources_f.add(vss.indexOf(tow)); isAlways = false; } int bi = berths.indexOf(b); for (int j=0; j0) clause = "-1 " + xij(i, j, nTimes, true) + " " + xij(i, j-1, nTimes, false) + " +1 " + xij(i, j, nTimes, true) +" " + xij(i, j-1, nTimes, false); String clause_f = clause; String clause_m = clause; if (resources_f.size()>0) { for (Integer r : resources_f) clause_f += " " + wrbj(r, bi, j, nBerths, nTimes, nVars, isMooring, false, true); if (isAlways || j==0) writer.write(clause_f + " >= 1 ;\n"); else writer.write(clause_f + " >= 0 ;\n"); nCons++; } if (resources_m.size()>0) { for (Integer r : resources_m) clause_m += " " + wrbj(r, bi, j, nBerths, nTimes, nVars, isMooring, true, true); if (isAlways || j==0) writer.write(clause_m + " >= 1 ;\n"); else writer.write(clause_m + " >= 0 ;\n"); nCons++; } } } // Состояние загрузки судов writer.write("* Ship Loading States \n"); // Тут пок огшраничение только на местонахождение транспортных судов for (TransportShip s : ships) { StorageState state1 = null; StorageState state2 = null; MovingObjectState eState = null; for (StorageState state : storageInitialState) if (state.getStorage().equals(s)) { state1 = (StorageState)state; break; } for (StorageState state : storageEndState) if (state.getStorage().equals(s)) { state2 = (StorageState)state; break; } for (MovingObjectState state : vesselEndState) if (state.getVessel().equals(s)) { eState = (MovingObjectState)state; break; } for (Cargo c : cargoes) { 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(); List vc = new ArrayList(); List intens = new ArrayList(); for (OperationTemplate tp : templates) if (tp instanceof LoadingTemplate) { int i = templates.indexOf(tp); LoadingTemplate ltp = (LoadingTemplate)tp; if (ltp.getLoader().equals(s) && ltp.getStorage().getCargo().equals(c)) { vc.add(i); intens.add((int)ltp.getIntensity()); } } for (int j=0; j0) clause += " +" + intens.get(counter) + " " +xij(vci, k, nTimes, true); if (intens.get(counter)<0) clause += " " + intens.get(counter) + " " +xij(vci, k, nTimes, true); counter++; } } if (clause.length()>0) { if (j= -" + start + " ;\n"); nCons++; } // Ограничение на грузоподъемность судна int maxLoad = (int)(s.getCargoMax()+1.0); if (sumplus > (maxLoad - start)) { writer.write(clause + " <= " + (maxLoad - start) + " ;\n"); nCons++; } } else { // Конечное состояние судна writer.write(clause + " = " + (finish - start) + " ;\n"); nCons++; } } } } // Нахождение всех судов в конечный момент в нужном состоянии writer.write("* Final Ship Locations \n"); if (eState!=null) { int vi = vss.indexOf(s); for (Berth berth : berths) { int bi = berths.indexOf(berth); String clause = " +1 "+wrbj(vi, bi, nTimes-1, nBerths, nTimes, nVars, isMooring, false, true) + " = "; if (eState.getLocation().equals(berth)) { writer.write(clause + "1 ;\n"); nCons++; } else { writer.write(clause + "0 ;\n"); nCons++; } } } } // Невозможность одновременного нахождения двух пришвартованных судов у одного причала writer.write("* No more than 1 vessel moored to berth \n"); if (isMooring) { for (Berth b : berths) { if (b.getIsRaid()) continue; int bdx = berths.indexOf(b); for (int j=1; j