Autor Beitrag
klabri
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: 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'....



ausblenden volle Höhe Delphi-Quelltext
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)//Markierung d.Dame
then
begin
dauf[x+y]:=false;    //Dame zurück,Markierung weg
dab[y-x]:=false;     //dauf,dab:Diagonalen 

Feld[x][y]:=False;
end;
erfolg:=false;  //noch keine Dame gesetzt
if (erfolg=false) and (y<8then
begin
y:=y+1;
d[x]:=y;

erfolg:=True ; //Dame gesetzt
if (dauf[x+y]=True)// Dame bedroht ?
or (dab[y-x]=True)
then

erfolg:=false;

if (erfolg=false) and(y<8)Then //neue Position suchen
begin
Suche (x,y);
end;
if (erfolg=False) and(y=8AND (x>1then //Sackgasse,
begin                                     //keine Lösung
Sackgasse:=True;                          //in einer Zeile

 Damen(x-1,d[x-1]);    // hier sollte das "Backtracking
                       // kommen ...

end;                  //d[x-1] Pos. der Dame in Zeile x-1
end;
{******************************************};
If erfolg=true then
begin
dauf[x+y]:=True;      //Dame gesetzt
dab[y-x]:=True;


Feld[x][y]:=True;  //Feld der Dame markiert
ListBox1.Items.Add('Dame:'+IntToStr(x)+'**'+IntToStr(d[x]));
  //Ausgabe
 y:=0;
end;
if x<8 then
Suche  (x+1,y);  //neur Aufruf
end;



Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mo 05.01.2009 um 20:09
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19314
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 05.01.09 20:06 
Durch die globalen Variablen und die fehlenden Einrückungen ist der Code so gut wie unlesbar. :roll:

Was mir auffällt:
ausblenden Delphi-Quelltext
1:
2:
3:
if (Sackgasse=True) and (Feld[x][y]=True)//Markierung d.Dame
then
begin
Das ist falsch. Es muss heißen:
ausblenden Delphi-Quelltext
1:
2:
if Sackgasse and Feld[x][y] then //Markierung d.Dame
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?
ausblenden 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 //neue Position suchen
begin
Suche (x,y);
end;
if (erfolg=False) and(y=8AND (x>1then //Sackgasse,
begin                                     //keine Lösung
Sackgasse:=True;                          //in einer Zeile

 Damen(x-1,d[x-1]);    // hier sollte das "Backtracking
                       // kommen ...
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Mo 05.01.09 21:21 
Also ich hab irgendwie gar nichts verstanden. Bitte formuliere deine Frage noch mal. :roll:

Was weißt du? Was soll das Programm machen? Was ist Zeile x-1?
klabri Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: 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;

ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
  public
        procedure Suche(x:integer);
    { Public-Deklarationen }
  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; //Dame zurücknehmen 
dab[d[x]-x]:=false;
vertikal[d[x]]:=false;
d[x]:=0//zurückgenomme Dame erscheint i.d. Listbox als Null
         // sonst "verwirrt" die Ausgabe.

end;
erfolg:=false; // noch keine Dame gesetzt 
if (erfolg=false)and (y<8then
begin
y:=y+1;
//d[x]:=y; // hier lag ein Fehler ...
erfolg:=True;
if dauf[x+y]=true then Erfolg:=false; //wenn Dame bedroht
if dab[y-x]=true then Erfolg:=false;  // 
if vertikal[y]=True then Erfolg:=false;
if erfolg=false then  //Suche weiter 
begin
//ListBox1.Items.Add(IntToStr(x)+'****'+ IntToStr(d[x]));
Suche(x);
end;
end;
{********************************************}
if erfolg=True  then  //Dame auf einem nicht bedrohten Feld 
d[x]:=y;
dauf[x+y]:=True;    // Diagonalen,Vertikale markieren 
dab[y-x] :=true;
vertikal[y]:=True;


ListBox1.Items.Add(IntToStr(x)+'*'+IntToStr(d[x]));//Ausgabe
y:=0;
end;
if (x<8and (erfolg=True) Then
begin

Suche(x+1); //Neuer Aufruf 
end;
{:::::::::::::::::::::::::::::::::}
if (y=8)and (erfolg=false)  then //hier beginnt das                              //Backtracking
begin
Sackgasse:=True;  // keine Lösung mehr  
//ListBox1.Items.Add('Sackgasse');
y:=d[x-1];
 Suche(x-1);
 end;
 end;


procedure TForm1.Button1Click(Sender: TObject);
begin
Suche(1);
end;

end.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Di 06.01.09 10:29 
user profile iconjaenickes 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.
ausblenden Delphi-Quelltext
1:
if (erfolg = true) then					

wird zu:
ausblenden Delphi-Quelltext
1:
if (erfolg) then //Klammern sind (zumindest in Delphi) Geschmackssache					

ausblenden Delphi-Quelltext
1:
if (erfolg = false) then					

wird zu
ausblenden Delphi-Quelltext
1:
if (not erfolg) then					

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



BeitragVerfasst: Di 06.01.09 10:48 
user profile iconklabri hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: Di 06.01.09 13:37 
Hallo
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure Suche(x:integer);
begin 
....
.....
erfolg:=false; // noch keine Dame gesetzt 
if (erfolg=false)and (y<8then
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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 682

Mac OS X Snow Leopard
Xcode 3.1
BeitragVerfasst: Di 06.01.09 18:10 
user profile iconklabri hat folgendes geschrieben Zum zitierten Posting springen:

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: 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 user profile iconKha: 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 user profile iconKha: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: 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(8): 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 50



BeitragVerfasst: 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.