Entwickler-Ecke

Alle Sprachen - Alle Plattformen - Java Sudoku generieren


LINUS19 - Di 09.01.18 00:51
Titel: Java Sudoku generieren
Ich habe eine Methode gemacht um Sudokus zu generieren, die ein leeres Sudokufeld mit zufälligen Zahlen füllt und darauf dann solange die Lösemethode anwendet bis ein lösbares Sudoku entsteht.

Eigentlich müssten ja 2 unterschiedlich gefüllte Sudokus mit 30 Zahlen entstehen wenn ich generiere() 2 mal aufrufe, aber als Ergebnis kommt ein Sudoku mit 30 Zahlen und eins mit 60 Zahlen. Beim 2.Aufruf von generiere() wird wahrscheinlich die anzahl Variable, der Zufallszahlen weiter hochgezählt und deswegen sind es 60 Zahlen.



Quelltext
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:
static int[][] generiere(int Matrix[][]) {
    int counter=0;           
        System.out.println("Wie viele Zahlen sollen vorgegeben sein?");            
      int anzahl=30; //Anzahl der Zufallszahlen
  
    int m,n,random;
    
    Random generator = new Random();
        
    while(counter<anzahl) {
      m=generator.nextInt(9); // zufälliges Feld der Matrix
      n=generator.nextInt(9);
      random=generator.nextInt(10);
      
      if(random==0) { // nur Zahlen von 1-9
        continue;
      }        
      
      if( Matrix[m][n]==0 && check(m, n, random, Matrix)==true ) //übeprüft Zeilen,Spalten und Blöcke
      Matrix[m][n]=random;
            
      else continue;              
                                
    if(counter==anzahl) { // wenn alle Zufallszahlen gesetzt, restliche Felder auf Null setzten
          if(Matrix[m][n]!=random)
            Matrix[m][n]=0;            
        
    }    
    anzahl++;      
  
    
    }        
    for ( m = 0; m < 9; m++) {  //Feld ausgeben      
      for ( n = 0; n < 9; n++) {
        if(Matrix[m][n]==0)
        
          System.out.print(Matrix[m][n]+"");
      }
      System.out.println();
    }            
  }


