簡單粗暴地理解動態規劃

2021-10-04 10:13:22 字數 1562 閱讀 1510

動態規劃可以說是做題時比較難以理解的演算法了,我之前也不是很理解,直到在隨機過程中學習了馬爾科夫過程後,再看動態規劃就覺得很簡單了。

本文只是幫助簡單粗暴的理解動態規劃,熟練地運用需要親自進行大量的習題練習。

一、動態規劃適合解決什麼樣的問題?

1、問題具有最優子結構

舉乙個直白易懂的例子:求你走路的時候邁三步能走出的最大距離。如果你想三步走過距離最大,那你每一步都應該很大,在這三步走的過程中,邁出兩步的距離也應該是最大的距離。這樣,三步最大的就有乙個子結構——兩步最大。

2、無後效性

仍用上面的例子:你走完第二步的時候,最大距離是2.5公尺,這個2.5公尺就包含了你前兩步的資訊了,就不用再管你第一步是怎麼走的了。

粗暴的說就是:當前面的結果知道了,我根本不關心得出這個結果的過程是啥。

如果這兩點還不夠簡單粗暴,那就記住求最值問題一般都能用動態規劃。

二、動態規劃的解題思路

動態規劃所處理的問題是乙個多階段決策問題,不斷的求區域性最優解,最終得到全域性最優。

可以分為四步:

1、問題分解成子問題:按照問題的時間或空間特徵,把全域性問題分為若干個區域性問題。在劃分階段時,注意劃分後的階段一定要是有序的或者是可排序的,否則問題就無法求解。

2、確定狀態和狀態變數:將問題發展到各個階段時所處於的各種客觀情況用不同的狀態表示出來。當然,狀態的選擇要滿足無後效性。

3、狀態轉移方程:因為決策和狀態轉移有著天然的聯絡,狀態轉移就是根據上一階段的狀態和決策來匯出本階段的狀態。

所以如果確定了決策,狀態轉移方程也就可寫出。但事實上常常是反過來做,根據相鄰兩個階段的狀態之間的關係來確定決策方法和狀態轉移方程。

4、尋找邊界條件:給出的狀態轉移方程是乙個遞推式,需要乙個遞推的終止條件或邊界條件。

三、動態規劃的關鍵步驟

動態規劃的主要難點在於理論上的設計,也就是上面4個步驟的確定,一旦設計完成,實現部分就會非常簡單。

使用動態規劃求解問題,最重要的就是確定動態規劃三要素:

(1)問題的階段

(2)每個階段的狀態

(3)從前乙個階段轉化到後乙個階段之間的遞推關係。

遞推關係是從次小的問題開始到較大的問題之間的轉化,從這個角度來說,動態規劃往往可以用遞迴程式來實現,不過因為遞推可以充分利用前面儲存的子問題的解來減少重複計算,所以對於大規模問題來說,有遞迴不可比擬的優勢,這也是動態規劃演算法的核心之處。

確定了動態規劃的這三要素,整個求解過程就可以用乙個最優決策表來描述,最優決策表是乙個二維表,其中行表示決策的階段,列表示問題狀態,**需要填寫的資料一般對應此問題的在某個階段某個狀態下的最優值(如最短路徑,最長公共子串行,最大價值等),填表的過程就是根據遞推關係,從1行1列開始,以行或者列優先的順序,依次填寫**,最後根據整個**的資料通過簡單的取捨或者運算求得問題的最優解。

f(n,m)=max

參考:

簡單粗暴理解匈牙利演算法

書本上的演算法往往講得非常複雜,我和我的朋友計畫用一些簡單通俗的例子來描述演算法的流程 匈牙利演算法是由匈牙利數學家edmonds於1965年提出,因而得名。匈牙利演算法是基於hall定理中充分性證明的思想,它是部圖匹配最常見的演算法,該演算法的核心就是尋找增廣路徑,它是一種用增廣路徑求二分圖最大匹...

C memset簡單粗暴的理解

memset函式本來是c語言中對char陣列的整體賦值函式。但是我們一般都是要用它來對int陣列或者其他型別的陣列進行整體初始化。具體操作如下 int array 10 memset array,0,sizeof array int array 10 memset array,1 sizeof ar...

如何簡單粗暴理解函式

一 初次見面,請多關照。計算列表內的元素個數。用程式設計去計算 li 1,2,3,4,5,6,6,5,4 count 0 for i in li count 1 print count 如果再計算字串的元素個數還得再寫一段同樣的 重複 較多。可讀性差。解決上述問題就需要 函式式程式設計 用函式去計算...