Sudoku mittels Backtracking Problem

Hi ich hab ein Problem mit meinem Sudoku Programm.
Die relevante Stelle ist aus meiner Sicht die hier:
Java:
  boolean loese(int[][] f) {
    //    System.out.println(f[suche(f) % 10][(int) suche(f) / 10] + "," +
    //                       (suche(f) % 10) + "," + ((int) suche(f) / 10));
        int x = suche(f) % 10;
    int y = (int) suche(f) / 10;
    System.out.println(x + "," + y);

    int[][] test = new int[9][9];
    test = f;
    if (suche(f) == -1) {
      feld = test;

      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
        NF[j][i].setText(Integer.toString(feld[j][i]));
        System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        }
      }
    }



    for (int i = 1; i < 10; i++) {
    System.out.println(i+"zähler");
      if (reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)) {
        test[x][y] = i;
        System.out.println(test[x][y]);
        loese(test);
      }
    }

    return false;
  }

Die Ausgabe ist bei leerer Eingabe:
1,2,3,4,5,6,7,8,9,
2,1,4,3,6,5,8,9,7,
3,4,1,2,7,8,9,6,5,
7,9,2,8,1,4,6,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

Danach geht er zurück zu 0/0 und endet damit.

Es wäre nett von euch mir hierbei zu helfen, da ich es für ein Referat morgen bräuchte.
 
S

SlaterB

Gast
richtest du dich an Sudoku-Experten? wenn nicht-gepostete Methoden wie
> reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)
allgemein bekannt sind, dann nimm doch diesen Standardcode, ich kann mir gut vorstellen dass man dazu jede Menge im Forum bzw. bei google findet,
ansonsten poste besser das ganze Programm,
> suche(f)
sieht besonders wichtig aus, was das wohl ist

-----

was mir technisch schon auffällt:
> int[][] test = new int[9][9];
> test = f;
das neu erstellte Array wird überhaupt nicht verwendet, im nächsten Schritt bist du wieder bei f, da wird keine Kopie angelegt wie du vielleicht vermutest, sondern test und f sind exakt dasselbe,
besser nicht zwei verschiedene Variablen für dasselbe Array verwenden

> feld = test;

