共有回帖数  0  个 
	 
	
	
	
     
          
          
               
				
			 
				
					 
 
            
				   - 
						
						
							 
									最近看到又有不少人在讨论八皇后问题,乃至N皇后问题,我就把去年的作业贴出来给大家探讨下吧。 
本文主要内容:用回溯和局部搜索方法,实现求解N皇后问题的程序,并且比较耗费时间 
先给出两种方法的耗费时间比较: 
方法棋盘大小	15	20	27	29	30	100	200	500	1000 
回溯法耗时(ms)	0	47	125	409	15719	
局部搜索法耗时(ms)	0	0	0	0	15	100	1000	12000	40000 
以下是两种方法的程序: 
回溯法程序: 
#includeiostream.h 
#includestring.h 
#includetime.h 
#define size 100 
int board[size]; 
int ver[size]; 
int ru[size*2];//右上 
int rd[size*2];//右下 
int n,find;	int rec[size]; 
//回溯搜索 
void dfs(int t) 
{ 
int i; 
if(find)	return; 
if(t==n) 
{ 
find=1; 
for(i=0;in;i++) 
{ 
rec=board; 
} 
return; 
} 
for(i=0;in;i++) 
{ 
if(ver==1)	continue; 
if(ru[i-t+n]==1)	continue; 
if(rd[i+t]==1)	continue; 
ver=1; 
ru[i-t+n]=1; 
rd[i+t]=1; 
board[t]=i; 
dfs(t+1); 
rd[i+t]=0; 
ru[i-t+n]=0; 
ver=0; 
} 
return; 
} 
int main() 
{ 
int i,j,t1,t2; 
cout"输入棋盘大小:"; 
cinn; 
t1=clock(); 
find=0;	memset(ver,0,sizeof(ver)); 
memset(ru,0,sizeof(ru));	memset(rd,0,sizeof(rd)); 
dfs(0); 
t2=clock(); 
if(find) 
for(i=0;in;i++) 
{ 
for(j=0;jn;j++) 
{ 
if(rec==j)	cout'X'; 
else	cout'+'; 
} 
coutendl; 
} 
else 
cout"Can't find!n"; 
cout"耗费时间:"t2-t1"msn"; 
return 0; 
}
局部搜索程序: 
#includeiostream.h 
#includestring.h 
#includestdlib.h 
#includetime.h 
#define size 2000 
int board[size];//记录棋盘状况的数组 
//记录冲突的数组 
int ru[size*2];//右上 
int rd[size*2];//右下 
int recran[size]; 
int n;	int rec[size]; 
int f() 
{//计算冲突的函数 
int i,r=0; 
memset(ru,0,sizeof(ru)); 
memset(rd,0,sizeof(rd)); 
for(i=0;in;i++) 
{ 
ru[board-i+n]++; 
rd[board+i]++; 
} 
for(i=0;i2*n;i++) 
{ 
if(ru1)	r+=ru-1; 
if(rd1)	r+=rd-1; 
} 
return r; 
} 
//生成x个不重复的随机数,放入board数组 
void randgen(int x) 
{ 
int i,temp; 
memset(recran,0,sizeof(int)*(n+1)); 
for(i=0;in;i++) 
{ 
do 
{ 
temp=rand()%x; 
} 
while(recran[temp]==1); 
board=temp; 
recran[temp]=1; 
} 
} 
int main() 
{ 
srand((unsigned) time(NULL)); 
int i,j,temp,now,t1,t2,fnow; 
cout"输入棋盘大小:"; 
cinn; 
coutendl; 
t1=clock(); 
//find=0; 
//局部搜索部分 
while(1) 
{ 
randgen(n); 
now=f(); 
next:	if(now==0)	goto	over; 
for(i=0;in-1;i++) 
{ 
for(j=i+1;jn;j++) 
{ 
temp=board;	board=board[j];	board[j]=temp; 
fnow=f(); 
if(fnownow) 
{ 
now=fnow; 
goto next; 
} 
temp=board;	board=board[j];	board[j]=temp; 
} 
} 
} 
over: 
t2=clock(); 
/*for(i=0;in;i++) 
{ 
for(j=0;jn;j++) 
{ 
if(board==j)	cout'X'; 
else	cout'+'; 
} 
coutendl; 
}*/ 
cout"耗费时间:"t2-t1"msn"; 
return 0; 
} 
经检验,在有解并且时间允许的情况下,两程序均可以找到一组正确解。 
棋盘大小在30以上,回溯法在有限时间内基本无法找到解,而棋盘大小直到1000,局部搜索法仍能找到正确��
							 
							 
							 
							  
							  
							  楼主 2016-02-19 16:44 回复
						 
						 
           
          
          
         
   
         
      
 
   
             
                  
                  
 
 
 
     
	 
  
	Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
	
	意见反馈 | 
	关于直线 | 
	版权声明 | 
	会员须知