Autor |
Beitrag |
klabri
      
Beiträge: 50
|
Verfasst: Mo 05.01.09 19:34
Hallo, ich weiss....
warum funktioniert das so nicht ?
Was funktioniert nicht... das Zurücknehmen der Dame
in Zeile x-1 ,wenn 'Sackgasse=True'....
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| procedure Suche(x,y:integer); begin if (Sackgasse=True) and (Feld[x][y]=True)then begin dauf[x+y]:=false; dab[y-x]:=false; Feld[x][y]:=False; end; erfolg:=false; if (erfolg=false) and (y<8) then begin y:=y+1; d[x]:=y;
erfolg:=True ; if (dauf[x+y]=True)or (dab[y-x]=True) then
erfolg:=false;
if (erfolg=false) and(y<8)Then begin Suche (x,y); end; if (erfolg=False) and(y=8) AND (x>1) then begin Sackgasse:=True; Damen(x-1,d[x-1]); end; end; ; If erfolg=true then begin dauf[x+y]:=True; dab[y-x]:=True;
Feld[x][y]:=True; ListBox1.Items.Add('Dame:'+IntToStr(x)+'**'+IntToStr(d[x])); y:=0; end; if x<8 then Suche (x+1,y); end; | Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Mo 05.01.2009 um 20:09
|
|
jaenicke
      
Beiträge: 19314
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 05.01.09 20:06
Durch die globalen Variablen und die fehlenden Einrückungen ist der Code so gut wie unlesbar.
Was mir auffällt: Delphi-Quelltext 1: 2: 3:
| if (Sackgasse=True) and (Feld[x][y]=True)then begin | Das ist falsch. Es muss heißen: Delphi-Quelltext 1: 2:
| if Sackgasse and Feld[x][y] then begin | Erklärung:
www.delphi-treff.de/...olean-werten/page/4/
Und dann noch etwas, was vielleicht der Fehler ist:
Du setzt Sackgasse auf True, aber nie wieder auf False.
Und was ist hier Damen? Mit Suche rufst du die eigene Prozedur rekursiv selbst auf. Aber wo ist Damen definiert? Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure Suche(x,y:integer); ... if (erfolg=false) and(y<8)Then begin Suche (x,y); end; if (erfolg=False) and(y=8) AND (x>1) then begin Sackgasse:=True; Damen(x-1,d[x-1]); |
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Mo 05.01.09 21:21
Also ich hab irgendwie gar nichts verstanden. Bitte formuliere deine Frage noch mal.
Was weißt du? Was soll das Programm machen? Was ist Zeile x-1?
|
|
klabri 
      
