用梯度上升法解决N皇后问题
一、最陡梯度上升法
1.先上代码
<span style="font-size:18px;">#ifndef GA
#define GA
#include<iostream>
#include<ctime>
using namespace std;
class queen
{
private:
int size;
int eva_now;
int *list;
void init()
{
for(int i=0;i<size;++i)
list[i]=rand()%size;
eva_now=evaluate(list);
}
int evaluate(int *li)
{
int eva=0,minx,miny,x;
for(minx=0;minx<size;++minx)
{
miny=li[minx];
for(x=minx+1;x<size;++x)
{
if(x==minx)
continue;
else if(li[x]==miny)
eva++;
else if(abs(miny-li[x])==abs(minx-x))
eva++;
}
}
return eva;
}
bool calculate()
{
if(eva_now==0)
return true;
int chx,chy,x,y,recoardy,recoardeva=eva_now;
int tmp;
bool change=false;
for(x=0;x<size;++x)
{
recoardy=list[x];
for(y=0;y<size;++y)
{
if(y==recoardy)
continue;
else
{
list[x]=y;
tmp=evaluate(list);
if(tmp<recoardeva)
{
chx=x;
chy=y;
change=true;
recoardeva=tmp;
}
}
}
list[x]=recoardy;
}
if(change==false)
return false;
eva_now=recoardeva;
list[chx]=chy;
return true;
}
public:
void output()
{
for(int i=0;i<size;++i)
cout<<list[i]<<endl;
}
bool start()
{
if(size==-1)
return false;
for(int i=0;i<100000;++i)
{
if(eva_now==0)
return true;
else
{
if(calculate())
continue;
else
init();
}
}
}
bool start(int &stp,int &res)
{
stp=0;
res=0;
if(size==-1)
return false;
for(int i=0;i<100000;++i)
{
stp++;
if(eva_now==0)
return true;
else
{
if(calculate())
continue;
else
{
init();
res++;
}
}
}
}
queen()
{
srand(clock());
size=-1;
list=NULL;
}
bool setsize(int n)
{
if(size!=-1)
delete[] list;
list=new int[n];
if(!list)
return false;
size=n;
init();
}
queen(int _size):size(_size)
{
srand(clock());
list=new int[size];
init();
}
~queen()
{
if(size!=-1)
delete[] list;
}
};
#endif</span>
2、详解
为了避免大家受来回翻页之苦,我会在每个函数的解释旁附上相应的代码,希望能让大家看得轻松。
a、构造函数
<pre class="cpp" name="code"><span style="font-size:18px;"> queen(int _size):size(_size)
{
srand(clock());
list=new int[s