|
楼主 |
发表于 2013-10-5 15:08:45
|
显示全部楼层
例题
马踏棋盘的贪心算法
123041-23 XX
【问题描述】
马的遍历问题。在8×8方格的棋盘上,从任意指定方格出发,为马寻找一条走遍棋盘每一格并且只经过一次的一条最短路径。
【初步设计】
首先这是一个搜索问题,运用深度优先搜索进行求解。算法如下:
⒈ 输入初始位置坐标x,y;
⒉ 步骤 c:
如果c> 64输出一个解,返回上一步骤c--
(x,y) ← c
计算(x,y)的八个方位的子结点,选出那此可行的子结点
循环遍历所有可行子结点,步骤c++重复2
显然⑵是一个递归调用的过程,大致如下:
C++程序:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #define N 8
……
……
void dfs(int x,int y,int count)
{
int i,tx,ty;
if(count> N*N)
{
output_solution();//输出一个解
return;
}
for(I=0;i <8;++i)
{
tx=hn[i].x;//hn[]保存八个方位子结点
ty=hn.y;
s[tx][ty]=count;
dfs(tx,ty,count+1);//递归调用
s[tx][ty]=0;
}
}
[/i] |
Pascal程序:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| Program YS;
Const FXx:array[1..8]of -2..2=(1,2,2,1,-1,-2,-2,-1);
FXy:array[1..8]of -2..2=(2,1,-1,-2,-2,-1,1,2);
Var
Road:array[1..10,1..10]of integer;
x,y,x1,y1,total:integer;
Procedure Find(x,y:integer);
var Nx,Ny,i:integer;
Begin
For i:=1 to 8 do
begin {8个方向}
If (x+FXx[i] in [1..8]) and (y+FXy[i] in [1..8]) Then{确定新坐标是否越界}
If Road[x+Fxx[i],y+Fxy[i]]=0 Then
begin{判断是否走过}
Nx:=x+FXx[i]; Ny:=y+FXy; Road[Nx,Ny]:=1;{建立新坐标}
If (Nx=x1) and (Ny=y1)
Then inc(total)
else Find(Nx,Ny); {递归}
Road[Nx,Ny]:=0 {回朔}
end
end
End;
BEGIN{Main}
Total:=0;
FillChar(Road,sizeof(road),0);
Readln(x,y); {读入开始坐标}
Readln(x1,y1); {读入结束坐标}
If (x>10) or (y>10) or (x1>10) or (y1>10) Then writeln('Eorror') {判断是否越界}
Else Find(x,y);
Writeln('Total:',total) {打出总数}
END.
[/i][/i][/i][/i][/i] |
这样做是完全可行的,它输入的是全部解,但是马遍历当8×8时解是非常之多的,用天文数字形容也不为过,这样一来求解的过程就非常慢,并且出一个解也非常慢。
怎么才能快速地得到部分解呢?
【贪心算法】
其实马踏棋盘的问题很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一个有名的算法。在每个结点对其子结点进行选取时,优先选择‘出口’最小的进行搜索,‘出口’的意思是在这些子结点中它们的可行子结点的个数,也就是‘孙子’结点越少的越优先跳,为什么要这样选取,这是一种局部调整最优的做法,如果优先选择出口多的子结点,那出口少的子结点就会越来越多,很可能出现‘死’结点(顾名思义就是没有出口又没有跳过的结点),这样对下面的搜索纯粹是徒劳,这样会浪费很多无用的时间,反过来如果每次都优先选择出口少的结点跳,那出口少的结点就会越来越少,这样跳成功的机会就更大一些。这种算法称为为贪心算法,也叫贪婪算法或启发式算法,它对整个求解过程的局部做最优调整,它只适用于求较优解或者部分解,而不能求最优解。这样的调整方法叫贪心策略,至于什么问题需要什么样的贪心策略是不确定的,具体问题具体分析。实验可以证明马遍历问题在运用到了上面的贪心策略之后求解速率有非常明显的提高,如果只要求出一个解甚至不用回溯就可以完成,因为在这个算法提出的时候世界上还没有计算机,这种方法完全可以用手工求出解来,其效率可想而知。
|
|