Algo de backtracking pour sudoku - C - Programmation
Marsh Posté le 03-05-2009 à 01:38:18
Il faudrait débugguer, soit avec un debuggeur et en suivant pas à pas, soit en écrivant des traces dans un fichier et en étudiant ces traces.
Je n'ai jamais programmé de Sudoku, mais j'ai fait plusieurs programmes qui fonctionnaient avec des arbres de recherche, et j'ai toujours utilisé un appel récursif avec une profondeur plus grande, comme sur la ligne 19, mais jamais avec une profondeur plus petite, comme sur la ligne 27, et je crains donc que cette dernière soit fautive.
Marsh Posté le 03-05-2009 à 11:21:06
Quelques pistes:
-> avoir la fonction qui retourne une valeur indiquant si une solution a été trouvée ou pas.
-> remettre a jour tes tableaux de booleens après la ligne 26.
-> supprimer la ligne 27
-> le return de la ligne 20 doit être conditionnel sur la valeur de retour de l'appel de la ligne 19
Marsh Posté le 03-05-2009 à 11:36:00
FWIW si tu fais de la résolution de sudoku tu devrais checker la solution "CPS" de Norvig (http://norvig.com/sudoku.html)
Marsh Posté le 03-05-2009 à 12:08:29
@billgatesanonym:
Le programme met l'erreur au moment où il rencontre cette ligne :
Code :
|
(Endroit localisé à l'aide de printf)
@Un programmeur:
Vu que c'est un projet de fin d'année, et que la "base" du code m'a été donnée, je suis extrêmement limité : ce n'est pas comme si j'écrivais le sudoku; on m'impose les prototypes des fonctions donc ici l'entier prof.
Il me semblait que si le programme atteignait la ligne 26 les tableaux de booléens ne seraient pas modifiés, la seule modification étant (grille[y][x]) = 1; à la ligne 7. Dîtes moi si je me trompe.
Si je supprime la ligne 27, comment l'algo peut-il revenir en arrière ? il faut que je lui envoie la valeur de la case précédente pour qu'il puisse retravailler dessus
Pourriez-vous m'expliquer le return à mettre en condition l20, je pensais que le fais qu'il soit dans le grand IF suffisait.
@Masklinn
Je suis malheureusement contraint à un code précis pour mon devoir.
Merci à tous pour vos réponses.
Marsh Posté le 03-05-2009 à 12:41:48
Je regarderais bien mes cours, mais étant en fac et avec la LRU, j'ai eu environ 1 mois de cours ...
Marsh Posté le 03-05-2009 à 16:09:31
Citation : Le programme met l'erreur au moment où il rencontre cette ligne : |
C'est bien de l'avoir localisée. Maintenant il faut se demander ce qui ne va pas sur cette ligne. En fait, elle est assez banale. Le problème est vraisemblablement causé par des valeurs abbérantes de l'un des indices ou de plusieurs indices. Donc il faudrait voir ce que contiennent les variables y, x, pav juste avant cette ligne. Il y a sans doute l'une d'elles qui est en dehors des limites. Il faudrait chercher comment l'une de ses variables pourrait contenir une valeur hors limite. Il y a deux hypothèses. Soit une mauvaise mise à jour de ces variables, soit un effet secondaire malheureux qui serait dû à "l'explosion de la pile", ce qui est un phénomène que l'on rencontre avec les fonctions récursives mal maîtrisées.
Citation : Si je supprime la ligne 27, comment l'algo peut-il revenir en arrière ? |
Le programme revient en arrière avec le return de la ligne 20 ou celui de la ligne 36 (qui est implicite, mais qui aurait pû être mis explicitement pour que le code soit plus clair). La variable prof est passée par valeur, et non pas par référence. Cela implique qu'après le return et la sortie de la fonction, cette variable prof retrouvera sa valeur d'avant.
Marsh Posté le 03-05-2009 à 17:02:01
D'abord, merci pour ta réponse;
J'ai appliqué les divers changements, voici la fonction :
Code :
|
Sur la console, rien d'anormal hormis qu'il ne traite que les 8 premières valeurs :
Code :
|
et que les solutions proposées sont fausses
@billgatesanonym : vois-tu ce qui ne va pas ?
edit: si je réexécute la fonction, il ne me "solutionne" plus que 3 cases puis 2 (ne descend pas en dessous de 2 "solutions" ).
Marsh Posté le 03-05-2009 à 18:47:53
Si ça ne plante plus, c'est déjà un progrès énorme. Bravo !
Mais, je suis désolé, je n'ai pas le temps de regarder en détail.
Cependant, Monsieur Un programmeur, qui n'est pas mauvais, semble avoir repéré des choses intéressantes ; par exemple, l'utilité de réinitialiser les booléens.
Marsh Posté le 03-05-2009 à 21:50:58
pourquoi gérer la profondeur de recursivité avec une seule valeur alros que tu est clairement en 2D. Ta fonction pourrais prendre un profx, profx et évité de te vautrer dans tes / %
Marsh Posté le 03-05-2009 à 22:47:30
Si ça ne tenait qu'à moi, il y aurait en effet deux valeurs ...
Cependant, je dois m'en tenir aux déclarations des fonctions de l'énoncé.
Marsh Posté le 02-05-2009 à 20:22:28
Salut à vous,
J'ai un sudoku à faire pour un projet de fin d'année et je bloque sur cet algo :
Voici la grille "énoncé" (0 correspond à une case vide) :
Dans le programme, je dois vérifier l'énoncé (fonctionne) et le copierdans un tableau 9*9 qui s'appelle "grille", c'est dans ce tableau queje travaille; à aucun moment je ne dois modifier enonce.
J'ai aussi 3 tableaux de booléens : c[9][10] l[9][10] et pave[9][10] tels que :
Pave[i][j] vrai ssi j est présent dans le pavé n°i.
l[i][j] vrai ssi j est présent dans la ligne n° i.
c[i][j] vrai ssi j est présent dans la colonne n° i.
Voici ma fonction :
Cette fonction est recursive et "prof" permet de transmettre la position à laquelle on se trouve, sachant que :
- prof % 9 = la colonne (x)
- prof / 9 = la ligne (y)
on obtient le pavé correspondant en faisant 3*(y /3) + x/3 .
(ce sont des divisions entières)
donc pour les pavés ils sont numérotés de 0 à 8 de gauche à droite puis de haut en bas.
Le programme se compile sans problème mais à l'execution j'ai cette erreur :
Pouvez-vous m'aider svp ?
Merci d'avance.