Sudoku-backtracking-Algorithmus

Zunächst werde ich erklären, dass dies eine Universität, die Zuordnung also ich verlange nicht, für jemanden zu schreiben, den code für mich, ich muss nur schon in die richtige Richtung. 🙂

Ok, also muss ich schreiben, einen Algorithmus zu lösen (lösbares) sudoku-Brett beliebiger Größe. Ich habe eine rekursive Funktion geschrieben, die kann lösen Sie jedes 9x9-Brett schnell (~1ms), aber wenn ich größere Platten (16x16), die schwer zu lösen Sie kämpfen.. ich habe ein test gehen für 20 Minuten und es kann nicht scheinen, um es zu lösen. Sie können lösen einfache 16x16 Rätsel oder sogar eine leere 16x16 Bord, so dass ich glaube nicht, dass es die Abmessungen sind das problem.. es ist eher der Algorithmus ist das problem, denke ich.

Sowieso, das ist die grundlegende Logik von meinem Programm..

  • Ich habe ein 3D-Vektor, in dem die möglichen Werte, die ich jedes Quadrat
  • Wenn ein Wert in ein Quadrat, dann ist es entfernt von den möglichen Werten der umgebenden Quadrat, Zeile und Spalte, dass es in

Dann meine lösen-Funktion ist im Grunde:

bool solve() {

    if (there are no unfilled squares)
        return true

    if (the board is unsolvable - there are empty squares that have no possible values)
        return false

    while (there are empty squares)
    {
        int squaresFilled = fillSquaresWithOnlyOneChoice(); //this method updates the possible results vector whenever it fills a square

        if (squaresFilled == 0)
            break;
    }

    //exhausted all of the 'easy' squares (squares with only one possible choice), need to make a guess

    while (there are empty squares that have choices left) {

        find the square with the least number of choices

        if (the square with the least number of choices has 0 choices)
            return false; //not solvable.

        remove that choice from the 3D vector (vector that has the choices for each square)
        make a copy of the board and the 3D choices vector

        fill the square with the choice

        if (solve())
            return true; //we're done

        restore the board and choices vector 
        //the guess didn't work so keep looping and make a new guess with the restored board and choices -- the choice we just made has been removed though so it won't get made again.

    }

    return false; //can't go any further
}

Ist es etwas ineffizient zu diesem Thema? Gibt es eine Möglichkeit, ich könnte es besser funktionieren? Ich vermute, dass eine 16x16 board so lange dauert ist weil der Entscheidungsbaum für es ist so groß, dass für ein board, das nicht gefüllt, sehr stark. Es ist komisch, obwohl, weil ein 9x9-Brett lösen wird wirklich schnell.

Irgendwelche Ideen oder Anregungen wäre absolut genial. Wenn es irgendwelche Informationen, die ich vermisst habe, lassen Sie mich auch wissen!

  • Ich schlage vor, Sie schauen in das Tanz links Algorithmus, es ist ein interessanter Ansatz zur Lösung dieser Art von Problemen. (Ganz anders als in Ihrem Ansatz aber.)
  • Sie Algorithmus ist exponentiell, es ist also nicht verwunderlich, dass das hinzufügen einer zusätzlichen Schwierigkeitsgrad macht es für eine lange Zeit laufen. Durch Zufall (d.h. Laufzeit/Grad der Schwierigkeit des Problems + cpu/ram-Geschwindigkeit + Programm-design) sind Sie auf der Manschette. Was bedeutet, Ihr computer verarbeiten kann, e^f(81), aber nicht e^f(256). Nicht verwunderlich - wenn der erste ist 1ms, das bedeutet, dass dein computer verarbeitet, um e^f(81) op/ms, was bedeutet, dass es dauern wird, e^f(256) / e^f(81) ms für die zweite. Diese Zahl kann um e^170ms, das ist länger als das Universum existiert.
  • f ist nur eine grobe Schätzung-Funktion, und die Schätzungen sollten als unterschätzen, denn ich habe nicht berücksichtigt, Basis ändern - Ihr Programm ist exponentiell mit einer Variante Basis als auch exponent (~9^81 theoretische Entscheidungen vs. ~16^256), und weil die größer Sie bekommen, verlieren Sie Geschwindigkeit, z.B. Zwischenspeichern.
  • Ich würde gerne versuchen und Update mein original-Algorithmus vor völlig ändern, aber danke für den link, wenn ich verzweifelt könnte ich give it a shot! 🙂
  • ah, das macht dann auch Sinn. Ich dachte wirklich, dass ich implementiert den Algorithmus gut aber ich denke, ich könnte brauchen, um vollständig zu überdenken es?
  • Peter Norvig hat auch geschrieben, ein Stück auf die Lösung von Sudokus (nur 9x9 zwar nicht, aber vielleicht hilfreich sowieso): norvig.com/sudoku.html

InformationsquelleAutor Sam | 2011-10-08
Schreibe einen Kommentar