Beiträge: 50
|
Verfasst: Di 06.01.09 00:54
Hallo, das war sehr unverständlich gefragt;
Danke für's Ansehen,da steckten noch eine Menge Fehler
drin...
also,dass Programm findet Lösungen für das
8-Dame-Problem.
Inzwischen hab ich alles noch mal neu gemacht und
,welche Freude,scheinbar funktioniert das Backtracking,
darum ging's mir eigentlich.
Also so funktioniert's; zumindest lässt sich das Back-
tracking gut verfolgen;
Die Ausgabe erfolgt in einer Listbox;
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93:
| unit Unitrec59;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; procedure Button1Click(Sender: TObject); private public procedure Suche(x:integer); end;
var Form1: TForm1; erfolg:boolean; d:array[1..8]of integer; dauf:array[2..16]of boolean; dab:array[-7..7]of boolean; vertikal:array[1..8]of boolean; y:integer; sackgasse:boolean; implementation
{$R *.dfm}
procedure TForm1.Suche(x:integer);
begin if sackgasse=True then begin dauf[x+d[x]]:=false; dab[d[x]-x]:=false; vertikal[d[x]]:=false; d[x]:=0; end; erfolg:=false; if (erfolg=false)and (y<8) then begin y:=y+1; erfolg:=True; if dauf[x+y]=true then Erfolg:=false; if dab[y-x]=true then Erfolg:=false; if vertikal[y]=True then Erfolg:=false; if erfolg=false then begin Suche(x); end; end;
if erfolg=True then d[x]:=y; dauf[x+y]:=True; dab[y-x] :=true; vertikal[y]:=True;
ListBox1.Items.Add(IntToStr(x)+'*'+IntToStr(d[x]));y:=0; end; if (x<8) and (erfolg=True) Then begin
Suche(x+1); end;
if (y=8)and (erfolg=false) then begin Sackgasse:=True; y:=d[x-1]; Suche(x-1); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin Suche(1); end;
end. |
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Di 06.01.09 10:29
jaenickes Beitrag hast du aber nicht zur Kenntnis genommen, oder? Auch wenn es in deinem Fall höchstwahrscheinlich nicht zu Problemen führt, sind Konstrukte wie (erfolg=True) auch meiner Ansicht nach unsinnig.
Delphi-Quelltext 1:
| if (erfolg = true) then |
wird zu:
Delphi-Quelltext
Delphi-Quelltext 1:
| if (erfolg = false) then |
wird zu
Delphi-Quelltext
Man kann nämlich nicht immer davon ausgehen, dass trueauch wirklich trueist. Klingt komisch, ist aber so. Das liegt daran, dass man keine einzelnen Bits speichern kann und ein booleandeshalb immer als ein Byte abgelegt wird. Wobei man sich selbst da nicht sicher sein kann. Es gibt also 256 Zustände (statt 2) die rein theoretisch von boolean angenommen werden können. Ob das jetzt immer die Werte 1 ( true) oder 0 ( false) sind, kann man nicht mit Bestimmtheit sagen.
mfg
|
|
WInfo
Hält's aus hier
Beiträge: 12
|
Verfasst: Di 06.01.09 10:48
klabri hat folgendes geschrieben : | Hallo, das war sehr unverständlich gefragt; |
Moin Moin klabri,
wenn dein Codebeispiel verständlich formatiert und dokumentiert wäre, werden sich sicher auch andere den Code mal ansehen. Aktuell finde ich das nur für Grauenhaft und ist mir keines Blickes wert.
|
|
klabri 
      
Beiträge: 50
|
Verfasst: Di 06.01.09 12:34
Hallo,
erstmal danke an alle,die hier geantwortet haben.
Ich hab jänickes beitrag gelesen und war auch auf dem
Delphi-Link;
Ich schreib das noch mal richtig und erklär das auch aus-
führlich und stell's hier dann noch mal als PDF-Datei rein.
|
|
klabri 
      
Beiträge: 50
|
Verfasst: Di 06.01.09 13:37
Hallo
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure Suche(x:integer); begin .... ..... erfolg:=false; if (erfolg=false)and (y<8) then begin y:=y+1;
erfolg:=True; |
ich bemüh mich mal, dieses erfolg:=false am Anfang
der Procedur Suche(x) zu erklären:
-Die Procedure wird mit Suche(1) aufgerufen
-auf einem Schachbrett wäre wir jetzt in der ersten Zeile
-y:=y+1, die erste Spalte in der Zeile oder das erste Feld
-erfolg:=True :wir haben ein nicht besetztes Feld gefunden
-in der Procedure geht es mit erfolg:=True weiter
-die Diagonalen und Vertikal werden als besetzt
-dauf[x+y]:=True etc. markiert
-die Procedure wird wieder aufgerufen :Suche(2)
-wenn dieses erfolg=false fehlt
-wird alles ,was in "If erfolg=false...."steht
übersprungen
-das Programm prüft dann nicht,ob die Dame in der zweiten
Zeile bedroht wird und sucht auch in dieser Zeile keine
neue Lösung
Ich weiss,es ist nicht verständlich so,aber dieses
erfolg:=false am Anfang der Procedure hat so seinen Sinn.
|
|
Dunkel
      
Beiträge: 682
Mac OS X Snow Leopard
Xcode 3.1
|
Verfasst: Di 06.01.09 18:10
klabri hat folgendes geschrieben : |
Ich weiss,es ist nicht verständlich so,aber dieses
erfolg:=false am Anfang der Procedure hat so seinen Sinn. |
Darum geht es ja auch garnicht.
Es geht um Deine if-Konstrukte, in denen Du explizit auf True oder False prüfst. Dass das zu Problemen führen kann (nicht muss!), steht recht gut erklärt in dem Link, welchen Du Dir offensichtlich nicht genau genug durchgelesen hast.
_________________ Ich streite einsam mich mit dieser Oberflächenwelt
Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod [Das Ich - Im Ich]
|
|
klabri 
      
