動態規劃--切鋼筋問題

 鋼條切割問題:

       某公司購買長鋼條,將其切割爲短鋼條出售。切割工序本身沒有成本支出。公司管理層希望知道最佳的切割方案。假設我們知道該公司出售一段長度爲i英寸的鋼條的價格爲Pi(i=1,2,3,....)鋼條的長度均爲整數。下面給出一個價格表的樣例

長度i     1 2 3 4 5 6 7 8 9  10      價格Pi 1 5 8 9 10 17 17 20 24  30

       首先,我們分析這個問題。其目的很簡單,就是要求給你一根長鋼條,讓你切割不同的長度,然後出售,但是前提是要獲取最大的利潤。

 

爲了找出他的規律,或者說是爲了體會一下這個分割求解的過程。

我們假設我們獲取到了一根4米長的長鋼條。

對有這個4米長的長鋼條來說,我們一共有8種分割方式:

第一種:就是不分割,如果分割都可以獲取最大的利潤,我爲什麼要分割呢?對於這種情況,我們的收益是9美元

第二種:分割爲1米和3米。從圖表中我們可以得到,我們的收益是1+8 = 9美元

第三種:分割爲2米和2米。從圖表中我們可以得到,我們的收益是5+5 = 10美元

第四種:分割爲3米和1米。從圖表中我們可以得到,我們的收益是8+1 = 9美元

第五種:分割爲1米、1米和2米。從圖表中我們可以得到,我們的收益是1+1+5 = 7美元

第六種:分割爲1米、2米和1米。從圖表中我們可以得到,我們的收益是1+5+1 = 7美元

第七種:分割爲2米、1米和1米。從圖表中我們可以得到,我們的收益是5+1+1 = 7美元

第八種:分割爲1米、1米、1米、1米。從圖表中我們可以得到,我們的收益是1+1+1+1 = 4美元

綜上所述:我們可以得出在長鋼條爲4米的情況下,其最大收益爲10美元。

 

下面我們開始分析這個過程:

首先我們要清楚一個事實,就是對於一個長爲n米的長鋼條,有多少種組合的可能?還有對於長度爲4米的長鋼條能被分爲8次這個是怎麼計算的呢?

下面我們開始推斷出這個公式:

 對於一個長度爲n的長鋼條不切割時:只有1種  (9和0)

切割1次時有Cn1 = n種

切割2次時有Cn2 = n(n-1)/2種

。。。

切割n次時有Cnn = 1種

於是我們就得出這麼一個公式,一個長度爲n的長鋼條,可以被分割爲Cn1 +  Cn2 + Cnn = 2^n-1

所有對於n=4時,分割的次數爲2^3 = 8

 

在明白這個的基礎下,我們繼續下面的分析。

我們可以假設,在鋼條被切割爲k段時,有最優解,其中(1<=k<=n)

所以可以得到最優解分割方案爲:n = i1+i2+i3+...+ik;

所有同樣可以得到最大收益爲: rn = Pi1+Pi2+...Pik;

 

對於rn,我們可以用更短的鋼條的最優切割收益來描述它:

rn = max(Pn,r1+rn-1,r2+rn-2,...,rn-1+r1)

對於這個式子,我需要做一些解釋,如果對於這個式子有什麼不瞭解的,不用擔心,因爲這或許就是動態規劃原理的核心部分。

這句話是什麼意思呢?

我們可以這樣理解:對於一根4米的長鋼條。我們可以用1和3的最優解表示,或者2和2的最優解表示,還有用不分割的情況下4和0的最優解表示。

每一根鋼條,我們都分割兩短,例如一根鋼條爲9米,我們可以把他分割爲4,5米。只需要知道4米時的最優解和5米時的最優解,我們就可以知道當9米被分割爲4米和5米的時的最優解了。但是此時我們並不能保證,這個4,5分割一定是最優方案,所以我們同樣要進行其他的方案分割。同時還要獲取其他的方案情況下的最優解。最終。我們可以知道,對於本問題的最優解,一定產生於這些最優子問題的最優解之中。

Pn:代表不分割的情況下

r1+rn-1:代表分割成1,n-1的情況下的最優解

。。。

rn-1+r1:代表分割爲n-1,1的情況下的最優解

最終只需獲取這些最優解的最大值,必然就爲本問題的最優解了。對於這些子問題的最優解,有一個專用術語:最優子結構。   

如果我們用暴力法求解這個遞歸式的話。我們經過簡單的計算可以知道,這個時間複雜度爲:T(n) = 1+T(1)+T(2)+...T(n-1) = 2^n

對於一個指數級別的算法來說,這簡直可以說是一個很糟糕的算法,我想這也沒有任何的利用價值。

 

不過還好,我們有動態規劃,該算法可以很輕鬆的解決這個指數級別的問題。可以將其複雜程度降至n^2

 

首先。我們分析,爲什麼暴力法會有這麼糟糕的效率呢?

我們舉例說明:

如果對於一個8米長的長鋼條可以分解爲 1+7  2+6  3+5  4+4

所以在之前必須要計算出1,2,3,4,5,6,7時所對應的最優解

對於一根長爲9米的長鋼條可以分解爲1+8  2+7  3+6  4+5

所以在之前必須要計算出1,2,3,4,5,6,7,8時所對應的最優解

 

如果我要給你一個9米的長鋼條:

你需要計算1,2,3,4,5,6,7,8 時的最優解

在遞歸時計算8的最優解時,你有要必須計算1,2,3,4,5,6,7時的最優解

。。。

你重複計算了太多的選項,

此時如果你從1開始,

計算了1的最優解,並用一個數組保存起來啊a[1]

然後計算2的最優解,有組合(2,0)  (1,1)

對於組合(2,0)     直接讀取價格表就好了

對於組合(1,1)    直接從數組a中讀取就可以得出1時的最優解了,因爲我們已經保存在了數組中a[1] 

將此時計算的2的最優解,保存在數組中a[2]...以此向上。最終所有的當前問題的最優解都可以通過之前的計算結果獲取(最優子結構數組),在這種算法條件下,我們最大可能減少了計算量,並且最大可能的利用了我們的計算結果,所以可以大大的降低的計算,提高的效率,這就是動態規劃的厲害之處。

int Best_Value(int p[],int n){
	int a[100];//初始化一個數組,其目的就是爲了保存子結構的最優解
	int i,j;
	int temp;
	a[0] = 0;
	for(i = 1 ; i <= n ; i++) {
		temp = -1;
		for(j = 0 ; j < i ; j++) {
			if(temp < a[j]+p[i-j-1]) {
				temp = a[j]+p[i-j-1];
			}
		}
		a[i] = temp;
	}
     return a[n];
}

 

發佈了50 篇原創文章 · 獲贊 13 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章