貪心算法思想
貪心算法總是做出在當前看來做好的選擇。也就是說貪心算法並不從整體最后考慮,他做出的選擇只是局部最優選擇。他所做出的僅是在某種意義上的局部最優解。貪心算法不是對所有問題都能得到整體最優解,但對范圍相當廣泛的許多問題他能產生整體最優解或者是整體最優解的近似解。
1.算法思路
貪心算法是一種不追求最優解,只希望得到較為滿意解的方法。貪心算法一般可以快速得到滿意的解,因為它省去了為找最優姐要窮盡所有肯呢個而必須耗費大量時間。貪婪(心)算法是一種改進了的分級處理方法。其核心是根據題意選取一種量度標准。然后將這多個輸入排成這種量度標准所要求的順序,按這種順序一次輸入一個量。如果這個輸入和當前已構成在這種量度意義下的部分最佳解加在一起不能產生一個可行解,則不把此輸入加到這部分解中。這種能夠得到某種量度意義下最優解的分級處理方法稱為貪婪算法。
對於一個給定的問題,往往可能有好幾種量度標准。初看起來,這些量度標准似乎都是可取的,但實際上,用其中的大多數量度標准作貪婪處理所得到該量度意義下的最優解並不是問題的最優解,而是次優解。因此,選擇能產生問題最優解的最優量度標准是使用貪婪算法的核心。
一般情況下,要選出最優量度標准並不是一件容易的事,但對某問題能選擇出最優量度標准后,用貪婪算法求解則特別有效。最優解可以通過一系列局部最優的選擇即貪婪選擇來達到,根據當前狀態做出在當前看來是最好的選擇,即局部最優解選擇,然后再去解做出這個選擇后產生的相應的子問題。每做一次貪婪選擇就將所求問題簡化為一個規模更小的子問題,最終可得到問題的一個整體最優解。
2.基本特性
從問題的某一個初始解除發逐步逼近給定的目標,以盡可能快的求得更好的解。當達到算法中的某一步不能再繼續前進時就停止算法,給出近似解。
3.實例:換零錢
該程序實現超市收銀的找零方案,輸入需要找補給顧客的金額,由程序計算出該金額可有哪些面值人民幣組成。人民幣假設有100 50 20 10 5 2 1 0.5 0.2 0.1
package 練習; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class 貪心算法找零錢 { public static int MAX=10; public static double Value[]={10000,5000,2000,1000,500,200,100,50,20,10}; // public static double Value[]={100,50,20,10,5,2,1,0.5,0.2,0.1};如果改成這行,結果就會出錯 public static int num[]=new int[MAX]; public static void main(String[] args) { List ag=new ArrayList(); for(int i=0;i<Value.length;i++){ ag.add(Value[i]); } System.out.println("請輸入要換的數值"); Scanner scanner=new Scanner(System.in); double a=scanner.nextDouble(); conver(a*100); System.out.println("找零"); for(int i=0;i<MAX;i++){ if(num[i]>0){ System.out.println("面值"+Value[i]/100+"一共需要 "+num[i]+"張"); } } } private static void conver(double a) { // TODO Auto-generated method stub int i,j; for( i=0;i<MAX;i++) if (a>Value[i]) break; while (a>0&&i<MAX){ if(a>=Value[i]){ a-=Value[i]; num[i]++; }else if(a<10&&a>=5){ num[MAX-1]++; break; }else i++; } } }
結果:
請輸入要換的數值
212.1
找零
面值100.0一共需要 2張
面值10.0一共需要 1張
面值2.0一共需要 1張
面值0.1一共需要 1張