Backtracking-Algorithmus zur Lösung eines Sudokus

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Backtracking-Algorithmus zur Lösung eines Sudokus

    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.

    Quellcode

    1. class Sudoku {
    2. int[][][] grid = new int[9][9][10]; // Sudoku-Feld; grid[x][y][0] speichert sichere Werte;
    3. // grid[x][y][1-9] ist 1-9 falls die entsprechende Ziffer
    4. // hier eine mögliche Lösung ist
    5. // Hier wird einiges unwichtiges ausgelassen ...
    6. Sudoku() {
    7. int i,j,k;
    8. // initializing grid
    9. for (i=0;i<9;i++) {
    10. for (j=0;j<9;j++) {
    11. for (k=0;k<10;k++) {
    12. grid[i][j][k] = k;
    13. }
    14. }
    15. }
    16. }
    17. // Hier wird einiges unwichtiges ausgelassen ...
    18. boolean gridSolved() { // prüft ob das Sudoku vollständig ist
    19. int i,j;
    20. boolean solved = true;
    21. for (i=0;i<9;i++) {
    22. for (j=0;j<9;j++) {
    23. if (grid[i][j][0] == 0)
    24. solved = false;
    25. }
    26. }
    27. return solved;
    28. }
    29. boolean contradiction(int x, int y) { // prüft den neu durch backtracking eingefügten Wert (ist die Zahl
    30. // in dieser Spalte/Zeile/diesem Unterquadrat doppelt?)
    31. // hier vermute ich den Fehler
    32. int i,j;
    33. boolean ok = true;
    34. HashSet<Integer> Co = new HashSet<Integer>(); // Spalte
    35. HashSet<Integer> Ro = new HashSet<Integer>(); // Zeile
    36. HashSet<Integer> Sq = new HashSet<Integer>(); // Unterquadrat
    37. for (i=0;i<9;i++) {
    38. if (grid[x][i][0]!=0) {
    39. ok = Co.add(grid[x][i][0]);
    40. if (!ok)
    41. return true; // Widerspruch -> return true;
    42. }
    43. if (grid[i][y][0]!=0) {
    44. ok = Ro.add(grid[i][y][0]);
    45. if (!ok)
    46. return true;
    47. }
    48. }
    49. for (i=x-(x%3);i<=x-(x%3)+2;i++) {
    50. for (j=y-(y%3);j<=y-(y%3)+2;j++) {
    51. if (grid[i][j][0]!=0) {
    52. ok = Sq.add(grid[i][j][0]);
    53. if (!ok)
    54. return true;
    55. }
    56. }
    57. }
    58. return false; // kein Widerspruch gefunden -> return false;
    59. }
    60. int[] setCoord(int x, int y) { // wird beim backtracking verwendet um ins nächste Feld zu wechseln
    61. int[] Coord = new int[2];
    62. if (x==8) {
    63. x=0;
    64. y++;
    65. } else {
    66. x++;
    67. }
    68. Coord[0] = x;
    69. Coord[1] = y;
    70. return Coord;
    71. }
    72. boolean backtrack(int x, int y) {
    73. int i;
    74. int[] Coord = new int[2];
    75. if (this.contradiction(x,y))
    76. return false; // Widerspruch -> falscher Pfad
    77. if (this.gridSolved())
    78. return true; // Sudoku gelöst?
    79. if (x!=0 || y!=0) { // wenn nicht am anfang, gehe zum nächsten Feld
    80. Coord = setCoord(x,y);
    81. x = Coord[0];
    82. y = Coord[1];
    83. }
    84. if (grid[x][y][0] != 0) { // wenn dieses Feld bereits belegt ist...
    85. Coord = setCoord(x,y); // springe zum nächsten Feld
    86. x = Coord[0];
    87. y = Coord[1];
    88. if (this.backtrack(x,y)) // und führe die selbe Funktion damit aus
    89. return true;
    90. }
    91. for (i=1;i<10;i++) { // wenn das Feld noch nicht belegt ist
    92. if (grid[x][y][i]==i) { //... und i eine mögliche Belegung ist
    93. grid[x][y][0]=i; //... dann setze das aktuelle Feld gleich i
    94. if (this.backtrack(x,y)) // und führe diese Funktion damit aus
    95. return true;
    96. }
    97. }
    98. return false; // wenn noch nichts zurückgegeben wurde, gebe false zurück
    99. }
    100. }
    Alles anzeigen
    Dateien
    • Konsole.java

      (12,13 kB, 664 mal heruntergeladen, zuletzt: )