tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
5
ZUGRIFFE
2090
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    sra sra ist offline Mitglied Gold
    Registriert seit
    Aug 2003
    Beiträge
    169
    Hallo

    Ich habe ein Problem mit Backtracking. Ein ähnliches Problem habe ich schon gestern ins C# Board geschrieben, und mein Code ist auch in C#. Allerdings bekomme ich da kaum Rückmeldung.

    Darum (und weil es sowieso nichts sprachspezifisches ist, sondern der Algorithmu entscheidend ist) versuche ich es noch hier.

    Also... Ich versuche per Backtracking jeden Weg aus einem Labyrinth zu finden. Die Zahlen, spielen dabei zunächst nur eine zweitrangige Rolle, und müssen auch gar nicht beachtet werden.

    Mein Problem ist, dass ich - einmal in einer Sackgasse angekommen - nciht mehr rauskomme, und das Programm frühzeitig beendet.

    Hier der Code (lasst euch nicht einschüchtern, das meiste ist nur die switch/case anweisung):

    Code :
    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
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    
    using System;
     
    namespace sonja
    {
        class SOI_BackTrack
        {
            [STAThread]
     
            public static void Main(string[] args)
            {
                int actTime = 0;
                findBestPath('x', actTime);
                Console.WriteLine(bestTime);
                Console.ReadLine();
                Console.ReadLine();
            }
     
            static int r=0, s=0, bestTime=32000; // r=Reihe s=Spalte
            /*static char[,] Lab = {{'A','1','4','7','X'},
                    {'1','9','5','X','2'},
                    {'X','4','6','7','9'},
                    {'1','X','9','1','1'},
                    {'7','9','3','7','E'}};*/
                    
            static char[,] Lab = {{'A','X','X','X','X'},
                    {'1','X','5','X','2'},
                    {'5','X','6','7','9'},
                    {'1','X','X','X','X'},
                    {'7','9','3','7','E'}};
     
            public static bool findBestPath(char compass, int actTime)
            {
                switch(compass)
                {
                    case 'x': break;
     
                    case 'r': 
                        if((s+1 <= 4) && (Lab[r,s+1] != 'X'))  
                        { 
                            Lab[r,s] = 'X';
                            s++;
                            if ((Lab[r,s] != 'E') && (Lab[r,s] != 'A')) 
                            {
                                actTime += Convert.ToInt32(Lab[r,s].ToString());
                            }
                        } else {
                            return (false);
                        } break;
     
                    case 'u': 
                        if((r+1 <= 4) && (Lab[r+1,s] != 'X')) 
                        { 
                            Lab[r,s] = 'X'; 
                            r++; 
                            if ((Lab[r,s] != 'E') && (Lab[r,s] != 'A')) 
                            {
                                actTime += Convert.ToInt32(Lab[r,s].ToString());
                            }
                        } else { 
                            return (false); 
                        } break;
     
                    case 'l': 
                        if((s-1 >= 0) && (Lab[r,s-1] != 'X')) 
                        { 
                            Lab[r,s] = 'X';
                            s--;
                            if ((Lab[r,s] != 'E') && (Lab[r,s] != 'A')) 
                            {
                                actTime += Convert.ToInt32(Lab[r,s].ToString());
                            }
                        } else {
                            return (false);
                        } break;
     
                    case 'o': 
                        if((r-1 >= 0) && (Lab[r-1,s] != 'X'))
                        {
                            Lab[r,s] = 'X';
                            r--;
                            if ((Lab[r,s] != 'E') && (Lab[r,s] != 'A')) 
                            {
                                actTime += Convert.ToInt32(Lab[r,s].ToString());
                            }
                        } else {
                            return (false);
                        } break;
     
                    default: return (false);
                }
                
                Console.Write(Lab[r,s]);
                Console.WriteLine(" - " + actTime);
     
                if(Lab[r,s] == 'E')
                {
                    if(actTime < bestTime)
                    {
                        bestTime = actTime;
                    }
                    Console.Write("we are the Best");
                    return (false);
                }
     
                if(findBestPath('r', actTime)){ }
                if(findBestPath('u', actTime)){ }
                if(findBestPath('l', actTime)){ }
                if(findBestPath('o', actTime)){ }
                return (false);
            }
        }
    }

    Eigentlich sollte er, wenn er in eine Sackgasse kommt, und alle wege versperrt sind false zurückgeben, und die aktion also gar nicht machen:

    Code :
    1
    2
    3
    4
    5
    
    if(findBestPath('r', actTime)){ }
    if(findBestPath('u', actTime)){ }
    if(findBestPath('l', actTime)){ }
    if(findBestPath('o', actTime)){ }
    return (false);

    Da es doch ganz schön kompliziert ist (wie ich finde), habe ich euch schnell ein Bild erstellt.

    http://mypage.bluewin.ch/destiny/backtracking.JPG

    Bei Schritt 2 schaut er zuerst rechts. -> ist nicht gespert, also rein da.
    In Schritt 3 sieht schaut er rechts -> false, unten -> false, links -> false, oben -> false, also gibt die funktion (if(findBestPath()) { }) false zurück.
    Er hat also schritt 2 zu 3 (nach rechts) gar nie gemacht, und versuchts nun neu in schritt 2 unten, wo er fündig wird.

    Hoffe ihr wiss was ich meine
     
    Die Geschichte lehrt den Menschen, dass er aus der Geschichte nichts lernt //gandhi

  2. #2
    Registriert seit
    Jul 2003
    Ort
    Duisburg (NRW)
    Beiträge
    1.788
    Da es doch ganz schön kompliziert ist (wie ich finde)
    Stimmt, ist es. Mir ist aufgefallen, dass findBestPath() nie ein true zurückgibt. Ist das Absicht?
     
    Chor: "Wir sind der Chor, und wir stimmen zu. Wir stimmen zu, wir stimmen zu, wir stimmen zu."

  3. #3
    sra sra ist offline Mitglied Gold
    Registriert seit
    Aug 2003
    Beiträge
    169
    Ja das ist Absicht.
    Enweder er kann noch weiter (in irgendeine Richtung), und dann macht er das, oder er gibt false zurück, wenn es nicht mehr weitergeht.

    Die Idee ist ja, dass der Funktionaufruf in der if Anweisung steht, und sobald es irgndwo nicht geht, dann macht er es auch nicht

    Auch wenn er schon viel weiter im weg ist, und dann auf eine sackgasse trifft, wird solange false zurückgegeben, bis er wieder an einer "verzweigung" ist, und einen anderen Weg einschalgen kann.
     
    Die Geschichte lehrt den Menschen, dass er aus der Geschichte nichts lernt //gandhi

  4. #4
    Registriert seit
    Jul 2003
    Ort
    Duisburg (NRW)
    Beiträge
    1.788
    Du solltest vielleicht die aktuelle Position als Parameter an die Funktion übergeben. Bei jedem rekursiven Aufruf werden die quasi globalen Koordinaten r und s überschrieben. Das kann nicht gut gehen. Für Backtracking muss in irgendeiner Weise Buch geführt werden über vorhergehende Zustände der Suche. Beim rekursiven Aufruf wäre das eventuell gewährleistet, wenn du die Postion übergibst - vorhergehende Zustände liegen dann auf dem Stack. Das ist kompliziert zu erklären, sorry.
     
    Chor: "Wir sind der Chor, und wir stimmen zu. Wir stimmen zu, wir stimmen zu, wir stimmen zu."

  5. #5
    sra sra ist offline Mitglied Gold
    Registriert seit
    Aug 2003
    Beiträge
    169
    Du meinst, dass wenn ich die Variablen r und s während eines Aufrufes ändere, dann weiss das Programm nicht mehr, wie es vorher war?

    Ist es aber nicht so, dass, da der Funktionsaufruf ja im if drinn ist, die Variablen im Endeffekt gar nicht mal berührt werden, da die Funktion ja schlussendlich sowieso false zurückgibt?

    Du hast recht. es ist schwer das irgendwie zu formulieren
    Geändert von sra (11.03.04 um 15:01 Uhr)
     
    Die Geschichte lehrt den Menschen, dass er aus der Geschichte nichts lernt //gandhi

  6. #6
    sra sra ist offline Mitglied Gold
    Registriert seit
    Aug 2003
    Beiträge
    169
    also...

    in gewisser weise hast du recht. So geht es schon besser.
    Es funktioniert zwar immer noch nicht ganz.

    Sobald ich den Fehler lokalisiert habe, werde ich mich melden

    //edit: Funktioniert nun perfekt! Danke dir Kachelator
    Geändert von sra (12.03.04 um 09:44 Uhr)
     
    Die Geschichte lehrt den Menschen, dass er aus der Geschichte nichts lernt //gandhi

Ähnliche Themen

  1. Backtracking
    Von EddieG im Forum Java Grundlagen
    Antworten: 2
    Letzter Beitrag: 17.01.10, 20:21
  2. Problem beim Backtracking
    Von Dragonate im Forum C/C++
    Antworten: 13
    Letzter Beitrag: 17.12.09, 13:36
  3. Backtracking
    Von jenny-birdy im Forum Algorithmen & Datenstrukturen mit Java
    Antworten: 1
    Letzter Beitrag: 16.11.09, 11:51
  4. Backtracking Problem C-Sharp
    Von Audrey im Forum Sonstige Sprachen
    Antworten: 0
    Letzter Beitrag: 03.06.08, 08:40
  5. Backtracking für Newbies?
    Von sra im Forum .NET Archiv
    Antworten: 15
    Letzter Beitrag: 10.03.04, 08:33