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);
        }
Пример #2
0
        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);
        }