使用openmp c优化N-queen

时间:2015-12-07 19:48:37

标签: c openmp

我正在使用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;
}

如何优化此代码?什么使代码变慢,缓存或什么?

1 个答案:

答案 0 :(得分:1)

并行化NQueens是学习递归和/或任务并行性(这不是你实际使用的)时的典型练习。为了并行化NQueens,使用反向跟踪算法;回溯算法在很多地方都有很好的描述: