Ich arbeite an einem Projekt, wo ich ein Sudoku-Rätsel lösen muss. N ist kleiner als gleich 20.Um ein Sudoku mit Grid-Größe von mehr als 9 * 9 zu lösen Multi-threading-parallele Ausführung verwenden
Ich habe einen Sudoku-Solver mit einem Gewinde geschrieben, der gut mit Rätseln funktioniert, die den N-Wert 5 haben, aber wenn ich den N-Wert wie N = 10 oder 20 erhöhe, reagiert der Code nicht mehr. Ich habe auch versucht, Thread-Pool (java.concurrent) und zuweisen N^2
Nummer des Threads parallel auszuführen. Aber es funktioniert nicht, kann mir jemand eine Lösung geben, die die Leistung verbessern kann.
Hier ist mein Single-Threaded-Ansatz:
public class SUDOKU {
public static int[][] grid;
public boolean solveSUDOKU() {
int row;
int col;
int[] blankCell = findBlankLocation();
row = blankCell[0];
col = blankCell[1];
if (row == -1) {
// means will have filled the grid, return;
return true;
}
// we need to fill grid[row][col] cell
for (int i = 1; i <= grid.length; i++) {
// check if number i is safe for grid[row][col] cell
if (isSafe(row, col, i)) {
// means its safe to fill the number
grid[row][col] = i;
// fill the rest of the grid
if (solveSUDOKU()) {
return true;
}
// if we are here that means current selection of number didnt
// work, revert back the changes
grid[row][col] = 0;
}
}
return false; // This will cause the backtracking
}
public boolean isSafe(int row, int col, int n) {
// we need to check row contains number n OR
// Column contains number n OR
// Block in which cell appears contains number n
// If Any of the above statement is true, return false
if (!UsedInRow(row, n)
&& !UsedInColumn(col, n)
&& !UsedInBox((int) (row - row % Math.sqrt(grid.length)),
(int) (col - col % Math.sqrt(grid.length)), n)) {
return true;
}
return false;
}
// check if n not in particular row
public boolean UsedInRow(int row, int n) {
for (int i = 0; i < grid.length; i++) {
if (grid[row][i] == n) {
return true;
}
}
return false;
}
// check if n not in particular column
public boolean UsedInColumn(int col, int n) {
for (int i = 0; i < grid.length; i++) {
if (grid[i][col] == n) {
return true;
}
}
return false;
}
// check if n not in particular box
public boolean UsedInBox(int boxStartRow, int boxStartCol, int n) {
for (int i = 0; i < Math.sqrt(grid.length); i++) {
for (int j = 0; j < Math.sqrt(grid.length); j++) {
if (grid[i + boxStartRow][j + boxStartCol] == n) {
return true;
}
}
}
return false;
}
public int[] findBlankLocation() {
int[] cell = new int[2]; // cell[0]-row cell[1] -column
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid.length; j++) {
if (grid[i][j] == 0) {
cell[0] = i;
cell[1] = j;
return cell;
}
}
}
cell[0] = -1;
cell[1] = -1;
return cell; // means grid is full
}
public void print() {
for (int row = 0; row < grid.length; row++) {
if (row % Math.sqrt(grid.length) == 0) {
System.out.println(); // for more readability
}
for (int col = 0; col < grid.length; col++) {
if (col % Math.sqrt(grid.length) == 0) {
System.out.print(" "); // for more readability
}
System.out.print(grid[row][col] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
grid = 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
SUDOKU s = new SUDOKU();
if (s.solveSUDOKU()) {
s.print();
} else {
System.out.println("NO SOLUTION");
}
}
}
Wenn Sie nicht Hunderte von Kernen haben, vergessen Sie Multithreading, da es nur einen kleinen Faktor geben kann. Mit einem intelligenteren Algorithmus können Sie viel mehr für weniger Arbeit. +++ Ich schätze, dass das einfache Finden von Orten, die einen einzelnen Wert erlauben und sie sofort füllen, sehr hilfreich sein könnte. – maaartinus
Danke für die schnelle Annahme. Zwei kurze Fragen: A) Denk daran, mir zu erzählen, wie du bei deinem Problem vorankommst? B) falls ein Upvote nicht von deiner Seite ist; Gibt es irgendetwas, was ich tun könnte, um meine Antwort von Ihrer Seite zu erheben? – GhostCat