//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())); } }
private void ResetDomainsOfAllRelatedFields(SudokuVariable variable) { foreach (SudokuVariable related in relatedFields[variable]) { related.ResetDomain(); } }
public SudokuVariable(SudokuVariable other) { Row = other.Row; Col = other.Col; Value = other.Value; Domain = other.Domain; OrderedDomain = other.OrderedDomain; }
public bool CheckConstraints(SudokuVariable variable) { foreach (SudokuVariable related in relatedFields[variable]) { if (related.Value == variable.Value) { return(false); } } return(true); }
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]); } } }
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]); } } }
private int FilterDomainsOfAllRelatedFields(SudokuVariable variable) { int removedValues = 0; foreach (SudokuVariable related in relatedFields[variable]) { if (related.IsEmpty()) { removedValues += FilterDomain(related); } } return(removedValues); }
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); }
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]); } } } }
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; }
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; }
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(); }