De Manière Récursive La Résolution D'Un Puzzle De Sudoku À L'Aide De Mandature Théoriquement
Réponse: Mon pseudo est floue dans l'aspect récursif, mais cette vidéo est utile avec les ressources ci-dessous
http://www.youtube.com/watch?v=p-gpaIGRCQI
Ne pouvez pas saisir la mise en œuvre de cette backtrack algorithme récursif à l'égard d'un puzzle de sudoku.
J'essaie de résoudre un puzzle de sudoku en utilisant récursive de retours en arrière. J'ai toujours pas en mesure d'envelopper l'algorithme général autour de ma tête étant donné le domaine du problème, je suis en train de travailler.
La mandature algorithme que je suis en train d'utilisation semble être la norme, mais je ne peux pas suivre la logique et de savoir ce qui se passe en dessous.
Inclus est la mandature de l'algorithme et de sa définition.
Edit: "Encore une fois, a pris la définition de la classe, de gauche la déclaration et de mettre en place le code de pseudo"
Voici mon pseudo l'utilisation de ce.
Pseudo-Code (C++ mettre en œuvre)
backtrack jeu (81,9) //représente toutes les combinaisons possibles d'entrée et les valeurs de jeu
//All info is loading into a vector of size 81 with the initial state
//puzzle = the initial state 9x9 grid from left to right of integers
vector <int> puzzle
while(!not solved && not the end of the vector){
for(int i =puzzle.begin::iterator i , puzzle.end()) //from 0-80 of the vector until end
if puzzle[i] != 0
//leave alone, original state of board
else
if (valid move) //a guess is allowed in this column/row/square of the board
solution[i] = puzzle_guess[i] //guess a move and insert
else //one of previous guesses were wrong
game.prune(i); //backtracks, or reverses guesses until valid move
}
//état initial du jeu
4 0 0 6 0 5 2 0 3
0 0 0 0 4 9 0 7 5
0 0 0 1 0 7 6 0 0
6 0 1 0 0 0 4 8 7
0 8 0 0 0 0 0 3 0
2 7 4 0 0 0 5 0 6
0 0 8 7 0 3 0 0 0
3 1 0 9 6 0 0 0 0
7 0 9 2 0 8 0 0 1
Merci
Le seul indice à savoir, c'est la déclaration en utilisant backtrack jeu (81,9) //ce qui signifie l'81, éventuellement, de chiffres et de 9 pour les 9 différentes options.
#ifndef BACKTRACK_H
#define BACKTRACK_H
#include <vector>
#include <algorithm>
class BackTrack {
public:
typedef std::vector<unsigned>::const_iterator const_iterator;
typedef std::vector<unsigned>::const_iterator iterator;
BackTrack (unsigned nVariables, unsigned arity=2);
//Create a backtracking state for a problem with
//nVariables variables, each of which has the same
//number of possible values (arity).
template <class Iterator>
BackTrack (Iterator arityBegin,
Iterator arityEnd);
//Create a backtracking state in which each variable may have
//a different number of possible values. The values are obtained
//as integers stored in positions arityBegin .. arityEnd as per
//the usual conventions for C++ iterators. The number of
//variables in the system are inferred from the number of
//positions in the given range.
unsigned operator[] (unsigned variableNumber) const;
//Returns the current value associated with the indicated
//variable.
unsigned numberOfVariables() const;
//Returns the number of variables in the backtracking system.
unsigned arity (unsigned variableNumber) const;
//Returns the number of potential values that can be assigned
//to the indicated variable.
bool more() const;
//Indicates whether additional candidate solutions exist that
//can be reached by subsequent ++ or prune operaations.
void prune (unsigned level);
//Indicates that the combination of values associated with
//variables 0 .. level-1 (inclusive) has been judged unacceptable
//(regardless of the values that could be given to variables
//level..numberOfVariables()-1. The backtracking state will advance
//to the next solution in which at least one of the values in the
//variables 0..level-1 will have changed.
BackTrack& operator++();
//Indicates that the combination of values associated with
//variables 0 .. nVariables-1 (inclusive) has been judged unacceptable.
//The backtracking state will advance
//to the next solution in which at least one of the values in the
//variables 0..level-1 will have changed.
BackTrack operator++(int);
//Same as other operator++, but returns a copy of the old backtrack state
//Iterator operations for easy access to the currently assigned values
const_iterator begin() const {return values.begin();}
iterator begin() {return values.begin();}
const_iterator end() const {return values.end();}
iterator end() {return values.end();}
private:
bool done;
std::vector<unsigned> arities;
std::vector<unsigned> values;
};
inline
unsigned BackTrack::operator[] (unsigned variableNumber) const
//Returns the current value associated with the indicated
//variable.
{
return values[variableNumber];
}
inline
unsigned BackTrack::numberOfVariables() const
//Returns the number of variables in the backtracking system.
{
return values.size();
}
inline
unsigned BackTrack::arity (unsigned variableNumber) const
//Returns the number of potential values that can be assigned
//to the indicated variable.
{
return arities[variableNumber];
}
inline
bool BackTrack::more() const
//Indicates whether additional candidate solutions exist that
//can be reached by subsequent ++ or prune operaations.
{
return !done;
}
template <class Iterator>
BackTrack::BackTrack (Iterator arityBegin,
Iterator arityEnd):
//Create a backtracking state in which each variable may have
//a different number of possible values. The values are obtained
//as integers stored in positions arityBegin .. arityEnd as per
//the usual conventions for C++ iterators. The number of
//variables in the system are inferred from the number of
//positions in the given range.
arities(arityBegin, arityEnd), done(false)
{
fill_n (back_inserter(values), arities.size(), 0);
}
#endif
Je ne prétends pas avoir écrit l'algorithme. Ce serait tout un exploit d'écrire un travail sans aucune connaissance :). Heres un peu légère pont, avec un semi pertinentes de la diapositive qui est un peu plus explicité see.stanford.edu/materials/icspacs106b/Lecture11.pdf j'avoue mon pseudo code pourrait être truffée d'erreurs à l'égard de ce général algorthim
Supprimer le code C++ à partir de la question. Il n'est pas pertinent et ne vous aidera pas. Votre problème est avec l'algorithme, pas avec une mise en œuvre spécifique. Se concentrer sur l'ancien.
N'oubliez pas de Stanford code de l'honneur.
Je pense que je n'ai pas moi-même exprimé assez clair. Permettez-moi d'essayer de nouveau. Il y a des problèmes dans le pseudo-code qui suggèrent que vous ne comprenez pas vraiment l'algorithme. C'est vide de sens pour discuter d'un corps de assez complexe de code C++, basé sur une simple, mais mal comprise de l'algorithme. Maintenant que vous avez retiré le pseudo-code, ce qui pourrait avoir servi de base utile pour la discussion parce qu'elle est petite et facile à saisir, et à gauche le code à la place. Vous devriez avoir fait exactement le contraire.
OriginalL'auteur Bjarn127 | 2013-08-11
Vous devez vous connecter pour publier un commentaire.
Voici un pseudo-code qui peut vous aider à comprendre la récursivité et les retours en arrière:
Une fois que vous pouvez comprendre cela, la prochaine chose est de comprendre comment les différentes implémentations de
getNextEmptySquare()
affectera les performances par élagage de l'espace d'état graphique de différentes manières.Je ne vois pas de récursivité ou méthodique de la recherche dans le pseudo-code, bien qu'il n'est pas tout à fait clair, il semble juste essayer de permutations aléatoires et plus?
Bonne explication, merci!
OriginalL'auteur The111
Le point sur le Sudoku est, que vous avez un grand nombre de membres: 9^81 est un certain nombre de 78 chiffres. Par conséquent, toute "bête" retour en arrière algorithme en partant du haut à gauche du champ et de la transformation vers le bas à droite est susceptible d'être coincé dans un apparemment sans fin de la boucle.
Donc, ma recommandation est de résoudre Sudoku comme un être humain n': Trouver un terrain, pour qui la déjà rempli les numéros de ne permettre qu'une valeur spécifique, et de remplir ce champ. Ensuite, regardez pour le prochain champ. Si aucune des champs vides existent, pour lequel une seule valeur est legal, regardez pour les champs, qui permettent à plus de deux (ou plus généralement, le nombre minimum d'possible) des valeurs, et essayer un de ces valeurs, et de continuer avec la récursivité. Revenir en arrière, si les contradictions surviennent, et puis essayer de la prochaine valeur d'un champ, qui avait plusieurs solutions de rechange.
En pseudo code:
La fonction find_most_constrained_square() compte pour chaque champ vide, combien de nombres différents peuvent encore être mis là, et renvoie l'index de ce champ, qui a eu le plus faible nombre de possibilités. Cela pourrait même être un domaine avec 0 alternatives.
Avec qui a modifié la récursivité, Sudoko problème devrait être résolu rapidement, même avec une lenteur des langues sur des ordinateurs lents. N'oubliez pas de jeter les différentes copies de l'état de la partie réalisés dans le foreach boucle intérieure!
"Annuler" un déménagement en le Sudoku n'est pas une opération facile, en particulier, si l'on enregistre état supplémentaire pour chaque champ. Par exemple, on peut utiliser un champ de bits des valeurs, qui sont encore possible pour chaque champ. Dans ce cas, paramétrer une valeur à un certain cellulaire implique la suppression de la valeur juridique de la loi-les valeurs de champ de bits dans les autres cellules de la même ligne, colonne ou d'un groupe. Mais re-réglage de ces bits après un déménagement fait marche arrière peut-être tort, que la valeur pourrait avoir déjà été rejeté pour certains autres, précédemment fixée champ. Par conséquent, je recommande que "copier" sur "annuler".
OriginalL'auteur Kai Petzke