怎样用随机法求出八皇后问题的一个解

yangling18 2005-02-06 08:12:35
这是我们的老师提出来的问题,具体要求如下
八皇后问题在以前的上机题中已经实现过一次,但是很多同学都是在回溯法思想上用确定法求解的。用确定法求解能够完整地将92个解全部求出,但是在求解其中地任意一个解时,性能还是差了些。
现在请同学们用概率法求解八皇后问题的一个解。用到的基本思想还是回溯法,但是在将下一个皇后放入某一个格子时,不是按照从左到右的次序来,而是随机放入某一个位置中。如果这个位置不合适,再随机生成另一个位置放入皇后。
我现在的问题是用随机函数真的能碰巧求出一个解吗,虽然理论上可行,但是实际上rand函数很多时候产生的数都相同,不能把1到8的数都随机产生一遍,我试了一下,产生不出来(我是在我以前写的求出92个解的程序上改动的),有高手能提点一下吗
...全文
240 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
terry6394 2005-02-13
  • 打赏
  • 举报
回复
好经典的问题,可是我就是没学好...
只知道回溯法了
ehom 2005-02-12
  • 打赏
  • 举报
回复
>>回溯是性能最好的算法

性能最好?回溯的时间,空间复杂度都很高,如何体现性能好?现实中的很多问题根本无法用回溯去求解.

不过八皇后问题比较简单,回溯确实是最好的方法.

如果由此扩展到N皇后,N远大于8,回溯就不一定好使了.

其实模拟退火,遗传算法都是有导向性的随机算法,楼主可以很容易找到资料看看.

示例程序的话,另一个经典问题TSP比较容易找到.

不过很多时候只能做到以极高的效率趋近最优解,要绝对保证是全局最优解,多数情况也只能全局遍历.当然这其中也有其它一些一般技巧,比如利用Hash Table实现用空间换时间等等.
yangling18 2005-02-09
  • 打赏
  • 举报
回复
上面的随机算法有问题
sanoul 2005-02-07
  • 打赏
  • 举报
回复
呵呵,学习
yangling18 2005-02-07
  • 打赏
  • 举报
回复
我用随机法的c++程序如下
#include<iostream.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
int x[9];
bool a[9],b[17],c[15];
int index(1);
int i;
DWORD t;
DWORD Tstart;
DWORD Tend;

void print()
{
int k;
cout<<index;
for(k=1;k<=8;k++)

cout<<'('<<k<<','<<x[k]<<')';
cout<<endl;
index++;

}
/*void FindPos(int i)
{
int j;
for (j=1;j<=8;j++)
{
t=i-j;
if (t<0)
t=7-t;
if (a[j]&&b[i+j]&&c[t])
{
x[i]=j;
a[j]=false;
b[i+j]=false;
c[t]=false;
if (i<8)
FindPos(i+1);
else
print();
a[j]=true;
b[i+j]=true;
t=i-j;
if (t<0)
t=7-t;
c[t]=true;
}//end if

} */
void RandomFindPos(int i)
{
int t;
int j;
int temp;
temp1: srand(time(NULL));
// for (j=1;j<=8;j++)
j=rand()%8+1;
temp=j;
// {
t=i-j;
if (t<0)
t=7-t;
if (a[j]&&b[i+j]&&c[t])
{
x[i]=j;
a[j]=false;
b[i+j]=false;
c[t]=false;
if (i<8)
RandomFindPos(i+1);
else
{
print();

return;
}
a[j]=true;
b[i+j]=true;
if (t<0)
t=7-t;
c[t]=true;
goto temp1;
}//end if
// }

}// end FindPos
void main()
{
for(int i=0;i<9;i++)
a[i]=true;
for(i=0;i<17;i++)
b[i]=true;
for(i=0;i<15;i++)
c[i]=true;
Tstart=GetTickCount();
RandomFindPos(1);
Tend=GetTickCount();
t=Tend-Tstart;
cout<<t<<endl;

}
用/**/注释的是原来的回溯算法(已经运行是正确的),下面是随机算法,但是只能最多确定6个位置(用单步调试观察到),要确定八个位置很难,大家可以看看我的写法是否正确,给点意见。
jinjazz 2005-02-07
  • 打赏
  • 举报
回复
回溯是性能最好的算法

16,746

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