/** * Establishes arc-consistency for (xi, xj). * @return value true if the domain of xi was reduced. */ private bool makeArcConsistent(VAR xi, VAR xj, IConstraint <VAR, VAL> constraint, CSP <VAR, VAL> csp) { Domain <VAL> currDomain = csp.getDomain(xi); ICollection <VAL> newValues = CollectionFactory.CreateQueue <VAL>(); Assignment <VAR, VAL> assignment = new Assignment <VAR, VAL>(); foreach (VAL vi in currDomain) { assignment.add(xi, vi); foreach (VAL vj in csp.getDomain(xj)) { assignment.add(xj, vj); if (constraint.isSatisfiedWith(assignment)) { newValues.Add(vi); break; } } } if (newValues.Size() < currDomain.size()) { csp.setDomain(xi, new Domain <VAL>(newValues)); return(true); } return(false); }
/** * Ignores constraints which are not binary. */ private int countLostValues(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment, VAR var, VAL value) { int result = 0; Assignment <VAR, VAL> assign = new Assignment <VAR, VAL>(); assign.add(var, value); foreach (IConstraint <VAR, VAL> constraint in csp.getConstraints(var)) { if (constraint.getScope().Size() == 2) { VAR neighbor = csp.getNeighbor(var, constraint); if (!assignment.contains(neighbor)) { foreach (VAL nValue in csp.getDomain(neighbor)) { assign.add(neighbor, nValue); if (!constraint.isSatisfiedWith(assign)) { ++result; } } } } } return(result); }
public override Assignment <VAR, VAL> solve(CSP <VAR, VAL> csp) { Assignment <VAR, VAL> assignment = new Assignment <VAR, VAL>(); // Select a root from the List of Variables VAR root = _useRandom ? Util.selectRandomlyFromList(csp.getVariables()) : csp.getVariables().Get(0); // Sort the variables in topological order ICollection <VAR> orderedVars = CollectionFactory.CreateQueue <VAR>(); IMap <VAR, IConstraint <VAR, VAL> > parentConstraints = CollectionFactory.CreateInsertionOrderedMap <VAR, IConstraint <VAR, VAL> >(); topologicalSort(csp, root, orderedVars, parentConstraints); if (csp.getDomain(root).isEmpty()) { return(null); // CSP has no solution! (needed if orderedVars.size() == 1) } // Establish arc consistency from top to bottom (starting at the bottom). csp = csp.copyDomains(); // do not change the original CSP! for (int i = orderedVars.Size() - 1; i > 0; i--) { VAR var = orderedVars.Get(i); IConstraint <VAR, VAL> constraint = parentConstraints.Get(var); VAR parent = csp.getNeighbor(var, constraint); if (makeArcConsistent(parent, var, constraint, csp)) { fireStateChanged(csp, null, parent); if (csp.getDomain(parent).isEmpty()) { return(null); // CSP has no solution! } } } // Assign values to variables from top to bottom. for (int i = 0; i < orderedVars.Size(); ++i) { VAR var = orderedVars.Get(i); foreach (VAL value in csp.getDomain(var)) { assignment.add(var, value); if (assignment.isConsistent(csp.getConstraints(var))) { fireStateChanged(csp, assignment, var); break; } } } return(assignment); }
private Assignment <VAR, VAL> generateRandomAssignment(CSP <VAR, VAL> csp) { Assignment <VAR, VAL> result = new Assignment <VAR, VAL>(); foreach (VAR var in csp.getVariables()) { VAL randomValue = Util.selectRandomlyFromList(csp.getDomain(var).asList()); result.add(var, randomValue); } return(result); }
/** * Primitive operation, ordering the domain values of the specified variable. */ protected override IEnumerable <VAL> orderDomainValues(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment, VAR var) { if (valSelectionStrategy != null) { return(valSelectionStrategy.apply(csp, assignment, var)); } else { return(csp.getDomain(var)); } }
/** Returns the values of Dom(var) in a special order. The least constraining value comes first. */ public ICollection <VAL> apply(CSP <VAR, VAL> csp, Assignment <VAR, VAL> assignment, VAR var) { ICollection <Pair <VAL, int> > pairs = CollectionFactory.CreateQueue <Pair <VAL, int> >(); foreach (VAL value in csp.getDomain(var)) { int num = countLostValues(csp, assignment, var, value); pairs.Add(new Pair <VAL, int>(value, num)); } pairs.Sort(new PairComparer <VAL>()); ICollection <VAL> obj = CollectionFactory.CreateQueue <VAL>(); foreach (Pair <VAL, int> val in pairs) { obj.Add(val.GetFirst()); } return(obj); }
/** Returns variables from <code>vars</code> which are the best with respect to MRV. */ public ICollection <VAR> apply(CSP <VAR, VAL> csp, ICollection <VAR> vars) { ICollection <VAR> result = CollectionFactory.CreateQueue <VAR>(); int mrv = int.MaxValue; foreach (VAR var in vars) { int rv = csp.getDomain(var).size(); if (rv <= mrv) { if (rv < mrv) { result.Clear(); mrv = rv; } result.Add(var); } } return(result); }
private VAL getMinConflictValueFor(VAR var, Assignment <VAR, VAL> assignment, CSP <VAR, VAL> csp) { ICollection <IConstraint <VAR, VAL> > constraints = csp.getConstraints(var); Assignment <VAR, VAL> testAssignment = assignment.Clone(); int minConflict = int.MaxValue; ICollection <VAL> resultCandidates = CollectionFactory.CreateQueue <VAL>(); foreach (VAL value in csp.getDomain(var)) { testAssignment.add(var, value); int currConflict = countConflicts(testAssignment, constraints); if (currConflict <= minConflict) { if (currConflict < minConflict) { resultCandidates.Clear(); minConflict = currConflict; } resultCandidates.Add(value); } } return((!resultCandidates.IsEmpty()) ? Util.selectRandomlyFromList <VAL>(resultCandidates) : default(VAL)); }