package inport; import javafx.util.Pair; import java.io.FileWriter; import java.io.IOException; import java.util.*; import java.util.function.Function; public class ConversionUtil { static class PairComparator implements Comparator> { public int compare(Pair p1, Pair p2) { int res = p1.getKey().compareTo(p2.getKey()); if (res != 0) { return res; } else { return p1.getValue().compareTo(p2.getValue()); } } } static private void write2DArray(FileWriter writer, String name, ArrayList>> operations) throws IOException { writer.write(name + " = \n"); boolean isFirst0 = true; for (ArrayList> m1 : operations) { if (isFirst0) { isFirst0 = false; writer.write(" [| "); } else { writer.write(" | "); } boolean isFirst1 = true; for (ArrayList m2 : m1) { if (isFirst1) { isFirst1 = false; } else { writer.write(", "); } writer.write("{"); boolean isFirst2 = true; for (Integer val : m2) { if (isFirst2) { isFirst2 = false; } else { writer.write(", "); } writer.write((val + 1) + ""); } writer.write("}"); } writer.write("\n"); } writer.write(" |];\n"); } static private void writeArray(FileWriter writer, String name, ArrayList data, Function f) throws IOException { writer.write(name + " = ["); for (int i = 0; i < data.size(); i++) { if (i != 0) { writer.write(", "); } writer.write(f.apply(data.get(i)).toString() + ""); } writer.write("];\n"); } static private void writeArray(FileWriter writer, String name, ArrayList data) throws IOException { writeArray(writer, name, data, (T val) -> val); } static private String setToString(Set s) { StringBuilder res = new StringBuilder(); res.append("{"); boolean isFirst = true; for (T t : s) { if (isFirst) { isFirst = false; } else { res.append(", "); } res.append(t.toString()); } res.append("}"); return res.toString(); } static private ArrayList integerArray(int size, int initVal) { ArrayList res = new ArrayList<>(); for (int i = 0; i < size; i++) { res.add(initVal); } return res; } 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()); 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"); ArrayList movingObjects = new ArrayList<>(); Map mObjNumberById = new TreeMap<>(); for (MovingObject obj : task.getShips()) { mObjNumberById.put(obj.getId(), movingObjects.size()); movingObjects.add(obj); } for (MovingObject obj : task.getTows()) { 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<>()); } } for (int i = 0; i < operationTemplates.size(); i++) { if (operationTemplates.get(i) instanceof MovingTemplate) { MovingTemplate op = (MovingTemplate)operationTemplates.get(i); ArrayList movingObjN = new ArrayList<>(); for (MovingObject obj : op.getResources()) { movingObjN.add(mObjToN.apply(obj)); } movingObjN.add(mObjToN.apply(op.getMover())); for (Integer n : movingObjN) { arrivalOp.get(n).get(locationNumberById.get(new Pair<>(op.getDestination().getId(), false))).add(i); departureOp.get(n).get(locationNumberById.get(new Pair<>(op.getStartLocation().getId(), false))).add(i); } } } write2DArray(writer, "arrival_op", arrivalOp); write2DArray(writer, "departure_op", departureOp); } { // Начальные положения объектов. ArrayList initialStates = integerArray(movingObjects.size(), 0); for (MovingObjectState state : task.getVesselInitialState()) { initialStates.set(mObjToN.apply(state.getVessel()), locationNumberById.get(new Pair<>(state.getLocation().getId(), false)) + 1); } writeArray(writer, "initial_m_obj_loc", initialStates); } // TODO окна погоды. 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); int duration = (int)Math.ceil(op.getDuration()); operationsDuration.set(i, duration); isMovingObj.add(true); } else { isMovingObj.add(false); } } writeArray(writer, "operations_duration", operationsDuration); writeArray(writer, "is_moving_operation", isMovingObj); } { // Конечные положения объектов. ArrayList finalStates = integerArray(movingObjects.size(), 0); for (MovingObjectState state : task.getVesselEndState()) { finalStates.set(mObjToN.apply(state.getVessel()), locationNumberById.get(new Pair<>(state.getLocation().getId(), false))); } writeArray(writer, "final_m_obj_loc", finalStates); } { // Наличие всех ресурсов на месте. 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, locationNumberById.get(new Pair<>(op.getStartLocation().getId(), false))); } // TODO швартовка, погрузка. } writeArray(writer, "operations_start_loc", operationsStartLoc); writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString); } } } }