Und die Main methode:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
public static void main(String[] args) {
              
    int  Matrix[][] =         
    
     new  int[][] {          { 0,0,0,0,0,0,0,0,0},
                                 { 0,0,0,0,0,0,0,0,0},
                                 { 0,0,0,0,0,0,0,0,0},                                      
                                 
                                 { 0,0,0,0,0,0,0,0,0},
                                 { 0,0,0,0,0,0,0,0,0},
                                 { 0,0,0,0,0,0,0,0,0},                                     
                                 
                                 { 0,0,0,0,0,0,0,0,0},
                                 { 0,0,0,0,0,0,0,0,0},
                                 { 0,0,0,0,0,0,0,0,0}};       
     
  
           generiere(Matrix);
         System.out.println() ;
           generiere(Matrix);


Und als Ergebnis kommt das:
1 . Aufruf:
600524037
050000000
070000500
080700040
000809002
190005000
000371800
900240003
530008070
Hier sind 30 Zahlen

2.Aufruf:
601524037
258000901
479163580
385702149
704819062
196405008
040371856
910240003
532698070
Hier sind 60 Zahlen

LG
LINUS19


Symbroson - Di 09.01.18 01:38

Wie wäre es damit, dass du Matrix in main() zwischendurch nochmal resettest?


Th69 - Di 09.01.18 10:34

Zeile 13 der Methode generiere kannst du verbessern (so daß bisherige Zeilen 15-17 entfernt werden können):

Java
1:
random = 1 + generator.nextInt(9);                    


Horst_H - Di 09.01.18 15:24

Hallo,

als Anregung:
https://www1.wdr.de/radio/wdr5/sendungen/leonardo/sudoku-anzahl-102.html
user profile iconGravitar hat ein Programm Sudoku V0.753_Exe.zip mit 100 minimalen Sudoku's https://www.entwickler-ecke.de/viewtopic.php?t=65038

Gruß Horst


LINUS19 - Di 09.01.18 16:06

Es funktioniert jetzt, aber es werden auch alle Fehlversuche mit gedruckt ,wie bekomme ich es hin das nur das lösbare Sudoku gedruckt wird?.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
 generiere(Matrix);
          while(solve(0, 0, Matrix)==false)  {  
               for(int m=0; m<9; m++) { // Matrix wir wieder auf Null gesetzt
            for(int n=0; n<9; n++) {
              Matrix[m][n]=0;
            }
          }
             generiere(Matrix);                                                         
           
          }
          
            
           if(solve(0, 0, Matrix)==true)                                                                
               return;



LG
LINUS19


Symbroson - Di 09.01.18 16:08

Zitat:

C++-Quelltext
1:
if(solve(00, Matrix)==truereturn;                    
für mich sieht das so aus als ob du nur nicht lösbare Sudokus ausgibst. Wo ist denn deine Ausgabe?

PS: bitte formatiere deine Quelltexte damit man ihn besser lesen kann ;)

C++-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
  generiere(Matrix);
  while(solve(00, Matrix)==false)  {  
    for(int m=0; m<9; m++) { // Matrix wir wieder auf Null gesetzt
      for(int n=0; n<9; n++) {
        Matrix[m][n]=0;
      }
    }
    generiere(Matrix);                                                         
  }
  if(solve(00, Matrix)==truereturn;


LINUS19 - Di 09.01.18 16:20

Ja er gibt alle Versuche aus und das letzte ist lösbar,das habe ich mit dem Löseprogramm probiert.


LINUS19 - Di 09.01.18 20:59

Wenn ich das so mache wird nur das gelöste Sudoku ausgegeben:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
if (solve(0, 0, Matrix) == true) {

      for (int m = 0; m < 9; m++) {
        for (int n = 0; n < 9; n++) {          
          System.out.print(Matrix[m][n] + "");
        }
        System.out.println();
      }
            
    }

Die Ausgabe:
364895172
279164835
185732649
712548963
436917528
598623714
647289351
853471296
921356487

LG
LINUS19


Th69 - Mi 10.01.18 10:52

Aber warum rufst du zweimal die solve-Methode auf? Nach der while-Schleife brauchst du den erneuten Aufruf doch nicht mehr.

Du solltest lernen, etwas strukturierter zu programmieren - z.B. das Initialisieren sowie die Ausgabe der Matrix in eine eigene Methode auslagern.
Ein guter Ansatz dafür ist die Top-Down-Methode (s. z.B. Top-Down- und Bottom-Up-Design [https://de.wikipedia.org/wiki/Top-Down-_und_Bottom-Up-Design]), d.h. zuerst einmal den Code als groben Methodenaufruf (Pseudocode) zu entwerfen und dann nach und nach die einzelnen Methoden auszuprogrammieren (dann können diese Methoden auch gleich für Unit-Tests herangezogen werden).


LINUS19 - Mi 10.01.18 15:12

Ich habe jetzt eine Ausgabe Methode gemacht und den 2. solve() Aufruf weggenommen.
Aber wenn ich die print(Matrix) Methode innerhalb der while() Schlaufe aufrufe, werden alle Versuche ausgegeben und am Ende das zu lösenden Sudoku und wenn ich die print Methode ausserhalb der while() Schlaufe aufrufe wird nur das komplett gelöste Sudoku ausgegeben.


Th69 - Mi 10.01.18 15:46

Achso, jetzt verstehe ich.
Du mußt dir natürlich nach dem Generieren die Matrix als Kopie speichern, damit du dann dieses Ausgangs-Sudoku nach erfolgreichem Lösen ausgeben kannst (denn innerhalb der solve-Methode veränderst du ja die übergebene Matrix).


LINUS19 - Mi 10.01.18 17:53

Nachdem die Matrix generiert wird wollte ich sie in ein mit Nullen gefülltes Array Kopie[][] kopieren.
Wenn ich dann die print(Kopie) mache wird wieder ein gefülltes Array ausgegeben.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
while(solve(0, 0, Matrix)==false)  {  
                         
              for( m=0; m<9; m++) { // Matrix wir wieder auf Null gesetzt
            for( n=0; n<9; n++) {
              Matrix[m][n]=0;
            }
          }  
             generiere(Matrix);                                                                      
             System.arraycopy(Matrix, 0, Kopie, 0, Kopie.length); //Matrix wird in Kopie kopiert
                               
                
         }
 print(Kopie);


Th69 - Mi 10.01.18 18:10

Für ein 2-dimensionales Array mußt du für eine Kopie (wie die print-Methode) selber über die Werte iterieren (zumindestens über die 1. Dimension), s.a. How do I copy a 2 Dimensional array in Java? [https://stackoverflow.com/questions/5617016/how-do-i-copy-a-2-dimensional-array-in-java] - so kopierst du nur Array-Referenzen.

PS: Packe am besten auch das Initialisieren (Zurücksetzen) der Matrix in eine eigene Methode.


LINUS19 - Mi 10.01.18 19:16

Das mit dem kopieren funktioniert jetzt. Ich habe jetzt 10 Programmdurchläufe gemacht mit 17 vorgegeben und komischerweise wird das generierte Feld dann immer nur mit Nullen ausgefüllt. Wenn ich aber 35 vorgegebene Zahlen nehme und 10 Durchläufe mache wird immer ein Sudoku mit 35 Zahlen richtig ausgegeben.
Woran könnte das liegen?


Th69 - Do 11.01.18 10:44

Dann wird wohl noch ein Fehler in der generiere-Methode sein.
Ist das immer noch die im Eingangsbeitrag stehende? Dort überprüfe noch mal die Verwendung der Variablen anzahl und counter (wundert mich, daß die Methode so überhaupt [in kurzer Zeit] terminiert)...


LINUS19 - Do 11.01.18 16:47

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Dann wird wohl noch ein Fehler in der generiere-Methode sein.
Ist das immer noch die im Eingangsbeitrag stehende? Dort überprüfe noch mal die Verwendung der Variablen anzahl und counter (wundert mich, daß die Methode so überhaupt [in kurzer Zeit] terminiert)...


Also wenn ich nur die generiere() Methode einpaar mal ausführe, dann werden die Sudokus mit 17 Zahlen immer richtig erzeugt. Die generiere() Methode habe ich auch nicht verändert. Wieso wundert es dich den, das die Methode terminiert?


Th69 - Do 11.01.18 17:27

Du erhöhst in Zeile 29 anzahl, fragst aber die Schleife auf counter < anzahl ab...


LINUS19 - Do 11.01.18 17:57

Dann habe ich anscheinend doch noch was verändert, da muss natürlich counter ++ stehen sonst würde ja gar nichts ausgegeben werden. Damit habe ich die Methode aber auch getestet. ( Nicht mit anzahl++)


Th69 - Do 11.01.18 18:26

Dann debugge mal die Methode (bzw. lass dir innerhalb der Schleife mal die Matrix testweise ausgeben).


LINUS19 - Do 11.01.18 19:31

Ich bin nochmal die generiere() Methode durchgegeangen und ich glaube doch nicht das dort der Fehler liegt, wahrscheinlich doch bei der main Methode.

Quelltext
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:
  public static void main(String[] args) {
      
        int  Matrix[][] = new  int[9][9];      //     
        int  Clone[][] = new  int[9][9];       // Kopie
       
          generiere(Matrix);          
         
          while( solve(0, 0, Matrix)==false  )  {  
               
            
                 for( int m=0; m<9; m++) { // Matrix wir wieder auf Null gesetzt
            for( int n=0; n<9; n++) {
              Matrix[m][n]=0;
              
            }
          }  
                             
                   generiere(Matrix);                                                                                             
             
             for(int m=0; m<9; m++) {
               for(int n=0; n<9; n++) {
                 Clone[m][n]=Matrix[m][n]; //kopiere
               }
             }            
             print(Clone);                                   
          }
          print(Clone);        
  }


Symbroson - Do 11.01.18 21:46

wie war das mit dem Formatieren? ;) bitte bitte mach es

Mit folgendem Code würde theoretisch solange ein neues Spiel generiert und getestet, bis ein lösbares gefunden wurde, und dieses dann ausgegeben:
java code:

C++-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
public static void main(String[] args) {

  int  Matrix[][] = new int[9][9];
  
  do {
    generiere(Matrix);
    
    // Matrix wir wieder auf Null gesetzt
    for(int m=0; m<9; m++) {    
      for(int n=0; n<9; n++) {
        Matrix[m][n]=0;
      }
    }
  } while(solve(00, Matrix) == false);
  
  print(Matrix);        
}

Wenn du mehrere generieren willst packst du eben die do-while Schleife und die Ausgabe in eine For-Schleife


LINUS19 - Do 11.01.18 22:28

Dabei ist nur das Problem,das wieder nur die Lösung ausgegeben wird. Deswegen wollte ich ja auch wie in meinem vorherigen Post das ganze Feld kopieren, was anscheinend nicht funktioniert.
PS: Beim nächsten Mal achte ich auf die Formatierung.


Symbroson - Do 11.01.18 22:31

achso ja ich verstehe - dann musst du natürlich eine Kopie des generierten Feldes erstellen und ausgeben, wenn sie lösbar ist.


Th69 - Fr 12.01.18 10:56

Überlege mal genau, wann du die Matrix kopierst! Und bedenke den guten Tipp bezüglich der do...while-Schleife.

Und du hättest die Lösung schon selbst gefunden, wenn du - wie ich schon schrieb - deinen Code strukturierter angehen würdest, d.h. die Matrixoperationen in eigene Methoden auslagern würdest.
Gehe einfach mal hin und schreibe den Algorithmus als Pseudo-Code auf...


LINUS19 - Fr 12.01.18 19:36

Jetzt werden 17 zufällige Zahlen ausgegeben und das mit dem kopieren funktioniert, aber es gibt nur einen Durchlauf der Schlaufe, weil wenn das Feld wieder komplett auf Null gesetzt wird,es dann ja für die solve () Methode lösbar ist. Und die Methode true zurück gibt und die while Schlaufe dann ja abbricht.


Symbroson - Fr 12.01.18 20:25

Mach doch bitte wirklich mal ein Pseudo-Code wie es TH90 schon 3x oder so vorgeschlagen hat. Das hilft dir und uns bestimmt mehr als deine kryptische Beschreibung eben ^^

wenn du nicht weißt was Pseudo-Code ist - schreib einfach hin was Zeile für Zeile gemacht werden soll, als ob du jede Zeile in deinem Quelltext kommentieren würdest.


LINUS19 - Fr 12.01.18 21:15

Naja ich meinte das wenn das Feld komplett wieder auf Null gesetzt wird , ist das Sudoku für die solve() Methode lösbar und dewegen läuft die while Schleife nur einmal durch und gibt eben nur ein zufällig generiertes Sudoku aus.
Was war in meiner Nachricht vorher den kryptisch?


LINUS19 - Sa 13.01.18 17:26

Das mit dem Sudoku generieren klappt jetzt, ich wollte aber noch erreichen das die Sudokus eindeutig lösbar sind. In meinem SudokuLöser habe ich die solve() Funktion, bei der Abbruchbedingung folgendendes verändert um alle Lösungen zu bekommen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
static int anzahl = 0; // Azahl der Lösungen für das Sudoku

  static boolean solve(int i, int j, int Matrix[][]) {
    aufrufe++;

    if (i == 9 && j == 8) { // unteres rechtes Feld erreicht
      anzahl++;
      System.out.println(anzahl);
      if (anzahl < 2) {

        print(Matrix);
        System.out.println("Das S. ist nicht eindeutig: hier eine mögliche Lösung");
      }

      return false; // nach neuer Lösung wird gesucht
    }

Das ganze funktionier, aber wenn ich das bei meinem Sudokugeneraator mache, also in der do- while Schleife
 while(solve(0,0,Matrix)==false && anzahl>1) schreibe läuft die Schleife nur einmal durch und das Sudoku ist nicht lösbar.

LG
LINUS19


Symbroson - Sa 13.01.18 17:31

Ich nehme mal an anzahl ist die Anzahl der Lösungen, warum prüfst du ob anzahl < 2 ist, und sagst dann, dass es nicht eindeutig ist, also mehrere Lösungen hat? Wenn es nicht eindeutig ist müsste doch anzahl > 1 sein, oder nicht?


LINUS19 - Sa 13.01.18 17:52

Stimmt, es muss anzahl >1 sein. Die do -while Schleife ist jetzt 10. Millionnen mal durchgelaufen und hat kein Sudoku ausgegeben.
Das kann doch nicht so viele Durchläufe brauchen, oder ?


Symbroson - Sa 13.01.18 17:54

du kannst dir ja einfach mal ausgeben lassen, wieviele Möglichkeiten es jeweils gam. Ich denke das kann durchaus sein, je nachdem, wieviele Startziffern du Anfänglich einträgst. Je weniger Ziffern du vorgibst, desto höher ist die Wahrscheinlichkeit, dass es viele Möglichkeiten gibt.


LINUS19 - Sa 13.01.18 18:16

Ich muss eben doch irgendwo noch einen Fehler gemacht haben , jetzt läuft die Schleife wieder nur einmal durch.

user profile iconSymbroson hat folgendes geschrieben Zum zitierten Posting springen:
du kannst dir ja einfach mal ausgeben lassen, wieviele Möglichkeiten es jeweils gam.
Was meinst du damit?


Symbroson - Sa 13.01.18 18:36

einfach von jedem Durchlauf anzahl in der Konsole ausgeben lassen
Apropos: setzt du anzahl irgendwo an einer sinvollen Stelle auf 0?


LINUS19 - Sa 13.01.18 19:12

anzahl setze ich am Ende der do Bedingung auf Null, aber ich verstehe immer noch nicht warum die Schleife nur einmal durchläuft.


LINUS19 - Sa 13.01.18 20:34

Hier nochmal die main Methode:

Quelltext
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:
public static void main(String[] args) {

    int m;
    int n;
    int Matrix[][] = new int[9][9]; 
    int Clone[][] = new int[9][9];
    int a = 0;

    do {

      for (m = 0; m < 9; m++) { // Matrix wir wieder auf Null gesetzt
        for (n = 0; n < 9; n++) {
          Matrix[m][n] = 0;  lösbar
                    // ist

        }
      }
      generiere(Matrix);
      System.out.println(anzahl);
      for (m = 0; m < 9; m++) { // Matrix wird kopiert
        for (n = 0; n < 9; n++) {
          Clone[m][n] = Matrix[m][n];
        }
      }
      // print(Clone);

      a++;
      System.out.println(a);
      anzahl = 0;
    } while (solve(0, 0, Matrix) == false && anzahl >1); // ||    
                
                print(Clone);
    System.out.println(a);
         
       
       
  }

und wenn ich mir anzahl ausgeben lasse, wird immer Null gedruckt.


Symbroson - So 14.01.18 10:39

Natürlich ist anzahl immer null, weil die solve Methode zu dem Zeitpunkt wo du anzahl ausgibst noch garnicht aufgerufen wurde


Th69 - So 14.01.18 11:40

LINUS' Bastelstunde... - mehr fällt mir dazu nicht mehr ein. :?!?:


LINUS19 - So 14.01.18 17:15

Das Problem bei der while Schleife ist, wenn ich wie weiter oben steht bei der solve() Methode immer false returne um alle Lösungen zuzählen, die while Schleife dann immer weiter läuft.

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
static boolean solve(int i, int j, int Matrix[][]) {
    
    if (i == 9 && j == 8) { // unteres rechtes Feld erreicht
      anzahl++;
      
       System.out.println(anzahl)

return false;


Symbroson - So 14.01.18 17:24

Hier mal ein Vorschlag:
gebe bei solve() die Anzahl der Lösungsmöglichkeiten zurück
in deiner while-schleife oder wie auch immer prüfst du dann als abbruchbedingung, ob die zurückgegebe Anzahl = 1 ist. Zum debuggen speicherst du die Anzahl zwischen, gibst sie aus und dann kommt die while-abbruch-Bedingung


LINUS19 - So 14.01.18 18:05

Meintest du sowas ?

Quelltext
1:
2:
3:
4:
static int solve(int i, int j, int Matrix [][]) {
...
return anzahl;
}


Symbroson - So 14.01.18 18:14

ja.


LINUS19 - So 14.01.18 18:34

Aber wenn ich zum Beispiel diesen Teil der solve() Methode nehme :

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
for (int value = 1; value <= 9; value++) { // Alle Zahlen von 1-9 werde getestet

      if (check(i, j, value, Matrix) == true) { // Gehe auf nächstes freies Feld
        Matrix[i][j] = value; // setze den Wert
        if (solve(i + 1, j, Matrix) == true)          
          return true;
        
      }
    }

Verstehe ich nicht wie ich das ganze umschreiben soll. Da wüde ja return anzahl; nicht viel Sinn ergeben.


Symbroson - So 14.01.18 18:39

wieso nicht


Christian S. - So 14.01.18 19:09

Hallo,

ich habe diesen Thread für 24h gesperrt. Dies soll Dir, Linus, Gelegenheit geben, Dir selbstständig grundsätzliche Gedanken zu Deinem Programm zu machen. Insbesondere den Hinweis, einfach mal in normalen Sätzen aufzuschreiben, was Dein Programm Schritt für Schritt tun soll, halte ich für sinnvoll. Es kann hier nicht so weiter gehen, wie bisher, dass Du völlig planlos Dinge ausprobierst und dann fragst, warum es nicht geht.

Der Thread entsperrt sich in 24h von selbst.

Christian


LINUS19 - Mo 15.01.18 20:06

Ich habe jetzt in der Abbruchbedingung while ( solve(0, 0,Matrix)<1 ); , es werden also solange Sudoku generiert bis es mehr als eine Lösung hat. z.b kommt jetzt nach 9 Schleifen Durchläufen das hier:

63 Lösungen // Lösungen Die anzahl der Lösungen wird auch richtig gezählt.

802100000
400063000
090085074
200000050
080000000
500000007
005700009
010002000
009408300

Aber wenn ich jetzt while ( solve(0, 0,Matrix)>1 ); als abbruchbedingung habe, also so lange suche bis es nur eine Lösung gibt, läuft die Schleife nur einmal durch. ( um unlösbare Sudokus wegzunehmen

Quelltext
1:
2:
 if(anzahl==0)
      continue; // unlösbare Sudokus werden wegelassen
)


Symbroson - Mo 15.01.18 20:10

Zitat:
while ( solve(00,Matrix)<1 ); , es werden also solange Sudoku generiert bis es mehr als eine Lösung hat
denk darüber nochmal nach. du durchläufst die Schleife, solange die Anzahl der Lösungen kleiner als 1 ist.

Zitat:

C++-Quelltext
1:
2:
3:
while ( solve(00,Matrix)>1 );
if(anzahl==0)
      continue// unlösbare Sudokus werden wegelassen

warum nicht einfach while(solve(..) != 1) ?!


LINUS19 - Mo 15.01.18 20:41

user profile iconSymbroson hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
while ( solve(00,Matrix)<1 ); , es werden also solange Sudoku generiert bis es mehr als eine Lösung hat
denk darüber nochmal nach. du durchläufst die Schleife, solange die Anzahl der Lösungen kleiner als 1 ist

Verstehe ich nicht so ganz ,es hat doch 63 Lösungen.

Mit =! 1 funktioniert es wenn ich z.B 25 als vorgegebe Zahlen mache, aber wenn ich jetzt 17 eingebe, hängt sich das Programm nach einem Durchlauf auf, es rechnet noch ( man kann auf terminate klicken) aber es passiert dann auch nichts mehr.Liegt das daran das zu viele Sachen durchgerechnet werden müssen, weil bei 17 Zahlen kann es ja sehr viele Lösungsmöglichkeiten geben?


Symbroson - Mo 15.01.18 20:59

nochmal.
1.
was du willst: solange Sudokus generieren bis eines mehr als eine Lösung hat
dein code: while ( solve(00,Matrix)<1 );
was er tut: lösen, solange es weniger als eine Lösung gibt.
was bedeutet das in der solange-bis Bedingung?
Fällt dir zwischen gewolltem und passierendem ein gewisser Unterschied auf?

2.
du sagst, dass du solange suchst bis es nur eine Lösung gibt
gibst aber als code an while ( solve(00,Matrix) > 1 );
das Heißt in dem Falle, dass du alle Zahlen kleiner gleich eins, also auch 0 mit einschließt.
Das fixt du, indem du folgendes tust: if(anzahl==0continue;
das ist aber eigentlich unnötig, wenn du gleich prüfst, ob anzahl == 1 und dann abbrichst, also solange anzahl != 1

Ansonsten verstehe ich irgendetwas an deiner Umsetzung nicht, vmtl weil ich nicht den gesamten Quelltext kenne.


Mal davon abgesehen: Hast du dir denn jetzt erstmal überlegt, wie die Grundstruktur deines Programmes aussehen soll? Sprich einen Pseudo-Code geschrieben? Dann haben wir wenigstens alle ein Muster nach dem wir uns richten können, was die Hilfe ungemein vereinfachen könnte.
Bitte ignoriere das nicht schon wieder - sonst habe auch ich keine Lust mehr dir hier zu helfen. Das ist nicht böse gemeint oder so, sondern du machst es einem echt schwer dir helfen zu können.

Danke.


LINUS19 - Mo 15.01.18 21:24

Es funktioniert jetzt doch schon, z.b nach 699 Durchläufen mit 25 Zahlen bekomme ich folgendes Sudoku(dauert aber ziemlich lange):
900000047
310700020
004008000
470900050
000064000
208000000
000207600
090000300
000036001

Und das ist laut meinem Sudoku Löser eindeutig lösbar. Wofür brauche ich dann noch den Pseudotext?
Ich meinte ja nur das es sich bei kleineren Zahlen wie z.B 17 "aufhängt" und zu keiner Ausgabe kommt wie ich weieter oben schon geschrieben habe.
Oder verstehe ich dich gerade völlig falsch?


Symbroson - Mo 15.01.18 21:59

Zitat:
Ich meinte ja nur das es sich bei kleineren Zahlen wie z.B 17 "aufhängt" und zu keiner Ausgabe
Ich glaube auch schonmal erwähnt zu haben, dass die Anzahl der Lösungsmöglichkeiten steigt, je weniger Zahlen du vorgibst. Höchstwahrscheinlich mehrfach exponentiell - das kann man so ohne weiteres nicht herleiten.


LINUS19 - Mo 15.01.18 22:21

Eine Frage hätte ich noch:
Ich wollte noch verschiedene Schwierigkeitsgrade machen, aber die Schwierigkeit hängt ja nicht nur von der Anzahl der vorgegebenen Zahlen ab, würde es unterschiedlich schwierig sein wenn ich die Schwierigkeit in Abhängigkeit von der Anzahl der Methodenaufrufe mache, oder was gibt es noch für Möglichkeiten?


Symbroson - Mo 15.01.18 22:27

Ich vermute, dass es schwieriger wird, je mehr Lösungsmöglichkeiten es gibt, denn viele Möglichkeiten bedeutet, dass es in vielen Feldern mehrere Ziffern zur Auswahl gibt, die folglich erst relativ spät ausgefüllt werden könnten.
Du darfst es aber auch nicht übertreiben ;)


LINUS19 - Mo 15.01.18 22:35

Was meinst du übertreiben?
Die Schwierigkeit einfach zufällig lassen?


Symbroson - Mo 15.01.18 22:38

Nein, zu wenige Ziffern vorgeben.
Ich hoffe das Thema hat sich damit erledigt