基于Las Vegas 和回溯法的皇后问题(C语言描述)

来源:互联网 发布:mac自带的图片编辑器 编辑:程序博客网 时间:2024/05/19 13:14

基于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    100enum 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、一半略少的皇后随机放置比较好。



0 0
原创粉丝点击