Sudoku rekursiv lösen

Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hi, hatte folgenden Aufgabe:

"Einfach gesagt, lässt sich ein Sudoku folgendermaßen lösen:

- finde das erste freie Feld
- setze die Zahlen 1-9 ein und versuche bei jeder das restliche Sudoku zu lösen
- ist eine Lösung gefunden gib sie aus
- ansonsten sag, dass es nicht möglich ist, das Sudoku zu lösen"

Das Sudoku wird in nem 9x9 Array übergeben.
Meine Methode dazu sieht bisher so aus:
------------------------------------------------------------------------
Code:
int[][] loese (int[][] feld){
		int x=0,y=0;
		while (feld[x][y]!=0){     //hier soll das erste leere Feld gefunden werden
			if (x==8 && y==8) return feld;      //Abbruchbedingung: ganzes Feld geloest
			if (x!=8) x++; else {x=0; y++;}   //zu naechstem Feld springen
		}
		for (int a=1; a<=10; a++){  //Zahlen von 1-9 versuchen einzusetzen
			if (a==10) {feld[x][y]=0; return feld;} //zweite Abbruchbedingung: wenn 1-9 nicht geht, Feld freim.
			feld[x][y]=a;
			if (Sudoku.SudokuTest(feld)){ //wenn Zahl zulässig, versuche restliche Felder zu lösen
				feld=loese(feld);
			}
		}
		return feld; //eigentlich unnötig, wird aber für Syntax benötigt
	}
------------------------------------------------------------------------

dürfte alles richtig sein (die Methode SudokuTest funktioniert nachweislich einwandfrei). Ich habe schließlich in ner extra Klasse die Methode mit nem Testsudoku aufgerufen, aber genau dieses wird auch wieder zurückgegeben, obwohl es lösbar ist... Ich glaube das Problem steckt bei "feld= loese(feld);" da ich ja bei arrays nur die referenzen übergebe, könnte mir das Probleme machen oder? Wäre nett, wenn ihr mir helfen könntet :)
 

Marco13

Top Contributor
Beim ersten Draufschauen fehlt da Am anfang sowas wie
if (fertig()) return feld;
oder so. Hobbit_Im_Blutrausch hat auch mal einen solchen Löser geschrieben (Forensuche).
 
G

Gast

Gast
das wäre ja dann die erste abbruchbedingung, also wenn er kein leeres Feld findet, wird feld returned
 

Marco13

Top Contributor
Ja, aber irgendwie mußt du unterscheiden, ob gelöst wurde oder nicht. So geht er immer durch die for-Schleife, und landet am Ende bei 10 - und dann löscht er der Reihe nach die zuletzt gesetzten Felder. Eine Möglichkeit wäre vielleicht sowas
Code:
boolean loese (int[][] feld)
{
      int x=0,y=0;
      while (feld[x][y]!=0){     //hier soll das erste leere Feld gefunden werden
         if (x==8 && y==8) return true;      //Abbruchbedingung: ganzes Feld geloest
         if (x!=8) x++; else {x=0; y++;}   //zu naechstem Feld springen
      }
      for (int a=1; a<10; a++){  //Zahlen von 1-9 versuchen einzusetzen
         feld[x][y]=a;
         if (Sudoku.SudokuTest(feld)){ //wenn Zahl zulässig, versuche restliche Felder zu lösen
            boolean solved = loese(feld);
            if (solved) return true;
         }
         feld[x][y]=0;
      }
      return false;
   }
 
G

Gast

Gast
aber wenn die methode ein boolean zurückbekommt, wird ja im endeffekt nur ausgesagt, ob das Sudoku nun lösbar war oder nicht. Ich brauche doch aber das gelöste Sudoku und das existiert ja nur für die Laufzeit in deiner Version und wird nirgendwo gesichert oder?
 

mahe

Aktives Mitglied
Na, das Feld wird in der Methode verändert. Da es sich nur um eine Referenz handelt, bleiben diese Änderungen erhalten.


