基本知识
适用:求解搜索问题和优化问题
搜索空间:树,结点对应部分解向量,叶结点是解
结点分支判定条件:满足约束条件继续扩张解向量也就是继续搜索;否则回溯到父结点,从父结点继续搜索
结点状态:动态生成。建立搜索树的同时完成遍历和是否满足约束条件的判断。满足则继续建树,否则停止
回溯算法求得一个解向量。
适用条件:
p(
x
1
x_1
x1,
x
2
x_2
x2,…
x
k
+
1
x_k+1
xk+1)->p(
x
1
x_1
x1,
x
2
x_2
x2,…
x
k
x_k
xk)
或者!p(
x
1
x_1
x1,
x
2
x_2
x2,…
x
k
x_k
xk)->!p(
x
1
x_1
x1,
x
2
x_2
x2,…
x
k
+
1
x_k+1
xk+1)
以上成为多米诺性质
设计步骤:
(1)定义解向量和每个分量的取值范围
(2)在(
x
1
x_1
x1,
x
2
x_2
x2,…
x
k
−
1
x_k-1
xk−1)确定的情况下,
x
k
x_k
xk的取值集合
S
k
S_k
Sk
(3)确定结点儿子的排列规则,即
S
k
S_k
Sk中各元素如何排列
(4)判断是否满足多米诺性质
(5)确定每个结点分支的约束条件
(6)确定搜索策略:深度优先,宽度优先等
(7)确定存储搜索路径的数据结构
例子
问题描述:
有m个集装箱,需装到两个船上,载重分别为
c
1
c_1
c1和
c
2
c_2
c2,集装箱的重量为
w
1
w_1
w1,
w
2
w_2
w2…
w
m
w_m
wm,且集装箱的重量不超过两船的载重和。问是否可以将集装箱装到船上。
回溯算法设计:
使用回溯算法求一个装载方案使第一艘装的尽量多,假定
c
1
c_1
c1>
c
2
c_2
c2,第一艘实际装入的重量为
W
1
W_1
W1,也就是使
c
1
c_1
c1-
W
1
W_1
W1尽可能小,下文使用空隙表征。
伪代码:
1.sort(w)
2.b<-
c
1
c_1
c1,best<-
c
1
c_1
c1,i<-1
//b为当前空隙,best为最小空隙
3.while i<=n do
if 装入
w
i
w_i
wi后第一艘船不超重
then b<-b-
w
1
w_1
w1;x[i]=1;++i;
else x[i]=0;++i
4.if b<best then 记录解,best<-b
5.back_track(i);//回溯
6.if i==1 then return 最优解
else goto3
算法back_track(i)的伪代码:
1.while(i>1&&x[i]=0)
2. i<-i-1
3.if x[i]=1
4.then x[i]=0
5.++i
6.b<-b+
w
i
w_i
wi
该算法用于向上回溯到最后装入第一艘的集装箱,然后该集装箱不装入第一艘船,继续搜索。