双调欧几里得旅行家问题

内容提要:

问题背景
问题分析
问题解决
复杂分析
附录代码

问题背景:
欧几里得旅行商问题是对平面给定的 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 )







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值