動態規劃迷思

動態規劃中遞推式的求解方法不是動態規劃的本質。


  1. 動態規劃的本質,是對問題狀態的定義狀態轉移方程的定義
    引自維基百科

dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems.
動態規劃是通過拆分問題,定義問題狀態和狀態之間的關係,使得問題能夠以遞推(或者說分治)的方式去解決。
本題下的其他答案,大多都是在說遞推的求解方法,但如何拆分問題,纔是動態規劃的核心。
拆分問題,靠的就是狀態的定義狀態轉移方程的定義
1. 什麼是狀態的定義?
**
首先想說大家千萬不要被下面的數學式嚇到,這裏只涉及到了函數相關的知識。**
我們先來看一個動態規劃的教學必備題:
給定一個數列,長度爲N,
求這個數列的最長上升(遞增)子數列(LIS)的長度.

1 7 2 8 3 4
爲例。
這個數列的最長遞增子數列是 1 2 3 4,長度爲4;
次長的長度爲3, 包括 1 7 8; 1 2 3 等.

要解決這個問題,我們首先要定義這個問題和這個問題的子問題。
有人可能會問了,題目都已經在這了,我們還需定義這個問題嗎?需要,原因就是這個問題在字面上看,找不出子問題,而沒有子問題,這個題目就沒辦法解決。
所以我們來重新定義這個問題:

給定一個數列,長度爲N,
F_{k}爲:以數列中第k項結尾的最長遞增子序列的長度.
F_{1}..F_{N} 中的最大值.

顯然,這個新問題與原問題等價。
而對於F_{k}來講,F_{1} .. F_{k-1}都是F_{k}的子問題:因爲以第k項結尾的最長遞增子序列(下稱LIS),包含着以第1..k-1中某項結尾的LIS。

上述的新問題F_{k}也可以叫做狀態,定義中的“F_{k}爲數列中第k項結尾的LIS的長度”,就叫做對狀態的定義。
之所以把F_{k}做“狀態”而不是“問題” ,一是因爲避免跟原問題中“問題”混淆,二是因爲這個新問題是數學化定義的。

對狀態的定義只有一種嗎?當然不是
我們甚至可以二維的,以完全不同的視角定義這個問題:

給定一個數列,長度爲N,
F_{i, k}爲:
在前i項中的,長度爲k的最長遞增子序列中,最後一位的最小值. 1\leq k\leq N.
若在前i項中,不存在長度爲k的最長遞增子序列,則F_{i, k}爲正無窮.
求最大的x,使得F_{N,x}不爲正無窮。

這個新定義與原問題的等價性也不難證明,請讀者體會一下。
上述的F_{i, k}就是狀態,定義中的“F_{i, k}爲:在前i項中,長度爲k的最長遞增子序列中,最後一位的最小值”就是對狀態的定義。


  1. 什麼是狀態轉移方程
    上述狀態定義好之後,狀態和狀態之間的關係式,就叫做狀態轉移方程。
    比如,對於LIS問題,我們的第一種定義:

F_{k}爲:以數列中第k項結尾的最長遞增子序列的長度.設A爲題中數列,狀態轉移方程爲:
F_{1} = 1 (根據狀態定義導出邊界情況)
F_{k}=max(F_{i}+1 | A_{k}A_{i}, i\in (1..k-1)) ” eeimg=”1”>(k1)” eeimg=”1”>
用文字解釋一下是:
以第k項結尾的LIS的長度是:保證第i項比第k項小的情況下,以第i項結尾的LIS長度加一的最大值,取遍i的所有值(i小於k)。
第二種定義:
F_{i, k}爲:在數列前i項中,長度爲k的遞增子序列中,最後一位的最小值設A爲題中數列,狀態轉移方程爲:
A_{i}F_{i-1,k-1}” eeimg=”1”>則F_{i,k}=min(A_{i},F_{i-1,k})
否則:F_{i,k}=F_{i-1,k}

(邊界情況需要分類討論較多,在此不列出,需要根據狀態定義導出邊界情況。)
大家套着定義讀一下公式就可以了,應該不難理解,就是有點繞。

這裏可以看出,這裏的狀態轉移方程,就是定義了問題和子問題之間的關係。
可以看出,狀態轉移方程就是帶有條件的遞推式。

3. 動態規劃迷思
本題下其他用戶的回答跟動態規劃都有或多或少的聯繫,我也講一下與本答案的聯繫。

a. “緩存”,“重疊子問題”,“記憶化”:
這三個名詞,都是在闡述遞推式求解的技巧。以Fibonacci數列爲例,計算第100項的時候,需要計算第99項和98項;在計算第101項的時候,需要第100項和第99項,這時候你還需要重新計算第99項嗎?不需要,你只需要在第一次計算的時候把它記下來就可以了。
上述的需要再次計算的“第99項”,就叫“重疊子問題”。如果沒有計算過,就按照遞推式計算,如果計算過,直接使用,就像“緩存”一樣,這種方法,叫做“記憶化”,這是遞推式求解的技巧。這種技巧,通俗的說叫“花費空間來節省時間”。都不是動態規劃的本質,*不是動態規劃的核心。*

b. “遞歸”:
遞歸是遞推式求解的方法,連技巧都算不上。

c. “無後效性”,“最優子結構”:
上述的狀態轉移方程中,等式右邊不會用到下標大於左邊i或者k的值,這是”無後效性”的通俗上的數學定義,符合這種定義的狀態定義,我們可以說它具有“最優子結構”的性質,在動態規劃中我們要做的,就是找到這種“最優子結構”。
在對狀態和狀態轉移方程的定義過程中,滿足“最優子結構”是一個隱含的條件(否則根本定義不出來)。對狀態和“最優子結構”的關係的進一步解釋,什麼是動態規劃?動態規劃的意義是什麼? - 王勐的回答 寫的很好,大家可以去讀一下。

需要注意的是,一個問題可能有多種不同的狀態定義和狀態轉移方程定義,存在一個有後效性的定義,不代表該問題不適用動態規劃
動態規劃方法要尋找符合“最優子結構“的狀態和狀態轉移方程的定義在找到之後,這個問題就可以以“記憶化地求解遞推式”的方法來解決。而尋找到的定義,纔是動態規劃的本質。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章