Backtracking (Springer-Problem)

dbrust_2000

Mitglied
Hallo zusammen,

ich habe ein kleines Problem mit meiner Implementierung des Algorithmus. Mein Algorithmus scheint für n,m = 5 zu funktionieren aber nicht für n,m = 6 geschweige denn darüber. Irgendwie bricht der Algorithmus nicht ab, und ich weiß nicht warum? Wenn ich mir das schrittweise debugge scheint alles so zu laufe, wie ich mir das vorstelle.

Java:
public class SpringerTour
{
    private int n,m;

    private Position[] loesung;
    private Position[] moeglZuege = {new Position (2,1),new Position (-2,1),
            new Position (2,-1),new Position (-2,-1),new Position (1,2),
            new Position (-1,2),new Position (1,-2),new Position (-1,-2),};

    public SpringerTour(int n, int m){
        this.n=n;this.m=m;
        loesung=new Position [n*m];
        loesung[0] = new Position(0,0);

      

    }

    public void behandleKnoten(){

        behandleKnoten(0);
    }

    private void behandleKnoten(int ebene){
        // wenn ich alle Felder besucht habe
        if (ebene == n*m-1){
            druckeLoesung();

        }
        else{
            // für alle möglichen Züge
            for(int j = 0; j<8;j++){
                //bestimme die neue Position
                Position neuePos = loesung[ebene].add(moeglZuege[j]);
                // ist die neue Position zulaessig
                if(pruefe(neuePos,loesung)){
                    // dann fuege sie der loesung hinzu und gehe eine Ebene weiter
                    loesung[ebene+1]=neuePos;
                    behandleKnoten(ebene+1);
                }
            }
            // sollte kein Zug möglich sein von dieser Ebene, so entferne die Position aus der Loesung
            loesung[ebene]=null;

        }

    }

    private boolean pruefe(Position neuePos, Position[] a){

  //schaue, ob die Koordinaten der neuen Position aufs Brett passen      
 if(neuePos.getX()>=0 && neuePos.getY()>=0 && neuePos.getX()<m  && neuePos.getY()<n){
//schaue, ob die Koordinaten der neuen Position schon in der Loesung vorkommen                 
if(!Position.contains(neuePos,a)){
                return true;
            }

        }

        return false;
    }

    public void druckeLoesung(){
        for (int i = 0 ; i<loesung.length;i++){
            if(loesung[i]!=null){
                System.out.println(loesung[i].toString());
            }
            else{
                System.out.println("null");
            }
        }
    }

    public static void main(String [] argv) {

        SpringerTour tour = new SpringerTour(5,5);
        tour.behandleKnoten();

    }
}

Java:
public class Position
{
    // Instanzvariablen - ersetzen Sie das folgende Beispiel mit Ihren Variablen
    private int x;
    private int y;
    private boolean visited;

    /**
     * Konstruktor für Objekte der Klasse Position
     */
    public Position(int x ,int y)
    {
        // Instanzvariable initialisieren
        this.x=x;this.y=y;
        visited = false;
    }

    public void setPos(int x, int y)
    {
        // tragen Sie hier den Code ein
        this.x=x;this.y=y;
    }

    public Position add(int dx, int dy){
        int newx = x+dx;int newy=y+dy;
        return new Position (newx,newy);
    }
  
        public Position add(Position zug){
        int newx = x+zug.x;int newy=y+zug.y;
        return new Position (newx,newy);
    }

    public void setVisited(boolean visited){
        this.visited = visited;
    }

    public int[] getPos(){
        int[] pos = new int[2];
        pos[0] = x;
        pos[1] = y;
        return pos;
    }

    public boolean getVisited(){
        return this.visited;
    }

    public boolean equals(Position other){
        return other.getX() == this.x && other.getY() == this.y;
    }

    public String toString(){
        return "("+ x +", " +y+", " +visited+ ")";
    }

    public static boolean contains(Position p, Position[] a){
        for (int i = 0;i<a.length;i++){
            if(a[i]!=null)
                if (a[i].equals(p)) return true;
        }
        return false;
    }

    //Start GetterSetterExtension Source Code
    /**GET Method Propertie x*/
    public int getX(){
        return this.x;
    }//end method getX

    //End GetterSetterExtension Source Code
    //!

    //Start GetterSetterExtension Source Code
    /**GET Method Propertie y*/
    public int getY(){
        return this.y;
    }//end method getY

