我有一個家庭作業,需要在Java中使用數獨求解器的順序和並行版本(使用ForkJoin框架,並行版本爲)。Java中的並行數獨求解器
我寫了順序的一個,它工作正常。算法的思想是一個簡單的回溯練習:對於每個單元格(從表格的左上角開始)尚未填充,填充它(依次,並一次一個)與所有合法候選人(從1到9)直到你到達矩陣的最後(第9列第9列)。如果您已達到最終結果,則增加解決方案編號。
我認爲實施並行版本只是爲每個有效的候選人找到一個特定的單元格,然後等待他們產生一個新的線程。它似乎不工作,我無法找到原因。
我張貼應該做的全部工作,希望找到一個很好的建議類:
class SolveSudoku extends RecursiveAction{
private int i, j;
private int[][] cells;
SolveSudoku(int i, int j, int[][] cells){
this.i = i;
this.j = j;
this.cells = cells;
}
@Override
protected void compute(){
if (j == 9) {
j = 0;
if (++i == 9){
solutions++;
System.out.println(solutions);
return;
}
}
if (cells[i][j] != 0){ // skip filled cells
SolveSudoku s = new SolveSudoku(i, j+1, cells);
s.compute();
return;
}
ArrayList<Integer> vals = new ArrayList<Integer>();
for (int val = 1; val <= 9; val++) // try all the legal candidates for i, j
if (legal(i,j,val,cells))
vals.add(val);
if(vals.size() == 1){ // only one, no new threads
cells[i][j] = vals.get(0);
new SolveSudoku(i, j+1, cells).compute();
}
else{
SolveSudoku threads[] = new SolveSudoku[vals.size()];
int n = 0;
int first;
for(int k=0; k<vals.size(); k++){
if(k == vals.size()-1){
cells[i][j] = vals.get(k);
threads[n] = new SolveSudoku(i, j+1, cells);
threads[n].compute();
}
else{
cells[i][j] = vals.get(k);
threads[n] = new SolveSudoku(i, j+1, cells);
threads[n].fork();
}
n++;
}
for(int k=0; k<threads.length-1; k++)
if(k != vals.size()-1)
threads[k].join();
}
cells[i][j] = 0;
return;
}}
new ForkJoinPool().invoke(new SolveSudoku(0, 0, M)); // where *M* is a sudoku instance to solve where all the unfilled cells contain '0'
那麼並行算法應該一次解決整個數獨? – vatbub
是的,@vatbub!實際上,如果你定義了一個經典的* main *方法(在類定義之外的那一行),並且如果你在else塊的最後一行的下面添加了* threads [n] .join(); *循環),一切工作正常。 不知道錯誤在哪裏,但似乎線程做他們想做的事... – Process0