zoukankan      html  css  js  c++  java
  • 基于Las Vegas 和回溯法的皇后问题(C语言描述),求N=12..20的最优StepVegas值

          算法采用多次执行这种QueenLV算法(100次),求取成功率。对于不同的N(12—20)皇后问题,记录随机放n(n<N)个皇后,算法成功一次需要的平均时间。

    算法源代码(C描述):

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h>
    
    #define N  12
    #define RUN_TIME    100
    
    enum boolean {false,true};
    
    int x[N+1]={0};
    int y[N+1]={0};
    
    int randomi(int m,int n)
    {
      int j;
      if(m > n)
      {
        printf("n must large than m!!!\n");
        return -1;
      }
      if(m==n)
        return n;
    //  srand((unsigned)time(NULL));
      while(1)
      {
        j = rand();
        j %= n;
        if(j < m)
            j += n-m;
        else
            return j;
      }
    }
    
    int place(int k)
    {
     int j;
     for(j=1;j<k;j++)
     {
       if((abs(k-j)==abs(x[j]-x[k])) || (x[j]==x[k]))
          return false;
     }
     return true;
    }
    
    void backtrack(int t)
    {
     int i;
     if(t>N)
     {
       for(i=1;i<=N;i++)
         y[i]=x[i];
       return;
     }
     else
       for(i=1;i<=N;i++)
       {
        x[t]=i;
        if(place(t))
        {
          backtrack(t+1);
    //      printf("in backtrace x[%d]=%d\n",t,x[t]); 
        }
       }
    }
    
    int QueensLV(int stopLV)
    {
     int i,j,count=1,k=1;
     while((k <= stopLV) &&(count>0))
     {
       count=0;
       j=0;
       for(i=1;i<=N;i++)
       {
        x[k]=i;
        if(place(k))
        {
         count++;
         if(randomi(0,count)==0)
           j=i;
        }  
       }
       if(count>0)
         x[k++]=j;
    
    //   for(i=1;i<k;i++)
    //      printf("x[%d]=%d ",i,x[i]);
    //   printf("\n(k) = %d\n",k);
     }
     if(count>0)
       return true;
     else
       return false;
    }
    
    int main(void)
    {int dif_n,time_now,time_end;
     for(dif_n=0;dif_n<N;dif_n++)
    
     {int i,stop,j=0,sucess=0;
      printf("Please input the integer to stopLV and start backtrack(<=%d):",N);
      scanf("%d",&stop);
      time_now=clock();
      srand((unsigned)time(NULL));
      do{
             if(stop<N)
          {    
              while(!QueensLV(stop))
               ;
             }
        else
            QueensLV(stop);
          backtrack(stop+1);
        if(y[N]!=0)
        {
            sucess++;
            // printf("sucess = %d\n",sucess);
            for(i=0;i<=N;i++)
                y[i]=0;
        }
        j++;
        // printf("j=%d\n",j);
      }while( j<RUN_TIME);
    //  printf("\n%d Queens's problem,y[%d]=",N,N);
    //  for(i=1;i<=N;i++)
    //    printf("%d ",y[i]);
    //  printf("\n");
        printf("Run %d times,success %d times!, success rate is %3.0f%%\n",RUN_TIME,sucess, 100.0*sucess/RUN_TIME );
        time_end=clock();
        printf("it takes %ldms to solve this problem\n",(time_end-time_now)*1000/CLOCKS_PER_SEC/sucess);//输出成功一次的平均时间
        }
    
      return 0;
    }

    运行结果:

    N=12时

    N=20时

    有运算结果可知:

    1、纯回溯的方法成功率高,但耗时长;纯贪心LV成功率太低,采用stepVegas可以有效解决这个问题。在成功率满足需求的情况下可以大大缩短算法时间。

    2、一半略少的皇后随机放置比较好。

  • 相关阅读:
    Pytorch使用tensorboardX实现loss曲线可视化。超详细!!!
    numpy安装失败:numpy和cv2的版本不一样吧 pip安装/卸载
    问题解决:RuntimeError: CUDA out of memory.(....; 5.83 GiB reserved in total by PyTorch)
    前端刷题网站
    vscode如何使用ssh连接远程linux
    marginnote使用
    前端知识点
    HTTP状态码
    内置对象总结
    微信小程序
  • 原文地址:https://www.cnblogs.com/yuzeren48/p/2733653.html
Copyright © 2011-2022 走看看