回溯算法是所有搜索算法中最为基本的一种算法,其采用了一种“走不通就掉头”思想作为其控制结构,其相当于采用了先根遍历的方法来构造解答树,可用于找解或所有解以及最优解。具体的算法描述如下:
[非递归算法]
<type>
node(节点类型)=record
situtation:tsituation(当前节点状态);
way-no:integer(已使用过的扩展规则的数目);
end
<var>
list(回溯表):array[1..max(最大深度)] of node;
pos(当前扩展节点编号):integer;
<init>
list<-0;
pos<-1;
list[1].situation<-初始状态;
<main program>
while (pos>0(有路可走)) and ([未达到目标]) do
begin
if pos>=max then (数据溢出,跳出主程序);
list[pos].way-no:=list[pos].way-no+1;
if (list[pos].way-no<=totalexpendmethod) then (如果还有没用过的扩展规则)
begin
if (可以使用当前扩展规则) then
begin
(用第way条规则扩展当前节点)
list[pos+1].situation:=expendnode(list[pos].situation,
list[pos].way-no);
list[pos+1].way-no:=0;
pos:=pos+1;
end-if;
end-if
else begin
pos:=pos-1;
end-else
end-while;
[递归算法]
procedure backtrack(situation:tsituation;deepth:integer);
var i :integer;
begin
if deepth>max then (空间达到极限,跳出本过程);
if situation=target then (找到目标);
for i:=1 to totalexpendmethod do
begin
backtrack(expendnode(situation,i),deepth+1);
end-for;
end;
范例:一个m*m的棋盘上某一点上有一个马,要求寻找一条从这一点出发不重复的跳完棋盘上所有的点的路线。
评价:回溯算法对空间的消耗较少,当其与分枝定界法一起使用时,对于所求解在解答树中层次较深的问题有较好的效果。但应避免在后继节点可能与前继节点相同的问题中使用,以免产生循环。