Backtracking - kennt Java keine Rücksprungmarken?

Status
Nicht offen für weitere Antworten.

ayrton89

Mitglied
Hallo,
ich möchte mit dem Backtracking-Algorithmus Wege durch ein Labyrinth finden. Das Prinzip ist klar, es ist ein rekursiver Algorithmus den man jeweils mit der erweiterten Teillösung aufruft und der returnt, wenn das Ende erreicht ist bzw. wenn er in einer Sackgasse landet. Ich übergebe der Funktion konkret eine ArrayList mit allen Feldern die zu dem Weg gehören. Nur dummerweise verwendet der Interpreter scheinbar nach dem returnen nicht den Wert vom Rücksprungkeller, sondern nimmt immer den aktuellsten, sodass er auch wenn das Zielfeld schon erreicht ist immer noch Felder hintendranhängt.

Ich denke mal das hat irgendwas damit zu tun dass Objekte per Referenz übergeben werden, kann man das also irgendwie ändern bzw. umgehen?

Danke
 

ARadauer

Top Contributor
ja referenzen.... hilft dir das...
Code:
   public static void main(String[] args) {
      ArrayList<String> list = new ArrayList<String>();
      list.add("Test");
      System.out.println("Size: "+list.size());
      cleerList(list);
      System.out.println("Müsste 0 sein, die die Referenz übergeben wurde: "+list.size());
      
      list.add("Nochmal");
      cleerList((ArrayList<String>)list.clone());
      System.out.println("Müsste 1 sein da eine Kopie übergeben wurde: "+list.size());
   }
   
   public static void cleerList(ArrayList<String> list){
      list.clear();      
   }
 

SchonWiederFred

Bekanntes Mitglied
Ich denke mal das hat irgendwas damit zu tun dass Objekte per Referenz übergeben werden, kann man das also irgendwie ändern bzw. umgehen?
Vorsicht, in Java werden keine Objekte übergeben, und es wird auch nichts per Referenz übergeben -- sowohl primitive Typen als auch Referenztypen werden per Wert übergeben.

Wenn Du die Übergabe von Objekten per Wert simulieren willst, musst Du Objekte klonen. Statt
funktion(meineListe); musst Du also
funktion(new ArrayList(meineListe)); oder sowas schreiben.
 

ayrton89

Mitglied
Nein das hilft leider auch nicht. Ich will ja nur dass er beim Herauswinden aus der Rekursion die in dem Rekursionsschritt hinzugefügten Felder wieder „vergisst” (also ein korrektes Backtracking mit richtigem pulsierenden Speicher). Einen Klon der Liste zu übergeben ändert leider gar nichts.
 

ayrton89

Mitglied
Ich seh schon, es wird Zeit den Code zu posten.

Code:
private void findPath( ArrayList<Field> wayPart ) {
		Field f = wayPart.get( wayPart.size()-1 );
		if( f.equals( END_FIELD ) ) {
			finishWays.add( (ArrayList<Field>) wayPart.clone() );
			return;
		} else {
			for( Field g : getTouchedFields( f ) ) {
				if( !g.isBlocked() && !wayPart.contains(g) ) {
					wayPart.add(g);
					findPath( wayPart );
				}
			}
		}
	}

Ganz klassisches Backtracking, nur dummerweise werden Objekte augenscheinlich per Referenz übergeben. Jedenfalls wird nach dem Ende einer Funktionsinstanz nicht der Wert der als letztes auf dem Rücksprungmarkenkeller liegt genommen, sondern der vollständige Weg behalten. Stichwort pulsierender Speicher
 

0x7F800000

Top Contributor
"Design graphs, not algorithms" (S. Skiena)
:autsch:
Was auch immer du da anstellst: am ende ist es doch sowieso ein wegsuchalgorithmus auf irgendeinem Graphen, und die lassen sich alle wunderbar in java implementieren... ???:L
 

Marco13

Top Contributor
Code:
list.add(newPosition);
recursion(list);
list.remove(list.size()-1);
->
Code:
wayPart.add(g);
findPath( wayPart );
wayPart.remove(wayPart.size()-1);
!?!?!?
 

ayrton89

