我创建了一个程序,该程序接受未完成的数独难题的测试用例,并且应该使用多线程来快速解决它。我遇到了一个问题,它只能工作1/3次,并且当它“起作用”时,它会返回一个破坏规则的谜题。例如,同一列中有两个5。我想知道线程是否执行得太快并且无法通信?我可以改变哪些事情或看不到问题?
这是我的SudokuSolver课。它包含两种方法:cellChecker和fillPuzzle。单元格检查器检查单个单元格,并在其填充时返回false;如果单元格为空(包含0),则返回true。它也包含多线程的代码,我怀疑这是问题所在。
fillPuzzle仅在需要时创建拼图,然后使用cellChecker正确解决数独难题。
public boolean cellChecker(int puzzle[][], int row, int col, int number) {
//Set the cellCheck boolean to true for a default case
cellCheck = true;
//variables that give us the start of the row and column respectively
//If it doesn't get divided by 3 and then multiplied by 3, the threads
//get an out of bounds exception and gets real mad. found this math
//from stackoverflow.
int rowStart = (row / 3) * 3;
int colStart = (col / 3) * 3;
//The threads are created to do the 9x9 grid in 3x3 sections,
//so it can get done quicker and cut down the large task at hand.
//checks via col
Thread thread1 = new Thread(new Runnable() {
public void run() {
//for loop that checks the col
for (int i = 0; i < 9; i++) {
if (puzzle[row][i] == number) {
cellCheck = false;
}
}
}
});
thread1.start();
//another thread to take on it's 3x3 part via row
Thread thread2 = new Thread(new Runnable() {
public void run() {
//for loop that checks the row
for (int i = 0; i < 9; i++) {
if (puzzle[i][col] == number) {
cellCheck = false;
}
}
}
});
thread2.start();
//another thread to take on it's 3x3 part via cell by cell
Thread thread3 = new Thread(new Runnable() {
public void run() {
//for loop that checks the specific cell
for (int rowCell = rowStart; rowCell < rowStart + 3; rowCell++) {
for (int colCell = 0; colCell < colStart + 3; colCell++) {
if (puzzle[rowCell][colCell] == number) {
cellCheck = false;
}
}
}
}
});
thread3.start();
//returns the boolean whether the box is empty or not. If it is false,
//it is filled with the number it needs. if it's true, it still needs
//a number
return cellCheck;
}
public boolean fillPuzzle(int puzzle[][], int row, int col) {
if (row < 9) {
//if the 9x9 puzzle is not created and filled with 0's, create it
if (puzzle[row][col] != 0) {
if (col < 8) {
//returns created 9x9 puzzle
return fillPuzzle(puzzle, row, col + 1);
} else if (row < 8) {
//returns created 9x9 puzzle
return fillPuzzle(puzzle, row + 1, 0);
}
//already created, return true!
return true;
} else {
//if the puzzle is created, go through and check for the number
//up until or equal to 9 because sudoku goes from 1-9
//once it finds the number that belongs in the cell, it
//puts it in that cell
for (int i = 1; i <= 9; i++) {
if (cellChecker(puzzle, row, col, i)) {
puzzle[row][col] = i;
//If at the end of col, add a row to finish the table
if (col == 8) {
if (fillPuzzle(puzzle, row + 1, 0)) {
return true;
}
} else {
//add 1 to the col if it doesn't == 8 because
//that means there's not enough cols
if (fillPuzzle(puzzle, row, col + 1)) {
return true;
}
}
//all else fails, set it to 0 and we'll check it later
puzzle[row][col] = 0;
}
}
return false;
}
}
return true;
}
这是我的菜单类,其中发生拼图测试用例
public class Menu {
private SudokuSolver solver = new SudokuSolver();
//This is a test case sudoku puzzle I found off the internet to use as
//an example
private int sudokuPuzzle[][] = {{8, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 3, 6, 0, 0, 0, 0, 0},
{0, 7, 0, 0, 9, 0, 2, 0, 0},
{0, 5, 0, 0, 0, 7, 0, 0, 0},
{0, 0, 0, 0, 4, 5, 7, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 3, 0},
{0, 0, 1, 0, 0, 0, 0, 6, 8},
{0, 0, 8, 5, 0, 0, 0, 1, 0},
{0, 9, 0, 0, 0, 0, 4, 0, 0}};
public void start() {
//set to the method fillPuzzle. It tries to solve the
//sudoku puzzle and if it does, it is set to true. If it doesn't
//it says no thank you.
boolean filledPuzzle = solver.fillPuzzle(sudokuPuzzle, 0, 0);
//if it filled the puzzle, it prints it out.
if (filledPuzzle) {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
System.out.print(sudokuPuzzle[row][col] + " ");
}
System.out.println();
}
//if it can't, it let's the person know.
} else {
System.out.println("Solution not found");
}
}
}
最后,这听起来可能很愚蠢,但是我不确定100%如何实现Runnable的工作,但是它确实在sudokusolver类中给了我一个空的run方法,如果我删除它,我会很生气。我想知道是否需要放置一些东西才能使其正确有效地工作?
@Override
public void run() {
}