private async Task <Assignment <Tval> > Backtrack(ConstraintSatisfactionProblem <Tval> csp, Assignment <Tval> assignment) { if (assignment.IsComplete(csp.GetVariables())) { return(assignment); } Variable <Tval> variable = variableSelectionStrategy.SelectUnassignedVariable(csp, assignment); foreach (Tval value in domainValueSelectionStragety.getOrderedDomainValues(variable, assignment, csp)) { assignment.Assign(variable, value); OnVariableAssigned(variable, value); InferenceResults <Tval> inference = new InferenceResults <Tval>(); inference.StoreDomainForVariable(variable, variable.GetDomain()); variable.UpdateDomain(new Domain <Tval>(value)); // it should already be consistent if it reached this point // since we make a pre-solving inference //bool isConsistent = assignment.IsConsistent(csp.GetAllDiffConstraints()); //if (isConsistent) if (true) { inference = await inferenceStrategy.Infer(csp, variable, value, inference); if (inference.IsAssignmentConsistent()) { Assignment <Tval> result = await Backtrack(csp, assignment); if (result != null) { return(result); } } } assignment.RemoveAssignment(variable); OnAssignmentRemoved(variable, value); inference.RestoreOldDomains(); } return(null); }
public override async Task <Assignment <Tval> > Solve(ConstraintSatisfactionProblem <Tval> csp, Assignment <Tval> initialAssignment = null) { initialAssignment = initialAssignment ?? new Assignment <Tval>(); InferenceResults <Tval> preliminaryResults = await inferenceStrategy.Infer(csp); if (preliminaryResults.IsAssignmentConsistent()) { Assignment <Tval> solution = await Backtrack(csp, initialAssignment); if (solution != null) { OnSolutionFound(solution); return(solution); } } OnNoSolutionFound(); return(null); }
// we assume that, if the variable has already been assigned, // the old value of the variable has been removed // by an inference at a previous step, and therefore it is not // present in the domain of its neighbours, but since we might // have another variable that has the same value in its neighbour // (the assignment was not consistent) there is going to be another // inference to rule out inconsistent domains. public override async Task <InferenceResults <Tval> > UpdateVariable(ConstraintSatisfactionProblem <Tval> csp, Assignment <Tval> assignment, Variable <Tval> variable, Tval value) { if (csp == null) { throw new ArgumentNullException("csp"); } if (assignment == null) { throw new ArgumentNullException("assignment"); } if (variable == null) { throw new ArgumentNullException("variable"); } InferenceResults <Tval> removeInference = await RemoveVariable(csp, assignment, variable); assignment.Assign(variable, value); variable.UpdateDomain(new Domain <Tval>(value)); return(await inferenceStrategy.Infer(csp, variable, value, removeInference, false)); }