diff --git a/src/inport/ConversionUtils/Utils.java b/src/inport/ConversionUtils/Utils.java index 67e885e7bb9f1dfa8b02102f960bd6f68709c0bf..4ab62221f0b8903cb20e5d80e6207111c19ff0fd 100644 --- a/src/inport/ConversionUtils/Utils.java +++ b/src/inport/ConversionUtils/Utils.java @@ -2,8 +2,22 @@ package inport.ConversionUtils; import inport.*; import java.util.*; +import java.util.function.Function; public class Utils { + public static Collection map(Collection as, Function f) { + Collection b; + try { + b = as.getClass().newInstance(); + } catch (Exception e) { + throw new IllegalArgumentException("Type " + as.getClass() + " needs a parameterless constructor"); + } + for (A x : as) { + b.add(f.apply(x)); + } + return b; + } + static class PairComparator, U extends Comparable> implements Comparator> { public int compare(Pair p1, Pair p2) { int res = p1.getKey().compareTo(p2.getKey()); diff --git a/src/inport/Operation.java b/src/inport/Operation.java index a1615a4884578b8eaaa8f800b52748cfd4534eb3..c98315770b67b53528a91c6555883be0ea08bfb9 100644 --- a/src/inport/Operation.java +++ b/src/inport/Operation.java @@ -117,8 +117,57 @@ public class Operation { public Operation() { } + private static String getTransportName(MovingObject obj) { + if (obj instanceof TransportShip) { + return "судно " + obj.getId(); + } + if (obj instanceof Bunker) { + return "бункеровщик " + obj.getId(); + } + if (obj instanceof Tow) { + return "буксир " + obj.getId(); + } + return (obj.getName().isEmpty()) ? "оборудование " + obj.getId() : obj.getName(); + } + + private static String getShortTransportName(MovingObject obj) { + if ((obj instanceof TransportShip) || (obj instanceof Bunker) || (obj instanceof Tow)) { + return Integer.toString(obj.getId()); + } + return (obj.getName().isEmpty()) ? Integer.toString(obj.getId()) : obj.getName(); + } + + private static String firstCharToUppercase(String s) { + return s.substring(0, 1).toUpperCase() + s.substring(1); + } + + private static String resourcesToString(List resources) { + return "{" + String.join(", ", Utils.map(resources, Operation::getShortTransportName)) + "}"; + } + @Override public String toString() { + return toString(false, null); + } + + public String toString(boolean includeAnnotations, ArrayList maxSizes) { + ArrayList components = getComponentsOfStringValue(includeAnnotations); + StringBuilder sb = new StringBuilder(); + + for (int compNo = 0; compNo < components.size(); compNo++) { + sb.append(components.get(compNo)); + if (maxSizes != null) { + for (int delta = maxSizes.get(compNo) - components.get(compNo).length(); delta > 0; delta--) { + sb.append(" "); + } + } + } + return sb.toString(); + } + + public ArrayList getComponentsOfStringValue(boolean includeAnnotations) { + ArrayList res = new ArrayList<>(); + if (executor == null) { executor = Utils.getExecutor(template); } @@ -126,8 +175,12 @@ public class Operation { resources = Utils.getResources(template); } StringBuilder sb = new StringBuilder(); - sb.append(template.getId()).append("; "); - sb.append(fixation ? "F" : "R").append("; ").append(start).append("; ").append(duration); + + res.add(Integer.toString(template.getId())); + res.add("; " + (fixation ? "F" : "R")); + res.add("; " + start); + res.add("; " + duration); + sb.append(" (").append(executor.getId()).append(" "); sb.append(bunker.map(b -> b.getId() + " ").orElse("")).append("["); boolean isFirst = true; @@ -142,7 +195,68 @@ public class Operation { sb.append("]"); sb.append(intensity.map(i -> " " + i).orElse("")); sb.append(")"); - return sb.toString(); + + res.add(sb.toString()); + + sb = new StringBuilder(); + + if (includeAnnotations) { + sb.append(" \\* "); + if (template instanceof MovingTemplate) { + MovingTemplate o = (MovingTemplate) template; + sb.append(firstCharToUppercase(getTransportName(executor)) + " идёт к причалу " + o.getDestination().getId() + + " от причала " + o.getStartLocation().getId()); + if (! resources.isEmpty()) { + sb.append(" используя буксиры " + resourcesToString(resources)); + } + sb.append("."); + } else if (template instanceof LoadingTemplate) { + LoadingTemplate o = (LoadingTemplate) template; + sb.append(firstCharToUppercase(getTransportName(executor))); + + sb.append(" принимает груз " + o.getCargo().getId()); + if (bunker.isPresent()) { + sb.append(" из бункеровщика " + bunker.get().getId()); + } else { + sb.append(" из хранилища " + o.getStorage().getId()); + } + sb.append(" с интенсивностью " + o.getIntensity()); + sb.append(" у причала " + o.getStartLocation().getId()); + if (! resources.isEmpty()) { + sb.append(" используя оборудование " + resourcesToString(resources)); + } + sb.append("."); + } else if (template instanceof MooringTemplate) { + MooringTemplate o = (MooringTemplate) template; + sb.append(firstCharToUppercase(getTransportName(executor))); + if (o.isDirect()) { + sb.append(" швартуется к причалу "); + } else { + sb.append(" отшвартовывается от причала "); + } + sb.append(o.getStartLocation().getId()); + if (! resources.isEmpty()) { + sb.append(" используя буксиры " + resourcesToString(resources)); + } + sb.append("."); + } + } + res.add(sb.toString()); + return res; + } + + public static ArrayList getMaxSizesOfComponents(Collection operations, boolean includeAnnotations) { + ArrayList res = new ArrayList<>(); + for (Operation operation : operations) { + ArrayList components = operation.getComponentsOfStringValue(includeAnnotations); + for (int i = 0; i < components.size(); i++) { + if (i >= res.size()) { + res.add(0); + } + res.set(i, Math.max(res.get(i), components.get(i).length())); + } + } + return res; } public Operation(String str, diff --git a/src/inport/TaskCase.java b/src/inport/TaskCase.java index 940a959bc96b0d36133c1ac6365bb8edd9ac43e8..8ce85f1bea6556cf195c6dd94618e9a6e3a137f7 100644 --- a/src/inport/TaskCase.java +++ b/src/inport/TaskCase.java @@ -812,19 +812,24 @@ public class TaskCase { writer.write("\n"); writer.write("\nTask Properties"+"\n"); writer.write(planningInterval+"; "+criterionType+"\n"); + { + ArrayList maxSizes = Operation.getMaxSizesOfComponents(fixedOperations, true); - writer.write("\n" + Tag.Fixed_Operations.text + "\n"); - for (Operation op : fixedOperations) { - writer.write(op.toString() + "\n"); + writer.write("\n" + Tag.Fixed_Operations.text + "\n"); + for (Operation op : fixedOperations) { + writer.write(op.toString(true, maxSizes) + "\n"); + } } writer.write("\n"); writer.write("\nSolution"+"\n"); writer.write(solution_result+"\n"); solution.sort(new OperationsComparator()); - - for (Operation c : solution) - writer.write(c.toString()+"\n"); + { + ArrayList maxSizes = Operation.getMaxSizesOfComponents(solution, true); + for (Operation c : solution) + writer.write(c.toString(true, maxSizes) + "\n"); + } writer.flush(); } catch(IOException ex) {