内容提要:
•问题背景
•问题分析
•问题解决
•复杂分析
•附录代码
问题背景:
•
欧几里得旅行商问题是对平面给定的
n
个点确定一条连接各点的最短闭合路径旅程的问题。这个问题的一般形式是
NP
完全的,故其解需要
多
于
多项式
(
n^k
)
的时间。
•
J. L. Bentley
建议通过只考虑双调旅程来简化问题,这种旅程即为从左点开始,严格地从左到右直至最右点,然后严格地从右直至出发点。
分析准备:
•
排序
将点按
x
坐标使用快速排序
(
O(n
log
n
))
表示为
p1p2
…
pj
•
最优子结构
–
最短路径问题具有最优子结构:假设节点
u ≠ v
,这样任何从
u
到
v
的路径
p
必定包含一个中间顶点,譬如
w
。
(w
可以是
u
或
v)
–
于是,可以将
u
→p →v
分解为子路径
u
→p1→
w
→p2→
v
。显然,
p
上边的数目等于
p1
上边的数目加上
p2
上边的数目。如果
p
是从
u
到
v
最优路径,那么
p1
必定是从
u
到
w
的一条最短路径。(cut-and-paste)
•
最优子结构
–
首先定义路径
p(i,j)
(i <= j)
,对于路径
p(i,j)
来说,它包含的点为
p1p2
…
pj
。其中以
pi
点为起点,
p(i,j)
表示从
pi
点开始走,一直向左走到
p1
然后从
p1
沿不同的路径向右走直到
pj
。
–
其次,定义数组
d[
i,j
]
表示
p(i,j)
路径上的最短
Bitonic
路线
–
题目所求为
d[
n,n
]
–
cut-and-paste
可证得最优子结构
•
递归求解
–
只有一个
点没有意义,
d[1,1]
–
两
个点时
d[1,2]=|
p_1p_2
|
–
一般
地:
d[i,j]=(d[i,j-1]+|p(j-1)pj| i≤j
=min(1≤k<j-1){ d[k,j-1]+|pkpj| } i=j
=|p1p2| i=1
d[n,n] = d[n-1,n] + |p(n-1)pn|
•
计算一个
最优解
–
采用自底向上的
方法,在计算过程中需要保存两个值,一个
d[
i,j
]
的值,第二个是要记录
p(i,j)
中
pj
点的相邻链接点的下标,用数组
pre[
i
,j
]
表示
Bitonic-tour(p)
Quicksort{p1,p2,…pn} in order of increasing x-coordinate
d[1,2]←|p1p2|
for j←3 to n
do for i←1 to j-2
do d[i,j] ← d[i,j-1]+|pj-1pj|
pre[i,j]=j-1
d[j-1,j] ← ∞
for k←1 to j-2
do a←b[k,j-1]+|pkpj|
if a<d[j-1,j]
then d[j-1,j] ←a
pre[j-1,j] ←k
d[n,n]=d[n-1,n]+|pn-1pn|
return d and pre
•
构造一个序列
–
我们定义一个如下的输出
序列:
•
从最右侧的
pn
输出,依次从右至左输出至
p1
,然后从
p1
输出到
pn
。本题示例输出为
p7p6p4p3p1p2p5
Output-tour(p)
print pn
print pn-1
k←pre[n-1,n]
Print-tour(pre,k,n-1)
print pk
Print-tour(pre,i,j)
if i<j
then k←pre[i,j]
print pk
if k>1
then Print-tour(pre,i,k)
else k←pre[j,i]
if k>1
then Print-tour(pre,k,j)
print pk
时间复杂度分析:
•
QUICK-SORT : O(n
logn
)
•
EUCLIDEAN-TSP : O(
n^2
)
•
PRINT-TOUR : O(n)
•
•
BITONIC PATH : O(
n^2
)