Sudoku in Prolog

  • Hallo!

    Mir war grad langweilig, also habe ich mir ein kleines programm in prolog geschrieben, dass mir ein beliebiges sudoku-rätsel löst.

    jetzt rechnet der swi-prolog interpreter schon seit einer halben stunde und ist immer noch nicht fertig. ich weiß, es gibt sehr viele mögliche kombinationen, aber dass die berechnung so lange dauert .... bin enttäuscht von prolog.

    es kann natürlich sein, dass ich da etwas in meinem prog vergessen/übersehn/falsch gemacht habe.

    Testfall:

    Code
    sudoku(	2,X12,X13,X14,X15,7,X17,X18,4,
    	X21,7,X23,5,X25,X26,9,X28,X29,
    	8,5,X33,X34,3,X36,X37,7,1,
    	X41,6,X43,X44,X45,3,7,X48,X49,
    	X51,9,7,6,X55,1,X57,X58,X59,
    	3,4,X63,X64,X65,X66,6,X68,5,
    	X71,X72,X73,9,1,X76,4,X78,X79,
    	X81,2,X83,X84,X85,X86,X87,6,X89,
    	6,X92,5,2,8,4,X97,X98,X99).

    bitte um anregungen!

  • Es ist in Prolog zwar relativ straight forward, sowas zu formulieren, aber wenn der Suchraum exponentiell ist, dann wird der Interpreter auch exponentiell lang suchen...
    Was extrem ineffizient ist, ist daß dein Programm (sehr oft) alle möglichen Kombinationen der Ziffern 1 bis 9 aufzählt und erst dann auf Ungleichheit testet. Besser ist sicher, zuerst mit dif/2 alle Constraints zuzusichern und erst dann die Variablen mit Werten zu belegen. dif/2 unterscheidet sich von =\= und anderen Ungleichheitsprädikaten darin, daß die Argumente noch nicht instanziiert sein müssen; wenn irgendwann später mal beide bekannt sind, wird erst verglichen. Damit schließt man schon während der Aufzählung möglichst früh ungünstige Konstellationen aus.

    Hier ist dein Code mit entsprechenden Modifikationen:

    Das ist mit deinem Testfall ziemlich schnell: 429,041 inferences, 0.34 CPU in 0.38 seconds (89% CPU, 1261885 Lips)
    Ob auch das Ergebnis stimmt, kann wer anderer überprüfen :)

    Hübscher wäre das ganze übrigens mit Listen, aber was soll's. Und auch mit Constraints, siehe 11.8 im SWI-Manual.

    *plantsch*

  • thx, sehr elegant mit dif/2.

    hatte zuerst probleme mit dif in meiner swi-prolog version (die schon komplett veraltet ist, aber noch immer in den repositories von ubuntu ist). habs jetzt per ssh im inflab ausprobiert, funktioniert wunderbar:thumb:
    der respekt vor prolog ist wiederhergestellt ;)

    P.S.: Plantschkuh muss ich jetzt respekt oder angst vor dir haben, weil du mir mit einer vollwertigen lösung binnen einer stunde aufwartest?:zwinker:

  • Zitat von klausi

    Plantschkuh muss ich jetzt respekt oder angst vor dir haben, weil du mir mit einer vollwertigen lösung binnen einer stunde aufwartest?:zwinker:


    Mir ist beides recht :) Naja, viel war echt nicht zu machen, der größte Teil des Codes stammt von dir. Ich hab nur ein paar Sachen umbenannt und die Vergleiche nach vorne gezogen.
    Außerdem hätte ich gerade total fleißig eine Präsentation ausarbeiten sollen, also hatte ich viel Zeit für sowas...

    *plantsch*

  • Zitat von klausi


    Mir war grad langweilig, also habe ich mir ein kleines programm in prolog geschrieben, dass mir ein beliebiges sudoku-rätsel löst.

    Verwend den FD-Constraint-Solver von SWI (library(bounds)). Tipp: all_different/1 Constraint, bzw. all_distinct/1 aus library(clp_distinct). Du findest eine effiziente Loesung in einem alten Thread hier: http://www.informatik-forum.at/showthread.php?t=38825

  • In der einen Datei kannst du deine Instanzen definieren:

    Code
    sudokuinstanz([[1,2,3,_,_,9,7,8,4], ...]).


    oder

    Code
    sudokuinstanz(1,2,3,_,_,9,7,8,4, ...).

    Und in der anderen Datei in deinem Sudoku-Prädikat diese sudokuinstanz als Ziel (am Anfang) einfügen.

    *plantsch*

  • Zitat von Plantschkuh!

    ...diese sudokuinstanz als Ziel (am Anfang) einfügen.


    Hmm...also ich stehe noch ziemlich am Anfang mit dem guten Prolog, googlen nach "Prolog Ziel" ergab nichts was mir unmittelbar weiterhilft...oder meinst Du damit das "consult(raetsel.pl)." ?

    Bin da etwas ratlos, vielen Dank schonmal !

    de Maddin...

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!