# 貪婪演算法 貪婪演算法就是做眼前最佳的動作,也就是局部解,但是到最後不見得是最好的動作,以下舉一個找零錢的例子。 通常找顧客零錢都是先將面額大的給顧客,再將較第二大的面額給顧客,依序這樣下去,直到不能找為止,所以貪婪演算法就是運用這個想法。 ```cpp= #include <iostream> using namespace std; int main(){ int cash[10],n; cash[0] = 1; cash[1] = 5; cash[2] = 10; cash[3] = 50; cash[4] = 100; cash[5] = 500; cash[6] = 1000; cin >> n; cout << n << "="; for(int i = 6;i >= 0;i--){ if(n >= cash[i]){ cout << cash[i] << "*" << n/cash[i] << " "; n = n%cash[i]; } } return 0; } ``` ## 貪婪演算法-最小生成樹(Minimum spanning trees)MST 其實tree是一種資料結構,但我配合greedy來講。 Tree的特性,必連通,但不能有cycle。 MST的定義就是生成出來的樹,他的邊的總和最小的。 英文版定義(由於翻譯成中文可能無法清楚表達他的含義,所以這邊使用別人的定義,原文是英文): Definition: G = (V,E):weighted connected undirected graph * <span style = "color:blue">Spanning tree</span> : S = (V,T),T ⊆ E,undirected tree * <span style = "color:blue">Minimum spanning tree(MST)</span> : a spanning tree with the smallest total weight. 中文定義: 1. 樹(tree):一個無向連通非環狀圖(acyclic,connected, undirected graph) 2. 有根樹(rooted tree):以某個頂點為跟的樹(獨立於樹之外的頂點不能作為根)。因此有根樹也被直接稱為樹。 3. 生成樹(spanning tree):包含圖中所有頂點且符合樹的定義的連通子圖。 4. 最小生成樹(minimum spanning tree):即具有最小的權重的生成樹。 ## 用貪婪演算法解最小生成樹 ```cpp= F = empty set while(當問題未得解){ 找出問題區域最佳解的方式找出一個邊; if(選出來的邊不會使F產生任何cycle) 將邊加入F中; if(答案是生成樹) 此問題得解; } ``` ## Kruskal algorithm 先將所有邊拿掉,接著再依序找小邊,並隨時確保他不會形成一個cycle。 ## Prim algorithm 先挑一個點,然後找那個頂點連接的邊哪個最小,然後當所有的點都選到後就結束了。