예제 #1
0
 //dynamiczna heurystyka - wybierz zmienna o aktualnie najmniejszej liczbie dozwolonych wartości
 private SudokuVariable SelectNextVariableMRV()
 {
     if (BackTrack)
     {
         SudokuVariable nextVar           = null;
         int            maxExcludedValues = 0;
         foreach (SudokuVariable variable in Variables)
         {
             if (variable.IsEmpty())
             {
                 List <int> excludedValues = new List <int>();
                 foreach (SudokuVariable related in relatedFields[variable])
                 {
                     if (!related.IsEmpty() && !excludedValues.Contains(related.Value))
                     {
                         excludedValues.Add(related.Value);
                     }
                 }
                 if (excludedValues.Count > maxExcludedValues)
                 {
                     maxExcludedValues = excludedValues.Count;
                     nextVar           = variable;
                 }
             }
         }
         return(nextVar);
     }
     else
     {
         return(Variables.OrderBy(v => v.Domain.Count).FirstOrDefault(v => v.IsEmpty()));
     }
 }
예제 #2
0
 private void ResetDomainsOfAllRelatedFields(SudokuVariable variable)
 {
     foreach (SudokuVariable related in relatedFields[variable])
     {
         related.ResetDomain();
     }
 }
예제 #3
0
 public SudokuVariable(SudokuVariable other)
 {
     Row           = other.Row;
     Col           = other.Col;
     Value         = other.Value;
     Domain        = other.Domain;
     OrderedDomain = other.OrderedDomain;
 }
예제 #4
0
        public bool CheckConstraints(SudokuVariable variable)
        {
            foreach (SudokuVariable related in relatedFields[variable])
            {
                if (related.Value == variable.Value)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #5
0
        private void AddFromCol(SudokuVariable variable)
        {
            int col = variable.Col;

            for (int i = 0; i < 9; i++)
            {
                if (i != variable.Row)
                {
                    relatedFields[variable].Add(Board[i][col]);
                }
            }
        }
예제 #6
0
        private void AddFromRow(SudokuVariable variable)
        {
            int row = variable.Row;

            for (int i = 0; i < 9; i++)
            {
                if (i != variable.Col)
                {
                    relatedFields[variable].Add(Board[row][i]);
                }
            }
        }
예제 #7
0
        private int FilterDomainsOfAllRelatedFields(SudokuVariable variable)
        {
            int removedValues = 0;

            foreach (SudokuVariable related in relatedFields[variable])
            {
                if (related.IsEmpty())
                {
                    removedValues += FilterDomain(related);
                }
            }
            return(removedValues);
        }
예제 #8
0
        private int FilterDomain(SudokuVariable variable)
        {
            variable.ResetDomain();
            int removedValues = 0;

            foreach (SudokuVariable related in relatedFields[variable])
            {
                if (!related.IsEmpty())
                {
                    bool removed = variable.Domain.Remove(related.Value);
                    if (removed)
                    {
                        removedValues++;
                    }
                }
            }

            return(removedValues);
        }
예제 #9
0
        private void AddFromSquare(SudokuVariable variable)
        {
            int row = variable.Row;
            int col = variable.Col;

            int box_start_row = (row / 3) * 3;
            int box_start_col = (col / 3) * 3;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (box_start_row + i != row || box_start_col + j != col)
                    {
                        relatedFields[variable].Add(Board[box_start_row + i][box_start_col + j]);
                    }
                }
            }
        }
예제 #10
0
        public void RunForwardChecking()
        {
            if (firstRun)
            {
                RemoveInitiallyBlockedValuesFromDomains();
                StartTiming();
            }

            SudokuVariable currElem = SelectNextVariable();

            if (currElem == null)
            {
                if (Solutions.Count == 0)
                {
                    SaveFirstSolutionData();
                }

                Solutions.Add(
                    Board.Select(
                        s => s.Select(v => v.Value).ToArray())
                    .ToArray());
                return;
            }

            foreach (int value in currElem.Domain)
            {
                currElem.Value = value;
                TotalNodesVisited++;

                FilterDomainsOfAllRelatedFields(currElem);
                if (!IsAnyDomainEmpty())
                {
                    RunForwardChecking();
                }
            }
            currElem.Value = 0; // nawrot - brak kolejnej wartosci
            FilterDomainsOfAllRelatedFields(currElem);
            TotalReturns++;
            TotalTime = stopwatch.Elapsed.TotalSeconds;
        }
예제 #11
0
        public void RunBacktracking()
        {
            if (firstRun)
            {
                BackTrack = true;
                StartTiming();
            }

            SudokuVariable currElem = SelectNextVariable();

            if (currElem == null)
            {
                if (Solutions.Count == 0)
                {
                    SaveFirstSolutionData();
                }

                Solutions.Add(
                    Board.Select(
                        s => s.Select(v => v.Value).ToArray())
                    .ToArray());
            }
            else
            {
                //OrderDomain(currElem);
                foreach (int value in currElem.Domain)
                {
                    currElem.Value = value;
                    TotalNodesVisited++;
                    bool correct = CheckConstraints(currElem);
                    if (correct)
                    {
                        RunBacktracking();
                    }
                }
                currElem.Value = 0;
            }
            TotalReturns++;// nawrot
            TotalTime = stopwatch.Elapsed.TotalSeconds;
        }
예제 #12
0
        private void OrderDomain(SudokuVariable currElem)
        {
            int removedValues;
            Dictionary <int, int> valuesRemovedByEachNumber = new Dictionary <int, int>();

            foreach (int value in currElem.Domain)
            {
                removedValues  = int.MaxValue;
                currElem.Value = value;
                if (CheckConstraints(currElem))
                {
                    removedValues  = FilterDomainsOfAllRelatedFields(currElem);
                    currElem.Value = 0;
                    ResetDomainsOfAllRelatedFields(currElem);
                }
                else
                {
                    currElem.Value = 0;
                }
                valuesRemovedByEachNumber.Add(value, removedValues);
            }
            currElem.OrderedDomain = valuesRemovedByEachNumber.OrderBy(kv => kv.Value).Select(kv => kv.Key).ToList();
            currElem.ResetDomain();
        }