旅行商问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
旅行商问题:
问题描述:已知一个由n个城市(顶点)组成的有向网G , n个城市为v1, v2,…, v n , G的邻接矩阵为D=(d ij)nxn , d ij为边< v i, v j>上的权(表示城市v i到v j的耗费)。一个旅行商从v1开始,巡回访问每个城市一次且仅一次,最后返回v1, 这个旅行商该如何选择旅行线路,使得整个行程耗费最小?
● 分析:
可利用求一般问题的所有解的回溯算法得到解最优化问题的回溯算法。
(1) 该问题是求最短的哈密顿回路。
(2) 用min表示当前最优值,s[1..n]表示当前最优解。
(3) 除了解的约束条件,用如下剪枝条件进一步剪枝:
当前路径长度>=min
(4) 设置一个标记数组tag[1..n]:
tag[i]=1, 顶点i在当前路径上
tag[i]=0, 顶点i不在当前路径上
当一个顶点退出当前路径时,该顶点的标记应复原为0。
● 回溯算法:
算法 TRAVELING_SALESMAN
输入:正整数n和含n个顶点的有向网G的邻接矩阵D。
输出:关于G的旅行商问题的一条最短旅行线路和最小耗费, 若问题无解,则输出no solution。
min=∞
x[1]=1 //用x[1..n]表示当前搜索路径, 从顶点1开始。
len=0 //len表示当前路径的长度
tag[1]=1; tag[2..n]=0 //设顶点标记初值。
salesman( 2 )
if min<∞ then
output (min, s[1..n]) //输出最优值和最优解。
else
output (“no solution”)//输出无解
end if
end TRAVELING_SALESMAN
过程 salesman(k)
//在已得到当前路径x[1..k-1]的情况下,求G的长度 for i=2 to n x[k]=i //试将顶点i作为当前路径上的第k个顶点。 if route(k) then //当前顶点可作为当前路径的下一顶点。 tag[x[k]]=1; //当前顶点加入当前路径。 len=len+D[x[k-1], x[k]] if k=n then //找到一条新的哈密顿回路。 if len+D[x[k], 1] min=len+D[x[k], 1]; s[1..n]=x[1..n] end if else if len salesman(k+1) end if end if tag[x[k]]=0 //顶点x[k]退出当前路径。 len=len-D[x[k-1], x[k]] end if end for end salesman 过程 route(k) //判断当前顶点x[k]是否可作为当前路径x[1..k-1]的下一顶点, //是则返回true, 否则返回false。 if (D[x[k-1], x[k]]<∞)and (tag[x[k]]=0)and(k then return true else return false end route