贪心算法-背包问题

贪心算法-背包问题

完全背包问题
一个旅行者有一个最多能用m公斤的背包,现在有n种物品,每件的重量分别是W1,W2,…,Wn,
每件的价值分别为C1,C2,…,Cn.若的每种物品的件数足够多.
求旅行者能获得的最大总价值。

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。

贪心算法的基本思路
1.建立数学模型来描述问题。  
2.把求解的问题分成若干个子问题。  
3.对每一子问题求解,得到子问题的局部最优解。  
4.把子问题的解局部最优解合成原来解问题的一个解。  
实现该算法的过程:  
从问题的某一初始解出发;  
while 能朝给定总目标前进一步 do求出可行解的一个解元素;  
由所有解元素组合成问题的一个可行解。

代码

/**
 * 背包贪心法
 *
 * Created by YYL on 2017/2/17
 *
 */
public class Greedy {
    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();
        /**
         * 按单位重量价值r[i] = v[i] / w[i]降序排列
         *
         * ps:排序用到了选择排序,详情请查看选择排序
         */
        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]];
        }
        /**
         * 初始化解向量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!");
    }
}

你可能感兴趣的:(算法笔记)