    //End GetterSetterExtension Source Code
    //!
}
 

httpdigest

Top Contributor
Soll dein Algorithmus denn die erste gefundene Lösung ausgeben und sich dann beenden, oder soll er alle möglichen Lösungen finden und ausgeben?
 

dbrust_2000

Mitglied
Ja ja, das war auch noch so ne Sache. Mich wundert, dass er bei dem 5,5 Problem nur eine Lösung ausgibt, obwohl es bestimmt mehrere gibt. Ich weiß, dass ds 6,6 auch länger dauern kann, aber eine Lösung sollte er doch trotzdem finden
 

Jangste

Mitglied
Ich weiß, dass ds 6,6 auch länger dauern kann, aber eine Lösung sollte er doch trotzdem finden
Also bei mir läuft er in Sekundenbruchteilen bei 6,6:
Java:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class KnightsTour {
	public List<int[]> tour(final int n) {
		boolean[][] a = new boolean[n][n];
		List<int[]> b = new ArrayList<int[]>();
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a.length; j++) {
				a[i][j] = true;
				b.add(new int[] { i, j });
				List<int[]> c = getTour(a, b);
				if (c != null)
					return c;
			}
		}
		return null;
	}

	public List<int[]> getTour(boolean[][] a, List<int[]> b) {
		if (allTrue(a))
			return b;
		List<int[]> moves = getMoves(a.length, b.get(b.size() - 1));
		for (int[] c : moves) {
			if (a[c[0]][c[1]] == false) {
				a[c[0]][c[1]] = true;
				b.add(c);
				List<int[]> d = getTour(a, b);
				if (d != null)
					return d;
				a[c[0]][c[1]] = false;
				b.remove(b.size() - 1);
			}
		}
		return null;
	}

	public boolean allTrue(boolean[][] a) {
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a.length; j++) {
				if (a[i][j] == false) {
					return false;
				}
			}
		}
		return true;
	}

	public List<int[]> getMoves(int n, int[] b) {
		List<int[]> c = new ArrayList<int[]>(8);
		if (b[0] + 2 < n && b[1] + 1 < n)
			c.add(new int[] { b[0] + 2, b[1] + 1 });
		if (b[0] + 2 < n && b[1] - 1 >= 0)
			c.add(new int[] { b[0] + 2, b[1] - 1 });
		if (b[0] - 2 >= 0 && b[1] + 1 < n)
			c.add(new int[] { b[0] - 2, b[1] + 1 });
		if (b[0] - 2 >= 0 && b[1] - 1 >= 0)
			c.add(new int[] { b[0] - 2, b[1] - 1 });

		if (b[0] + 1 < n && b[1] + 2 < n)
			c.add(new int[] { b[0] + 1, b[1] + 2 });
		if (b[0] + 1 < n && b[1] - 2 >= 0)
			c.add(new int[] { b[0] + 1, b[1] - 2 });
		if (b[0] - 1 >= 0 && b[1] + 2 < n)
			c.add(new int[] { b[0] - 1, b[1] + 2 });
		if (b[0] - 1 >= 0 && b[1] - 2 >= 0)
			c.add(new int[] { b[0] - 1, b[1] - 2 });
		return c;
	}

	public static void main(String[] args) {
		KnightsTour k = new KnightsTour();
		List<int[]> tour = k.tour(5);
		for (int[] a : tour) {
			System.out.println(Arrays.toString(a));
		}

		System.out.println("");
		List<int[]> tour6 = k.tour(6);
		for (int[] a : tour6) {
			System.out.println(Arrays.toString(a));
		}
	}
}
 

httpdigest

Top Contributor
Ja ja, das war auch noch so ne Sache. Mich wundert, dass er bei dem 5,5 Problem nur eine Lösung ausgibt, obwohl es bestimmt mehrere gibt. Ich weiß, dass ds 6,6 auch länger dauern kann, aber eine Lösung sollte er doch trotzdem finden
Das Problem ist, dass du den aktuellen Zug nur "zurücksetzt" bzw. "backtrackst", wenn der Move nicht gültig ist. Um alle Lösungen zu finden, musst du immer gleich den aktuellen Zug wieder zurücknehmen, also:
Java:
                //bestimme die neue Position
                Position neuePos = loesung[ebene].add(moeglZuege[j]);
                // ist die neue Position zulaessig
                if(pruefe(neuePos,loesung)){
                    // dann fuege sie der loesung hinzu und gehe eine Ebene weiter
                    loesung[ebene+1]=neuePos;
                    behandleKnoten(ebene+1);
                    loesung[ebene+1]=null; // <- WICHTIG UM ALLE LÖSUNGEN ZU FINDEN!
                }
 

