動態規劃系列(2)——收益最大問題
阿新 • • 發佈:2019-02-05
考慮一個問題,如果有多個任務,每個任務有自己存在時間段(任務之間的時間段可能有重複),求如果選擇任務可以使收益最大化,計算收益時,每個任務段之間不能有重合。我們舉個實際的例子,存在8個任務,如下圖所示,圖中標明瞭每個任務的時間段和收益。
這個問題我們這樣考慮,從頭到尾,當看到一個任務時,此時不考慮排在後面的任務,考慮在選擇和不選擇這個任務時各自的收益,然後選其中的最大值。
第1個任務:選擇時收益為5,不選時則不做任何任務收益為0,。所以面對第一個任務時的最大收益為5;
第2個任務:選擇時收益為1(自身收益+之前最近的一次任務的收益,選擇1時,之前的任務時間重合,收益為0),不選擇時,則是上一個任務的最大收益;
。。。。
我們可以寫一個優化過程的公式,其中OPT代表optimizer(最佳方案),分成選擇和不選擇當前任務兩種情況,如果選擇的話,當前任務的收益和之前可以最近一次時間不衝突的任務的收益;不選擇的話,上一次任務情況下的收益。
根據上面過程可以計算得出下面的結果
按照上面的思路編寫程式碼,首先根據題目求出不選擇本次任務時,上一次的任務標號 。
# -*- coding: utf-8 -*- ''' 假設有8個任務需要完成,每個任務有各自的時間段,8個任務間任務段可能存在重合,如何選擇任務使最後是收益最大 下面為8個任務的時間段 0 1 2 3 4 5 6 7 8 9 10 11 ******5****** ****1**** ************8************ *******4***** ***********6********* ********3******* ********2******** *********4**** *所覆蓋的範圍代表所經歷的時間段,其中的數字代表這個任務可以帶來的收益 ''' def maxIncome(): tast_incomes = [5,1,8,4,6,3,2,4] # 每項任務的收入 # 根據時間段的重合情況計算,如果選擇當前任務的話,前面的離得最近的可以做的任務 prev = [-1,-1,-1,0,-1,1,2,4] # -1代表如果選擇當前任務的話,之前沒有可選的任務 # 在面臨每項任務時,選擇或者不選擇的最大收益 result = [tast_incomes[0]] for i in range(1,8): if prev[i] == -1: result.append(max(tast_incomes[i]+0,result[i-1])) else: result.append(max(tast_incomes[i]+result[prev[i]],result[i-1])) return max(result) if __name__ == '__main__': print(maxIncome())