dynamic programming动态规划实例之【1】Longest path in DAG

对于理论性比较强的学科、自己看书就可以没问题了、多看几遍也能理解了,比如说计算机网络这门课程

然而有的东西并不是多看几遍就能掌握的,如果自学的话就需要一些能让自己入门的实例,

从简单到稍微复杂、弄清楚了后也就能逐步掌握

不说废话、先来一个简单的例子吧:

longest path in DAG

Problem: 
Given a weighted directed acyclic graph  G=(V, E),  an vertex v,  where each edge is assigned an integer weight,  find a longest path in graph G

问题描述:

给一个带权有向无环图G=(V,E),找出这个图里的最长路径。

说实话初学者直接给出这个图会看蒙的、再看看问题,不知道从何下手。

好了,对上图做个简单的处理:

现在看起来是不是清晰多了呢

用dilg(v)表示 以点结尾的最长路径,现在考虑dilg(D), dilg(B), dilg(C)

dilg(D)=max{dilg(B)+1, dilg(C)+3}

来解释一下:点D的入度边有CD、BD。

以D结尾的最短路径必定经过C、D中的最后一点;如果是C点,则以dilg(C)+3(权值)定会大于等于dilg(D)+2(权值)

如果没能看懂,请注意dilg(V)的定义

对于任意的点V可以有如下表达式:
      dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)}

这样、问题dilg(V)就会被转化为较小的子问题dilg(U)(当然,U是连入V的点)

任何一个问题都可以用这样的方式转化、变小。

但总不能无限变小啊,最后回成为最简单的问题。当有两个点,且其中的一个点入度为0的时候如图中的S-->C他们的最长距离就是

权值2。入门篇中说过,思考方向是从复杂到简单,而计算方向是从简单到复杂。

算法如下

Initialize all dilg(.) values to ∞;
1.Let S be the set of vertices with indegree=0;                       设集合S,里面的是入度为0的点
2.For each vertex v in S do            
     dilg(v)=0;
3. For each v∈V\S in Topological Sorting order do    //对于V中除S外的点、按照拓扑排序的顺序,依次求出最长路径并保存好
       dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)}        //拓扑排序可以简单的理解为从起点到终点的最短路径
4. Return the dilg(.) with maximum value.

现在是找到最长路径的大小了、但是如何得到最长路径呢?
只需做点小小的改动:

Dplongestpath(G)
Initialize all dilg(.) values to ∞;
Let S be the set of vertices with indegree=0;
for each vertex v in S do
     dist(v)=0;
4. For each v∈V\S in Topological Sorting order do
       dilg(v)=max(u,v)∈E{dilg(u)+w(u, v)}
     let (u,v) be the edge to get the maximum     
     value;
     dad(v)=u;
5. Return the dilg(.) with maximum value.

 每一步都记下V的父节点、最后根据dad()数组即可得到路径。

 

对于上面的问题:先找出子问题、然后解决由子问题如何得到父问题以及如何把子问题分为更小的子问题

注意:问题的本质没有改变,只是规模变小。

我的理解:

动态规划的目的正是在不改变问题本质的情况下不断缩小子问题的规模、规模很小的时候,也就能很容易得到解啦(正如上面的只有两个点的情况)

上图可以这样理解:

问题A5被分成了子问题A3、A4解决它们就能解决A5,由于A3、A4和A5有相同的结构(问题的本质没变)所以A3可以分为问题A1、A2。当然A4也能

分为两个子问题,只是图中没画出来。

下面的是再网上看到的不错的思路: 

Dynamic programming:
(1)problem is solved by identifying a collection of    
    subproblems, 
(2) tackling them one by one, smallest rst,
(3) using the answers of small problems to help  
     figure out larger ones, 
(4) until the whole lot of them is solved.

 

第一次觉得要讲清楚一件事还挺不容易的O(∩_∩)O~大半个晚上才搞定得。。。汗!

有不得当的地方希望高手指正呀!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值