Jangste

Mitglied
Habe in "tour" noch etwas vergessen.
Java:
public List<int[]> tour(final int n) {
		boolean[][] a = new boolean[n][n];
		List<int[]> b = new ArrayList<int[]>();
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a.length; j++) {
				a[i][j] = true;
				b.add(new int[] { i, j });
				List<int[]> c = getTour(a, b);
				if (c != null)
					return c;
				a[i][j] = false;
				b.remove(b.size() - 1);
			}
		}
		return null;
	}

Wichtigkeit hat, wie es httpdigest geschrieben hat, dass du den Rekursionsschritt auch wieder rückgängig machst.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Schachspiel:Matt mit Springer und Läufer Frameworks - Spring, Play, Blade, Vaadin & Co 4
8u3631984 Problem beim Mocken Frameworks - Spring, Play, Blade, Vaadin & Co 9
W DI-Problem in Spring Boot Frameworks - Spring, Play, Blade, Vaadin & Co 4
Z Versuch mit Rest-Api-Tester geben offenbar ein lib Problem Frameworks - Spring, Play, Blade, Vaadin & Co 1
OnDemand Spring Security/Boot/Vaadin Cookie Problem bei iFrame Frameworks - Spring, Play, Blade, Vaadin & Co 4
B Java Spring Boot - POM-Problem Frameworks - Spring, Play, Blade, Vaadin & Co 8
J Spring Boot Autowired Problem Frameworks - Spring, Play, Blade, Vaadin & Co 2
E Tomcat mit Hibernate und Spring - Problem mit Connection Pool Frameworks - Spring, Play, Blade, Vaadin & Co 5
M Spring property problem Frameworks - Spring, Play, Blade, Vaadin & Co 2
E Springerproblem - Problem Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Problem bei Velocity und Spring Validation Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Problem mit Spring LTW Frameworks - Spring, Play, Blade, Vaadin & Co 5
NoXiD SpringSecurity Problem Frameworks - Spring, Play, Blade, Vaadin & Co 3
B Axis2 1.6 + Spring -> ClassLoader Problem Frameworks - Spring, Play, Blade, Vaadin & Co 0
M Problem mit spring und log4j Frameworks - Spring, Play, Blade, Vaadin & Co 0
M Problem mit spring security Frameworks - Spring, Play, Blade, Vaadin & Co 0
B SpringMVC-EntityManagerFactory-Hibernate-Problem Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Problem mit Hibernate und Spring Frameworks - Spring, Play, Blade, Vaadin & Co 0
M Problem mit Gilead und Spring Frameworks - Spring, Play, Blade, Vaadin & Co 1
B SpringLayout Problem Frameworks - Spring, Play, Blade, Vaadin & Co 3
tfa Problem mit Maven, Tomcat, Spring und XML-Schema Frameworks - Spring, Play, Blade, Vaadin & Co 0
H JSF + SpringSecurity Problem Frameworks - Spring, Play, Blade, Vaadin & Co 2
A Problem mit Spring-WS und Marshalling Frameworks - Spring, Play, Blade, Vaadin & Co 0
H file upload problem mit spring Frameworks - Spring, Play, Blade, Vaadin & Co 33
H Spring: Problem mit CommandClass in SimpleFormController (aus Step-by-Step Tutorial) Frameworks - Spring, Play, Blade, Vaadin & Co 1
D Spring: Problem beim ausführen eines JUnit Tests. Frameworks - Spring, Play, Blade, Vaadin & Co 4
dunhillone Problem mit Spring & Hibernate Sessions Frameworks - Spring, Play, Blade, Vaadin & Co 2
dunhillone Problem mit Spring & Hibernate Sessions Frameworks - Spring, Play, Blade, Vaadin & Co 2
M Spring DM: Problem mit Tomcat als OSGI-Service Frameworks - Spring, Play, Blade, Vaadin & Co 2
chik Spring ACEGI Problem Frameworks - Spring, Play, Blade, Vaadin & Co 1
M JSF Navigation - Spring Security Logout Problem Frameworks - Spring, Play, Blade, Vaadin & Co 5

Ähnliche Java Themen

Neue Themen


Oben