/*问题描述
背包问题描述如下: 已知
背包容量M=120
物品种类数n=10
各种物品的总效益pi(i=1,2,………10) : 50,60,70,80,90,80,70,60,50,40
各种物品的总重量wi(i=1,2………10) : 17,30,25,41,80,70,64,56,47,38
求: 各种物品所取重量占其总重量的比例xi(i=1,2,…..10),满足0<=xi<=1,
基本要求
按三种不同的量度标准分别计算所得最大总效益,然后比较哪个最大
1.按效益值由大到小取物品. 2. 按重量值由小到大取物品
3.按比值pi/wi的值由大到小取物品*/
package greedy;
public class Greedy {
public static void main(String[] args) {
float w[] = { 17, 30, 25, 41, 80, 70, 64, 56, 47, 38 }; // 物体的重量
float v[] = { 50, 60, 70, 80, 90, 80, 70, 60, 50, 40 }; // 物体的价值
float M = 120; // 背包所能容纳的重量
int n = w.length; // 物体的个数
float[] x = new float[n]; // 每个物体装进的比例,>=0&&<=1
float[] t = new float[n]; // 定义一个数组存放单位重量物体的价值
System.out.print("\n\t\t\t*****************效益贪心*****************");
sort1(w, v, n);
f(w, v, M, n, x); // 调用贪心算法
print(w, v, n, x); // 调用输出装入比例和最大价值函数
System.out.print("\n\t\t\t*****************重量贪心*****************");
sort2(w, v, n);
f(w, v, M, n, x); // 调用贪心算法
print(w, v, n, x); // 调用输出装入比例和最大价值函数
System.out.print("\n\t\t\t***************v[i]/w[i]贪心*****************");
sort3(w, v, n,t);
f(w, v, M, n, x); // 调用贪心算法
System.out.println();
print(w, v, n, x); // 调用输出装入比例和最大价值函数
}
/*--------将物品装入背包 -------------*/
private static void f(float[] w, float[] v, float M, int n, float[] x) {
double c = M; // 背包剩余的容量,刚开始时还没用装东西,为M
int i;// 表示第几种物体
for (i = 0; i < n; i++) {
if (w[i] <= c) { // 如果背包剩余的容量大于等于第i个物体的重量
x[i] = 1; // 把第i个物体整个装进背包
c -= w[i]; // 背包的剩余容量减少了第i个物体的重量
} else {
break; // 退出循环
}
}
if (i < n) {// 判断是否第n个物体整个装进去背包里了,如果i<=n表示否定
x[i] = (float) (c / w[i]);
}
}
/*-------------------价值大到小排序,对应的重量随之改变------------*/
private static void sort1(float[] w, float[] v, int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (v[j] < v[j + 1]) {
double temp = v[j];
v[j] = v[j + 1];
v[j + 1] = (float) temp;
double temp2 = w[j];
w[j] = w[j + 1];
w[j + 1] = (float) temp2;
}
}
}
}
/*------------重量小到大排序,对应的效益随之改变--------------*/
private static void sort2(float[] w, float[] v, int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (w[j] > w[j + 1]) {
float temp = w[j];
w[j] = w[j + 1];
w[j + 1] = temp;
double temp2 = v[j];
v[j] = v[j + 1];
v[j + 1] = (float) temp2;
}
}
}
}
/*-------------v[i]/w[i]大到小排序 ---------------------*/
private static void sort3(float[] w, float[] v, int n,float[]t) {
for (int i = 0; i < n; i++) {
t[i] = v[i] / w[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (t[j] < t[j + 1]) {
float temp = t[j];
t[j] = t[j + 1];
t[j + 1] = temp;
float temp2 = w[j];
w[j] = w[j + 1];
w[j + 1] = temp2;
float temp3 = v[j];
v[j] = v[j + 1];
v[j + 1] = temp3;
}
}
}
}
/*------------------用来输出排序后每个物体装进背包的比例,以及最大价值总和 ------------------------*/
private static void print(float[] w, float[] v, int n, float[] x) {
float maxValueSum = 0; // 用来存放背包能装下的物体的最大价值总和
for (int i = 0; i < x.length; i++) {
maxValueSum += x[i] * v[i];
}
System.out.println();
System.out.println("排序后每个物体装进背包的比例:");
for (int i = 0; i < n; i++) {
System.out.print(x[i] + "\t");
}
System.out.println();
System.out.println("背包能装下的物体的最大价值总和为: " + maxValueSum);
}
}
eclipse输出:
*****************效益贪心*****************
排序后每个物体装进背包的比例:1.0 0.9756098 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
背包能装下的物体的最大价值总和为: 168.04878
*****************重量贪心*****************
排序后每个物体装进背包的比例:
1.0 1.0 1.0 1.0 0.24390244 0.0 0.0 0.0 0.0 0.0
背包能装下的物体的最大价值总和为: 239.51219
***************v[i]/w[i]贪心*****************
排序后每个物体装进背包的比例:
1.0 1.0 1.0 1.0 0.1 0.0 0.0 0.0 0.0 0.0
背包能装下的物体的最大价值总和为: 268.0