public virtual void BacktrackingAlgorithm(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(); List <Tuple <int, T> > nodes = new List <Tuple <int, T> >(); bool[][] domainsState = new bool[VariablesWithConstraints.Length][]; for (int i = 0; i < VariablesWithConstraints.Length; i++) { domainsState[i] = new bool[VariablesWithConstraints[i].Item2.Size]; } Domain <T> currentVariableDomain = null; bool[] currentVariableDomainState = null; while (true) { if (current == null) { current = _variableSelectionHeuristics.StartVariable(); } else { if (backtrack) { if (_variableSelectionHeuristics.HasPrev()) { current = _variableSelectionHeuristics.Prev(); backtrack = false; } else { _timeToComplete.Stop(); break; } } else { if (_variableSelectionHeuristics.HasNext()) { current = _variableSelectionHeuristics.Next(); } else { _hasSolution = true; if (_foundSolutionsNumber == 0) { _timeToFirst.Stop(); _visitedNodesToFirst = _visitedNodes; _backtracksNumberToFirstSolution = _backtracksNumber; } _foundSolutionsNumber++; _foundSolutions.Add(SaveSolution()); if (currentVariableDomain != null && !ValueSelectionHeuristics.HasNext()) { if (currentVariableDomainState != null) { ArrayExtensions.Fill(ref currentVariableDomainState, false); } current.Value = currentVariableDomain.Default; current = _variableSelectionHeuristics.Prev(); _backtracksNumber++; } } } } currentVariableDomain = VariablesWithConstraints[current.Index].Item2; currentVariableDomainState = domainsState[current.Index]; // Send current domain to heuristics ValueSelectionHeuristics.RegisterDomain(current, currentVariableDomain, ref currentVariableDomainState); bool constraintsSatisfied = false; if (!ValueSelectionHeuristics.HasNext()) { ArrayExtensions.Fill(ref currentVariableDomainState, false); current.Value = currentVariableDomain.Default; backtrack = true; _backtracksNumber++; } else { while (ValueSelectionHeuristics.HasNext()) { var currentDomainValue = ValueSelectionHeuristics.Next(); current.Value = currentDomainValue; _visitedNodes++; if (CheckConstraints(current)) { constraintsSatisfied = true; break; } _backtracksNumber++; } if (!constraintsSatisfied) { ArrayExtensions.Fill(ref currentVariableDomainState, false); current.Value = currentVariableDomain.Default; backtrack = true; _backtracksNumber++; } } //if (_iteration % 100000 == 0) // Console.Out.WriteAsync($"{alreadySet} "); //if (alreadySet != AlredySetVariables()) //{ // alreadySet = AlredySetVariables(); //} //_iteration++; //PrintCurrentVariablesState(); } if (printSolutions) { PrintSolutionsInfo(); } }
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(); } }