AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Sudoku Logik

Ein Thema von hans ditter · begonnen am 20. Dez 2010 · letzter Beitrag vom 7. Mär 2011
Antwort Antwort
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#1

AW: Sudoku Logik

  Alt 20. Dez 2010, 14:54
Ah ja... hatte ich schon fast befürchtet, dass das in die Richtung geht.... -.-

Kannst du mir was zu Backtracking erzählen? Backtracking = zurück suchen ?? Ich würd mir drunter vorstellen, dass man alle Schritte irgendwie speichert und dann rückgehen schaut, ob das ganze funktionieren kann. Aber ich hab definitiv keine Ahnung wie das gehen soll!!

lg, hans ditter
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

Registriert seit: 5. Aug 2004
Ort: München
1.062 Beiträge
 
#2

AW: Sudoku Logik

  Alt 20. Dez 2010, 19:20
Kannst du mir was zu Backtracking erzählen? Backtracking = zurück suchen ?? Ich würd mir drunter vorstellen, dass man alle Schritte irgendwie speichert und dann rückgehen schaut, ob das ganze funktionieren kann.
Grob beschrieben ist das Backtracking. Man trifft Entscheidungen, und wenn man an einen Widerspruch/Fehler gerät, ändert man eine (normalerweise die letzte) Entscheidung und probiert dann weiter. Wikipedia hat auch nen eigenen Eintrag dazu.
Auf Sudoku angewand würde das ca. so aussehn (der Einfachheit halber rekursiv beschrieben):
Code:
SetzeFeld(i)
  Wenn i > Size*Size
    return true; //Abbruchbedingung
  GültigeEntscheidungen = {1..Size}
  solange Anzahl(GültigeEntscheidungen) > 0
    Wähle zufällige, gültige Entscheidung x //(z.B. x=3, d.h. ins i-te Feld wird eine 3 geschrieben)
    Wenn EntscheidungGültig(i, x) //x ist auf dem i-ten Feld gültig
      Setze(i, x)
      Wenn SetzeFeld(i+1) //Probieren, das restliche Sudoku zu füllen
        return true;     //Sudoku konnte gefüllt werden, also Funktion "erfolgreich" beenden
    Entferne x aus GültigeEntscheidungen //Weil x keine gültige Entscheidung war
  return false //keine Gültige Entscheidung gefunden, also muss in den vorherigen Feldern was geändert werden
Das ist dann eine sehr einfache Implementierung von Backtracking. Dadurch, dass man Rekursion anwendet, muss man auch nicht ehemalige Entscheidungen speichern, bzw. der Compiler&Stack erledigen das für einen.
Wie schnell dieser Code dann läuft hängt sehr davon ab, wie man die Gültigkeit einer Entscheidung überprüft. Diese muss natürlich false zurückgeben, (genau dann) wenn die Zahl nicht gültig ist. Hier ist aber bspw. auch bereits viel Optimierungs-Potential drin. Im weiter oben genannten Beispiel könnte die Funktion auch bereits erkennen, dass die 1 im 7. Feld nicht gültig ist. Hierfür können dann die verschiedensten Methoden zum Einsatz kommen.

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Sudoku Logik

  Alt 20. Dez 2010, 19:29
Danke Mike,

deine Beschreibung hört sich erstmal reichlich wirr an, werd mich aber mal ransetzten und probieren die umzusetzten. Ich poste dann mein Endergebnis hier, wenn man da dann nochmal rüberschauen könnte, wäre das klasse!

LG, hans ditter
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Sudoku Logik

  Alt 26. Dez 2010, 15:20
Hi Mike,

hab mich mal mit deinem Beitrag beschäftigt. Da sind allerdings 2 Fragen aufgetaucht:
1.) Wenn i > Size * Size --> wofür braucht man das? was bedeutet es?
2.) Gueltige Entscheidung = {0..Size} --> was ist das? ein Array? wie ist es aufgebaut?

Zu 2.: Ich dachte schonmal an ein Array of Array, dass man dann ein 4x4 Array z.B. anlegt, für jedes einzelne Feld im Sudoku und in dem Arrayfeld dann ein weiters Array oder Record speichert, für alle zulässigen Zahlen dieses Feldes. Wäre das praktikabel und sinnvoll?

LG, hans ditter

P.S.: Mein Quelltext zu deinem Post soll heute noch folgen, also vlt heute abend nochmal reinschauen... würd mich freuen!
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

Registriert seit: 5. Aug 2004
Ort: München
1.062 Beiträge
 
#5

AW: Sudoku Logik

  Alt 26. Dez 2010, 17:07
1.) Wenn i > Size * Size --> wofür braucht man das? was bedeutet es?
Das ist die Abbruchbedingung. i zählt mit, das wievielte Feld gerade gefüllt wird. Wenn i dann größer als Size*Size ist, dann hat man bereits alle Felder gefüllt.
2.) Gueltige Entscheidung = {0..Size} --> was ist das? ein Array? wie ist es aufgebaut?
Das ist eine Liste oder ein Array (in dem Fall eigentlich egal), und enthält, welche Entscheidungen gültig sind, bzw. noch nicht durchprobiert wurden.

