1. 程式人生 > >JAVA貪心演算法實現揹包問題

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