[edit]
Ich hab das auch mal machen müssen und hab das so gelöst gehabt:
Code:
	static boolean solveSudoku(int[][] field, int i) {
		if (i == 81)
			return true;
		
		int x1 = (i%9);
		int y1 = (i/9);

		if(isValidValue(field[x1][y1])) {

			return solveSudoku(field, i+1);

		} else {
			int nr = 0;
			
			while(++nr < 10) {
				field[x1][y1] = nr;
				if (checkSudoku(field) && solveSudoku(field, i+1)) {
					return true;
				}
			}
			field[x1][y1] = 0;
			return false;
		}
	}

	static boolean checkSudoku(int[][] field) {

		for(int i = 0; i < 9; ++i) {

			boolean[] c1 = new boolean[10];
			boolean[] c2 = new boolean[10];
			boolean[] c3 = new boolean[10];

			for(int j = 0; j < 9; ++j) {
				if (isValidValue(field[i][j])) {
					if(c1[field[i][j]])
						return false;
					c1[field[i][j]] = true;
				}
				if (isValidValue(field[j][i])) {
					if(c2[field[j][i]])
						return false;
					c2[field[j][i]] = true;
				}
			}
			
			int x1 = (i%3)*3;
			int y1 = (i/3)*3;
			
			for(int x = 0; x < 3; ++x)
			for(int y = 0; y < 3; ++y) {

				if (isValidValue(field[x+x1][y+y1])) {
					if (c3[field[x+x1][y+y1]])
						return false;
					c3[field[x+x1][y+y1]] = true;
				}
			}
		}
		return true;
	}

	static boolean isValidValue(int nr) {
		return (nr > 0 && nr < 10);
	}


Bereits ausgefüllte (Angabe) werden einfach übergangen. Ansonsten immer passende Zahl suchen -> Methodenaufruf machen. So lange bis es irgendwann passt.

Also im Grunde das selbe wie Deins.

Achja, wichtig ist, dass die Kontroll-Methode ungültige Werte (<0 und >9) ignoriert.

Ich hoffe, dass Dir das weiterhilft :)
 
G

Gast

Gast
also ich habe deinen ersten Tipp jetzt gut einbauen können, jetzt hat das Programm auch einmal schon funktioniert, allerdings funktioniert es nicht immer - manchmal werden letztendlich nur einzelne Zahlen eingesetzt (was eig nicht passieren dürfte...) hier der Code:

Code:
int[][] loese (int[][] feld){
		int x=0,y=0;
		if (komplett(feld) && Sudoku.SudokuTest(feld)) return feld; //Abbruchbedingung: ganzes Feld geloest
		while (feld[x][y]!=0){ //hier soll das erste leere Feld gefunden werden
			if (x!=8) x++; else {x=0; y++;} //zu naechstem Feld springen
		}
		for (int a=1; a<=9; a++){  //Zahlen von 1-9 versuchen einzusetzen
			feld[x][y]=a;
			if (Sudoku.SudokuTest(feld)){ //wenn Zahl zulässig, versuche restliche Felder zu lösen
				feld=loese(feld);
				if (komplett(feld) && Sudoku.SudokuTest(feld)) return feld; //Abbruchbedingung: ganzes Feld geloest
			} else 
			if (a==9){feld[x][y]=0; return feld;} //zweite Abbruchbedingung: wenn 1-9 nicht geht, Feld freimachen
		}
		return feld; //eigentlich unnötig, wird aber für Syntax benötigt
	}
 

Marco13

Top Contributor
Hübsch und effizient ist das jetzt zwar nicht, aber ...
manchmal werden letztendlich nur einzelne Zahlen eingesetzt...
"Manchmal" verhalten sich Computer aber deterministisch....
 
G

Gast

Gast
ah ok...hab mein problem erkannt, ich darf wirklich nicht das array returnen...mit deiner boolean-variante hat es geklappt :) ...mich hat nur gewundert, dass wenn ich im hauptprogramm ein array habe, dieses ja nicht verändert wird (klar, dass es in der Methode verändert wird, aber dort "bleibt" es ja auch und wird nicht ausgegeben)..aber es scheint ja zu funktionieren, da mecker ich mal nicht :) vielen dank für die hilfe
 

Marco13

Top Contributor
Man übergibt der Methode eine Referenz auf den Array. D.h. der Array, der in der aufrufenden Methode angelegt wird, und der Array IN der Methode sind ein und derSELBE Array.
Code:
void foo()
{
    int a[] = new int[1];
    change(a);
    System.out.println(a[0]); // Gibt 123 aus
}
void change(int a[])
{
    a[0] = 123;
}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Sudoku Rekursiv lösen Java Basics - Anfänger-Themen 9
K Sudoku mit 2D Arrays Java Basics - Anfänger-Themen 19
B Sudoku prüfen Java Basics - Anfänger-Themen 13
S GUI-Programmierung Sudoku-Rätsel lösen Java Basics - Anfänger-Themen 1
J Sudoku mehrere Lösungen Java Basics - Anfänger-Themen 29
J Sudoku Blocküberprüfung Java Basics - Anfänger-Themen 9
S Sudoku Checker Frage Java Basics - Anfänger-Themen 1
G Sudoku Java Basics - Anfänger-Themen 3
S Methoden Java Sudoku Solver Java Basics - Anfänger-Themen 2
C Klassen Sudoku-Spiel Werte werden nicht gesetzt Java Basics - Anfänger-Themen 4
A Sudoku mit Backtracking lösen Java Basics - Anfänger-Themen 3
L Sudoku Backtracking Pseudocode Java Basics - Anfänger-Themen 3
L Sudoku Löser Java Basics - Anfänger-Themen 9
V Sudoku-Solver Probleme bei der Fehlerbehandlung Java Basics - Anfänger-Themen 12
H Unterquadrate bei Sudoku füllen Java Basics - Anfänger-Themen 9
D Sudoku lösen mit Backtracking Java Basics - Anfänger-Themen 20
M Sudoku-Löser: Fragen zu Pointer und Rekursion Java Basics - Anfänger-Themen 15
S Bisschen hilfe beim Sudoku Lösen benötigt Java Basics - Anfänger-Themen 7
X Sudoku Backtracking Java Basics - Anfänger-Themen 6
S Sudoku hilfe Java Basics - Anfänger-Themen 4
N Sudoku/BLocküberprüfung Java Basics - Anfänger-Themen 24
F Sudoku Grid zeichnen Java Basics - Anfänger-Themen 2
C Frage zu Sudoku Java Basics - Anfänger-Themen 20
MEETyA NullPointer Exception - Sudoku Java Basics - Anfänger-Themen 2
J Sudoku-ähnliche Aufgabe Java Basics - Anfänger-Themen 3
Antoras Sudoku Java Basics - Anfänger-Themen 3
F sudoku generieren Java Basics - Anfänger-Themen 16
B Sudoku! Java Basics - Anfänger-Themen 26
H Passwort Brute Force rekursiv Java Basics - Anfänger-Themen 7
1 Array rekursiv durchlaufen Java Basics - Anfänger-Themen 8
E Rekursiv Objekte erzeugen - geht das? Java Basics - Anfänger-Themen 2
Cassy3 Binäre Bäume Rekursiv durchlaufen und bestimmte Elemente Zählen Java Basics - Anfänger-Themen 6
R0m1lly Kombinationen aus int array rekursiv Java Basics - Anfänger-Themen 2
L Rekursiv gegebenes Passwort herausfinden. Java Basics - Anfänger-Themen 2
P9cman Char Index rekursiv finden Java Basics - Anfänger-Themen 4
B Methoden Rekursiv festellen, ob eine Zahl gerade-oft vorkommt oder nicht Java Basics - Anfänger-Themen 4
S Methoden Methodenaufruf rekursiv zählen Java Basics - Anfänger-Themen 4
B Array nach Wert prüfen rekursiv Java Basics - Anfänger-Themen 5
sashady Zahlen rekursiv zerlegen und Ziffern addieren Java Basics - Anfänger-Themen 38
jhCDtGVjcZGcfzug Fibonacci Zahlen rekursiv und iterativ Java Basics - Anfänger-Themen 21
H Binominalkoeffizient tail-rekursiv in java darstellen Java Basics - Anfänger-Themen 0
GAZ Tribonacci Folge Rekursiv Java Basics - Anfänger-Themen 11
G Primzahlen von Rekursiv nach Iterativ Java Basics - Anfänger-Themen 6
A Ackermmanfunktion rekursiv Java Basics - Anfänger-Themen 4
A Binärbaum rekursiv durchsuchen und Referenz zurückgeben Java Basics - Anfänger-Themen 4
H Rekursiv Methode ausführen bei Kindern Java Basics - Anfänger-Themen 12
G Methode Rekursiv umschreiben Java Basics - Anfänger-Themen 8
L Jede zweite Ziffer entfernen (rekursiv) Java Basics - Anfänger-Themen 6
J Dateien in Verzeichnissen rekursiv auflisten wirft Exception Java Basics - Anfänger-Themen 4
D Pentagonale Nummern in Rekursiv Java Basics - Anfänger-Themen 14
O Enum Array Rekursiv abarbeiten Java Basics - Anfänger-Themen 44
E Weg-Suche-Problem rekursiv Java Basics - Anfänger-Themen 12
O Primzahl rekursiv mit einem Wert ohne i, wie? Java Basics - Anfänger-Themen 6
E Erste Schritte Potenz Negativ (rekursiv) Java Basics - Anfänger-Themen 2
O Rekursiv aufrufen Java Basics - Anfänger-Themen 2
F In List Rekursiv suchen Java Basics - Anfänger-Themen 12
F Iterativ in Rekursiv Java Basics - Anfänger-Themen 2
S Fibonacci Zahlen rekursiv Java Basics - Anfänger-Themen 1
L Rekursiv zwei Strings vergleichen Java Basics - Anfänger-Themen 3
B Fakultätsfunktion Rekursiv Berechnen aber mit Array Java Basics - Anfänger-Themen 10
J Fibonacci -Folge rekursiv berechnen Java Basics - Anfänger-Themen 18
B Wie kann ich Linien rekursiv zeichnen? Java Basics - Anfänger-Themen 4
kilopack15 Sin(x) rekursiv lösen Java Basics - Anfänger-Themen 17
T Rekursiv Tiefe eines binären Suchbaums ermitteln Java Basics - Anfänger-Themen 22
P Methoden Arrays.AsList kleinste Zahl ausgeben Rekursiv Java Basics - Anfänger-Themen 9
W A hoch N Rekursiv Java Basics - Anfänger-Themen 3
K Rechtecke rekursiv zeichnen Java Basics - Anfänger-Themen 20
V Quadrate rekursiv zeichnen Java Basics - Anfänger-Themen 7
M Fibonacci rekursiv mittels Cache Java Basics - Anfänger-Themen 17
E Binärbaum - von rekursiv zu iterativ Java Basics - Anfänger-Themen 10
Y Rekursiv Palindrom herausfinden Java Basics - Anfänger-Themen 5
B Fibonacci Zahlen rekursiv Array Java Basics - Anfänger-Themen 12
M String rekursiv Spiegeln mit Originalwort davor Java Basics - Anfänger-Themen 3
K Türme von Hanoi - Rekursiv. Java Basics - Anfänger-Themen 1
T MergeSort rekursiv programmieren Java Basics - Anfänger-Themen 8
M Zahlenpyramide rekursiv programmieren Java Basics - Anfänger-Themen 7
hello_autumn Potenz selber berechnen, Rekursiv. Java Basics - Anfänger-Themen 6
V Text wüerfeln-Rekursiv Java Basics - Anfänger-Themen 4
J Baum rekursiv durchlaufen Java Basics - Anfänger-Themen 2
D Münzverteilung Möglichkeiten | Rekursiv Java Basics - Anfänger-Themen 3
R Hanoi rekursiv lösen Problem Java Basics - Anfänger-Themen 1
D Rekursiv Kombinationen ausgeben klappt nur bei einer Wiederholung Java Basics - Anfänger-Themen 4
shiroX OOP String rekursiv zurückgeben Java Basics - Anfänger-Themen 6
Z Fibonacci rekursiv meine Erklärung stimmt so? Java Basics - Anfänger-Themen 2
S java rekursiv iterativ hilfee :s Java Basics - Anfänger-Themen 5
E Erste Schritte Pi, rekursiv Java Basics - Anfänger-Themen 6
A Frage Methode ggt Rekursiv Java Basics - Anfänger-Themen 5
E Hanoi-Varianten rekursiv Java Basics - Anfänger-Themen 2
P Hanoi rekursiv zu iterativ umbauen Java Basics - Anfänger-Themen 20
P Mittelwert rekursiv Java Basics - Anfänger-Themen 13
E Integral Rekursiv Java Basics - Anfänger-Themen 15
M MergeSort rekursiv Java Basics - Anfänger-Themen 2
D Ziffer in Zahl Rekursiv Java Basics - Anfänger-Themen 4
B Array rekursiv untersuchen Java Basics - Anfänger-Themen 21
I Rekursiv Java Basics - Anfänger-Themen 13
C Rekursiv Zahlenfolgen berechnen mit zwei Variablen Java Basics - Anfänger-Themen 5
K Rekursiv zu Literal Java Basics - Anfänger-Themen 12
R Verzeichnisse rekursiv nach Dateiduplikaten durchsuchen Java Basics - Anfänger-Themen 5
L File Tree rekursiv Java Basics - Anfänger-Themen 10
W Binomialkoeffizient iterativ/rekursiv Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben