コード例 #1
0
        private IEnumerable <Dictionary <TK, TD> > Ac3Search(CspProblem <TK, TD> problem)
        {
            NodesVisited  = 0L;
            SolutionCount = 0L;

            foreach (var assignment in Search())
            {
                yield return(assignment);
            }


            IEnumerable <Dictionary <TK, TD> > Search()
            {
                if (problem.Complete)
                {
                    SolutionCount++;
                    yield return(problem.Assignment);
                }
                else
                {
                    var variable = problem.NextUnassigned(SelectVariableHeuristic);


                    foreach (var value in variable.OrderDomainValues(OrderDomainHeuristic))
                    {
                        NodesVisited++;
                        variable.Value = value;
                        if (variable.Consistent)
                        {
                            var removals = Ac3(problem, out var isConsistent);

                            if (isConsistent)
                            {
                                // try finding solution
                                foreach (var solution in Search().Where(s => s is not null))
                                {
                                    yield return(solution);
                                }
                            }

                            foreach (var(v, removalCount) in removals)
                            {
                                v.RestorePreviousDomain(removalCount - 1);
                            }
                        }

                        variable.Assigned = false;
                    }

                    yield return(null);
                }
            }
        }
コード例 #2
0
        private IEnumerable <Dictionary <TK, TD> > ForwardCheckingSearch(CspProblem <TK, TD> problem)
        {
            NodesVisited  = 0L;
            SolutionCount = 0L;
            foreach (var assignment in Search())
            {
                yield return(assignment);
            }

            IEnumerable <Dictionary <TK, TD> > Search()
            {
                if (problem.Complete)
                {
                    SolutionCount++;
                    yield return(problem.Assignment);
                }
                else
                {
                    var variable = problem.NextUnassigned(SelectVariableHeuristic);
                    foreach (var value in variable.OrderDomainValues(OrderDomainHeuristic))
                    {
                        NodesVisited++;
                        variable.Value = value;

                        if (variable.Consistent)
                        {
                            var emptyDomainFound = false;
                            var removals         = new List <Variable <TK, TD> >();
                            // forward checking ->
                            // remove from Variables connected by constraints
                            // the values that are inconsistent with selected value
                            foreach (var v in variable.Constraints
                                     .Where(c => !c.VariableTwo.Assigned)
                                     .Select(c => c.VariableTwo))
                            {
                                var toRemove = v.Domain.Where(d => !v.CheckConsistency(d)).ToArray();
                                if (!toRemove.Any())
                                {
                                    continue;
                                }

                                v.RemoveFromDomain(toRemove);
                                removals.Add(v);
                                if (v.Domain.Any())
                                {
                                    continue;
                                }

                                emptyDomainFound = true;
                                break;
                            }

                            if (emptyDomainFound)
                            {
                                yield return(null);
                            }
                            else
                            {
                                // try finding solution
                                foreach (var solution in Search().Where(s => s is not null))
                                {
                                    yield return(solution);
                                }
                            }

                            // restore domains to previous state
                            foreach (var v in removals)
                            {
                                v.RestorePreviousDomain();
                            }
                        }

                        variable.Assigned = false;
                    }

                    yield return(null);
                }
            }
        }