我试图编写一个用于解决数独的蛮力算法的并行版本。
串行算法如下,伪码:
solve(matrix, x, y):
for i in [0,9]:
//If test number fits rules
if(valid(matrix, x, y, i):
matrix[y,x] = i
//Try next cell recursively
if(solve(matrix, nextEmptyX, nextEmptyY)) return true
//test number not the solution, backtrack.
matrix[y][x] = 0
return false;
如果我在这个伪代码中犯了错误,我很抱歉,但我认为这是正确的。无论哪种方式,我的串行算法都可以工作。
问题在于我试图像这样对其进行并行化
solve(matrix, x, y):
for i in [0,9]:
if(valid(matrix, x, y, i):
val = 0
#pragma omp task firstprivate(x, y, i, matrix, val)
copy_matrix = copyOf(matrix)
copy_matrix[y][x] = i
val = solve(copy_matrix, nextEmptyX, nextEmptyY)
if(val) print_matrix
if(val) return true
matrix[y][x] = 0
#pragma omp taskwait
return false;
在我看来,这段代码应该尝试新任务中每个单元格的每个暂定值,并且至少有一个任务应该有正确的解决方案。但是当我运行它时,它并没有测试(y,x)的每个组合(它实际上似乎只测试矩阵的第一行而且它没有找到结果。
我这样打电话:
#pragma omp parallel sections
{
#pragma omp section
solve(matrix, 0, 0);
}
通过设置omp_set_num_threads(1)
如果除了删除OMP注释之外什么都不做,那么该算法可以正常工作。
有人能看到问题吗?
编辑:我刚刚意识到有时执行会跳过任务块,我不知道为什么会发生这种情况,但似乎导致问题。答案 0 :(得分:0)
在C
中,#pragma omp
仅适用于以下行。
缩进表明你应该
solve(matrix, x, y):
for i in [0,9]:
if(valid(matrix, x, y, i):
val = 0
#pragma omp task firstprivate(x, y, i, matrix, val)
{
copy_matrix = copyOf(matrix)
copy_matrix[y][x] = i
val = solve(copy_matrix, nextEmptyX, nextEmptyY)
if(val) print_matrix
}
if(val) return true
matrix[y][x] = 0
#pragma omp taskwait
return false;
不确定这是否足以解决您的问题。