1. 程式人生 > >演算法初識_動態規劃

演算法初識_動態規劃

      最近做題用到動態規劃,去B站看到燈哥視訊,從實戰出發講解很是清楚,連線地址第一講第二講,本文結合相關理論和視訊學習總結如下。

1.動態規劃是什麼

    是求解最優解的一個策略,將大問題分成同質的小問題,可以是求得最大,最小,或判斷是否有解……。

2.分類

    一般可分為線性動規,區域動規,樹形動規,揹包動規四類。

3.為什麼動態規劃是具有重疊子結構的問題

     從斐波那契數列和一個動態規劃問題的例子談起。


      從圖中可以看出,動態規劃也可以用遞迴來分析,存在重疊子問題,但是動態規劃不推崇使用,可以避免重複計算。

4. 用例項重新認識動態規劃

(1)給出一組數1,2,4,1,7,8,3,選出一組資料,要求其和最大,且被選資料不能相鄰

分析:假設有陣列arr=[1,2,4,1,7,8,3]

0123456
1241783

        動態規劃問題都可以理解為選或不選問題。

        1)假設對arr[6]進行選取判斷,則會有兩種結果

               選:maxsum += arr[6]+opt[6-2]   #opt表示選取的最優解

               不選:maxsum += arr[6-1]

       ……

       2)按照上述對第i個元素進行操作時結果如下:

               選:maxsum += arr[i]+opt[i-2]   #opt表示選取的最優解

               不選:maxsum += arr[i-1]

       3)結束條件:

               假設只有一個元素,則maxsum = arr[0]

               假設包含兩個元素,則maxsum = max(arr[0],arr[1])

       4)程式碼如下:

import numpy as np

arr = [1,2,4,1,7,8,3]

def rec_opt(arr,i):  #遞迴解法
    if i == 0:
        return arr[0]
    elif i==1:
        return max(arr[0],arr[1])
    else:
        A = rec_opt(arr,i-2)+arr[i]
        B = rec_opt(arr,i-1)
        return max(A,B)

def dp_opt(arr):   #非遞迴解法
    opt = np.zeros(len(arr))
    opt[0] = arr[0]
    opt[1] = max(arr[0],arr[1])
    for i in range(2,len(arr)):
        A = opt[i-2]+arr[i]
        B = opt[i-1]
        opt[i] = max(A,B) 
    return opt[len(arr)-1]
dp_opt(arr)

(2)一組資料3,34,4,12,5,2,問是否可以通過若干個數相加獲得9

       1)假設對arr[6]進行選取判斷,則會有兩種結果

               選:maxsum += arr[6]+opt[6-2]   #opt表示選取的最優解

               不選:maxsum += arr[6-1]

       ……

       2)按照上述對第i個元素進行操作時結果如下:

               選:maxsum += arr[i]+opt[i-2]   #opt表示選取的最優解

               不選:maxsum += arr[i-1]

       3)結束條件:

               假設只有一個元素,則maxsum = arr[0]

               假設包含兩個元素,則maxsum = max(arr[0],arr[1])