動態規劃初步學習及理解

前言

最近又看到一篇文章,說到算法對前端的重要性,遂抽出時間(玩的時間),逼着本身看一些相關的知識,當看到動態規劃相關文獻時,也勾起了很大的興趣,學習各位大神的博客,有了初步理解,藉此記載,可能比較淺顯,對於一樣初學相關知識的同窗,或許會有幫助,若有問題,望大神指出前端

正文

學習的最好方法即是帶着問題學習,因此首先先採用網上廣泛的、對理解動態規劃很友好的一個問題做爲學習切入點,問題解決後再總結概括算法

問題:

如今有10級臺階,每次只能上1級或2級臺階,問:到達10級臺階的方法有多少?學習

解析:

首先按照正常邏輯,看到這個問題或許會懵,由於狀況太多無從下手,可是最優解每每須要更改思考方式優化

  1. 這裏能夠從結果考慮,最後咱們踩在第10級臺階上,因爲每次只能上1 或 2級臺階,因此上一步,我門應該在第9級臺階,或第8級臺階;
  2. 基於1的結論,從0 到 9 級臺階有多少種方法,對應的從9 到 10級臺階就有多少種方法(這裏須要理解下),同理從0 到 8級臺階的方法總數等於從8 到 10級臺階的方法總數,可得從0 到 10級臺階的方法總數(如下簡稱methods(10))等於 從0 到 9級臺階的方法總數 加 從0 到 8級臺階的方法總數,即methods(10) = methods(9) + methods(8);這裏的methods(9) 和 methods(8)就是methods(10)的最優子結構(思惟導圖有點大,只展現一部分)clipboard.png
  3. 從第2點我門已經發現了問題的解決邏輯和一點思路,按照第2點的思路,咱們將以二叉樹的形式將問題分裂成「無數」的子問題,直到分裂成 methods(2) 和 methods(1)時,methods(2)(從0 到 2級臺階的方法數)等於2,而methods(1)等於1,這裏的methods(2) 和 methods(1)也就是動態規劃裏邊界
  4. 由3的結論,咱們只須要將全部子問題的解相加即是問題結果,這裏將思路轉爲代碼,經過遞歸實現, methods(n) = methods(n - 1) + methods(n - 2),methods(n - 1) = ......,以此類推
function methods(n) {

    if (n == 1) return 1
    
    if (n == 2) return 2
    
    console.log('計算')
    
    return methods(n - 1) + methods(n - 2)
  }

  console.log(methods(10)); // 89

問題到這看似已經解決了,可是我想同窗在思惟導圖中應該也發現了,不少子問題是重複的,可是上面代碼卻作了不少重複工做,很浪費 冗餘(以下圖),咱們但願已經計算過的就不要在重複計算spa

clipboard.png

因此優化下, 保存計算過的結果:code

var resultList = [] // 保存計算過的結果,以計算的臺階數作索引下標

  function methods(n) {

    if (n == 1) return 1
    if (n == 2) return 2
    if (!resultList[n]) { // 沒有就保存
      console.log('計算', n)
      resultList[n] = methods(n - 1) + methods(n - 2)
    }
    return resultList[num]
  }

clipboard.png

這樣看,就節省了不少計算,臺階總數越大,越明顯
而後我們再精簡下代碼:遞歸

var resultList = [0, 1, 2]; // 對於本題的結果預存了,方便點

  function fnSumF(n) {
  
    if (!resultList[n]) resultList[n] = fnSumF(n - 1) + fnSumF(n - 2);
  
    return resultList[n]
  }

總結

動態規劃的英文名是Dynamic Programming,是一種分階段求解決策問題的數學思想;與分治方法相似,都是經過組合子問題的解來來求解原問題的。再來了解一下什麼是分治方法,以及這二者之間的差異,分治方法將問題劃分爲互不相交的子問題,遞歸的求解子問題,再將它們的解組合起來,求出原問題的解。而動態規劃與之相反,動態規劃應用與子問題重疊的狀況,即不一樣的子問題具備公共的子子問題(子問題的求解是遞歸進行的,將其劃分爲更小的子子問題)。在這種狀況下,分治方法會作許多沒必要要的工做,他會反覆求解那些公共子子問題。而動態規劃對於每個子子問題只求解一次,將其解保存在一個表格裏面,從而無需每次求解一個子子問題時都從新計算,避免了沒必要要的計算工做。索引

其實關於和分治的區別,在咱們解決問題優化時已經能夠看出ip

初學的淺層理解,若有問題但願你們指出,指點,若是問題或者好文章,也但願能夠評論推薦博客

學的越多,才發現本身懂得越少

相關文章
相關標籤/搜索