protected virtual bool FilterOutDomains(S current, ref bool[][] currentDomainsState, IVariableSelectionHeuristics <T, S> variableSelectionHeuristics) { bool reducedToZero = false; var currentVariableConstraints = VariablesWithConstraints[current.Index].Item3; for (int i = 0; i < currentVariableConstraints.Count; i++) { var pairVariable = VariablesWithConstraints[currentVariableConstraints[i].Id2].Item1; var constraint = currentVariableConstraints[i]; if (variableSelectionHeuristics.IsBefore(current, pairVariable)) { var pairVariableDomain = VariablesWithConstraints[pairVariable.Index].Item2; var domainArray = pairVariableDomain.AsArray(); var domainMask = currentDomainsState[pairVariable.Index]; int domainSize = domainArray.Length; for (int j = 0; j < domainSize; j++) { if (!constraint.Check(current.Value, domainArray[j])) { currentDomainsState[pairVariable.Index][j] = true; domainSize--; } } if (domainSize == 0) { reducedToZero = true; break; } } } return(reducedToZero); }
public virtual void BacktrackingAlgorithmForwardCheck(bool printSolutions = false) { int alreadySet = 0; _timeToFirst = new Stopwatch(); _timeToComplete = new Stopwatch(); _foundSolutions = new List <S[]>(); S current = null; bool backtrack = false; _timeToFirst.Start(); _timeToComplete.Start(); var domainsStateStack = new Stack <bool[][]>(); bool[][] domainsState = new bool[VariablesWithConstraints.Length][]; for (int i = 0; i < VariablesWithConstraints.Length; i++) { domainsState[i] = new bool[VariablesWithConstraints[i].Item2.Size]; } domainsStateStack.Push(domainsState); bool[][] currentDomainsState = domainsStateStack.Peek(); Domain <T> currentVariableDomain = null; while (true) { if (current == null) { current = _variableSelectionHeuristics.StartVariable(); } else { if (backtrack) { if (_variableSelectionHeuristics.HasPrev()) { current = _variableSelectionHeuristics.Prev(); backtrack = false; domainsStateStack.Pop(); currentDomainsState = domainsStateStack.Peek(); } else { _timeToComplete.Stop(); break; } } else { if (_variableSelectionHeuristics.HasNext()) { current = _variableSelectionHeuristics.Next(); } else { _hasSolution = true; if (_foundSolutionsNumber == 0) { _visitedNodesToFirst = _visitedNodes; _timeToFirst.Stop(); _backtracksNumberToFirstSolution = _backtracksNumber; } _foundSolutionsNumber++; _foundSolutions.Add(SaveSolution()); domainsStateStack.Pop(); domainsStateStack.Pop(); currentDomainsState = domainsStateStack.Peek(); currentVariableDomain = VariablesWithConstraints[current.Index].Item2; current.Value = currentVariableDomain.Default; current = _variableSelectionHeuristics.Prev(); _backtracksNumber++; } } } currentVariableDomain = VariablesWithConstraints[current.Index].Item2; ValueSelectionHeuristics.RegisterDomain(current, currentVariableDomain, ref currentDomainsState[current.Index]); bool constraintsSatisfied = false; if (!ValueSelectionHeuristics.HasNext()) { current.Value = currentVariableDomain.Default; backtrack = true; _backtracksNumber++; } else { while (ValueSelectionHeuristics.HasNext()) { var currentDomainValue = ValueSelectionHeuristics.Next(); current.Value = currentDomainValue; _visitedNodes++; bool[][] temp = new bool[currentDomainsState.Length][]; int tempSize = temp.Length; for (int i = 0; i < tempSize; i++) { if (_variableSelectionHeuristics.IsBefore(VariablesWithConstraints[i].Item1, current)) { temp[i] = currentDomainsState[i]; } else { int newSize = currentDomainsState[i].Length; var tempArr = new bool[newSize]; temp[i] = new bool[newSize]; for (int j = 0; j < newSize; j++) { temp[i][j] = currentDomainsState[i][j]; } } } domainsStateStack.Push(temp); currentDomainsState = domainsStateStack.Peek(); if (!FilterOutDomains(current, ref currentDomainsState, _variableSelectionHeuristics)) { constraintsSatisfied = true; break; } domainsStateStack.Pop(); currentDomainsState = domainsStateStack.Peek(); _backtracksNumber++; } if (!constraintsSatisfied) { current.Value = currentVariableDomain.Default; backtrack = true; } } } if (printSolutions) { PrintSolutionsInfo(); } }