演算法導論 第十六章 貪心演算法

2021-07-10 16:05:53 字數 3484 閱讀 3989

def:貪心演算法是一種以區域性最優最優選擇以期求得全域性最優解得演算法。

16.1活動選擇問題

求乙個活動選擇問題的域中求最大相容活動子集。

活動選擇問題具有最優子結構:解中若包含活動ak,s.t. s[...k]和s[k+1...]都為最大相容活動子集

若用c[i,j]來表示s[i...j]的大小則有遞迴公式:

由此可以通過動態規劃方法求解活動選擇問題的最優解。

若注意到此問題的乙個性質,則可以只需要遍歷一遍所有活動採用貪心選擇而求得最優解。

貪心選擇的是s中結束時間最早的活動。實現如下:

"""

因為 f由小到大排序,所以必然包含第乙個活動

"""def recursive_activity_selector(s, f, k, n):

m = k + 1

while m < n and s[m] < f[k]:

m = m + 1

if m < n:

ai = [m]

a = recursive_activity_selector(s, f, m, n)

if a != none:

ai.extend(recursive_activity_selector(s, f, m, n))

return ai

else:

return none

def greedy_activity_selector(s,f):

n = len(s)

a = [1]

k = 1

for m in range(2, n):

if s[m] >= f[k]:

k = m

return a

if __name__ == "__main__":

s = [0,1,3,0,5,3,5,6,8,8,2,12]

f = [0,4,5,6,7,9,9,10,11,12,14,16]

a = recursive_activity_selector(s,f,0, len(s))

print(a)

a = greedy_activity_selector(s, f)

print(a)

16.2貪心演算法原理

所有的貪心演算法問題都有乙個對應的動態規劃解法。對含有某些特性的動態規劃問題,我們用貪心策略,每一步求區域性的最優解而最後得到乙個最優解。為了保證可以實施貪心策略和貪心演算法正確我們需要證明以下三點:

貪心選擇性質:對比與動態規劃問題我們總是依賴子問題的最優解來構造出問題的最優解,而貪心選擇只考慮區域性最優,而不依賴於子問題的解。故貪心演算法由上而下的分解子問題,而動態規劃演算法由底向上的求解所有子問題。

所以我們必須要證明區域性最優能生成全域性最優解,既將問題分解為乙個區域性最優解和包含最優解的子問題。

通過以上分析0-1揹包問題不可以使用貪心演算法求解,而分數揹包問題可以是用貪心演算法求解。

16.3赫夫曼編碼

對於定長編碼的檔案的壓縮,使用變長編碼既使用短編碼表示出現概率高的字元,使用長編碼表示出現概率低的字元,以取得對定長編碼的優勢。為了保證編碼的唯一性,我們使用字首碼的特性來簡化編譯碼的過程。檔案的最優編碼方案就是一棵滿二叉樹,優於非滿二叉樹的定長編碼:

我們使用huffman來構造滿二叉樹:

此過程中使用貪婪策略每次以集合中概率最低的兩個物件作為葉子構造一棵子樹,通過如下兩個引理證明貪心策略有效:

16.4 擬陣和貪心演算法

加權的擬陣,可以用貪心演算法求解,求解與正確性的證明如下(其實就是動態規劃原理中的剪下-貼上技術證明和定義)

16.5用擬陣求解任務排程問題

def quicksort(a, p, r):

if p < r:

q = partition(a, p, r)

quicksort(a, p, q-1)

quicksort(a, q+1, r)

def partition(a, p, r):

x = a[r][1][0]

i = p

for j in range(p, r):

if a[j][1][0] <= x:

temp = a[i]

a[i] = a[j]

a[j] = temp

i = i + 1

temp = a[i]

a[i] = a[r]

a[r] = temp

return i

def scheduled(s):

a =

b =

for i in range(0, len(s)):

n = len(a)

if n > a[n-1][1][0]:

m = 0

w = a[0][1][1]

for j in range(1, n):

if a[j][1][1] < w:

m = j

w = a[j][1][1]

b = a.pop(m)

return a, b

if __name__ == "__main__":

s = [(1,(4,70)), (2,(2,60)), (3,(4,50)), (4,(3,40)), (5,(1,30)), (6,(4,20)), (7,(6,10))]

quicksort(s, 0, len(s)-1)

print(s)

a,b = scheduled(s)

print(a)

print(b)

習題解答

演算法導論 13 貪心演算法

與動態規劃類似,貪心演算法也將問題化簡為規模較小的子問題,並通過遞迴解決子問題來獲取整個問題的解。不同的是,貪心問題不對子問題進行比較,而是只生成乙個非空的子問題,而使選擇在當時看上去是最優的 即 貪心 的含義 幾個互相競爭的活動都要求以獨佔的方式占用某個公用資源 如選修課程對個人可支配時間的要求,...

演算法導論之貪心演算法

參考 下面請看示例題 有n個商品,每個商品的重量為wi,為 pi,現有乙個揹包,最多能裝 的重量 其中 0 i問 怎樣裝能使包中裝入的商品價值最高 對於每個商品可以只裝該商品的一部分 偽 引數分別為 n 物品數 m 揹包最多能裝的重量 v 價值陣列 w重量陣列 void knapsack int n...

第十六章 tcp wrappers

在伺服器向外提供的tcp服務上包裝一層安全檢測機制。外來連線請求首先通過這個安全檢測,獲得安全認證後才可被系統服務接受。hosts.allow hosts.deny 在配置檔案中為各服務分別定義訪問控制規則實現訪問控制,檔案中的規則是即時生效的。配置檔案語法 1 daemon list client...