我正在使用OpenMP解决n Queens问题。
(最初的八个皇后问题包括试图找到一种方法将八个皇后放在棋盘上,这样任何女王都不会攻击任何其他女王。
表达问题的另一种方法是在八乘八的网格上放置八个“任意”,这样它们就不会共享一个共同的行,列或对角线。)
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <sys/time.h>
#include <omp.h>
#define MAX_N 16
int check_acceptable(int queen_rows[MAX_N], int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = i+1; j < n; j++)
{
// two queens in the same row => not a solution!
if (queen_rows[i] == queen_rows[j]) return 0;
// two queens in the same diagonal => not a solution!
if (queen_rows[i] - queen_rows[j] == i - j ||
queen_rows[i] - queen_rows[j] == j - i)
return 0;
}
}
return 1;
}
int main(int argc, char* argv[])
{
int n;
int max_iter = 1;
double start_time, end_time;
int number_solutions = 0;
{
int num_workers;
int i;
n = (argc > 1) ? atoi(argv[1]) : 8;
num_workers = (argc > 2) ? atoi(argv[2]) : 30;
omp_set_num_threads(num_workers);
for (i = 0; i < n; i++)
{
max_iter *= n;
}
}
start_time = omp_get_wtime();
int iter;
#pragma omp parallel for
for (iter = 0; iter < max_iter; iter++)
{
int code = iter;
int i;
int queen_rows[MAX_N];
// the index correspond to the queen's number and the queen's column
// we only generate configurations where there's only one queen per column
for (i = 0; i < n; i++)
{
queen_rows[i] = code % n;
code /= n;
}
if (check_acceptable(queen_rows, n))
{
#pragma omp atomic
number_solutions++;
#pragma omp critical
{
printf("\n");
for (i = 0; i < n; i++)
{
int j;
for (j = 0; j < n; j++)
{
if (queen_rows[i] == j) printf("|X");
else printf("| ");
}
printf("|\n");
}
printf("\n");
}
}
}
// get end time
end_time = omp_get_wtime();
// print results
printf("The execution time is %g sec\n", end_time - start_time);
printf("Number of found solutions is %d\n", number_solutions);
return 0;
}
如何优化此代码?什么使代码变慢,缓存或什么?
答案 0 :(得分:1)
并行化NQueens是学习递归和/或任务并行性(这不是你实际使用的)时的典型练习。为了并行化NQueens,使用反向跟踪算法;回溯算法在很多地方都有很好的描述: