static void Main(string[] args) { Console.WriteLine("Grille de départ :"); Grille grille = Grille.GetGrilleFromFile("../../sudokus.txt", 0); if (grille != null) { grille.AfficherGrille(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Grille solution = Resolver.BackTrackingSearch(grille); stopwatch.Stop(); Console.WriteLine("Temps de résolution : " + stopwatch.Elapsed.TotalMilliseconds + " ms"); if (solution != null) { Console.WriteLine("Solution trouvée : "); solution.AfficherGrille(); } else { Console.WriteLine("Pas de solution trouvée."); } } Console.WriteLine("Press 'Enter' to exit"); Console.ReadLine(); }
/// <summary> /// Read the file and extracts the sudoku of the corresponding line /// </summary> public static Grille GetGrilleFromFile(String file, int line) { Grille grille = new Grille(); try { grille.cases.Clear(); string[] lines = System.IO.File.ReadAllLines(file); string sudoku = lines[line]; CharEnumerator enumerator = sudoku.GetEnumerator(); int i = 0; while (enumerator.MoveNext()) { grille.cases.Add(new Case(enumerator.Current - 48, i)); i++; } }catch (System.IO.FileNotFoundException e) { Console.WriteLine("Fichier non trouvé. Le fichier doit être nommé 'sudokus.txt' et être " + "placé deux dossiers au dessus du dossier debug"); return(null); } return(grille); }
public Grille(Grille grille) { cases = new List <Case>(); for (int i = 0; i < 81; i++) { cases.Add(new Case(grille.cases[i])); } }
private static Grille Recursive_Backtracking_Search(Grille grille) { nbRep++; //Test d'objectif if (grille.IsComplete()) { return(grille); } //On créé une copie de la grille de départ Grille tempGrille = new Grille(grille); //On détecte la case vide ayant le moins de valeurs possibles int indexLeastMRV = -1; int MRV = int.MaxValue; int compteur = 0; foreach (Case box in tempGrille.cases) { if (box.Value == 0) { int tempMRV = box.PossibleValues.Count; if (tempMRV < MRV) { indexLeastMRV = compteur; MRV = tempMRV; } } compteur++; } //Si aucune valeur ne mène à une solution satisfaisante, on //arrête d'explorer la branche. if (MRV == 0) { return(null); } //On créé les noeuds enfants Dictionary <Grille, int> dic = new Dictionary <Grille, int>(); List <Grille> grilles = new List <Grille>(); //Pour chaque valeur possible de la case, on calcule le nombre de contraintes ajoutées foreach (int valeur in tempGrille.cases[indexLeastMRV].PossibleValues) { Grille nextGrille = new Grille(tempGrille); nextGrille.cases[indexLeastMRV].Value = valeur; nextGrille.DefinePossibleValuesAllBoxes(); int nbConstraintsAdded = tempGrille.GetNbOfPossibleValues() - nextGrille.GetNbOfPossibleValues(); dic.Add(nextGrille, nbConstraintsAdded); } //On les trie en fonction du nombre de contraintes ajoutées sortDictionary(dic); //Création des noeuds enfants foreach (KeyValuePair <Grille, int> pair in dic) { Grille result = Recursive_Backtracking_Search(pair.Key); if (result != null) { return(result); } } return(null); }
/// <summary> /// Tries to resolve the grid in parameter. Returns the solution (or 'null' if no solution is found) /// </summary> /// <param name="grille"></param> public static Grille BackTrackingSearch(Grille grille) { nbRep = 0; grille.DefinePossibleValuesAllBoxes(); return(Recursive_Backtracking_Search(grille)); }