演算法設計思想(1) 窮舉法

2021-09-24 23:02:16 字數 2885 閱讀 9710

本文系 王曉華 老師 gitchat 【演算法應該怎麼玩】課程筆記。

窮舉法又稱窮舉搜尋法,是一種在問題域的解空間中對所有可能的解窮舉搜尋,並根據條件選擇最優解的方法的總稱。

數學上也把窮舉法稱為列舉法,就是在乙個由有限個元素構成的集合中,把所有元素一一枚舉研究的方法。

窮舉法一般用來找出符合條件的所有解,但是如果給出最優解的判斷條件,窮舉法也可以用於求解最優解問題。

使用窮舉法解決問題,基本上就是以下兩個步驟:

解空間就是全部可能的候選解的乙個約束範圍,確定問題的解就在這個約束範圍內,將搜尋策略應用到這個約束範圍就可以找到問題的解。

窮舉解空間的策略就是搜尋演算法的設計策略,根據問題的型別,解空間的結構可能是線性表、集合、樹或者圖,對於不同型別的解空間,需要設計與之相適應的窮舉搜尋演算法。

如果選擇一種搜尋策略,不帶任何假設的窮舉搜尋,不管行不行,眉毛鬍子一把抓,把所有可能的解都檢查一遍,這樣的搜尋通常被稱為「盲目搜尋」。

與之對應的是利用某種策略或計算依據,由啟發函式策動有目的的搜尋行為,這些策略和依據通常能夠加快演算法的收斂速度,或者能夠劃定乙個更小的、最有可能出現解的空間並在此空間上搜尋,這樣的搜尋通常稱為「啟發性搜尋」。

一般來說,為了加快演算法的求解,通常會在搜尋演算法的執行過程中輔助一些剪枝演算法,排除一些明顯不可能是正確解的檢驗過程,來提高窮舉的效率。

剪枝乙個很形象的比喻,如果某乙個狀態節點確定不可能演化出結果,就應該停止從這個狀態節點開始的搜尋,相當於狀態樹上這一分枝就被剪掉了。

除了採用剪枝策略,還可以使用限制搜尋深度的方法加快演算法的收斂,但是限制搜尋深度會導致無解,或錯過最優解,通常只在特定的情況下使用,比如博弈樹的搜尋。

對解空間窮舉搜尋時,如果有一些狀態節點可以根據問題提供的資訊明確地被判定為不可能演化出最優解,也就是說,從此節點開始遍歷得到的子樹,可能存在正確的解,但是肯定不是最優解,就可以跳過此狀態節點的遍歷,這將極大地提高演算法的執行效率,這就是剪枝策略,應用剪枝策略的難點在於如何找到乙個評價方法(估值函式)對狀態節點進行評估。

一百個錢買一百隻雞,是個典型的窮舉法應用。問題描述:每只大公雞值 5 個錢,每只母雞值 3 個錢,每 3 只小雞值 1 個錢,現在有 100 個錢,想買 100 隻雞,問如何買?有多少種方法?

盲目搜尋

假設買 x 只公雞,y 只母雞,z 只小雞,使用**求解如下:

%

%time

for x in

range(1

,100):

for y in

range(1

,100):

for z in

range(1

,100):

if x + y + z ==

100and

5*x +

3*y + z/

3.0==

100:

print x, y, z

輸出結果
4

1878811

8112484

cpu times: user 76.3 ms, sys: 0 ns, total: 76.3 ms

wall time: 75.2 ms

啟發搜尋

假設買 x 只公雞,y 只母雞,則 x 最大只能是 20 只,y 最大只能是 33 只,而小雞則應該為 100 -x-y 只,使用**求解如下:

%

%time

for x in

range(1

,21):

for y in

range(1

,34):

if5*x +

3*y +

(100

-x-y)

/3.0

==100

:print x, y,

100-x-y

輸出結果
4

1878811

8112484

cpu times: user 4.43 ms, sys: 0 ns, total: 4.43 ms

wall time: 2.56 ms

可以看出第二種搜尋演算法比第一種明顯快很多。

窮舉法的經典題目:雞兔同籠問題。有雞和兔在乙個籠子中,數頭共 50 個頭,數腳共 120 隻腳,問:雞和兔分別有多少只?

盲目搜尋

假設買 x 雞,y 只兔,使用**求解如下:

%

%time

for x in

range(1

,51):

for y in

range(1

,51):

if x + y ==

50and

2*x +

4*y ==

120:

print x, y

輸出結果
40

10cpu times: user 0 ns, sys: 3.19 ms, total: 3.19 ms

wall time: 2.17 ms

啟發搜尋

假設買 x 雞,則兔子數量只能是 50 - x ,使用**求解如下:

%

%time

for x in

range(1

,51):

if2*x +4*

(50-x)==

120:

print x,

50-x

輸出結果
40

10cpu times: user 190 µs, sys: 0 ns, total: 190 µs

wall time: 137 µs

同樣也可以看出第二種搜尋演算法比第一種明顯快很多。

1 演算法設計方法之窮舉法

窮舉法 窮舉搜尋法 列舉法,brute force 是一種在有限的解空間 解空間至少在理論上是有限的 內按照一定的策略進行查詢的思想。窮舉法的基本思想就是以下兩個步驟 確定問題的解 狀態 的定義,解空間的範圍以及正確解的判定條件。根據解空間的特點擊擇搜尋策略,一一檢驗解空間中的候選解是否正確,必要時...

窮舉法演算法練習

answer include include double a,b,c,d void sort num intmain 注意使用pow書寫冪函式 注意輸出條件 空格隔開,及最後乙個輸出數值後面不能加空格。因為該題輸出的個數有限,以上是乙個簡單方法。還可以使用c 的陣列進行操作。include ios...

第1 6課 演算法設計常用思想之窮舉法

這一課我們來介紹窮舉法,有一些人把窮舉法視為上不了檯面的低階方法,這種想法是錯誤的,雖然窮舉思想的原理簡單,但是用窮舉思想設計乙個演算法卻一點也不簡單。各種演算法模式或思想沒有高下之分,關鍵在於你是否能靈活運用,更不用說很多著名的演算法也會在某個區域性應用窮舉的思想了。某些最優解問題,如果有多個最優...