java 实现部分背包问题


/*问题描述
   背包问题描述如下:  已知
   背包容量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
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值