Beiträge: 50
|
Verfasst: Di 06.01.09 20:39
Hallo,
stimmt,ich hab mal so schnell drüber gelesen; aber es
leuchtet mir ein und ich werd's mal ändern;
Danke noch einmal für den Hinweis
-- Moderiert von Kha: Beiträge zusammengefügt - ab hier 10.03.10 --
Hallo,
ich beschäftige mich gerade mal wieder mit diesem 8-Damen-Problem.
Mein Programm findet mit 8 Damen, mit Back-Tracking 1 Lösung,
dabei steht die erste Dame in der ersten Zeile,in der ersten Spalte.
Während der Lösungssuche läuft das Backtracking von der achten Zeile bis zur
zweiten Zeile,dann findet es eine Lösung.
Die erste Dame müsste sich dann auf das nächste Feld bewegen,aber wie stelle ich das an ?
-- Moderiert von Kha: Beiträge zusammengefügt --
Hallo,
das Programm läuft nach folgendem Schema ab:
-Suche Position ,in der Dame(x) nicht geschlagen wird
-wenn Position gefunden,dann setze Dame(x)
-wenn in Zeile x keine Lösung ,
,mache in Zeile(x-1)weiter
-Suche Position....setze Dame.....
usw.
es gibt eine Funktion Setze_Dame(x:integer):integer;
,die,wenn eine Position gefunden ist mit Setze_Dame(x+1) wieder aufgerufen wird.
In dem Programm lässt sich das Backtracking gut verfolgen,aber
es findet eben nur eine Lösung..
Setze_Dame(x) wird so aufgerufen
if x<8 and gefunden:=True then
Setze_dame(x+1);
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Do 11.03.10 01:23
Da war ich mit dem Zusammenfassen wohl etwas übereifrig, also zum Pushen gleich eine Antwort hinterher  .
Im Prinzip darfst du nach dem Fund einer gültigen Position nicht aufhören, sondern musst für jede gültige Position in der Reihe die Funktion rekursiv aufrufen. Wenn dein Algorithmus die Menge aller Lösungen zurückgeben soll, bräuchtest du noch eine verschachtelte Liste wie im Wikipedia-Beispiel, für die bloße Anzahl oder weiterhin die direkte Ausgabe in einer Listbox solltest du nicht viel ändern müssen.
_________________ >λ=
|
|
klabri 
      
Beiträge: 50
|
Verfasst: Do 11.03.10 11:09
Hallo,
ich guck mir das Wikedepia mal ;
irgendwo fehlt ein rekursiver Aufruf.
Die Funktion Setze_dame(x+1) ruft sich auf bis
diese Abbruchbedingung
x<8 and gefunden =True erfüllt ist, beim Setzen der achten Dame.
dame(1): Pos 1
dame(2): Pos 5
dame(3): Pos 8
..
dame(  : Pos 4
Ende, weil Lösung gefunden...
weitergehn müsste die Suche mit dame(2),indem Pos 6,7,8 geprüft wird..
Hier fehlt mir also ein entsprechender Aufruf.
Wenn diese Positionen geprüft sind und die Lösungen gefunden sind,müsste die
1.Dame auf Pos 2 vorrücken usw.... ,dieser neue Aufruf fehlt mir aucn noch...
Aber ich bin schon mal zufrieden,dass das Backtracking so funktioniert
Ich häng die Unit mal als Datei dran,vielleicht hat jemand eine gute Idee,was
da noch fehlt..
Einloggen, um Attachments anzusehen!
|
|
klabri 
      
Beiträge: 50
|
Verfasst: So 14.03.10 17:58
So, inzwischen ist das Problem gelost;
nachdem das Programm eine Lösung gefunden hat, also die achte Dame in gesetzt ist
ruft es eine zweite Funktion auf, die weiter Positionen absucht
-zuerst in der Zeile, in der die letzte Dame gesetzt worden ist
-dann kommt das Backtracking in Zeile -1 ,wenn keine Lösung gefunden usw,
alle Fragen sind beantwortet,dass Rad wurde zum x-ten Mal erfunden.
Jetzt verpacke ich das ganze noch ein wenig.
Vielen Dank für das Beantworten meiner Fragen.Ich habe als verstanden,
wie "Backtracking" funktioniert.
|
|
|