注:本学期算法设计分析课刘老师讲课内容总结
回溯
搜索算法:
穷举搜索(brute-force Search)
图遍历(Graph traversal)
- 深度优先搜索(DFS)
- 广度优先搜索(BFS)
树遍历(Tree traversal) - 回溯(Backtracking)
- 分枝限界法(Branch and Bound);
- 博弈树搜索( α- β Search)等
启发式搜索(Heuristic Search) (上一篇提到的随机化算法其实随机化只是思想啦,就是这个启发式搜索,例如模拟退火)
装载问题与01背包
装载问题
n件货物(重w[1:n])装两艘船(载重量c1,c2), ∑_(𝒊=𝟏to𝒏)〖𝒘[𝒊]〗 <= c1+c2, 是否有装载方案.
讨论过类似问题: 0-1背包, 分数背包, 最优装载
装载方案: 尽可能装满第1艘, 剩余的装第2艘
尽可能装满第1艘等价于下面变形的0-1背包
w[1:n],用长为n的01字符串(x[1:n]∈{0,1}^n)表示物品取或不取
蛮力:
没看懂。。先往下
懂了,就是遍历每一种可能方案,要尽可能装满达到载重量(嗳,看不懂不要急也不要死扣,往下就明白了( •̀ ω •́ )✧)
x[1:n]∈{
0,1}^n,
1. x=first(n), bestw=0,
2. 当x≠last(n),
3. | cw=sumi=1n x[i]*w[i]
4. | 若cw ≤ c 且 cw > bestw, 则bestw=cw
5. | x=next(n,x)
字典序: 000,001,010,011,100,101,110,111. 执行?
逆字典序: 从1…1到0…0
格雷码序: 000,001,011,010,110,111,101,100, 减少cw计算量
缺点: 不容易剪枝
简单回溯:
在树上进行深度优先搜索, 通常同层结构相同.
backtrack(t)
// t:层号, cw:当前重量, bestw:最优重量, t=n对应树叶
若t>n, (若cw≤c且cw>bestw, bestw=cw.)返回---//记录更新
2. cw+=w[t], backtrack(t+1), cw-=w[t],-----------//左分支
3. backtrack(t+1), 返回------------------------------//右分支
初始: bestw=cw=0, 执行 backtrack(1), 简单, 优美
需要剪枝
- 若 cw + w[t] ≤c, 则 -------------------是约束条件,(剪枝,剪去不满足约束条件的子树)
初始: bestw=cw=0. r=sumt=1n w[t] //当前剩余重量
backtrack(t) //t层号, cw, bestw
1. 若t>n, (若cw>bestw, bestw=cw, bestx=x.) 返回
2. r-=w[t]
3. 若 cw + w[t] ≤ c, 则----------------//约束条件(剪枝)
4. | cw+=w[t], x[t]=1, backtrack(t+1), cw-=w[t], //左分支
5. 若 cw + r > bestw, 则--------------//限界条件(剪枝)
6. | x[t]