基于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时

基于Las Vegas 和回溯法的皇后问题(C语言描述),求N=12..20的最优StepVegas值

N=20时

基于Las Vegas 和回溯法的皇后问题(C语言描述),求N=12..20的最优StepVegas值

有运算结果可知:

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

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

你可能感兴趣的:(C语言)