Zu 2.: Ich dachte schonmal an ein Array of Array, dass man dann ein 4x4 Array z.B. anlegt, für jedes einzelne Feld im Sudoku und in dem Arrayfeld dann ein weiters Array oder Record speichert, für alle zulässigen Zahlen dieses Feldes. Wäre das praktikabel und sinnvoll?
Durchaus - allerdings muss man damit aufpassen, wenn man zu viel damit optimiert. Nehmen wir an der Algorithmus trifft eine Entscheidung, und deshalb ist eine Zahl in einem späteren Feld nicht mehr gültig. Die Entscheidung wird aber rückgängig gemacht - dann muss diese Zahl in dem späteren Feld wieder zu den gültigen Zahlen hinzugefügt werden. Entweder indem alle gültigen Zahlen erneut berechnet werden, oder indem man speichert, wegen welcher Entscheidung eine Zahl als ungültig markiert wurde.
Die beschriebene rekursive Methode vereinfacht diesen Prozess. Man kann dort, bevor man beginnt verschiedene Entscheidungen durchzuprobieren, offensichtlich ungültige Entscheidungen entfernen. Ums Zurücksetzen von Entscheidungen muss man sich dann nicht kümmern - das wird durch die Rekursion direkt erledigt.

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#6

AW: Sudoku Logik

  Alt 26. Dez 2010, 21:42
Hi,
danke für deine Antwort.

Ich sehe jetzt schon deutlich klarer. Aber eine Sache ist noch nicht ganz "aus dem Nebel aufgetaucht"...
Wird versucht, in SetzeFeld das gesamte Sudoku zu füllen? Es sieht für mich gerade so aus, dass immer wieder SetzeFeld aufgerufen wird, wenn eine Entscheidung gültig war. Das würde dann aber bedeuten, dass ich am Anfang nur einmal sagen muss, dass er für Feld 1 SetzeFeld aufrufen soll, weil sich der Rest dann eh alleine erledigt... hab ich das richitg verstanden?

So, dann mach ich mich wohl mal an den Quelltext ran...

LG, hans ditter
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
hans ditter

Registriert seit: 25. Jun 2010
Ort: Niedersachsen
263 Beiträge
 
Turbo Delphi für Win32
 
#7

AW: Sudoku Logik

  Alt 26. Dez 2010, 21:53
Delphi-Quellcode:
function SetDigit(X,Y,Size: integer) : boolean
var ValidDigit: [0..Size] as array of integer;
    nr: integer;
begin
   if (X > Size) OR (Y > Size) then
      Result:=true;
   while ValidDigit > 0 do
   begin
      nr:=random(length(ValidDigit))
      if DigitIsOk(X,Y,nr) then
      begin
         StringGrid1.Cells[X,Y]:=nr;
         if SetDigit(X+1,Y,Size) then
            Result:=True;
      end
      else
         Delete(nr);
   end
   else
      Result:=false;
end
so, nun nochmal einige Anmerkungen:
- ich hab diesen Code noch nicht selbst getestet
- ... dass hab ich noch nicht, weil ich noch ein paar Schwierigkeiten hab
- ... diese liegen vor allem im Umgang mit dem Array, was ich hier erstellen wollte
- ... und als letztes noch in der Frage, ob es für eine while-Schleife auch einen else-Zweig gibt.

angenehme Nachtruhe,
hans ditter
RudiRüsselSeineSocketKomponente - SirRufo (--> Chat mit PM)

Delphi Programming is the best one!
  Mit Zitat antworten Zitat
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

Registriert seit: 5. Aug 2004
Ort: München
1.062 Beiträge
 
#8

AW: Sudoku Logik

  Alt 26. Dez 2010, 22:35
Hi,
Wird versucht, in SetzeFeld das gesamte Sudoku zu füllen? Es sieht für mich gerade so aus, dass immer wieder SetzeFeld aufgerufen wird, wenn eine Entscheidung gültig war. Das würde dann aber bedeuten, dass ich am Anfang nur einmal sagen muss, dass er für Feld 1 SetzeFeld aufrufen soll, weil sich der Rest dann eh alleine erledigt... hab ich das richitg verstanden?
Ja Du rufst SetzeFeld für das 1. Feld auf, und das füllt dann durch die rekursiven Aufrufe das gesamte Sudoku.

Hier mal die Fehler die mir beim groben Überfliegen aufgefallen sind:
while ValidDigit > 0 do
Die Variable GültigeEntscheidungen aus dem PseudeCode ist eine Menge; Die Bedingung für die While-Schleife ist an die Anzahl der Elemente in dieser Menge geknüpft. Am einfachsten gehts hier tatsächlich mit einer Liste.
nr:=random(length(ValidDigit))
ValidDigit enthält ja alle noch gültigen Entscheidungen, aus der eine gewählt werden sollt. Folglich wäre das hier richtig:
nr:=ValidDigit[random(length(ValidDigit))]
Delphi-Quellcode:
if SetDigit(X+1,Y,Size) then
  Result:=True;
Zum einen: X+1 geht nur solange gut, bis X > Size wird; Dann muss die nächste Zeile genommen werden (Y+1). Zum anderen reicht ein result := true; nicht - Die Funktion muss komplett beendet werden.

Deswegen würde ich auf eine Liste zurückgreifen. Hier kann man dies einfacher implementieren.

- ... und als letztes noch in der Frage, ob es für eine while-Schleife auch einen else-Zweig gibt.
Nein Eine While-Schleife kennt kein else.

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:22 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz