public static BenchmarkResult <TK, TD> BenchmarkFirstOnly <TK, TD>( CspSolver <TK, TD> cspSolver, CspProblem <TK, TD> problem) { var stopWatch = new Stopwatch(); problem.ClearAll(); stopWatch.Start(); var first = cspSolver.FindSolutions(problem).First(); stopWatch.Stop(); var firstNodesVisited = cspSolver.NodesVisited; var firstSolutionTime = stopWatch.ElapsedMilliseconds; problem.ClearAll(); return(new BenchmarkResult <TK, TD>( firstSolutionTime, firstNodesVisited, null, null, null, first)); }
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); } } }
public Variable <TK, TD> SelectVariable(CspProblem <TK, TD> problem) { var maxDegree = int.MinValue; Variable <TK, TD> maxDegreeVariable = null; foreach (var variable in problem.UnassignedVariables) { if (variable.Constraints.Count <= maxDegree) { continue; } maxDegree = variable.Constraints.Count; maxDegreeVariable = variable; } return(maxDegreeVariable); }
public static BenchmarkResult <TK, TD> BenchmarkAll <TK, TD>( CspSolver <TK, TD> cspSolver, CspProblem <TK, TD> problem) { var stopWatch = new Stopwatch(); problem.ClearAll(); stopWatch.Restart(); _ = cspSolver.FindSolutions(problem).Last(); stopWatch.Stop(); problem.ClearAll(); return(new BenchmarkResult <TK, TD>( null, null, stopWatch.ElapsedMilliseconds, cspSolver.NodesVisited, cspSolver.SolutionCount, null)); }
public Variable <TK, TD> SelectVariable(CspProblem <TK, TD> problem) { var minRemaining = int.MaxValue; Variable <TK, TD> failFirstVariable = null; foreach (var variable in problem.UnassignedVariables) { var domainSize = variable.Domain.Count(); if (domainSize >= minRemaining) { continue; } if (domainSize == 0) { return(variable); } minRemaining = domainSize; failFirstVariable = variable; } return(failFirstVariable); }
public EinsteinVariable(EinsteinValue key, IList <House> domain, CspProblem <EinsteinValue, House> problem) : base(key, domain, problem) { }
public EinsteinVariable(EinsteinValue key, CspProblem <EinsteinValue, House> problem) : base(key, new List <House>() { House.First, House.Second, House.Third, House.Fourth, House.Fifth }, problem) { }
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); } } }
public override IEnumerable <Dictionary <TK, TD> > FindSolutions(CspProblem <TK, TD> problem) { return(ForwardCheckingSearch(problem)); }
public abstract IEnumerable <Dictionary <TK, TD> > FindSolutions(CspProblem <TK, TD> problem);
public Variable <TK, TD> SelectVariable(CspProblem <TK, TD> problem) { return(problem.UnassignedVariables.First()); }
private static Dictionary <Variable <TK, TD>, int> Ac3(CspProblem <TK, TD> problem, out bool isConsistent) { var queue = new LinkedList <BinaryConstraint <TK, TD> >(problem.Constraints); var removalsCounter = new Dictionary <Variable <TK, TD>, int>(); while (queue.Any()) { var con = queue.First?.Value; queue.RemoveFirst(); if (!RemoveInconsistentValues(con, out var emptyFound)) { continue; } if (emptyFound) { isConsistent = false; return(removalsCounter); } Debug.Assert(con?.VariableOne.Constraints != null, "con?.VariableOne.Constraints != null"); foreach (var c in con.VariableOne.Constraints) { queue.AddLast(c); } } isConsistent = true; return(removalsCounter); bool RemoveInconsistentValues(BinaryConstraint <TK, TD> c, out bool emptyDomainFound) { var(v1, v2) = (c.VariableOne, c.VariableTwo); if (v1.Assigned) { emptyDomainFound = false; return(false); } var removed = false; var toRemove = new LinkedList <TD>(); foreach (var d in v1.Domain) { if (v2.Domain.Any(d2 => c.Test(d, d2))) { continue; } toRemove.AddLast(d); removed = true; } if (!removed) { emptyDomainFound = false; return(false); } v1.RemoveFromDomain(toRemove); emptyDomainFound = !v1.Domain.Any(); removalsCounter[v1] = removalsCounter.GetValueOrDefault(v1, 0) + 1; return(true); } }
public override IEnumerable <Dictionary <TK, TD> > FindSolutions(CspProblem <TK, TD> problem) { return(Ac3Search(problem)); }