JAVA貪心演算法實現揹包問題
以下貪心演算法相關概念及題目轉載自http://blog.csdn.net/effective_coder/article/details/8736718,java實現程式碼為博主原創
貪心演算法思想:
顧名思義,貪心演算法總是作出在當前看來最好的選擇。也就是說貪心演算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的區域性最優選擇。當然,希望貪心演算法得到的最終結果也是整體最優的。雖然貪心演算法不能對所有問題都得到整體最優解,但對許多問題它能產生整體最優解。如單源最短路經問題,最小生成樹問題等。在一些情況下,即使貪心演算法不能得到整體最優解,其最終結果卻是最優解的很好近似。
貪心演算法的基本思路:
從問題的某一個初始解出發逐步逼近給定的目標,以儘可能快的地求得更好的解。當達到演算法中的某一步不能再繼續前進時,演算法停止。
該演算法存在問題:
1. 不能保證求得的最後解是最佳的;
2. 不能用來求最大或最小解問題;
3. 只能求滿足某些約束條件的可行解的範圍。
實現該演算法的過程:
從問題的某一初始解出發;
while 能朝給定總目標前進一步 do
求出可行解的一個解元素;
由所有解元素組合成問題的一個可行解;
用揹包問題來介紹貪心演算法:
揹包問題:有一個揹包,揹包容量是M=150。有7個物品,物品可以分割成任意大小。要求儘可能讓裝入揹包中的物品總價值最大,但不能超過總容量。
物品 A B C D E F G
重量 35 30 60 50 40 10 25
價值 10 40 30 50 35 40 30
分析如下
目標函式: ∑pi最大
約束條件是裝入的物品總重量不超過揹包容量:∑wi<=M( M=150)。
(1)根據貪心的策略,每次挑選價值最大的物品裝入揹包,得到的結果是否最優?
(2)每次挑選所佔重量最小的物品裝入是否能得到最優解?
(3)每次選取單位重量價值最大的物品,成為解本題的策略。
package cn.wit.algorithm;
import java.util.*;
class Obj{
int p;//price
int w;//weight
double pw;//price/weight
boolean mark=false;//標記位,表示是否被選中,本題中未使用,但很多類似的題中需要,加上供擴充套件演算法
}
public class Greedy {
public static double maxPrice(int cap,int num,int [][] objs){
Obj[] objArr=new Obj[num];
for(int i=0;i<num;i++){
objArr[i]=new Obj();
}
for(int i=0;i<num;i++){
objArr[i].w=objs[i][0];
objArr[i].p=objs[i][1];
objArr[i].pw=objs[i][1]*1.0/objs[i][0];
}
Arrays.sort(objArr,new Comparator<Obj>(){//過載Java陣列自帶排序方法,使用歸併排序,方便而且排序效率高
public int compare(Obj o1,Obj o2){
if(o1.pw<o2.pw){
return 1;
}
else if(o1.pw==o2.pw){
return 0;
}
else
return -1;
}
});
//總price與指示變數
double pSum=0;
int i=0;
while(cap>0){
cap-=objArr[i].w;
pSum+=objArr[i].p;
i++;
}
//若cap為負數,說明取多了,需要減去最後一個物品的一部分價值
if(cap<=0){
int gap=-cap;
pSum-=gap*objArr[--i].pw;
}
return pSum;
}
/**
* @param args
*/
public static void main(String[] args) {
int cap=150;
int num=7;
int[][] objs={{35,10},{30,40},{60,30},{50,50},{40,35},{10,40},{25,30}};
double maxP=maxPrice(cap, num, objs);
System.out.println(maxP);
}
}
執行結果為:190.625