private boolean branchAndBoundHelper(MetaVariable metaVariable) { if (metaVariable == null) return false; preBacktrack(); if (this.g.getRoot() == null) this.g.addVertex(currentVertex); ConstraintNetwork cn = metaVariable.getConstraintNetwork(); logger.fine("Solving conflict: " + metaVariable); ConstraintNetwork[] values = metaVariable.getMetaConstraint().getMetaValues(metaVariable); if (metaVariable.getMetaConstraint().valOH != null) Arrays.sort(values, metaVariable.getMetaConstraint().valOH); if (values == null || values.length == 0) { this.g.addEdge(new NullConstraintNetwork(null), currentVertex, new TerminalNode(false)); logger.fine("Failure... (1)"); } else { for (ConstraintNetwork value : values) { if (animationTime != 0) { try { Thread.sleep(animationTime); } catch (InterruptedException e) { e.printStackTrace(); } } logger.fine("Trying value: " + Arrays.toString(value.getConstraints())); if (hasConflictClause(value)) continue; this.addResolver(cn, value); setUpperBound(); // System.out.println("test: " + "U: " + getUpperBound() + " L: " + getLowerBound()); if (getUpperBound() <= getLowerBound()) { this.retractResolver(cn, value); continue; } logger.fine("Success..."); metaVariable.getMetaConstraint().markResolvedSub(metaVariable, value); MetaVariable newCon = this.getConflict(); if (newCon != null) { this.g.addEdge(value, currentVertex, newCon); currentVertex = newCon; } if (newCon == null) setLowerBound(); if (branchAndBoundHelper(newCon)) return true; logger.fine("Retracting value: " + Arrays.toString(value.getConstraints())); this.retractResolver(cn, value); logger.fine("Failure... (2)"); } } resetFalseClause(); logger.fine("Backtracking..."); currentVertex = this.g.getParent(currentVertex); postBacktrack(metaVariable); return false; }
@Override public String toString() { return variable.getName() + "=" + expression.toString() + ";"; }
/** * This backtrack method uses serialization to back up {@link ConstraintNetwork}s before * branching. This allows to backtrack without propagation - but is very memory intensive. In * practice, this does not work on reasonably sized problems. */ private boolean backtrackHelperWithSerialization(MetaVariable metaVariable) { preBacktrack(); if (this.g.getRoot() == null) this.g.addVertex(currentVertex); ConstraintNetwork mostProblematicNetwork = metaVariable.getConstraintNetwork(); logger.fine("Solving conflict: " + metaVariable); ConstraintNetwork[] values = metaVariable.getMetaConstraint().getMetaValues(metaVariable); if (metaVariable.getMetaConstraint().valOH != null && values != null) Arrays.sort(values, metaVariable.getMetaConstraint().valOH); if (values == null || values.length == 0) { this.g.addEdge(new NullConstraintNetwork(null), currentVertex, new TerminalNode(false)); logger.fine("Failure (1)..."); } else { for (ConstraintNetwork value : values) { if (animationTime != 0) { try { Thread.sleep(animationTime); } catch (InterruptedException e) { e.printStackTrace(); } } String valString = ""; if (value.getVariables().length != 0) valString += "Vars = " + Arrays.toString(value.getVariables()); if (value.getConstraints().length != 0) valString += " Cons = " + Arrays.toString(value.getConstraints()); logger.fine("Trying value: " + valString); this.backedUpCNs.add(backupCNs(this)); /** * PRINT INFO ** */ /* long sizeOfBackup = 0; for (HashMap<ConstraintSolver,byte[]> oneHM : backedUpCNs) { for (byte[] oneCN : oneHM.values()) sizeOfBackup += oneCN.length; } DecimalFormat df = new DecimalFormat("#.##"); logger.info("Current backup size: " + df.format((sizeOfBackup/1024.00)) + " KB"); */ /** * END PRINT INFO ** */ if (this.addResolver(mostProblematicNetwork, value)) { this.resolvers.put(mostProblematicNetwork, value); this.metaVarsToMetaCons.put(mostProblematicNetwork, metaVariable.getMetaConstraint()); this.resolversInverseMapping.put(value, mostProblematicNetwork); this.counterMoves++; logger.fine("Success..."); metaVariable.getMetaConstraint().markResolvedSub(metaVariable, value); MetaVariable newConflict = this.getConflict(); if (newConflict == null || breakSearch) { this.g.addEdge(value, currentVertex, new TerminalNode(true)); breakSearch = false; return true; } // addEdege(e,v,v) this.g.addEdge(value, currentVertex, newConflict); currentVertex = newConflict; if (backtrackHelper(newConflict)) return true; logger.fine("Retracting value: " + Arrays.toString(value.getConstraints())); // this.retractResolver(mostProblematicNetwork, value); this.restoreCNs(); this.retractResolverSub(mostProblematicNetwork, value); this.resolvers.remove(mostProblematicNetwork); this.metaVarsToMetaCons.remove(mostProblematicNetwork); this.resolversInverseMapping.remove(value); this.counterMoves--; } else { this.g.addEdge(value, currentVertex, new TerminalNode(false)); logger.fine("Failure... (2)"); } } } logger.fine("Backtracking..."); currentVertex = this.g.getParent(currentVertex); postBacktrack(metaVariable); return false; }
private boolean backtrackHelper(MetaVariable metaVariable) { preBacktrack(); if (this.g.getRoot() == null) this.g.addVertex(currentVertex); ConstraintNetwork mostProblematicNetwork = metaVariable.getConstraintNetwork(); logger.fine("Solving conflict: " + metaVariable); ConstraintNetwork[] values = metaVariable.getMetaConstraint().getMetaValues(metaVariable); if (values != null) for (ConstraintNetwork value : values) value.setAnnotation(metaVariable); if (metaVariable.getMetaConstraint().valOH != null && values != null) { // System.out.println("SORTING with " + metaVariable.getMetaConstraint().valOH.getClass()); Arrays.sort(values, metaVariable.getMetaConstraint().valOH); } if (values == null || values.length == 0) { this.g.addEdge(new NullConstraintNetwork(null), currentVertex, new TerminalNode(false)); logger.fine("Failure (1)..."); } else { for (ConstraintNetwork value : values) { if (animationTime != 0) { try { Thread.sleep(animationTime); } catch (InterruptedException e) { e.printStackTrace(); } } String valString = ""; if (value.getVariables().length != 0) valString += "Vars = " + Arrays.toString(value.getVariables()); if (value.getConstraints().length != 0) valString += " Cons = " + Arrays.toString(value.getConstraints()); logger.fine("Trying value: " + valString); if (this.addResolver(mostProblematicNetwork, value)) { this.resolvers.put(mostProblematicNetwork, value); this.metaVarsToMetaCons.put(mostProblematicNetwork, metaVariable.getMetaConstraint()); this.resolversInverseMapping.put(value, mostProblematicNetwork); this.counterMoves++; logger.fine("Success..."); metaVariable.getMetaConstraint().markResolvedSub(metaVariable, value); MetaVariable newConflict = this.getConflict(); if (newConflict == null || breakSearch) { this.g.addEdge(value, currentVertex, new TerminalNode(true)); breakSearch = false; return true; } // addEdege(e,v,v) this.g.addEdge(value, currentVertex, newConflict); currentVertex = newConflict; if (backtrackHelper(newConflict)) return true; logger.fine("Retracting value: " + Arrays.toString(value.getConstraints())); this.retractResolver(mostProblematicNetwork, value); this.resolvers.remove(mostProblematicNetwork); this.metaVarsToMetaCons.remove(mostProblematicNetwork); this.resolversInverseMapping.remove(value); this.counterMoves--; } else { this.g.addEdge(value, currentVertex, new TerminalNode(false)); logger.fine("Failure... (2)"); } } } logger.fine("Backtracking..."); currentVertex = this.g.getParent(currentVertex); postBacktrack(metaVariable); return false; }