1. 程式人生 > >動態規劃原理講解(上)

動態規劃原理講解(上)

版權宣告:本文為博主原創文章,歡迎大家轉載,但是要註明我的文章地址。 https://blog.csdn.net/xyk_hust/article/details/83933341

大家好,歡迎大家閱讀動態規劃部分。由於本人水平有限,文中錯誤之處還請大家批評指正。

動態規劃分為兩個部分進行講解,第一部分是原理講解,第二部分是進行例項分析。

1.1 預備知識:斐波那契數列(Fibonacci Sequence)

例如:arr[1,1,2,3,5,8,13,...]該數列就是斐波那契數列,即第三項是由第二項與第一項的和求得。

公式如下fib(n)=fib(n-1)+fib(n-2)

動態規劃問題與該數列的聯絡就在於,都是求解重疊序列子問題(overlap sub-problem)。

完整的斐波那契數列遞推式:

比如我們計算fib(6)的值,下面是利用計算機計算的過程原理:可以將fib(6)分為fib(5)+fib(6),依次進行遞迴分解。。。

如果進行fib(7)的計算,則需重新計算fib(5),這棵樹的規模就會是之前的兩倍之多。計算的數字每增加1,演算法的複雜度都會達到O(2^{n}),但實際上我們並不需要把整棵樹全部展開,比如fib(5)這個節點沒必要展開,只需要將之前計算的fib(5)保留一份,下次直接呼叫即可。

優點:加快運算速度。

計算fib(6),其與fib(5)和fib(4)有關。以此類推。。。

1.2 動態規劃問題引入

一個人一共有8個任務可選,圖中為灰色長條。任務獎勵為紅色數字,橫軸代表每個任務的時間段(比如值班任務)。比如,第一個任務是從1點到4點,第二個任務是從3點到5點。。。

最終目標:賺最多的獎勵。

限制:比如做第5個任務,則另外的任務只能選擇8,也就是說任務之間在時間範圍上不能有衝突。

採用動態規劃的方法來解決這個問題思路: 

方法:選和不選

設定:OPT\left ( i \right )代表最優解,當考慮第i個任務時的最優解。當我考慮第i個任務時,選和不選產生的效果。

考慮第8個任務:選了第8個則不能夠選第6個和第7個任務,最好只能選到第5個。不選第8個則考慮前面7個最好的結果。然後在選和不選中選擇一個最好的。

重新整理公式:

prev \left(i \right )是選擇第i個任務之後,前面可以做的任務。比如,prev \left(8 \right )=5prev \left(7 \right )=3prev \left(6 \right )=2prev \left(2 \right )=0

動態規劃展開圖:

需要事先將prev算出來。

 

全域性最優解為:

不斷進行分解:

  • 只考慮前兩個任務,最多隻能獲得2塊錢。

  • 考慮前3個任務:最多能賺8塊錢

  • 考慮前4個任務:最多能賺9塊錢

  • 最終得到:8個任務中最多可以獲得13元。

 

過程:考慮第8個任務時,選擇1,4,8任務。第8 個是從第5個匯出,第5個選擇1,4。最後選擇第1,4,8任務。

最終完成問題求解。

參考視訊:https://www.bilibili.com/video/av16544031/?spm_id_from=333.788.videocard.0,非常感謝視訊作者的精彩視訊。