package inport.ConversionUtils; import inport.*; import java.io.*; import java.util.*; public class MZnResultsResolver { public static void resolveMiniZincResults(TaskCase taskCase, String fileName) { ArrayList operations = null; Integer result = null; try (FileInputStream fstream = new FileInputStream(fileName)) { BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); String line; Map>> arrays = new TreeMap<>(); while (((line = br.readLine()) != null)) { line = line.trim(); if (line.equals("")) { continue; } int pos = 0; while ((pos < line.length()) && (line.charAt(pos) != ' ')) { pos++; } String name = line.substring(0, pos); if (name.equals("=====UNSATISFIABLE=====")) { result = -1; break; } if (name.equals("----------")) { break; } if (name.matches("\\d+")) { if (result != null) { continue; } result = Integer.parseInt(name); continue; } while ((pos < line.length()) && (line.charAt(pos) != '[') && (line.charAt(pos) != '{')) { pos++; } int arrayFirstDim = ((int) taskCase.getPlanningInterval()) + 2; if (line.charAt(pos) == '{') { pos++; int nextPos = pos; while (line.charAt(nextPos) != '}') { nextPos++; } String []dimensions = line.substring(pos, nextPos).trim().split(" "); if (dimensions.length > 0) { arrayFirstDim = Integer.valueOf(dimensions[0].trim()); } pos = nextPos + 1; while (line.charAt(pos) != '[') { pos++; } } int pos2 = pos; while ((pos2 < line.length()) && (line.charAt(pos2) != ']')) { pos2++; } String values = line.substring(pos + 1, pos2); ArrayList elements = new ArrayList<>(); for (String val : values.split(",")) { elements.add(val.trim()); } if ((arrayFirstDim != 0) && (elements.size() % arrayFirstDim == 0)) { ArrayList> res = new ArrayList<>(); for (int i = 0; i < elements.size(); i += arrayFirstDim) { ArrayList subRes = new ArrayList<>(); for (int j = 0; j < arrayFirstDim; j++) { subRes.add(elements.get(i + j)); } res.add(subRes); } arrays.put(name, res); } } if (result == null) { throw new ParserException("No result in input"); } for (String keyArray : Arrays.asList("op_status", "participation_as_resource")) { if (! arrays.containsKey(keyArray)) { if (result == -1) { operations = new ArrayList<>(); } else { throw new ParserException("No \"" + keyArray + "\" in input"); } } } if (result != -1) { Task task = new Task(taskCase, ""); operations = new ArrayList<>(); ArrayList> opStatus = arrays.get("op_status"); ArrayList templates = new ArrayList<>(taskCase.getTemplates()); if (taskCase.isTypified()) { templates = Task.renumberOperations(taskCase); } ArrayList> cargoOpIntensity; if (arrays.containsKey("cargo_op_intensity")) { cargoOpIntensity = arrays.get("cargo_op_intensity"); } else { cargoOpIntensity = new ArrayList<>(); for (int opNo = 0; opNo < opStatus.size(); opNo++) { cargoOpIntensity.add(new ArrayList<>()); for (String val : opStatus.get(opNo)) { if (val.equals("true") && (templates.get(opNo - 1) instanceof LoadingTemplate)) { LoadingTemplate op = (LoadingTemplate)templates.get(opNo - 1); cargoOpIntensity.get(opNo).add(Integer.toString((int)Math.ceil(Math.abs(op.getIntensity())))); } else { cargoOpIntensity.get(opNo).add("0"); } } } } Map operationById = new TreeMap<>(); for (OperationTemplate operation : taskCase.getTemplates()) { operationById.put(operation.getId(), operation); } Map objByNo = new TreeMap<>(); ArrayList> isFixed; for (MovingObject obj : task.getMovingObjects()) { objByNo.put(task.getMObjNumberById().get(obj.getId()), obj); } isFixed = task.getIsFixedArray(); Set oldSolution = new TreeSet<>(); for (Operation op : taskCase.getFixedOperations()) { if (op.getFixation()) { oldSolution.add(op.toString()); } } for (int opNo = 1; opNo < opStatus.size(); opNo++) { int duration = 0; int t = 1; boolean lastFixation = false; while (t < opStatus.get(opNo).size()) { boolean isOpLogicallyInterrupted = false; if (opStatus.get(opNo).get(t).equals("true") && (lastFixation != isFixed.get(opNo).get(t)) && (duration != 0)) { // У операции изменилась фиксация. isOpLogicallyInterrupted = true; } if (opStatus.get(opNo).get(t).equals("false") && (duration != 0)) { // Операция просто закончилась. isOpLogicallyInterrupted = true; } if ((! cargoOpIntensity.get(opNo).get(t - 1).equals(cargoOpIntensity.get(opNo).get(t))) && (duration != 0)) { // Изменилась интенсивность погрузки. isOpLogicallyInterrupted = true; } if (isOpLogicallyInterrupted) { // Добавляем новую операцию. Operation op = new Operation(); op.setStart(t - duration - 1); op.setDuration(duration); op.setTemplate(operationById.get(templates.get(opNo - 1).getId())); if (taskCase.isTypified()) { op.setExecutor(Utils.getExecutor(templates.get(opNo - 1))); ArrayList resources = new ArrayList<>(); // TODO ускорить. ArrayList> opOfResource = arrays.get("participation_as_resource"); for (int obj = 1; obj < opOfResource.size(); obj++) { if (opOfResource.get(obj).get(t - 1).equals(Integer.toString(opNo))) { resources.add(objByNo.get(obj - 1)); } } op.setResources(resources); } { // Установка бункеровщика. OperationTemplate template = templates.get(opNo - 1); if (template instanceof LoadingTemplate) { LoadingTemplate operation = (LoadingTemplate)template; if (operation.getBunker().isPresent()) { op.setBunker(operation.getBunker()); } } } if (! cargoOpIntensity.get(opNo).get(t - 1).equals("0")) { op.setIntensity(Optional.of(Integer.valueOf(cargoOpIntensity.get(opNo).get(t - 1)))); } op.setFixation(true); if (! oldSolution.contains(op.toString())) { op.setFixation(false); } operations.add(op); duration = 0; } if (opStatus.get(opNo).get(t).equals("true") && (lastFixation != isFixed.get(opNo).get(t))) { // Остаёмся на месте. lastFixation = isFixed.get(opNo).get(t); continue; } if (opStatus.get(opNo).get(t).equals("true")) { duration++; } else { duration = 0; } if ((0 <= t) && (t < isFixed.get(opNo).size())) { lastFixation = isFixed.get(opNo).get(t); } t++; } } } taskCase.setSolution(operations); taskCase.setSolution_result(result); } catch (IOException e) { throw new UncheckedIOException(e); } } }