第12讲 旅行售货商问题和斯坦纳最小树问题
旅行售货员问题

旅⾏售货员问题旅⾏售货员问题【题⽬】某售货员要到4个城市去推销商品,已知各城市之间的路程,如右图所⽰。
请问他应该如何选定⼀条从城市1出发,经过每个城市⼀遍,最后回到城市1的路线,使得总的周游路程最⼩?并分析所设计算法的计算时间复杂度。
【分析】该题利⽤回溯法求解,此时需要确定解空间的类型:我们可以知道该解空间为⼀棵排列树。
我们假设初始的⼀条路线为x,x中的值为 1,2,3,……,n,表⽰该路线为由城市1依次经过城市2、3……到n后再回到城市1(当然是假设该路线存在)。
如果不存在的话,我们只需改变⼀下这个排列的排列⽅式,再进⾏判断,所以可想⽽知,我们可以知道该解空间是⼀棵排列树。
当然上述的说法,只是单纯的穷举,这并不是我们想要的回溯法,我们通过递归实现,在递归的过程中适当地“剪枝”即除去那些不可能形成最优解的解。
现在我们来确定⼀下可⾏的约束条件,当我们进⾏递归搜索,搜索到第t层时,我们需要判断⼀下x[t]所代表的城市是否与上⼀层x[t-1]所代表的城市有“路”,如果没有的话,需要改变x[t]的值,然后继续上述判断,当出现⼀个满⾜条件的x[t]后还要判断当前从1到t-1所⾛的路程cc加上x[t]与x[t-1]的距离是否⼩于当前已经记录的最优解(最优解的初始值是⼀个⾜够⼤的数),如果到t的距离⽐当前最优解还要⼤的话,那么再以这条路线搜索下去的话回到城市1的路程⼀定⽐当前最优解还⼤,所以我们没有必要对这条路线进⾏下⼀步的搜索。
最后我们来确定当搜索到叶⼦结点的时候我们该如何处理?已知搜索到t层时,若t = n,说明已经搜索到了叶⼦结点,这个时候我们还需做上述所说的两个判断,如果两个判断都通过的话,说明该解⽐当前最优解还优,那么我们需要将该解记录下来,并记录该解的最优值。
【伪代码】void travel(int t) {if(t到达第n层即搜索到叶⼦结点) {if(城市x[t-1]可以到达城市x[t],并且城市x[t]可以回到城市1,且此时所⾛的路程cc加上x[t-1]与x[t]的距离和x[t]与1的距离⼩于当前最优值bestc) {将最优解记录下来;将最优值记录下来;}return;}for(int i = t; i < n; i++) {if(城市x[t-1]能达到城市x[i]即这两个城市间有边,并当前所⾛的路程cc加上这两个城市的距离没有⽐当前最优值bestc⼤) {swap(x[i], x[t]);修改此时所⾛的路程cc;进⼊下⼀层递归;恢复原来cc的值;swap(x[i], x[t]);}}}【程序】⽤C++语⾔编写程序,代码如下:#include<iostream>using namespace std;const int INF = 10000000;int n, cc = 0, bestc = INF;int **g;int *x, *bestx;void travel(int t) {if (t == n) {if (g[x[t - 1]][x[t]] != INF && g[x[t]][1] != INF &&(cc + g[x[t - 1]][x[t]] + g[x[t]][1] < bestc || bestc == INF)) { for (int i = 0; i < n + 1; i++)bestx[i] = x[i];bestc = cc + g[x[t - 1]][x[t]] + g[x[t]][1];}return;}for (int i = t; i < n; i++) {if (g[x[t - 1]][x[i]] != INF && (cc + g[x[t - 1]][x[i]] < bestc|| bestc == INF)) {swap(x[i], x[t]);cc += g[x[t - 1]][x[t]];travel(t + 1);cc -= g[x[t - 1]][x[t]];swap(x[i], x[t]);}}}void output() {cout << bestc << endl;cout << bestx[1];for (int i = 2; i < n + 1; i++)cout << " " << bestx[i];cout << " " << bestx[1] << endl;}int main() {n = 4;g = new int*[n + 1];x = new int[n + 1];bestx = new int[n + 1];for (int i = 0; i < n + 1; i++) {g[i] = new int[n + 1];x[i] = i;for (int j = 0; j < n + 1; j++)g[i][j] = INF;}}g[1][2] = g[2][1] = 30;g[1][3] = g[3][1] = 6;g[1][4] = g[4][1] = 4;g[2][3] = g[3][2] = 5;g[2][4] = g[4][2] = 10;g[3][4] = g[4][3] = 20;travel(2);output();return 0;}【结果】先设置好城市间的距离,调⽤回溯⽅法,输出最优值(最⼩路程)和最优解(路线):该算法的时间复杂度为O(n!)。
组合优化及算法 共36页PPT资料

