Ich habe ein Programm geschrieben, das automatisch Sudokus lösen soll. Ich bin auch schon relativ weit gekommen nur leider weiß ich jetzt nicht genau wo mein Fehler nun steckt. Ich habe unter anderem zum Lösen einen backtracking-ähnlichen Algorithmus implementiert, der allerdings nicht so arbeitet wie er eigentlich sollte obwohl ich das ganze schon x-mal durchgegangen bin^^
Vielleicht kann mir ja hier jemand weiterhelfen...
Ich hab mal versucht alles wichtige im Quellcode zu kommentieren.
Alles anzeigen
Vielleicht kann mir ja hier jemand weiterhelfen...
Ich hab mal versucht alles wichtige im Quellcode zu kommentieren.
Quellcode
- class Sudoku {
- int[][][] grid = new int[9][9][10]; // Sudoku-Feld; grid[x][y][0] speichert sichere Werte;
- // grid[x][y][1-9] ist 1-9 falls die entsprechende Ziffer
- // hier eine mögliche Lösung ist
- // Hier wird einiges unwichtiges ausgelassen ...
- Sudoku() {
- int i,j,k;
- // initializing grid
- for (i=0;i<9;i++) {
- for (j=0;j<9;j++) {
- for (k=0;k<10;k++) {
- grid[i][j][k] = k;
- }
- }
- }
- }
- // Hier wird einiges unwichtiges ausgelassen ...
- boolean gridSolved() { // prüft ob das Sudoku vollständig ist
- int i,j;
- boolean solved = true;
- for (i=0;i<9;i++) {
- for (j=0;j<9;j++) {
- if (grid[i][j][0] == 0)
- solved = false;
- }
- }
- return solved;
- }
- boolean contradiction(int x, int y) { // prüft den neu durch backtracking eingefügten Wert (ist die Zahl
- // in dieser Spalte/Zeile/diesem Unterquadrat doppelt?)
- // hier vermute ich den Fehler
- int i,j;
- boolean ok = true;
- HashSet<Integer> Co = new HashSet<Integer>(); // Spalte
- HashSet<Integer> Ro = new HashSet<Integer>(); // Zeile
- HashSet<Integer> Sq = new HashSet<Integer>(); // Unterquadrat
- for (i=0;i<9;i++) {
- if (grid[x][i][0]!=0) {
- ok = Co.add(grid[x][i][0]);
- if (!ok)
- return true; // Widerspruch -> return true;
- }
- if (grid[i][y][0]!=0) {
- ok = Ro.add(grid[i][y][0]);
- if (!ok)
- return true;
- }
- }
- for (i=x-(x%3);i<=x-(x%3)+2;i++) {
- for (j=y-(y%3);j<=y-(y%3)+2;j++) {
- if (grid[i][j][0]!=0) {
- ok = Sq.add(grid[i][j][0]);
- if (!ok)
- return true;
- }
- }
- }
- return false; // kein Widerspruch gefunden -> return false;
- }
- int[] setCoord(int x, int y) { // wird beim backtracking verwendet um ins nächste Feld zu wechseln
- int[] Coord = new int[2];
- if (x==8) {
- x=0;
- y++;
- } else {
- x++;
- }
- Coord[0] = x;
- Coord[1] = y;
- return Coord;
- }
- boolean backtrack(int x, int y) {
- int i;
- int[] Coord = new int[2];
- if (this.contradiction(x,y))
- return false; // Widerspruch -> falscher Pfad
- if (this.gridSolved())
- return true; // Sudoku gelöst?
- if (x!=0 || y!=0) { // wenn nicht am anfang, gehe zum nächsten Feld
- Coord = setCoord(x,y);
- x = Coord[0];
- y = Coord[1];
- }
- if (grid[x][y][0] != 0) { // wenn dieses Feld bereits belegt ist...
- Coord = setCoord(x,y); // springe zum nächsten Feld
- x = Coord[0];
- y = Coord[1];
- if (this.backtrack(x,y)) // und führe die selbe Funktion damit aus
- return true;
- }
- for (i=1;i<10;i++) { // wenn das Feld noch nicht belegt ist
- if (grid[x][y][i]==i) { //... und i eine mögliche Belegung ist
- grid[x][y][0]=i; //... dann setze das aktuelle Feld gleich i
- if (this.backtrack(x,y)) // und führe diese Funktion damit aus
- return true;
- }
- }
- return false; // wenn noch nichts zurückgegeben wurde, gebe false zurück
- }
- }