以區間調度爲例算法
有1,...,n次請求,去獲取單個資源,每一個請求的開始時間是s(i),結束時間是f(i), 對於請求i和j,若是兩者的區間不重合,即f(i)<=s(j) 或者 f(j)<=s(i),那麼這兩次請求認爲是兼容的。好比下面的兩個區間是兼容的優化
區間調度的問題是,如何才能獲取請求的兼容的區間最大的個數呢?.net
好比上圖是3個3d
可使用貪心算法。cdn
貪心算法的大體思路是:每次獲取問題的一小部分,決定對這小部分數據如何作處理,解決了這部分,再去處理其它的。blog
關鍵在於如何選取請求。能夠想象有一些方式資源
- 按照順序來,從這種狀況看,只能拿到第一個請求,不是最大的,不行
![]()
- 獲取時間區間最短的,有以下反例
![]()
- 計算每一個請求的不兼容的請求的數量,而後獲取最小的不兼容數量的,有以下反例,最少的不兼容的是紅色的區間
![]()
能夠選擇最先結束的請求做爲選擇的規則,這樣能得到最大的兼容區間的個數it
選擇最先結束的請求做爲選擇的規則,能得到最大的兼容區間的個數io
假設=1,只有1個區間,它是成立的。假設對於
也成立。
構造一個區間列表L,使得它的最大區間數爲:class
用s[1,..,k]表示經過貪心算法一樣的對L處理獲得的區間:
注意此時k和
沒有可比性
因爲貪心算法獲取的是最早完成的,根據提取的規則,能夠獲得的是 。那麼能夠給第一個作替換
同時能夠獲得的是
的其它部分的完成時間都一定在
以後
因爲新替換的和
沒有重合部分,而且替換後獲得的
長度也是
,那麼它也是一個最優的解。
獲取集合L',用來表示全部的的區間。
也就是排除全部的與
不兼容的區間,屬於貪心算法的第二步
因爲對於L來講是最優的,且
對於L'也是最優的,這意味着L'的最優數量爲
最優的子集也是最優的
經過假設:在L'上執行貪心算法,將產生的區間數量爲,且是最優解。 而對構造的L'執行貪心算法以後獲得的一定會是S[2,..,k]
構造的S[1,...,k]的最優解包含
,對於L'的構造條件,使用貪心算法獲得的最小值確定是
,並依次排列爲S[2,..,k]
而S[2,..,k]中共包含k-1個元素,可是依據假設是有個,因此
也就是說 ,從而說明,貪心算法經過獲取最早完成的區間所獲得的區間數,就是最大的(或者說最優的)數量。
每一個區間都有一個權重,,如今要求兼容區間上權重最大的區間數。
能夠舉出一個例子,證實使用上述貪心算法的策略再也不生效
優先最早完成的貪心算法一定會選擇權重爲w=1的兩個,可是它獲得的最終權重是小於w=3的區間。 ![]()
使用動態規劃能夠解決。
我不知道該從那個請求開始,那麼就去選擇全部可能做爲第一個請求的地方,而後獲取他們的最大值,即得結果。
選取好開始的節點以後,剩下的問題是什麼呢?若是選取了第一個請求以後,那麼應該排斥掉那些與它不兼容的區間,才能獲取兼容區間,那麼發生在這個請求以前的請求是否應該考慮?因爲選取的規則是認爲它是第一個請求,若是有以前的發生,實際上在整個的遍歷過程當中確定會經歷,因此只須要選取在它以後發生的便可,那麼剩下的問題也就是
獲取最大的權重的兼容空間也就是考慮,全部子問題中加上當前問題的最大數便可:
時間花銷:能夠看到一共有O(n)個子問題,由於選取第一個區間以後,其它的全部子問題要作一個max,須要遍歷全部的狀況,而後記下來,供後續使用。總共的遍歷爲從1,..,n,因此時間花銷爲
運行時間能夠優化到nlgn;
若是增長條件實在一批機器上運行,要去獲取一個最大的兼容區間個數,則是一個NP-hard問題