Combinatorial Optimization
组合优化是运筹学的后继课程,同时也是运筹学的 一个重要独立分支,是一类重要的优化问题
• 最优化(数学规划)
– 连续优化(数学规划): – 数学规划(线性规划、非线性规划)、非光
滑优化、全局优化、锥优化等 – 离散优化:网络优化、组合优化、整数规划等 – 不确定规划:随机规划、模糊规划等
30! / 10e+10 > 2.65e+22 (秒) 即 2.65e+22 / (365*24*60*60)
> 8.4e+13 (年)
计算复杂性的概念
多项式时间算法
构造算法的目的是能够解决问题(或至少是问题某个 子类)的所有实例而不单单是某一个实例
问题(Problem)是需要回答的一般性提问,通常含有若干个满 足一定条件的参数. 问题通过下面的描述给定:(1)描述所有
实例I,算法A总能找到一个可行解,那么这个算法
称为该问题的近似算法.
最优算法:如果进一步,如果这个可行解的目标值 总等于最优解值,则称A为最优算法.
典型组合优化问题
• 背包问题 • 装箱问题 • 平行机排序问题 • 图与网络优化问题
最小支撑树、最短路、最大流、最小费用流、最大基数匹 配问题 • 指派问题 • 旅行售货商问题 • 斯坦纳最小树问题
计算复杂性的概念
多项式时间算法
例 构造算法将n个自然数从小到大排列起来
算法
输入自然数a(1),a(2),…,a(n). for (i=1;i<n;i++)
for (j=i+1;j<=n;j++) if (a(i)>a(j)){ k=a(i);a(i)=a(j);a(j)=k; }
数学建模经典问题——旅行商问题

度最短的两条边之和; C*(T):最优回路长度;
25
于是,dmin(i, 1)代表与第i个结点关联的所有边 中最长边的长度,dmin_j(i, 1) 代表与第i个结点关联 的所有边中次长边的另一个结点编号(其中一个结点 编号为i),第i结点的dmin(i, k)和dmin_j(i, k)可由距 离矩阵w轻易求得。
20
当然,用该方法有时会找不到TSP的最优解, 因为很可能在进行了几轮迭代后,却找不到新的不 等式。Padborg与Hong曾计算了74个TSP,其中54 个得到了最优解,其余的虽未得到最优解,却得到 了很好的下界,如果与近似方法配合,可以估计近 似解的精确程度。如,他们解过一个有313个城市的 TSP,获得一个下界41236.46,而用近似方法能得 到一条长为41349的路线,于是可估计出所得近似解 与最优解的误差不超过0.26%。
14
早在1954年,Dantzig等人就曾提出过一种方 法(非多项式算法),并且求出了一个42城市的 TSP最优解。到了1960年代,不少人用分支定界法 解决了许多有几十个城市的TSP。还有人提出了一 些近似方法,也解决了许多有几十个城市甚至上百 个城市的TSP(有时找到的仅是近似解)。更值得 注意的是,从1970年代中期开始,Grotschel与 Padberg等人深入研究了TS多面体的最大面 (facet),并从所得结果出发获得了一种解TSP的 新算法,可以解决一些有100多个城市的TSP,且都 在不长的时间内找到了最优解。
一、数学模型 1. 标准TSP 旅行商问题(简称TSP),也称货郎担问题或 旅行推销员问题,是运筹学中一个著名的问题,其 一般提法为:有一个旅行商从城市1出发,需要到城 市2、3、…、n去推销货物,最后返回城市1,若任 意两个城市间的距离已知,则该旅行商应如何选择 其最佳行走路线
《旅行商问题》PPT课件

