private Assignment <TVar, TVal> RecursiveBacktrack(Assignment <TVar, TVal> currentAssignment, OptimizationProblem <TVar, TVal> problem, CancellationToken cancellationToken) { // This is based on an algorithm from // "Artificial Intelligence: A Modern Approach" 2nd Edition by Stuart Russel and Perter Norvig (page 142). if (currentAssignment.IsComplete(problem.Variables)) { return(currentAssignment); } cancellationToken.ThrowIfCancellationRequested(); Variable <TVar, TVal> variable = VariableSelectionStrategy.SelectUnassignedVariable(problem.Variables, currentAssignment, new Problem <TVar, TVal>(problem)); IEnumerable <TVal> domain = DomainSortStrategy.GetOrderedDomain(variable, currentAssignment, new Problem <TVar, TVal>(problem)); foreach (var value in domain) { var nextAssignment = currentAssignment.Assign(variable, value); if (this.costFunction.Cost(nextAssignment) >= this.best) { continue; } if (nextAssignment.IsConsistent(problem.Constraints)) { var result = RecursiveBacktrack(nextAssignment, problem, cancellationToken); if (result != null) { return(result); } } } return(null); }
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); }