【算法复习二】货郎担(旅行售货商)动态规划

一,问题由来

       货郎担问题也叫旅行商问题,即TSP问题(Traveling Salesman Problem),是数学领域中著名问题之一。

    

二,问题描述

        1)货郎担问题提法:有n个城市,用1,2,…,n表示,城i,j之间的距离为dij,有一个货郎从城1出发到其他城市一次且仅一次,最后回到城市1,怎样选择行走路线使总路程最短? 

  

        2)旅行商问题的提法:假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路经的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。


三,问题求解

 

  1)动态规划解
  

    例题: v1v2……..vn是已知的n个城镇,城镇vi到城镇vj的距离为dij,现求从v1出发,经各城镇一次且仅一次返回v1的最短路程。

  

          分析:S表示从v1vi中间所可能经过的城市集合,S实际上是包含除v1vi两个点之外的其余点的集合,但S中的点的个数要随阶段数改变。

          建模:状态变量(iS表示:从v1点出发,经过S集合中所有点一次最后到达vi
                      最优指标函数fkiS为从v1出发,经过S集合中所有点一次最后到达vi
                      决策变量PkiS表示:从v1k个中间城镇的S集合到vi城镇的最短路线上邻接vi的前一个城镇,则动态规划的顺序递推关系为:

                          fkiS=   min{  fk-1jS{ j }+dji}        j属于S

                         f0i,空集)=d1i k=12…,n-1,i=2,3,…n)


          求解K=0

                             
f0(2,空集)=d12=6  
                             f0(3,空集)=d13=7
                             
f0(4,空集)=d14=9

                     k=1:
                              从城市V1出发,经过1个城镇到达Vi的最短距离为:

f
1(2,{ 3 }) = f0 (3,)+d 32 =7+8=15
f
1(2,{ 4 }) = f0 (4,)+d 42 =9+8=14
f
1(3,{ 2 }) = f0 (2,)+d 23 =6+9=15
f
1(3,{ 4 }) = f0 (4,)+d 43 =9+5=14
f
1(4,{ 2 }) = f0 (2,)+d 24 =6+7=13
f
1(4,{ 3 }) = f0 (3,)+d 34 =7+8=15


  当k=2,
    

      从城市V1出发,中间经过2个城镇到达Vi的最短距离.

f2(2,{ 3,4 }) = min[ f1(3,{4})+d32,   f1(4,{3})+ d42]
=min[14+8,15+5]=20
                
P2(2,{3,4})=4

f2(3,{ 2,4 })= min[14+9,13+5]=18
P2(3,{2,4})=4
          
f2(4,{ 2,3})= min[15+7,15+8]=22
P2(4,{2,3})=2

   当k=3:

从城市V1出发,中间经过3个城镇最终回到Vi的最短距离.

  f3(1,{ 2,3,4 })= min[f2(2,{ 3,4 }) + d 21,f2(3,{ 2,4})+ d31,f2(4,{ 2,3 }) + d41]=min[20+8,18+5,22+6]=23

   
P3(1,{2,3,4})=3


逆推回去,货郎的最短路线是1  2  4  3  1,最短距离为23.

四,源码


源码解析:核心是动态规划,自底向上的思想。

                    写法是递归写法,自顶向下递归调用。

                    第一次调用:起点0,第一个节点是1时候

                         {

                                       进入递归---->value = d01 +imin(3,1)

                                          {

                                                 进入递归-----value = d12 +imin(2,2)

                                           {

                                                进入递归---->value = d23 +imin(1,3)

                                                                   {

                                                                             进入递归---->return d30;

                                                                   } 

                                                        ……}

                                      ……}

                   ……}

                     

          

posted on 2012-05-04 15:25  小田的专栏  阅读(1211)  评论(1编辑  收藏  举报

导航