3. 分支定界法 初始阶段:1. 将全部边按权由小到大排列;
2. 取前n边作为S,置d0:=∞。 (d0为已考察的H回路中最短的路长) 迭代阶段:3. 若S构成H回路且其路长d(S)<d0, 则d0:= d(S)。跳过比当前d0差的后续情形后, 用 剩下未考察的第一组边作为S,返回3 全部情形考察完毕时的d0即为最短H回路长 度,取其值的那个S就是问题的解。
d(vi) 0 1 1 2 2 2
18
2. 权有负数时最短路问题的求解
——Ford 算法
权有负数时Dijkstra算法失效。( 为什么? ) 若图中不含负回路时最短路问题可解。
Ford算法采用迭代的办法,逐步逼近并最终 得到最优解。
算法中第k 次迭代后,d(i)表示从起点v1 到点 vi 的一条路的长度,且d(i)小于或等于边数不超 过k 的最短路的长度。
(注意理解jS时标号d(j)的含义)
13
对本算法的理解及算法正确性的证明:
v1
vk0
S
S
(实线表示图中一条边,虚线表示若干条 边组成的一条路)
14
例 求v1到其它各点的最短路。
v4
令d(v1)=0, 则(红点集合表示S):
4
5
vi v1 v2 v3 v4 vvi) 0 7 1 ∞ ∞ ∞
5
故最优解为S6 ,其长度为32。 计算要掌握两个要点:
1. 按字典序逐一考察各边集; 2. 每次考察完一个边集后,应考虑是否可以 用过滤条件(当前d0值)跳过一些不必要情形的考 察,因为比当前d0值差的情形不需考虑。
6
4. 近似算法--“便宜”算法 分支定界法虽可求得旅行售货员问题的准确
旅行商问题

旅行商问题本页仅作为文档页封面,使用时可以删除This document is for reference only-rar21year.March旅行商问题旅行商问题(Traveling Saleman Problem,TSP)又译为、,简称为,是最基本的路线问题,该问题是在寻求单一旅行者由起点出发,通过所有给定的需求点之后,最后再回到原点的最小路径成本。
最早的旅行商问题的数学规划是由Dantzig(1959)等人提出。
目录1简介“旅行商问题”常被称为“”,是指一名推销员要拜访多个地点时,如何找到在拜访每个地点一次后再回到起点的最短路径。
规则虽然简单,但在地点数目增多后求解却极为复杂。
以42个地点为例,如果要列举所有路径后再确定最佳行程,那么总路径数量之大,几乎难以计算出来。
多年来全球数学家绞尽脑汁,试图找到一个高效的TSP问题在物流中的描述是对应一个物流配送公司,欲将n个客户的订货沿最短路线全部送到。
如何确定最短路线。
TSP问题最简单的求解方法是。
它的解是多维的、多局部极值的、趋于无穷大的复杂解的空间,搜索空间是n个点的所有排列的集合,大小为(n-1)。
可以形象地把看成是一个无穷大的丘陵地带,各山峰或山谷的高度即是问题的极值。
求解TSP,则是在此不能穷尽的丘陵地带中攀登以达到山顶或谷底的过程。
2研究历史旅行商问题字面上的理解是:有一个推销员,要到n个城市推销商品,他要找出一个包含所有n个城市的具有最短路程的环路。
TSP的历史很久,最早的描述是1759年欧拉研究的骑士周游问题,即对于棋盘中的64个方格,走访64个方格一次且仅一次,并且最终返回到起始点。
TSP由RAND公司于1948年引入,该公司的声誉以及线性规划这一新方法的出现使得TSP成为一个知名且流行的问题。
3问题解法旅行推销员的问题,我们称之为巡行(Tour),此种问题属于的问题,1、途程建构法(Tour Construction Procedures)从中产生一个近似最佳解的途径,有以下几种解法:2、途程改善法(Tour Improvement Procedure)先给定一个可行途程,然后进行改善,一直到不能改善为止。
旅行售货员问题

