分支限界:给出各个地点,及两个地点间的距离,遍历所有地点,且仅一次回到起点
例如表:
地点 | 1(终点) | 2 | 3 | 4 | 5 |
1(出发点) | 无穷远 | 17 | 7 | 35 | 18 |
2 | 9 | 无穷 | 5 | 14 | 19 |
3 | 29 | 24 | 无穷 | 30 | 12 |
4 | 27 | 21 | 25 | 无穷 | 48 |
5 | 15 | 16 | 28 | 18 | 无穷 |
对于每个地点,只能出一次,进一次。列代表出发点,行代表终点
所以对于任意一行或一列减去个常量s,总耗费都会少s。(因为每个点作为出发点和终点都只有一次)
第一步要进行表的评估,求出可能的最小耗费smin:
地点 | 1(终点) | 2 | 3 | 4 | 5 | 耗费ymin |
1(出发点) | 无穷远 | 10 | 0 | 25 | 11 | 7 |
2 | 4 | 无穷 | 0 | 6 | 14 | 5 |
3 | 17 | 12 | 无穷 | 15 | 0 | 12 |
4 | 6 | 0 | 4 | 无穷 | 27 | 21 |
5 | 0 | 1 | 13 | 0 | 无穷 | 15 |
耗费xmin |
|
|
| 3 |
|
|
表评估:每行减去个最小的值xmin,使得每行都有至少有一个为0,然后每列再减去个最小的值ymin,使得每列都有至少一个为0,将所有xmin,ymin相加得到最小总耗费
得到可能的最小耗费 smin为63(xmin=3,ymin=7+5+12+21+15,smin=xmin+ymin)
存储表格到table,并以smin的值大小排序,小的在前
第二步:在table中选出第一个表格(table【0】)
找每行第二小的路径min2,比较各行的min2,选择min2最大的行x,并得到路径
(x,y),使得(x,y)=0;
如上表,第二小最大的为第三行,min2=15;路径即为(3,5)=0;
第三步:求出包含路径(x,y)的表的评估值smin跟不包含路径(x,y)的smin;
当包含(x,y)时,去掉行x,列y,得到子表
地点 | 1(终点) | 2 | 3 | 4 |
1(出发点) | 无穷远 | 10 | 0 | 25 |
2 | 4 | 无穷 | 0 | 6 |
4 | 6 | 0 | 4 | 无穷 |
5 | 0 | 1 | 13 | 0 |
对子表评估smin,并加上父表的smin;
地点 | 1(终点) | 2 | 3 | 4 | 耗费s |
1(出发点) | 无穷远 | 10 | 0 | 25 | 0 |
2 | 4 | 无穷 | 0 | 6 | 0 |
4 | 6 | 0 | 4 | 无穷 | 0 |
5 | 0 | 1 | 13 | 0 | 0 |
耗费 | 0 | 0 | 0 | 0 |
|
得到smin=63
不包含(x,y):
将(x,y)置为无穷,再进行表评估
地点 | 1(终点) | 2 | 3 | 4 | 5 |
1(出发点) | 无穷远 | 10 | 0 | 25 | 11 |
2 | 4 | 无穷 | 0 | 6 | 14 |
3 | 17 | 12 | 无穷 | 15 | 无穷 |
4 | 6 | 0 | 4 | 无穷 | 27 |
5 | 0 | 1 | 13 | 0 | 无穷 |
表评估:
地点 | 1(终点) | 2 | 3 | 4 | 5 | 耗费s |
1(出发点) | 无穷远 | 10 | 0 | 25 | 0 |
|
2 | 4 | 无穷 | 0 | 6 | 3 |
|
3 | 5 | 0 | 无穷 | 3 | 无穷 | 12 |
4 | 6 | 0 | 4 | 无穷 | 16 |
|
5 | 0 | 1 | 13 | 0 | 无穷 |
|
耗费 |
|
|
|
| 11 |
|
则smin=86;
第四步:将子表存储,并把父表移除。每次找smin最小的进行子表拆分。直到表格拆为1*1
该1*1子表对应的smin即为最小耗费。
问题:子表拆解时候为什么要选每行第二小值中最大的行?
为使得不包含(x,y)路径的子表耗费增长最快为smin+min2,使得搜索更快。
问题:为什么使得每行每列都有一个为0
每行有一个为0,则使得(x,y)为0,x到y的路径耗费已经算到了耗费smin中,如果评估后的表格有一条所有边为0,且遍历各地的路那smin则代表要求的最小耗费。