Mitglied
"Design graphs, not algorithms" (S. Skiena)
:autsch:
Was auch immer du da anstellst: am ende ist es doch sowieso ein wegsuchalgorithmus auf irgendeinem Graphen, und die lassen sich alle wunderbar in java implementieren... ???:L

Also tut mir leid aber das ist einfach Unsinn. Der Backtracking-Algorithmus ist wie geschaffen für genau solche Probleme, denn er täte wunderbar einfach und schnell genau das was ich von ihm will, wenn die Java-eigenen Konzepte mir nicht einen Strich durch die Rechnung machen würden.
 

André Uhres

Top Contributor
Ich bin nicht sicher, ob das hilft, aber ich hatte sowas mal mit einem Stack gelöst, etwa so:
Code:
while(visitedCells < totalCells && currentCell != finishPoint){
    nextCell = nextNonvisitedNeighborCell(currentCell);
    if(nextCell == null){
        currentCell.backtrack = true;
        currentCell = stack.pop();
    }else{
        stack.push(currentCell);
        currentCell = nextCell;
        visitedCells++;
    }
}
Gruß,
André
 

0x7F800000

Top Contributor
Könntest du das etwas konkretisieren? Wie soll ich es denn implementieren?
Das weiß ich nicht, da mir von der Struktur deines Programms nichts bekannt ist. Da du von "Feldern" sprichst, glaube ich nicht, dass du dir die Mühe gegeben hättest, aus vielen Kästchen einen kleinen einfachen expliziten Graphen zu extrahieren (das ist schon eine menge Programmieraufwand. Ich weiß jetzt nicht, ob das wirklich so gemacht wird, aber imho wäre es eine tolle idee, die gesammte begehbare Fläche in sternförmige, oder gar konvexe, Gebiete zu unterteilen, und die Zentren dieser Gebiete zu Knoten eines Graphen zu machen, und diese einfach durch direkte Kanten zu verbinden. Dann hätte man einen ziemlich kleinen explizit gegebenen Graphen, und könnte darauf sofort die bekannten Wegsuchalgos a'la Dijkstra loslassen.)

Könntest du also vielleicht erläutern, in welcher Form du die Umgebung speicherst? ???:L

Also tut mir leid aber das ist einfach Unsinn. Der Backtracking-Algorithmus ist wie geschaffen für genau solche Probleme, denn er täte wunderbar einfach und schnell genau das was ich von ihm will, wenn die Java-eigenen Konzepte mir nicht einen Strich durch die Rechnung machen würden.
Ähm, what? Was ist denn "Backtracking" deiner meinung nach? Stinknormale Tiefensuche auf Graphen ist auch "Backtracking", kannst es doch nennen wie du willst, ändert nichts an der Funktionsweise..
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Ein Versuch - hingehackt - wenn's "anders ist als bei dir" gibt's da ne ganz einfache Lösung dafür...

Code:
import java.util.*;


class Field
{
    private String name;
    List<Field> touched = new ArrayList<Field>();

    public Field(String name)
    {
        this.name = name;
    }

    public boolean isBlocked()
    {
        return false;
    }

    public String toString()
    {
        return name;
    }

}


class BacktrackingTest
{

    public static void main(String args[])
    {
        new BacktrackingTest();
    }

    Field END_FIELD;
    ArrayList<List<Field>> finishWays = new ArrayList<List<Field>>();


    public BacktrackingTest()
    {
        Field f = new Field("f");
        Field f0 = new Field("f0");
        Field f1 = new Field("f1");
        Field f2 = new Field("f2");
        f.touched.add(f0);
        f.touched.add(f1);
        f.touched.add(f2);

        Field f10 = new Field("f10");
        Field f11 = new Field("f11");
        Field f12 = new Field("f12");
        f1.touched.add(f10);
        f1.touched.add(f11);
        f1.touched.add(f12);


        Field end = new Field("end");

        f10.touched.add(f);
        f11.touched.add(end);

        END_FIELD = end;

        ArrayList<Field> wayPart = new ArrayList<Field>();
        wayPart.add(f);
        findPath(wayPart);
        System.out.println(finishWays);
    }




    private List<Field> getTouchedFields(Field f)
    {
        return f.touched;
    }



    private void findPath(ArrayList<Field> wayPart)
    {
        Field f = wayPart.get(wayPart.size() - 1);
        if (f.equals(END_FIELD))
        {
            finishWays.add((ArrayList<Field>) wayPart.clone());
            return;
        }
        else
        {
            for (Field g : getTouchedFields(f))
            {
                if (!g.isBlocked() && !wayPart.contains(g))
                {
                    wayPart.add(g);
                    findPath(wayPart);
                    wayPart.remove(wayPart.size()-1);
                }
            }
        }
    }
}
 

ayrton89

Mitglied
Mein Programm ist so strukturiert, dass ich eine Labyrinth-Klasse habe, deren Konstruktor die Breit und Höhe (also jeweils Anzahl der Felder) entgegennimmt. Felder selbst sind Objekte vom Typ Field, diese haben eine x- und eine y-Koordinate und eine boolean-Eigenschaft, ob sie ein Hindernis enthalten oder nicht (isBlocked). Ein Labyrinth hat wie gesagt im Wesentlichen eine Breite und eine Höhe, und eine beliebige Anzahl an Hindernissen (blockierten Feldern). Außerdem gibt es die Methode getTouchedFields(Field f), die alle Nachbarfeldern, sofern vorhanden, eines Feldes zurückgibt.

Und richtig, Backtracking ist im Prinzip systematische Tiefensuche auf einem Graphen. Dieser „Graph” ist in meinem Fall das Labyrinth, bzw. dessen nicht blockierte Felder.

Dijkstra ist in dem Fall zwar prinzipiell möglich (wenn auch sehr aufwändig), allerdings gibt dieser die Wege zu allen Feldern, ich will aber nur den Weg zu genau einem Feld, nämlich dem END_FIELD.
 

0x7F800000

Top Contributor
Ookay...
Meinst du sowas?
[highlight=Java]
import java.util.*;

public class Labyrinth{

String mapData=
"########################################"+
"# ## ## ## ####### #"+
"# ### ## ######## ## ##### ###### ### #"+
"# ## ## #### ### # ## ### ## #"+
"## ## ### ##### ###### ### ## ##"+
"## ######### ### ###### ###### ### ## #"+
"## #### ### #### #### ### #"+
"### ### ## ### #### ######## ## #"+
"### # ####### ## ## ## ##"+
"# # # ####### ## ## ###### ## ## ## #"+
"# ### # ## ## # ## ## ### #"+
"# ########## ## ### # ######### ## #"+
"# ############ ## # ## ## ##"+
"# ### ## ### ## ######## ###### #"+
"# ######## ## ### ## # ### # ## #"+
"# #### ## ## #### # # #"+
"#### # ### ############ ## # # ####"+
"# # ###### ## ## ## # ### ####"+
"# ## ### ### ## ## # #"+
"######### ######## ## ############# ##"+
"#################### ## ## ## #"+
"# ## ## ## ## ## ## ####### ##"+
"# ### ## ######## ## ## ## ## ####### ##"+
"# ## ## #### ### ## ## ## ## ####### ##"+
"## ## ### # # ## ####### ##"+
"## ######### ### ## ## ############## ##"+
"## #### ### # ##### ##"+
"### ### ## ### #### ##### ### ##"+
"### # ####### ## ## ### ##"+
"########################################";
int w=40, h=30;

public static class Point{
int x,y;
Point(int _x, int _y){ x=_x; y=_y; }

List<Point> getNeighbors(boolean[][] map){
int w=map.length;
int h=map[0].length;

List<Point> neighbors=new LinkedList<Point>();
for(int i:new int[]{x-1,x+1}){
if(i<0 || i>=w) continue;
if(map[y]){
neighbors.add(new Point(i,y));
}
}
for(int i:new int[]{y-1,y+1}){
if(i<0 || i>=h) continue;
if(map[x]){
neighbors.add(new Point(x,i));
}
}
return neighbors;
}
@Override
public String toString(){ return "("+x+"|"+y+")"; }
@Override
public boolean equals(Object other){
return other instanceof Point
&& ((Point)other).x == this.x
&& ((Point)other).y == this.y;
}
}

boolean[][] map=new boolean[w][h];
{
for(int x=0; x<w; x++){
for(int y=0; y<h; y++){
map[x][y]=mapData.charAt(y*w+x)==' ';
}
}
}

//######################################################################### IRGENDEINEN WEG SUCHEN

public List<Point> deepFirstSearch(Point from, Point to){
return deepFirstSearch(from,to,new boolean[w][h]);
}

private LinkedList<Point> deepFirstSearch(Point from, Point to, boolean[][] visited){
//diesen punkt als besucht markieren
visited[from.x][from.y]=true;

//wenn ziel erreicht: rekursionsende
if(from.equals(to)){
LinkedList<Point> path=new LinkedList<Point>();
path.add(to);
return path;
}

//guggen, ob von einem nachbar das ziel erreichbar ist
for(Point p:from.getNeighbors(map)){
//nachbar muss unbesucht und begehbar sein
if(!visited[p.x][p.y] && map[p.x][p.y]){
LinkedList<Point> path=deepFirstSearch(p,to,visited);
if(path!=null){
path.addFirst(from);
return path;
}
}
}

//kein weg gefunden
return null;
}


public String toString(Point... markedPoints){
StringBuilder b=new StringBuilder();
for(int y=0; y<h; y++){
for(int x=0; x<w; x++){
if(Arrays.asList(markedPoints).contains(new Point(x,y))){
b.append("* ");
}else{
b.append(map[x][y]?" ":"||");//(char)0+""+(char)0);
}
}
b.append('\n');
}
return b.toString();
}

public static void main(String..._){
Labyrinth lab=new Labyrinth();

Point startPoint, target=new Point(1,1);


while(true){

startPoint=target;
target=null;
Random rand=new Random();
while(target==null){
int x=rand.nextInt(lab.w);
int y=rand.nextInt(lab.h);
if(lab.map[x][y]){
target=new Point(x,y);
}
}


Collection<Point> path=lab.deepFirstSearch(startPoint,target);

if(path!=null){
for(Point p:path){
for(int i=0; i<40; i++) System.out.println();
System.out.println(lab.toString(p,target));
try{
Thread.sleep(200);
}catch(Exception e){}
}
}else{
continue;
}

for(int i=0; i<40; i++) System.out.println();
System.out.println(lab.toString(path.toArray(new Point[path.size()])));
try{
Thread.sleep(1500);
}catch(Exception e){}

}
}
}
[/highlight]

(beim asuführen bitte die Konsole etwas in die höhe ziehen, hatte keine lust eine ordentliche animation zu basteln^^)

Bringt's dich weiter?

bemerkung: es ist besser, solche informationen wie "visited j/n" direkt in den Zellen unterzubringen, wie du es getan hast, ich habe mir hier nicht so doll viele gedanken gemacht, deswegen ist das etwas plump mit zwei arrays gelöst worden, ist eigentlich nicht so schön.:oops:
 
Zuletzt bearbeitet:
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Max246Sch 3D Box Filler BAcktracking Java Basics - Anfänger-Themen 1
P Frage zu Rekursion und Backtracking Java Basics - Anfänger-Themen 2
districon Backtracking Java Basics - Anfänger-Themen 2
districon Backtracking Java Basics - Anfänger-Themen 14
districon Dynamisch Programmierung/Backtracking/Memoization Java Basics - Anfänger-Themen 3
districon Backtracking funktioniert nicht ganz Java Basics - Anfänger-Themen 3
V Backtracking und Rekursion Java Basics - Anfänger-Themen 15
G Subset sum problem mit Backtracking Java Basics - Anfänger-Themen 18
O Backtracking Java Basics - Anfänger-Themen 5
C Rekursives Backtracking beim Spiel Peg Java Basics - Anfänger-Themen 22
A Backtracking Java Basics - Anfänger-Themen 56
R Backtracking Java Basics - Anfänger-Themen 1
V Feld sortieren mit Backtracking Java Basics - Anfänger-Themen 1
A Sudoku mit Backtracking lösen Java Basics - Anfänger-Themen 3
L Sudoku Backtracking Pseudocode Java Basics - Anfänger-Themen 3
N Backtracking - Labyrinth/Irrgarten Java Basics - Anfänger-Themen 14
I Backtracking Schach Java Basics - Anfänger-Themen 5
L Magisches Quadrat und Backtracking Java Basics - Anfänger-Themen 19
M Backtracking/Solve Methode Java Basics - Anfänger-Themen 7
P Labyrinth, Backtracking, verzögerte Anzeige Java Basics - Anfänger-Themen 15
D Sudoku lösen mit Backtracking Java Basics - Anfänger-Themen 20
E backtracking und Induktionsprinzip Java Basics - Anfänger-Themen 2
D Backtracking Waage Problem Java Basics - Anfänger-Themen 23
N Backtracking Solohalma Java Basics - Anfänger-Themen 2
W Backtracking und Frustration Java Basics - Anfänger-Themen 6
X Sudoku Backtracking Java Basics - Anfänger-Themen 6
J Solitaire via Backtracking Java Basics - Anfänger-Themen 7
G Backtracking mit globaler Variable Java Basics - Anfänger-Themen 5
M BackTracking Java Basics - Anfänger-Themen 22
J Backtracking Algorithmus Java Basics - Anfänger-Themen 16
M Kennt jemand die richtige Lösung? Java Basics - Anfänger-Themen 7
K Ein Objekt Auto kennt den Inhalt seines links und rechtsstehenden Autos, wie soll man das ermöglichen Java Basics - Anfänger-Themen 2
M Eclipse kennt keine String Klasse mehr Java Basics - Anfänger-Themen 1
B Java -Turtle Grafik - kennt sich jemand damit aus? Java Basics - Anfänger-Themen 1
B Wer kennt einen Link für vollständiges, leichtverständliches "Game of Life"? Java Basics - Anfänger-Themen 1
M java kennt Variable nicht? Java Basics - Anfänger-Themen 2
V kennt jemand empfehlenswerte online tutorials zur Hibernate ? gerne auch englisch. Java Basics - Anfänger-Themen 4
T Eclipse kennt mein Button nicht... Java Basics - Anfänger-Themen 5
J Kennt run() den ausführenden Thread? Java Basics - Anfänger-Themen 7
T Opaque kennt er nicht/ programm beenden?? Java Basics - Anfänger-Themen 9
A Eclipse kennt setLayout und add nicht!? Java Basics - Anfänger-Themen 5
S Mein Computer kennt "javac" und "java" nicht mehr! Java Basics - Anfänger-Themen 6
S Kennt jemand die Default-Cache Zeit beim Java-Plugin? Java Basics - Anfänger-Themen 2
H2SO3- wie kennt ein button sich selber? Java Basics - Anfänger-Themen 21
K Bresenham Algo // wer kennt sich aus? Java Basics - Anfänger-Themen 4
K Kennt jemand ein gutes Tutorial für Wertübergabe? Java Basics - Anfänger-Themen 4
N kennt ihr ein gutes java forum für anfänger? Java Basics - Anfänger-Themen 5
H .java Dateien in Eclipse einbinden und ausführen Java Basics - Anfänger-Themen 1
onlyxlia Schlüsselworte Was meint man mit "einen Typ" in Java erstellen? Java Basics - Anfänger-Themen 2
O Java Kara geschweifte Klammern Java Basics - Anfänger-Themen 2
richis-fragen Mausrad logitech kann links und rechts klick wie in java abragen. Java Basics - Anfänger-Themen 15
XWing Java Klssenproblem Java Basics - Anfänger-Themen 4
R Umgebungsvariable java -cp gibt immer Java-Hilfe... Java Basics - Anfänger-Themen 3
farbenlos Csv Datei in Java einlesen Java Basics - Anfänger-Themen 18
F TableModelListener: java.lang.ArrayIndexOutOfBoundsException: 132 Java Basics - Anfänger-Themen 3
G Java 8 - Support-Ende Java Basics - Anfänger-Themen 7
T Java Weihnachtsbaum + Rahmen Java Basics - Anfänger-Themen 1
N Will mit Java anfangen Java Basics - Anfänger-Themen 13
Ü Java Array - Buchstaben als Zahlen ausgeben Java Basics - Anfänger-Themen 22
M Java Iterator Verständnisfrage Java Basics - Anfänger-Themen 6
M Java Mail Programm Java Basics - Anfänger-Themen 4
Sniper1000 Java 391 für Windows Java Basics - Anfänger-Themen 37
J Java long- in int-Variable umwandeln Java Basics - Anfänger-Themen 6
JaZuDemNo Java im Studium Java Basics - Anfänger-Themen 7
E Java Programm zur anzeige, ob Winter- oder Sommerzeit herrscht Java Basics - Anfänger-Themen 62
I QR code in Java selber generieren Java Basics - Anfänger-Themen 5
V Java-Ausnahmebehandlung: Behandlung geprüfter Ausnahmen Java Basics - Anfänger-Themen 1
krgewb Java Streams Java Basics - Anfänger-Themen 10
A Überwältigt von der komplexen Java Welt Java Basics - Anfänger-Themen 29
O Mehrfachvererbung auf Spezifikations- und Implementierungsebene in Java. Interfaces Java Basics - Anfänger-Themen 19
John_Sace Homogene Realisierung von Generics in Java ? Java Basics - Anfänger-Themen 19
P Meldung aus Java-Klasse in Thread an aufrufende Klasse Java Basics - Anfänger-Themen 1
R mit Java API arbeiten Java Basics - Anfänger-Themen 9
P JDK installieren Probleme bei der Java-Installation Java Basics - Anfänger-Themen 8
S Java: Wie sortiere ich eine ArrayList benutzerdefinierter Objekte nach einem bestimmten Attribut? Java Basics - Anfänger-Themen 2
Timo12345 JNLP File mit Java öffnen Java Basics - Anfänger-Themen 2
S Video Editierung mit Java.._ Java Basics - Anfänger-Themen 2
F Einstelungen in Java - CursorBlinkRate Java Basics - Anfänger-Themen 10
A PHP $_POST["name"] in Java Java Basics - Anfänger-Themen 3
vivansai21 Is there a oneliner to create a SortedSet filled with one or multiple elements in Java? Java Basics - Anfänger-Themen 9
Athro-Hiro Weißes Bild in Java erstellen Java Basics - Anfänger-Themen 3
Arjunreddy Can someone please tell me how to use a debugger in BlueJ(a Java environment) Java Basics - Anfänger-Themen 1
M Java assoziationen (UML) Java Basics - Anfänger-Themen 8
H Excel-Tabellen mit Java erstellen Java Basics - Anfänger-Themen 4
Simon16 Java ArrayListe von einer Klasse sortieren Java Basics - Anfänger-Themen 2
P Wie kann ich in meinem Java Programm etwas dauerhaft speichern? Java Basics - Anfänger-Themen 5
H Nutzt Eclipse alle CPU-Threads beim Ausführen von Java-Programmen? Java Basics - Anfänger-Themen 4
xXGrowGuruXx Java einstieg, leichte sache 0 verstanden Java Basics - Anfänger-Themen 7
A java.sql.SQLException: Data type mismatch. Java Basics - Anfänger-Themen 1
H Java-Programm zur Ausgabe von Zuständen Java Basics - Anfänger-Themen 80
N Java Spiel Figur auf dem Hintergrundbild bewegen. Java Basics - Anfänger-Themen 11
G Kann Java-Programm nicht als jar aufrufen, auch als EXE nicht Java Basics - Anfänger-Themen 19
N Java Taschenrechner hat Jemand vlt einen Tipp dafür wie ich jetzt die buttons verbinden kann und das Ergebnis auf dem textfield anzeigen lassen kann Java Basics - Anfänger-Themen 13
A Lerngruppe Java Java Basics - Anfänger-Themen 2
G Help me in the Java Program Java Basics - Anfänger-Themen 2
L Java- Vererbung Java Basics - Anfänger-Themen 4
LimDul Suche Java Stream Tutorial Java Basics - Anfänger-Themen 2
_so_far_away_ Ich möchte Java lernen Java Basics - Anfänger-Themen 11
benny1993 Java Programm erstellen für ein Fußball-Turnier Java Basics - Anfänger-Themen 3
M Datentypen While-Schleife eine Java Methode erstellen Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben