Hallo,
Ich habe ein Programm gemacht das ein Sudoku rekursiv mit Backtracking löst.
Dabei wird aber nur eine Lösung ausgegeben. Ich würde gerne noch einen Zähler einbauen der die Anzahl der Lösungen angibt.
Wie könnte ich die Anzahl aller Lösungen bestimmen?
Wenn dein Algorithmus nach der ersten Lösung abbricht dann brauchst du auch keinen Zähler einbauen.. du wirst immer nur eine Lösung bekommen.
Schreib dein Algorithmus doch erstmal so um dass er dir alle Lösungen generiert und ausgibt. Danach kannst du immer noch mit einem Zähler mitzählen wie viele Lösungen es sind.
Pauschal gesagt musst du jede Möglichkeit ausprobieren. Wenn du eine Möglichkeit gefunden hast darfst du nicht abbrechen sondern dein Algo muss sich erneut aufrufen / weiter machen.
Das kommt aber auch ein bisschen drauf an wie dein Algo funktioniert / aufgebaut ist.
staticbooleansolve(int i,int j,intMatrix[][]){
aufrufe++;if(i ==9&& j ==8)returntrue;// rechtes unteres Feld erreicht,abbruchif(i ==9){// Eine Zeile weiter nach unten
i =0;
j++;}if(Matrix[i][j]!=0){// Nur Felder mit 0 sollen verändert werden returnsolve(i +1, j,Matrix);// -> gehe einen Schritt weiter}for(int value =1; value <=9; value++){// Alle Zahlen von 1-9 werde getestetif(check(i, j, value,Matrix)==true){// Gehe auf nächstes freies FeldMatrix[i][j]= value;// setze den Wertif(solve(i +1, j,Matrix)==true)returntrue;}}Matrix[i][j]=0;// Feld wird auf Null gesetzt(backtrack)returnfalse;}
Dann müsste ich die oberste Abbruchbedingung ändern. Die Lösemethode muss dann ja immer weiter aufgerufen werden, um neue Lösungen zufinden, aber was ist dann die Abbruchbedingung dafür?
staticbooleansolve(int i,int j,intMatrix[][]){
aufrufe++;if(i ==9&& j ==8)returntrue;// rechtes unteres Feld erreicht,abbruchif(i ==9){// Eine Zeile weiter nach unten
i =0;
j++;}if(Matrix[i][j]!=0){// Nur Felder mit 0 sollen verändert werden returnsolve(i +1, j,Matrix);// -> gehe einen Schritt weiter}for(int value =1; value <=9; value++){// Alle Zahlen von 1-9 werde getestetif(check(i, j, value,Matrix)==true){// Gehe auf nächstes freies FeldMatrix[i][j]= value;// setze den Wertif(solve(i +1, j,Matrix)==true)returntrue;}}Matrix[i][j]=0;// Feld wird auf Null gesetzt(backtrack)returnfalse;}
Dann müsste ich die oberste Abbruchbedingung ändern. Die Lösemethode muss dann ja immer weiter aufgerufen werden, um neue Lösungen zufinden, aber was ist dann die Abbruchbedingung dafür?
Dein Beispiel habe ich mir angesehen, aber es war mir zu kompliziert und ich habe es nicht wirklich verstanden.
Ich weiß das ich mit der Variable "aufrufe", nur die Anzahl der Aufrufe der Methode und nicht nicht die Anzahl der Lösungen bestimme.
Ich hatte die solve() nur gepostet damit mir vielleicht jemand einen Ansatz gibt, wo ich etwas verändern müsste damit ich die Anzahl aller Lösungen bestimmen kann.
Dann müsste ich die oberste Abbruchbedingung ändern. Die Lösemethode muss dann ja immer weiter aufgerufen werden, um neue Lösungen zufinden, aber was ist dann die Abbruchbedingung dafür?
Es gibt doch eine Stelle, an der du weisst, dass du eine Lösung gefunden hast. Dort kannst du deinen Zähler erhöhen und dem Aufrufer "vortäuschen", dass keine Lösung gefunden wurde. Das heisst, du musst nicht die Abbruchbedingung ändern, sondern die Information, die du zurück lieferst.
Nein, könnte es daran liegen das in der Mainmethode das hier steht:
Code:
if (solve(0, 0, Matrix) == true) // wenn Sudoku lösbar ->
print(Matrix); // wird es ausgegeben
else
System.out.println("Keine Lösung");
Es wird halt immer "keine Lösung" ausgegeben wie ich weiter oben schon geschrieben hatte.
Edit: Wenn ich das mit dem if wegnehme wird nur das ungelöste Sudoku gedruckt
Nein, wenn du die Ausgabe so organisierst natürlich nicht. Ich würde mich aber erst einmal um die eigentliche Kernaufgabe kümmern, nämlich ob alle Lösungen gefunden und korrekt gezählt werden.
Wenn ich die Ausgabe so mache, wird auch nur das unausgefüllte Sudoku gedruckt.
In der der solve() Methode wird doch auch nirgendwo true zurückgegeben.
Wenn ich die Ausgabe so mache, wird auch nur das unausgefüllte Sudoku gedruckt.
In der der solve() Methode wird doch auch nirgendwo true zurückgegeben.
Ja. Natürlich. Es ist doch gerade der "Trick" an der Sache, dass jede gefundene Lösung "verworfen" wird, damit weiter gesucht wird. Also ist die Matrix zum Schluß wieder in ihrem Ausgangszustand. Das sagt aber nichts darüber aus, ob in der Zwischenzeit alle Lösungen korrekt gefunden wurden oder ob noch etwas falsch ist. Warum gibst du die Matrix nicht einfach mal bei jeder Lösung aus und siehst dir an, ob es korrekt ist?
Danke dir ,es funktioniert jetzt mit allenLösungen finden.
Habe ein Sudoku getestet und es hatte 9734 Lösungen genau wie ein anderer Löser mir auch angezeigt hat.
Danke dir ,es funktioniert jetzt mit allenLösungen finden.
Habe ein Sudoku getestet und es hatte 9734 Lösungen genau wie ein anderer Löser mir auch angezeigt hat.
Jetzt ist doch noch ein Problem aufgetreten.
Ich habe ein Sudoku eingegeben und es hat mir angezeigt das es 2 Lösungen gibt, aber es wurden 2 Mal die gleiche Lösung ausgegeben.
Edit: Es wurden nur 2 Zahlen vertauscht, hat sich geklärt.