常用演算法設計方法 六 貪婪法

2021-04-19 06:31:54 字數 2376 閱讀 9670

貪婪法是一種不追求最優解,只希望得到較為滿意解的方法。貪婪法一般可以快速得到滿意的解,因為它省去了為找最優解要窮盡所有可能而必須耗費的大量時間。貪婪法常以當前情況為基礎作最優選擇,而不考慮各種可能的整體情況,所以貪婪法不要回溯。

例如平時購物找錢時,為使找回的零錢的硬幣數最少,不考慮找零錢的所有各種發表方案,而是從最大面值的幣種開始,按遞減的順序考慮各幣種,先盡量用大面值的幣種,當不足大面值幣種的金額時才去考慮下一種較小面值的幣種。這就是在使用貪婪法。這種方法在這裡總是最優,是因為

銀行對其發行的硬幣種類和硬幣面值的巧妙安排。如只有面值分別為1、5和11單位的硬幣,而希望找回總額為15單位的硬幣。按貪婪演算法,應找1個11單位面值的硬幣和4個1單位面值的硬幣,共找回5個硬幣。但最優的解應是3個5單位面值的硬幣。

【問題】   裝箱問題

問題描述:裝箱問題可簡述如下:設有編號為0、1、…、n-1的n種物品,體積分別為v0、v1、…、vn-1。將這n種物品裝到容量都為v的若干箱子裡。約定這n種物品的體積均不超過v,即對於0≤i<n,有0<vi≤v。不同的裝箱方案所需要的箱子數目可能不同。裝箱問題要求使裝盡這n種物品的箱子數要少。

若考察將n種物品的集合分劃成n個或小於n個物品的所有子集,最優解就可以找到。但所有可能劃分的總數太大。對適當大的n,找出所有可能的劃分要花費的時間是無法承受的。為此,對裝箱問題採用非常簡單的近似演算法,即貪婪法。該演算法依次將物品放到它第乙個能放進去的箱子中,該演算法雖不能保證找到最優解,但還是能找到非常好的解。不失一般性,設n件物品的體積是按從大到小排好序的,即有v0≥v1≥…≥vn-1。如不滿足上述要求,只要先對這n件物品按它們的體積從大到小排序,然後按排序結果對物品重新編號即可。裝箱演算法簡單描述如下:

ele;

typedef  struct  hnode

hnode;

void  main()

else   j->remainder-=a;

for (q=j->next;q!=null&&q->link!=null;q=q->link);

if (q==null)

else }

printf(「共使用了%d只箱子」,box_count);

printf(「各箱子裝物品情況如下:」);

for (j=box_h,i=1;j!=null;j=j->next,i++) }

【問題】   馬的遍歷

問題描述:在8×8方格的棋盤上,從任意指定的方格出發,為馬尋找一條走遍棋盤每一格並且只經過一次的一條路徑。

馬在某個方格,可以在一步內到達的不同位置最多有8個,如圖所示。如用二維陣列board[ ][ ]表示棋盤,其元素記錄馬經過該位置時的步驟號。另對馬的8種可能走法(稱為著法)設定乙個順序,如當前位置在棋盤的(i,j)方格,下乙個可能的位置依次為(i+2,j+1)、(i+1,j+2)、(i-1,j+2)、(i-2,j+1)、(i-2,j-1)、(i-1,j-2)、(i+1,j-2)、(i+2,j-1),實際可以走的位置盡限於還未走過的和不越出邊界的那些位置。為便於程式的同意處理,可以引入兩個陣列,分別儲存各種可能走法對當前位置的縱橫增量。

4      3   

5            2

馬      

6            1

7      0   

對於本題,一般可以採用回溯法,這裡採用warnsdoff策略求解,這也是一種貪婪法,其選擇下一出口的貪婪標準是在那些允許走的位置中,選擇出口最少的那個位置。如馬的當前位置(i,j)只有三個出口,他們是位置(i+2,j+1)、(i-2,j+1)和(i-1,j-2),如分別走到這些位置,這三個位置又分別會有不同的出口,假定這三個位置的出口個數分別為4、2、3,則程式就選擇讓馬走向(i-2,j+1)位置。

由於程式採用的是一種貪婪法,整個找解過程是一直向前,沒有回溯,所以能非常快地找到解。但是,對於某些開始位置,實際上有解,而該演算法不能找到解。對於找不到解的情況,程式只要改變8種可能出口的選擇順序,就能找到解。改變出口選擇順序,就是改變有相同出口時的選擇標準。以下程式考慮到這種情況,引入變數start,用於控制8種可能著法的選擇順序。開始時為0,當不能找到解時,就讓start增1,重新找解。細節以下程式。

【程式】

# include   

int delta_i[ ]=;

int delta_j[ ]=;

int board[8][8];

int exitn(int i,int j,int s,int a[ ])

return count;

} int next(int i,int j,int s)

if (step>64)   break;

start++;

} while(step<=64)

for (i=0;i<8;i++)

scanf(「%*c」); } }

演算法設計思想(2) 貪婪法

貪婪法,又稱貪心演算法,是尋找最優解問題的常用方法,這種方法模式一般將求解過程分成若干個步驟,但每個步驟都應用貪心原則,選取當前狀態下最好的或最優的選擇 區域性最有利的選擇 並以此希望最後堆疊出的結果也是最好或最優的解。貪婪法的每次決策都以當前情況為基礎並根據某個最優原則進行選擇,不從整體上考慮其他...

C C 程式設計常用演算法 貪婪法

文件宣告 以下資料均屬於本人在學習過程中產出的學習筆記,如果錯誤或者遺漏之處,請多多指正。並且該文件在後期會隨著學習的深入不斷補充完善。程式設計的關鍵就是演算法,演算法簡單來說就是程式設計時問題解題步驟或者資料資料的流程。這裡我們將介紹以下幾種常用的演算法 迭代法 窮舉法 遞推法 遞迴發 回溯法 貪...

常用演算法設計方法 回溯法

常用演算法設計方法 回溯法 a i continue else while 1 main 問題 填字遊戲 問題描述 在3 3個方格的方陣中要填入數字1到n n 10 內的某9個數字,每個方格填乙個整數,似的所有相鄰兩個方格內的兩個整數之和為質數。試求出所有滿足這個要求的各種數字填法。可用試探發找到問...