问题描述: 给定n个物品,物品价值分别为P1,P2,…,Pn,物品重量分别为W1,W2,…,Wn,背包容量为M。每种物品可部分装入到背包中。输出X1,X2,…,Xn, 0<=Xi<=1使得背包内的物品价值最大。试设计一个算法求解该问题
设计思路:先将所有物品按单位价值进行排序后,每次取出剩余物品内单位价值最大的物品尝试加入背包,如果背包容量足够,则将整个物品加入,否则加入该物品的一部分。
相关符号解释:
(1) 数组V存放各物品的价值
(2) 数组W存放各物品的重量
(3) L表示背包容量
(4) totalValue表示总价值
(5) flag (当值为false时表示所有物品全部装入背包,当值为true时表示最后一个物品部分装入)
(6) share (部分装入物品的份额)
(7) List集合result存放选出的物品
(8) uniValue 单位价值
Alogrithm:
Sort(V,W)//将物品按单位价值进行排序
For(i=0;i<n;i++)
Repeat
If(L>0)
If(L>W[i])//表示可将当前物品全部装入
Result.add(i)
totalValue += W[i]
L-=W[i];
else{//部分装入
uniValue = V[i]/W[i]//单位价值
totalValue+= L*uniValue;
share=L;
flag = true;
L=0;
Result.add(i)
}
Until L<=0;
Ouput result and totalValue;
运行结果:
import java.text.DecimalFormat; import java.util.*; /** * Created by Administrator on 2016/11/29. */ public class Knapsack { public static void main(String [] args){ double L =12; int[] V = {13,10,24,15,28,33,20,8};//存放价值 int[] W = {2,1,3,2,4,5,3,1};//存放重量 int len = V.length; double totalValue = 0; List result = new LinkedList<>(); sort(V,W);//按单位价值排序 for(int j = 0 ; j < len ; j++) System.out.println("物品"+(j+1)+": 价值为:"+ V[j]+" 重量为"+W[j] ); int i ; boolean flag = false;//flag = false代表所有物品全部装入,为true代表有物品部分装入 double share = 0 ;//部分装入部分的份额. for(i=0;i =W[i]){//能把整个物品装进去 result.add(i); L -= W[i]; totalValue += V[i]; }else{ double uniValue = V[i]/(double)W[i]; totalValue += L*uniValue; share = L; flag = true; L=0; result.add(i); } } DecimalFormat de = new DecimalFormat("0.00"); System.out.println("所选的结果为:"); for(Integer r : result){ System.out.print(r+1+" "); } System.out.println("总价值为"+de.format(totalValue)); if(flag = true){ System.out.println("最后一个物品为部分装入,装入的部分重量为"+share); }else { System.out.println("物品全部装入"); } } private static void sort(int[] p, int[] w) { int len = p.length; int tmp = 0; for(int i = 0 ; i < len - 1 ; i++){ int maxIndex = i ; double IUniValue = p[i]/(double)w[i] ; for(int j = i+1 ; j < len ; j ++){ double JUniValue = p[j]/(double)w[j]; if(JUniValue>IUniValue){ maxIndex = j ; } } tmp = p[i]; p[i] = p[maxIndex]; p[maxIndex] =tmp; tmp = w[i]; w[i] = w[maxIndex]; w[maxIndex] =tmp; } } }
贪心法部分背包问题的实现
最新推荐文章于 2024-05-22 21:55:29 发布