> NF[j].setText(..

feld und NF scheinen noch zwei [][] zu sein, da wirds langsam kompliziert..
 
Tut mir Leid, ich habe grade bemerkt dass ich ausversehen eine überholte Ausgabe geposted habe, bei der ich noch einen weiteren Fehler hatte (Merke: Datei nicht in verschiedenen Ordnern speichern).

Der gesamte Quelltext lautet:
Java:
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.*;


/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 15.11.2010
  * @author Christoph
  */
public class sudoku extends JFrame {
  // Anfang Attribute
  private JTextField[][] NF = new JTextField[9][9];
  int[][] feld = new int[9][9];
  private JButton jButton1 = new JButton();

  // Ende Attribute
  public sudoku(String title) {
    // Frame-Initialisierung
    super(title);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

    int frameWidth = 400;
    int frameHeight = 400;
    setSize(frameWidth, frameHeight);

    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);

    Container cp = getContentPane();
    cp.setLayout(null);

    // Anfang Komponenten
    for (int j = 0; j < 9; j++) {
      for (int i = 0; i < 9; i++) {
        NF[j][i] = new JTextField("0");
        NF[j][i].setBounds(65 + (j * 30), 16 + (i * 30), 30, 30);
        cp.add(NF[j][i]);
      }
    }

    jButton1.setBounds(160, 328, 75, 25);
    jButton1.setText("loesen");
    jButton1.setMargin(new Insets(2, 2, 2, 2));
    jButton1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
          jButton1_ActionPerformed(evt);
        }
      });
    cp.add(jButton1);
    // Ende Komponenten
    setResizable(false);
    setVisible(true);
  }

  // Anfang Methoden
  public void jButton1_ActionPerformed(ActionEvent evt) {
    speichern();
    if (!loese(feld)) {
      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
          System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        }
      }
    }
  }

  void speichern() {
    for (int i = 0; i < 9; i++) {
      for (int j = 0; j < 9; j++) {
        try {
          feld[j][i] = ((Integer.parseInt(NF[j][i].getText()) > 0)
                        ? Integer.parseInt(NF[j][i].getText()) : 0);
          System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        } catch (Exception e) {
        }
      }
    }
  }

  boolean loese(int[][] f) {
    //    System.out.println(f[suche(f) % 10][(int) suche(f) / 10] + "," +
    //                       (suche(f) % 10) + "," + ((int) suche(f) / 10));
        int x = suche(f) % 10;
    int y = (int) suche(f) / 10;
    System.out.println(x + "," + y);

    int[][] test = new int[9][9];
    test = f;
    if (suche(f) == -1) {
      feld = test;

      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
        NF[j][i].setText(Integer.toString(feld[j][i]));
        System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        }
      }
    }



    for (int i = 1; i < 10; i++) {
    System.out.println(i+"zähler");
      if (reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)) {
        test[x][y] = i;
        NF[x][y].setText(Integer.toString(test[x][y]));
        System.out.println(test[x][y]);
        loese(test);
      }
    }
    System.out.println("return"+x+","+y);
    return false;
  }

  boolean reihe(int z, int y, int[][] fel) {
    boolean gibtsnet = true;

    for (int i = 0; i < 9; i++) {
      if (z == fel[i][y]) {
        return false;
      }
    }

    return gibtsnet;
  }

  boolean spalte(int z, int x, int[][] fel) {
    boolean gibtsnet = true;

    for (int i = 0; i < 9; i++) {
      if (z == fel[x][i]) {
        return false;
      }
    }

    return gibtsnet;
  }

  boolean block(int z, int x, int y, int[][] fel) {
        int i_start = (int)(x/3) * 3;
    int j_start = (int)(y/3) * 3;

    for(int a=i_start; a<i_start+3; a++)
        for(int b=j_start; b<j_start+3; b++)
          if(fel[a][b] == z){
                return false;
                }


    return true;

  }

  int suche(int[][] fe, int z) {
    for (int i = 0; i < fe.length; i++) {
      for (int j = 0; j < fe.length; j++) {
        if (fe[j][i] == z) {
          return (10 * i) + j;
        }
      }
    }
     // System.out.println("falsch");
    return -1;
  }

  int suche(int[][] fe) {
    for (int i = 0; i < 9; i++) {
      for (int j = 0; j < 9; j++) {
        if (fe[j][i] == 0) {
          return (10 * i) + j;
        }
      }
    }

    return -1;
  }

  // Ende Methoden
  public static void main(String[] args) {
    new sudoku("sudoku");
  }
}

Die Ausgabe ist:
1,2,3,4,5,6,7,8,9,
4,5,6,7,8,9,3,2,1,
7,8,9,1,2,3,4,5,6,
2,1,4,3,6,5,8,9,7,
3,6,7,2,9,8,1,4,5,
5,9,8,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,

reihe(),spalte() und block() überprüfen ob die Zahl i in einer bereits vorkommt, also ob sie ungültig ist.
 
S

SlaterB

Gast
ich könnte es mir anschauen wenn du wenigstens
> int[][] test = new int[9][9];
> test = f;
erklärst
 
So wie ich das sehe hat der Teil nicht wirklich einen Sinn.
Ich bin noch Java Anfänger und dachte, dass ich eine Kopie erstelle und da ich wärend des programmierens nicht wusste ob ich ne Kopie brauche, habe ich einfach ne neue Variable genommen, es kommt mir nämlich nicht auf die geschwindigkeit an.
 
S

SlaterB

Gast
so, das war ja ein sehr klarer Fehler, sorry dass ich erst 2 Stunden weg war,
das Problem ist einfach, dass du beim Zurückgehen nicht das besetzte Feld wieder auf 0 löschst,
deshalb gehen die Prüfmethoden schief, es können keine anderen Kombinationen mehr ausprobiert werden,

Java:
  if (reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)) {
        test[x][y] = i;
        loese(test);
        test[x][y] = 0; // neu
      }
das wars schon im wesentlichen, wie du weiter vorgehst musst du wissen,

-----

