`

贪心算法解背包问题

 
阅读更多

 

背包问题:0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1 <= i <= n2类问题都具有最优子结构性质,极为相似,但背包问题可以用贪心算法求解,而0-1背包问题却不能用贪心算法求解。

基本步骤:

1、算每种物品单位重量的价值Vi/Wi

2、依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包

3、若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包

4、依此策略一直地进行下去,直到背包装满为止

 

package cn.edu.xmu.acm.greedy;

import java.util.Arrays;
import java.util.Scanner;

/**
 * desc:贪心策略求解背包问题
 * <code>KnapSackGreedy</code>
 * @author chenwq (irwenqiang@gmail.com)
 * @version 1.0 2012/03/27
 */
public class KnapSackGreedy{
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		System.out.println("Please enter the number of objects:");
		int n = in.nextInt();
		int[] w = new int[n];
		int[] v = new int[n];
		System.out
				.println("Now,please enter the weight of these objects:");
		for (int i = 0; i < n; i++) {
			w[i] = in.nextInt();
		}
		System.out
				.println("Now,please enter the value of these objects:");
		for (int i = 0; i < n; i++) {
			v[i] = in.nextInt();
		}
		System.out
				.println("Now,please enter the capacity of the pack:");
		int c = in.nextInt();

		/**
		 * 1、计算单位价值
		 * 2、按单位重量价值 r[i]=v[i]/w[i]降序排列
		 */
		double startTime = System.currentTimeMillis();
		double[] r = new double[n];
		int[] index = new int[n];
		for (int i = 0; i < n; i++) {
			r[i] = (double) v[i] / (double) w[i];
			index[i] = i;
		}
		double temp = 0;
		for (int i = 0; i < n - 1; i++) {
			for (int j = i + 1; j < n; j++) {
				if (r[i] < r[j]) {
					temp = r[i];
					r[i] = r[j];
					r[j] = temp;
					int x = index[i];
					index[i] = index[j];
					index[j] = x;
				}
			}
		}

		/**
		 * 排序后的重量和价值分别存到w1[]和v1[]中
		 */
		int[] w1 = new int[n];
		int[] v1 = new int[n];
		for (int i = 0; i < n; i++) {
			w1[i] = w[index[i]];
			v1[i] = v[index[i]];
		}
		/**
		 * 打印按单位价值降序之后的物品和物品价值序列
		 */
		System.out.println(Arrays.toString(w1));
		System.out.println(Arrays.toString(v1));

		/**
		 * 初始化解向量x[n]
		 */
		int[] x = new int[n];
		for (int i = 0; i < n; i++) {
			x[i] = 0;
		}

		/**
		 * 按照贪心策略求解并打印解向量
		 */
		for (int i = 0; i < n; i++) {
			if (w1[i] < c) {
				x[i] = 1;
				c = c - w1[i];
			}
		}

		System.out
				.println("The solution vector is:" + Arrays.toString(x));
		/**
		 * 根据解向量求出背包中存放物品的最大价值并打印
		 */
		int maxValue = 0;
		for (int i = 0; i < n; i++) {
			if (x[i] == 1)
				maxValue += v1[i];
		}
		double endTime = System.currentTimeMillis();
		System.out
				.println("Now,the largest values of objects in the pack is:"
						+ maxValue);
		System.out.println("Basic Statements take) "
				+ (endTime - startTime) + " milliseconds!");
	}
}
背包问题拓展:物品可以部分放入背包中。详细见下述代码
package cn.edu.xmu.acm.greedy;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.text.DecimalFormat;

/*
 * Basic knapsack problem:
 *
 * We are given n objects and a knapsack.  Each object has a positive
 * weight and a positive value.  The knapsack is limited in the weight
 * that it can carry.  Fill the knapsack in a way that maximizes the
 * value of the included objects, where you are allowed to take a
 * fraction of an object.
 *
 * Author:  Timothy Rolfe
 *
 * Based on Brassard and Bratley, _Fundamentals_of_Algorithmics_,
 * pp. 202-04.
 *
 * Note:  The array "avail" is sorted several times, each with a
 *        different criterion for sorting.  Only the last time is
 * the optimal knapsack obtained (when sorted by value per weight).
 */
public class FPKnapsack {
	// Instance-scope fields
	int n; // Number of objects

	Item[] avail;// Available objects for use
	Item[] used; // objects actually used
	int nUsed;

	double maxWeight; // Weight limit of the knapsack.

	// Easy-out for IOExceptions --- throw them back to the operating system
	public static void main(String[] args) throws Exception {
		// Code for reading console from "Java in a Nutshell", p. 166
		BufferedReader console = new BufferedReader(new InputStreamReader(
				System.in));
		FPKnapsack knap = new FPKnapsack();
		String lineIn;
		String[] header = { "ranked by increasing weight",
				"ranked by decreasing value",
				"ranked by decreasing value per weight" };
		int k; // Loop variable

		System.out.print("Input file name:  ");
		if (args.length < 1)
			lineIn = console.readLine();
		else {
			lineIn = args[0];
			System.out.println(args[0]);
		}

		File f = new File(lineIn);
		FileReader fis = new FileReader(f);
		BufferedReader inp = new BufferedReader(fis);

		knap.initialize(inp);
		for (k = 0; k < 3; k++) {
			knap.fill(k);
			knap.report(header[k]);
		}
	}

	/*
	 * Data file presumption:
	 * 
	 * 1. Weight ceiling for the knapsack (one number on the line) 2. Number of
	 * candidate objects (one number on the line) ...That many number PAIRS:
	 * weight value
	 */
	void initialize(BufferedReader inp) throws Exception {
		String lineIn;

		lineIn = inp.readLine();
		maxWeight = Double.parseDouble(lineIn.trim());

		lineIn = inp.readLine();
		n = Integer.parseInt(lineIn.trim());
		// Arrays "used" and "avail" are initialized here.
		used = new Item[n];
		avail = new Item[n];

		System.out.println("\nData accepted:  n = " + n);
		System.out.println("Individual object descriptions follow.");
		for (int k = 0; k < n; k++) {
			DecimalFormat fmt0 = new DecimalFormat("0"), fmt2 = new DecimalFormat(
					"0.00");
			java.util.StringTokenizer tk = new java.util.StringTokenizer(
					inp.readLine());
			double wt = Double.parseDouble(tk.nextToken()), val = Double
					.parseDouble(tk.nextToken());

			avail[k] = new Item(wt, val);
			System.out.println("w:  " + fmt0.format(wt) + "   v:  "
					+ fmt0.format(val) + "  v/w:  " + fmt2.format(val / wt));
		}
	}

	// Fill the knapsack (i.e., move items from the heap into used[])
	void fill(int basis) {
		int k;
		Item nxt;
		double remain = maxWeight;

		nUsed = 0;

		// Put the available items into requested order
		Item.setBasis(basis);
		java.util.Arrays.sort(avail);
		for (k = 0; remain > 0 && k < avail.length; k++) {
			nxt = avail[k];
			if (nxt.w <= remain)
				nxt.x = 1;
			else
				nxt.x = remain / nxt.w;
			remain -= nxt.x * nxt.w;
			used[nUsed++] = nxt;
		}
	}

	// Show the contents --- as number pairs and fraction used.
	void report(String header) {
		DecimalFormat fmt0 = new DecimalFormat("0"), fmt2 = new DecimalFormat(
				"0.00");
		double sigVal = 0;

		System.out.println("\n" + fmt0.format(maxWeight) + " total weight "
				+ header);
		System.out.println("Knapsack contents:");
		for (int k = 0; k < nUsed; k++) {
			String lineOut = "(";

			lineOut += fmt0.format(used[k].w) + ", ";
			lineOut += fmt0.format(used[k].v) + ") --- ";
			lineOut += fmt2.format(used[k].x) + " used.";
			System.out.println(lineOut);
			sigVal += used[k].v * used[k].x;
		}
		System.out.println("Total value:   " + fmt2.format(sigVal));
	}
}

/*
 * Class of items for inclusion in the knapsack
 */
class Item implements Comparable {
	double w, // For each object, the weight of the object
			v, // For each object, the value of the object
			x; // For each object, the fraction of the object used
	double vpw; // For each object, the value-per-weight ratio
	// Basis for sorting: 0: w ascending,
	// 1: v descending
	// x: vpw descending
	static private int basis = 2;

	Item(double w, double v) {
		this.x = 0;
		this.w = w;
		this.v = v;
		this.vpw = v / w;
	}

	Item(Item c) {
		this.w = c.w;
		this.w = c.w;
		this.v = c.v;
		this.vpw = c.vpw;
	}

	public static void setBasis(int basis) {
		Item.basis = basis;
	}

	// Comparable insists on the following method signature:
	public int compareTo(Object x) {
		Item rt = (Item) x;

		// Basis for ordering is set in the static field basis
		switch (basis) { // ascending
		case 0:
			return w < rt.w ? -1 : w > rt.w ? +1 : 0;
			// descending
		case 1:
			return v < rt.v ? +1 : v > rt.v ? -1 : 0;
			// descending
		default:
			return vpw < rt.vpw ? +1 : vpw > rt.vpw ? -1 : 0;
		}
	}

}

ref:http://penguin.ewu.edu/cscd320/Topic/Strategies/Knapsack.html#fill_method
0
0
分享到:
评论

相关推荐

    利用贪心算法解背包问题.doc

    "贪心算法解决背包问题" 贪心算法是一种常见的算法思想,它通过作出局部最优选择来解决问题。贪心算法的关键是贪心选择性质和最优子结构性质。贪心选择性质是指问题的整体最优解可以通过一系列局部最优解的选择,而...

    贪心算法背包问题(非0-1)

    ### 贪心算法在非0-1背包问题中的应用 #### 核心知识点解析: **1. 背包问题概述:** 背包问题是一种经典的组合优化问题,通常出现在计算机科学和数学中,特别是在算法设计与分析领域。它主要探讨的是如何在给定...

    用贪心算法实现背包问题

    当然,贪心算法并不总是能得到背包问题的全局最优解,特别是当物品的价值与重量比不均匀时。但对于某些特殊类型的背包问题,如完全背包和0-1背包,贪心算法可以得到正确的结果。 在实际开发中,我们可能会遇到更...

    背包问题的贪心算法要求按照单位容量效益值的高低的量度标准进行排序,然后再分级选取,

    背包问题:背包问题的贪心算法要求按照单位容量效益值的高低的量度标准进行排序,然后再分级选取, 求得最优解。实现此算法,物品个数,每件物品的效益值,容量值,背包容量值都由键盘输入; 输出结果要有每件物品的...

    贪心算法 背包问题 c语言

    ### 贪心算法在背包问题中的应用及C语言实现 #### 一、贪心算法简介 ...总之,贪心算法在解决分数背包问题上具有很好的效果,通过合理的物品选择策略,能够在较短的时间内找到接近最优解的解决方案。

    用贪心算法解非0-1背包问题

    贪心算法解背包问题,供读者参考,我想看看有没有动态规划算法的解决办法

    贪心算法 背包问题 C语言

    贪心算法是一种优化策略,它在每...在背包问题中,贪心算法对于某些特定类型的问题(如完全背包、非递减价值密度的物品)能得到最优解,但对于一般部分背包问题,可能需要结合动态规划等更强大的工具来确保全局最优。

    贪心算法贪心算法背包问题

    根据给定的文件信息,我们将深入探讨“贪心算法”在解决背包问题中的应用与实现。贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择策略,以便产生全局最优解的算法。然而,值得注意的是...

    贪心算法解部分背包问题

    然而,贪心算法并不总是能保证得到全局最优解,特别是在部分背包问题中,物品可以重复放置的情况下,单纯按价值密度排序可能无法达到最优。 为了实现贪心算法解决部分背包问题,我们可以使用以下步骤: 1. 计算每个...

    贪心算法 部分背包问题

    贪心算法是计算机科学中解决问题的一种策略,它通过做出局部最优选择来逐步达到全局最优解。在部分背包问题中,这种策略尤其适用。部分背包问题是一个经典的优化问题,经常出现在运筹学、算法设计和分析中。在此问题...

    Python基于贪心算法解决背包问题示例

    对于背包问题,贪心算法适用于完全背包问题,但对于0-1背包问题,贪心算法不一定能得到最优解。 - 在实际应用中,需要根据具体情况选择合适的算法。 - 对于背包问题,动态规划也是一种常用的解决方法,适用于更广泛...

    贪心算法在背包问题中的应用

    ### 贪心算法在背包问题中的应用 #### 背包问题背景介绍 背包问题是一种经典的优化问题,在计算机科学和运筹学中被广泛研究。这个问题的基本形式为:有一个背包,其最大承重能力为W;有n个物品,每个物品有自己的...

    贪心算法解决背包问题

    **贪心算法解决背包问题** 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。在背包问题中,贪心算法通常用于解决“最佳装载”背包问题,即...

    贪心算法_背包问题

    贪心算法_背包问题 贪心算法是解决背包问题的一种方法,它是一种简单、快速且近似最优的算法。贪心算法的基本思想是,每一步选择当前情况下最优的选择,以期获得整体最优的解。 在背包问题中,我们需要在有限的...

    背包问题的贪心算法,背包问题的贪心解法

    当问题的结构允许分割物品时,比如分数背包问题,我们可以将物品分割成更小的单位,这种情况下贪心算法能够得到全局最优解。这是因为背包问题中的物品可以被分割成任意小的单位,我们可以按照单位价值的非增次序装入...

    贪心算法——背包问题

    贪心算法中,背包问题的源代码。可以编译运行,用快速排序实现的。

    贪心算法实现背包问题c++

    在背包问题中,贪心算法通常用于处理具有特定结构的问题,但需要注意的是,对于一般的0-1背包问题,贪心算法可能无法得到全局最优解。然而,当我们面对非0-1背包问题时,贪心策略可能会更为有效。 非0-1背包问题与0...

    算法设计-贪心算法-背包问题

    背包问题.本算法比较清晰,易读。...背包问题是比较经典的算法。很具有代表性。在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

    java算法 0-1 背包问题贪心算法解决 netbeans

    用贪心算法解决背包问题,用netbeans做的。百分百下载就可以直接运行。JAVA 源文件。

Global site tag (gtag.js) - Google Analytics