一问题的重述售货员要到若干城市去推销商品,已知各城市之间的路程(或旅费)。
他要选定一条从驻地出发,经过每个城市一次,最后回到驻地的路线,使总的路程(或总旅费)最小。
路线是一个带权图。
图中各边的费用(权)为正数。
图的一条周游路线是包括V中的每个顶点在内的一条回路。
周游路线的费用是这条路线上所有边的费用之和。
旅行售货员问题的解空间可以组织成一棵树,从树的根结点到任一叶结点的路径定义了图的一条周游路线。
旅行售货员问题要在图G中找出费用最小的周游路线。
设有p个城市,假设每两个城市之间都有直通通道,两个城市之间的路程已知,一个售货员要到每个城市推销产品,然后返回原出发地,问这个售货员应该如何选择路线,能使每个城市都经过一次且仅一次,并且行程最短,这就是著名的旅行售货员问题,也即货郎担问题。
用图论的术语来描述旅行售货员问题:即在一个正权完全图中寻找一个具有最小权的哈密顿回路,对于此问题,由于完全图中必然存在哈密顿回路,那么目前可以用于求解的方法有枚举法,分枝限界法,这两种算法可以求得此问题的精确解,但到目前为止,还没有求解这一问题的有效算法,我们可以利用分支限界法,回溯法求解此问题的近似解,以求得与最优解最为接近的解。
二问题的求解方法1枚举法枚举法就是一一列出问题的所有解,然后进行比较,取权值最小的解为最优解,这种方法虽然可以求取问题的最优解,但是我们知道旅行售货员问题是对完全图而言的,对有N个结点的完全图,存在2)!1(N个不同的哈密顿回路,如果采用枚举法求解,则要对上述数目的不同的哈密顿回路一一进行运算且需要相互之间比较,当N取值较小时,此种求解方法没有任何问题,但若N值较大时,计算量则以级数级别递增,况且没有有效的算法,所以在计算机中也较难实现,故枚举法在大多数的实际应用中是不可取的。
2回溯法旅行售货员问题的解空间是一棵排列树。
对于排列树的回溯搜索与生成1,2,…,n的所有排列的递归算法perm类似。
旅行售货员问题

邻接矩阵
30 6 4
C=
30 6
5
5 10 20
414 24
25
25 59
优先队列式分支限界法用极小堆存储活结点表
初始扩展结点为B,优先队列为空。
4E
6 D C 30
B被扩展后,它的三个儿子结 点C,D,E被依次插入堆中
若考虑v1v2…vnv1和v1 vn v v n-1… 2 v1是同一条回路,
还共有(1/2)(n-1)!条不同的哈密顿回路。 为了比较权的大小,对每条哈密顿回路要做n-1次加法, 故加法的总数为(1/2)(n-1)(n-1)!。 时间复杂度O(n!)
例如当有40个城市时,(1/2)(n-1)(n-1)!的近似值为 3.77×10^47,假设一台计算机每秒完成1011次(百亿)次 加法,将需要超过1.19×1029年才能完成所需的加法次数, 显然是不可能的。
最大优先队列:使用最大堆,体现最大效益优先 最小优先队列:使用最小堆,体现最小费用优先
分支限界法和回溯法一样都是在解空间上搜索问题解的算法
回溯法:找出解空间中满足约束条件的所有解
1.求解目标
找出满足约束条件的一个解
分支限界法 在满足约束条件的解中找出使某一 目标函数值极大或极小的解
回溯法: 深度优先 DFS
NP问题近似算法
void approxTSP(Gragh g) {
(1)选择g的任意顶点r; (2)用Prim算法找出带权图g的一颗以r为根的最小生 成树T; (3)前序遍历树T得到顶点表L; (4)将r加入到表L的末尾,按表L中顶点次序组成回路 H,作为计算结果返回; }
在递归算法Backtrack中, 1.当i=n时,当前扩展节点是排列树的叶节点的父节点。
回溯法之旅行售货员问题

回溯法之旅⾏售货员问题问题描述:某售货员要到若⼲城市去推销商品,已知各城市之间的路程,他要选定⼀条从驻地出发,经过每个城市⼀遍,最后回到住地的路线,使总的路程最短。
算法描述:回溯法,序列树,假设起点为 1。
算法开始时 x = [1, 2, 3, ..., n]x[1 : n]有两重含义 x[1 : i]代表前 i 步按顺序⾛过的城市, x[i + 1 : n]代表还未经过的城市。
利⽤Swap函数进⾏交换位置。
若当前搜索的层次i = n 时,处在排列树的叶节点的⽗节点上,此时算法检查图G是否存在⼀条从顶点x[n-1] 到顶点x[n] 有⼀条边,和从顶点x[n] 到顶点x[1] 也有⼀条边。
若这两条边都存在,则发现了⼀个旅⾏售货员的回路即:新旅⾏路线),算法判断这条回路的费⽤是否优于已经找到的当前最优回路的费⽤bestcost,若是,则更新当前最优值bestcost和当前最优解bestx。
若i < n 时,检查x[i - 1]⾄x[i]之间是否存在⼀条边, 若存在,则x [1 : i ] 构成了图G的⼀条路径,若路径x[1: i] 的耗费⼩于当前最优解的耗费,则算法进⼊排列树下⼀层,否则剪掉相应的⼦树。
代码实现:#include <bits/stdc++.h>using namespace std;const int max_ = 0x3f3f3f;const int NoEdge = -1;int citynum;int edgenum;int currentcost;int bestcost;int Graph[100][100];int x[100];int bestx[100];void InPut(){int pos1, pos2, len;scanf("%d %d", &citynum, &edgenum);memset(Graph, NoEdge, sizeof(Graph));for(int i = 1; i <= edgenum; ++i){scanf("%d %d %d", &pos1, &pos2, &len);Graph[pos1][pos2] = Graph[pos2][pos1] = len;}}void Initilize(){currentcost = 0;bestcost = max_;for(int i = 1; i <= citynum; ++i){x[i] = i;}}void Swap(int &a, int &b){int temp;temp = a;a = b;b = temp;}void BackTrack(int i) //这⾥的i代表第i步去的城市⽽不是代号为i的城市{if(i == citynum){if(Graph[x[i - 1]][x[i]] != NoEdge && Graph[x[i]][x[1]] != NoEdge && (currentcost + Graph[x[i - 1]][x[i]] + Graph[x[i]][x[1]] < bestcost || bestcost == max_)){bestcost = currentcost + Graph[x[i - 1]][x[i]] + Graph[x[i]][x[1]];for(int j = 1; j <= citynum; ++j)bestx[j] = x[j];}}else{for(int j = i; j <= citynum; ++j){if(Graph[x[i - 1]][x[j]] != NoEdge && (currentcost + Graph[x[i - 1]][x[j]] < bestcost || bestcost == max_)){Swap(x[i], x[j]); //这⾥i 和 j的位置交换了, 所以下⾯的是currentcost += Graph[x[i - 1]][x[i]]; currentcost += Graph[x[i - 1]][x[i]];BackTrack(i + 1);currentcost -= Graph[x[i - 1]][x[i]];Swap(x[i], x[j]);}}}}void OutPut(){cout << "路线为:" << endl;for(int i = 1; i <= citynum; ++i)cout << bestx[i] << "";cout << "1" << endl;}int main(){InPut();Initilize();BackTrack(2);OutPut();}View Code测试样例:实现结果:参考:王晓东《算法设计与分析》。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1
4
2
说明
而τ=(1,3,5)(2,4)就不能表示一个旅游,它表示
3 1 5
2
3
表示
TSP可以表示为 min ∑ ciφ (i ) = c(φ ) ,其中φ为不可分解的所有n阶圈置换,
φ
n
φ(i)表示访问城市i后紧接着访问的城市.
i =1
1, 售货商访问城市i之后紧接着访问城市j; xij = 否则 0,
旅行售货商问题和斯坦纳最小树问题
旅行售货商问题
一个售货商想去几个城市推销商品,他希望从公司所在城市出发后, 在其旅途中恰好路过他所要去的每个城市一次,最后返回出发地.假 设他已知每对城市间的距离,问如何安排旅行路线,所走的路线总长 度最短,这就是旅行售货商问题(Travellin Salesman Problem , TSP).也称货郎担问题.
∑ (c π
i =0
n
i (i )
+ piπ (i ) ) = ∑ ciπ (i ) + ∑ piπ ( i )
i =0 i =0
n
n
实际问题
例子:现有一卷有图案的墙纸,墙纸上的图案以一定的周期重复出现, 不妨设周期为1,先要从这卷墙纸上切割下n片,设第i片纸需从图案的si 初开始,f i处结束,中间含li个重复的图案 0 ≤ si , f i ≤ 1 ,因此若从卷 纸上先割下第i片后再去割第j片,浪费的量为
�
Lawler算法
1. 计算最短路.如果网络中每条边的边长不满足三角不等式,则计 算所有顶点对之间的最短路及路长,用最短路长代替原来的边长, 产生一个完全网络. 2. 3. 求最小支撑树.对每个点集N V P, | N |≤ n 2 ,构造出 P ∪ N 的最小支撑树. 构造最小斯坦纳最小树.求出2中得到的所有树中的最小树,然后 将该树中的每条边还原成最短路中的边,从而还原成原来网络中的 一个树.
MST算法
1. 2. 对P中任何一对顶点,求出它的最短路; 构造一个一个以P为顶点集的完全图Gs,定义每条边的长为相应 顶点在G中的最短路长; 3. 求Gs的最小支撑树Tmin 4. 将Tmin中每条边还原成G中最短路的边,从而得到G中的一个连接 P的一个斯坦纳树.
作业
P153:4;
P165:7
19 27 0 23 18 25 0 12 8 16 9 8 0 0 3 7 6 2 0 0 0 4 4 9 18 18 18 18 0 17 0 0 0 0 0 3
18 23 9 6 6 {0} 4 7 18 18 {0} 15 0 {0} 0 1
19 27 0 23 18 23 0 12 8 16 9 6 0 0 3 7 6 0 0 0 0 4 4 7 18 18 18 18 0 15 0 0 0 0 0 1
min ∑∑ cij xij
i =1 j =1
n
n
s.t.∑ xij = 1, i = 1,2,...n; ∑ xij = 1, j = 1,2,..., n
j =1 j =1
n
n
xij = 0或1, i, j = 1,2,..., n, 且不含子旅游
实际问题
例子:现需在一台机器上加工n个零件,这些零件可按任意先后顺序在 机器上加工,我们希望加工完成所有零件总时间尽可能少.由于加工工 艺的要求,加工零件j时机器必须处于相应状态sj.设起始未加工任何零 件时机器处于状态s0,且当所有零件加工完成后续恢复到s0状态.一直 从状态si调整到状态sj需要时间cij,零件j本身加工时间为pj.为方便起 见,引入一个虚零件,其加工时间为p0=0,要求状态为s0工顺序,在此置换下,完成 所有加工所需要的总时间为
19 {0} 0 0 18 0
27 {0} 23 12 8 16 0 3 7 {0} 0 4 18 0
2 5 0 1 7 {20} 3 8 16 9 8 0 {0} 12 0 0 0 3 7 6 {2} C = 0 0 {0} 0 4 4 9 0 0 0 0 0 {18} 1 0 0 0 0 {0} 0 3 0 0 0 0 0 0 0
斯坦纳最小树
2
4
长度分别为8, 和 4 2 3 + 4 × 2 3 = 4 + 2 3
3 3
定义
给定欧氏平面上的点集P,如何设法添加新点集N,使关于P∪N的最小支 撑树为连接P中的点的最短网络:斯坦纳最小树问题. P中的点成为正则点或者原点;N中的点成为斯坦纳点或者斯点.
三角不等式:AB≤AC+CB
最小支撑树算法MST
1. 求网络的最小支撑树; 2. 从一个度为1的城市出发,沿每条边来回走一次,经过每个城市并, 回到出发点. 3. 按"抄近路"原则,使得除起点外,每个城市仅经过一次.
Christofides算法
1. 求出连接n个城市的最小支撑树T; 2. 找出T中度数为奇数的顶点,求出这些奇度点所组成的完全网络的 最小权完美匹配M,将M加入T,得到一个包含所有顶点的图; 3. 利用抄近路原则得到一个旅游;
s j fi , cij = 1 + s j fi , 如果f i ≤ si 否则
, 假设切割开始时,这卷墙纸起始位置为s0=0,且切割完成所需的n片纸后 也必须再切一次使剩下的墙纸起始位置仍未s0=f0=0.为此引入一个虚片, 它的起始位置和结束位置分别为s0,f0,则设计一个切割顺序使总浪费量 最小的问题就转化为n+1个城市的旅行售货商问题.
TSP问题是要求经过图中每个点一次,有一种问题是要求经过每条 边一次,称为中国邮路问题.
说明
记售货商要访问的城市为1,2,…,n,城市i与j之间的距离为cij,每一条旅 行路线称为一个旅游,它可用一个置换Φ表示.一个置换表示一个旅游 当且仅当该置换不能分解称两个因子的乘积,称这种置换为圈置换.圈 置换Φ=(1,3,5,4,2)表示从1出发如下一个旅游:
2
例子
0 0 0 C0 0 0 0 1 7 0 12 0 0 0 0 0 0 0 0 0 0 20 8 3 0 0 0 0 3 16 7 4 0 0 0 2 9 6 4 18 0 0 9 1 3 0 5 8 2
1 7 20 3 2 5 0 12 8 16 9 8 0 0 3 7 6 2 0 4 4 9 0 0 0 0 0 0 18 1 0 0 0 0 0 3
n
引理:设C是上三角阵,Φ满足Φ(n)=1的最优指派,则最优旅游τ的总 长度等于 c (Φ ) ,且τ可从Φ中构造出来.
算法
1 从C中删去第i列第n行,得到 (n 1) × (n 1) 矩阵 C ' ,然后求 C ' 的最优指派. 如果最优指派中不含子旅游则结束; 否则,取子旅游数目为s≥2,删掉最优指派中的反向弧(n,1),以及 s≥2, (n,1) 每个子旅游中的反向弧;则得到一些路,其中一条必为由1到n的; 设其它的路分别为j1到i1,j2到i2,…..,js-1到is-1,且j1 >j2>…>js-1,添加弧 (n,j1)(i1,j2)(i2,j3)….(is-2,js-1),(is-1,1).算法结束
易解的旅行售货商问题
1. C = (cij ) n× n 为上三角阵; 2. 金字塔形旅游
指派问题可以看成松弛的TSP问题,我们在解决上三角阵的情况时主要 使用指派问题的算法.
C为上三角阵的情况
引理:设C是上三角矩阵,Φ满足Φ(n)=1的最优指派,则 c(Φ ) = ∑ ciΦ (i ) i =1 为最有旅游总长度的下界.
正权网络中的斯坦纳最小树
给定无向网络 G = (V , E , ω ), P V , | P |= n, | V | | P |= s 网络上每条边权值为正.在允许使用V-P中的点的情况下,如何连接P 中的点成一个树,使总长度尽可能小.
P中的点称为正则点,原点,V-P中的点为斯坦纳的点,斯点.
最优指派为 1 → 4 → 3 → 7 → 1,2 → 2,5 → 6 → 5
1
2
3
4
5
6
7
1
2
3
4
5
6
7
最近邻域算法NN
1. 任选一个城市i1,构造一个仅含此城市的部分旅游(i1). 2. 设当前部分旅游为(i1,i2,…,ik),k<n; 若ik+1是不在当前部分旅游中的 所有城市里离ik最近的城市,则将ik+1加入原部分旅游中,那么得 到了新的部分旅游(i1,i2,…,ik+1). 3. 如果当前部分旅游已含有所有城市,则停止,否则,转2.