> if (suche(f) == -1)
paar Zeilen vorher ist die Bedingung für ein erfolgreich gelöstes Soduko,
bei lauter Nullen wird das ziemlich oft der Fall sein, mit vielen System.out.println() läuft das ganze ewig lange obwohl eigentlich schnell von Java zu rechnen, besonders wenn du auf das new int[9][9] verzichtest,
-----

wenn du die Berechnung in der actionPerformed() ausführst, dann ist die GUI solange blockiert, das ständige Update der Textfelder ist überhaupt nicht zu sehen,
du brauchst einen nebenläufigen Thread, etwa
Java:
	public void jButton1_ActionPerformed(ActionEvent evt) {
		Runnable r = new Runnable() {
			public void run() {
				speichern();
				loese(feld);
			}
		};
		new Thread(r).start();
	}
 
Vielen Dank für die schnelle und kompetente Hilfe, dass die Antwort 2 Stunden gedauert hat stört mich auch in keinster Weise, für ich wichtig ist nur dass es vor Morgen 8.10 Uhr funktioniert.
Ich denke auf die Threads wär ich nie im Leben gekommen, aber das mit dem test[x][y]=0; ist nur eine Alternative zu dem tatsächlichen erstellen einer Kopie eines Arrays. Die Proben sind alle für f aber die Änderungen werden in test vorgenommen, somit wäre eine Kopie eine andere Lösung, statt dem Referenz beibehalten und Stelle =0 setzen.
Also dann, ein widerholtes vielen Dank und freundliche Grüße.
"Wir sehn uns" dann bei meiner nächsen Frage( oder aber falls ich selbst jemand anderem helfen kann.):applaus::applaus:
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Sudoku generieren Schwierigkeitsgrad Allgemeine Java-Themen 3
J Sudoku Kommandozeile Allgemeine Java-Themen 13
J Sudoku Löser Allgemeine Java-Themen 10
B Sudoku-Block-Prüfung Allgemeine Java-Themen 1
B Sudoku-Überprüfer Allgemeine Java-Themen 1
K Sudoku-Solver - Backtracking Allgemeine Java-Themen 2
F Sudoku-Löser Allgemeine Java-Themen 6
E Threads Sudoku Threads Allgemeine Java-Themen 8
J Laufzeitberechnung - Sudoku Backtracking Allgemeine Java-Themen 7
F rekursiver Aufruf (Sudoku und Guice) Allgemeine Java-Themen 19
J Swing Sudoku GUI - Problem mit MaskFormatter Allgemeine Java-Themen 4
truesoul Sudoku programmieren Allgemeine Java-Themen 23
C Sudoku und KeyListener Allgemeine Java-Themen 2
M Problem bei Sudoku Allgemeine Java-Themen 21
V Strings aus externen Dateien Einlesen (Sudoku) Allgemeine Java-Themen 25
B sudoku backtrackingproblem Allgemeine Java-Themen 2
S Algorithmus für Sudoku Allgemeine Java-Themen 17
S Übergabe eines Sortierkriteriums für ein Artikel Array mittels BiPredicate<Artikel, Artikel> Allgemeine Java-Themen 13
N Value Wert aus HTML-Button mittels thymeleaf spring an java übergeben Allgemeine Java-Themen 2
N Lottowebsite programmieren mittels Java, HTML,.... Allgemeine Java-Themen 7
W PDFs signieren mittels IText / Lowagie Allgemeine Java-Themen 0
Zrebna Möglichkeit regelmäßige indentation mittels/innerhalb Stringbuilder Allgemeine Java-Themen 14
J RotSchwarzBaum: Löschen mittels insert-Methode Allgemeine Java-Themen 20
LimDul Mittels Streams aus Strings A B C den String A, B und C machen Allgemeine Java-Themen 12
X Brüche kürzen mittels Methoden und ggT Allgemeine Java-Themen 15
D HTTP Http-Link mittels GUI schreiben Allgemeine Java-Themen 5
B Java Sternchen ausgeben mittels Rekursion Allgemeine Java-Themen 3
J GUI-Einstellungen mittels Preferences Allgemeine Java-Themen 6
Todesbote JFileChooser im Vordergrund (*.jar wird mittels shell_exec in PHP aufgerufen) Allgemeine Java-Themen 1
E Videosequenz mittels Java aus Video schneiden Allgemeine Java-Themen 10
B Ordner öffnen mittels Java in Linux-Umgebung Allgemeine Java-Themen 7
I Webseite auslesen (welche mittels Javascript Inhalt einbindet) Allgemeine Java-Themen 4
T HTML Tag Position mittels Pattern ermitteln Allgemeine Java-Themen 7
RySa Variablenname mittels Reflexions rausbekommen (als String) ? Allgemeine Java-Themen 9
U Classpath DLLs mittels System.load() laden: Allgemeine Java-Themen 6
T Wie rufe ich mittels String-Inhalts eine Methode auf? Allgemeine Java-Themen 3
T Exif mittels Java auslesen Allgemeine Java-Themen 14
7 Webseiten mittels Java auslesen Allgemeine Java-Themen 7
H Zwei verschiedene Dateien mittels einem Binärstream übertragen? Allgemeine Java-Themen 13
dunhillone Mittels Annotations Methoden "erweitern"? Allgemeine Java-Themen 11
S Mittels eines Applets Bilder generieren die in einer Webseite angezeigt werden..? Allgemeine Java-Themen 8
X String zerlegen mittels regulärem Ausdruck Allgemeine Java-Themen 31
O Programm mittels Java installieren Allgemeine Java-Themen 15
S Array-Sort mittels Binärsuche Allgemeine Java-Themen 2
J Setter mittels invoice aufrufen Allgemeine Java-Themen 4
S Eingabeprüfung mittels Regexp Allgemeine Java-Themen 5
J Objekt in Datei speichern mittels Streams Allgemeine Java-Themen 6
D Einfaches Nutzen von Plugins mittels generischer Methode Allgemeine Java-Themen 3
E Aus mehreren PDFs eines machen, zusammenfügen mittels iText Allgemeine Java-Themen 1
G Graph mittels Punkte erstellen Allgemeine Java-Themen 27
M Problem bei PDF-Anzeige mittels Acrobat Viewer Bean Allgemeine Java-Themen 2
G HTML Code aus String mittels REGEX entfernen Allgemeine Java-Themen 2
spacegaier Performanceproblem beim Einlesen aus Datei mittels Threads Allgemeine Java-Themen 23
G Screenshot mittels robot ausführen Allgemeine Java-Themen 4
B Html Formulare mittels Java automatisch senden Allgemeine Java-Themen 5
E import mittels Eclipse Allgemeine Java-Themen 3
F mittels Collection<A> an A.class kommen? Allgemeine Java-Themen 7
T IF Abfrage + YES_NO Option mittels JOptionPane Allgemeine Java-Themen 3
F Zugriff mittels getObject() oder this.object ? Allgemeine Java-Themen 8
J Tonbalance mittels JMF regeln Allgemeine Java-Themen 3
G Font mittels ClassLoader in .jar wirft NotFoundException Allgemeine Java-Themen 10
R Interface mittels Reflection implementieren Allgemeine Java-Themen 8
G eigener logger mittels classe (dynamische logfilename) log4j Allgemeine Java-Themen 15
K Mittels Generics eine Methode verallgemeinern Allgemeine Java-Themen 2
A FTPS bzw. FTP over SSL mittels Java Allgemeine Java-Themen 9
Y komprimierung mittels Huffman-Algorithmus, bit-shifting. Allgemeine Java-Themen 2
G mysql datum umwandeln mittels jsp Allgemeine Java-Themen 10
F Hilfe: Adjazenzmatrix mittels JUnit testen. Allgemeine Java-Themen 2
Natorion Erkennen ob das Programm mittels Jar-Datei oder class . Allgemeine Java-Themen 9
P E-Mails mittels POP3 abrufen Allgemeine Java-Themen 2
S mail von server mittels mailapi löschen Allgemeine Java-Themen 2
Max246Sch Backtracking Problem Box Filler Allgemeine Java-Themen 6
T Methoden Backtracking Allgemeine Java-Themen 2
J Damenproblem mit Backtracking Allgemeine Java-Themen 33
B Magisches Quadrat per Backtracking Allgemeine Java-Themen 4
G Backtracking Problem Allgemeine Java-Themen 16

Ähnliche Java Themen

Neue Themen


Oben