算法-贪心算法(快速学习理解)

概念(基本思想)

贪心算法:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的**局部最优解 ** 。
因此贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择。

步骤

1.把求解的问题分成若干个子问题。
2.对每个子问题求解,得到子问题的局部优解 。
3.把子问题的解局部最优解合成原来解问题的一个解。

特点

贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,一步步的进行。每做一次贪心选择,就会将所需要解决的问题化为更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,因此全局解有时不一定是最优。贪心算法不要回溯 。
问题特征
1.贪心选择性质
每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择。
2.最优子结构性质
当一个问题的最优解包含其子问题的最优解时。

存在问题

1、不能保证解是最佳的。因为贪心算法总是从局部出发,并没从整体考虑 ;
2、贪心算法一般不用来解决求最大或最小解 ;
3、贪心算法只能确定某些问题的可行性范围 。

案例

【背包问题】有一个背包,容量是M,有n个物品,物品可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。其重量跟价值具体情况具体分析。
思路:将物品按照单位重量价值进行排序

代码

package tanxin;

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

/**
 * @author 奥特曼
 * @version 1.0
 * @date 2020/8/20 0020 下午 14:31
 * 贪心算法,背包问题
 */
public class BeiBao {
    static int beibaocapacity = 0;
    //总共有几个物品
    static int n;

    public static void bG(int beibaocapacity, int n, int[] weightArr, int[] valueArr) {
        //先计算单位价值权重
        float[] pi = new float[n];
        //用来存放原先的位置,即先放入第几个物体
        int[] index = new int[n];
        for (int i = 0; i < n; i++) {
            pi[i] = (float) valueArr[i] / weightArr[i];
            System.out.println("排序之前:权重" + (i + 1) + ": " + pi[i]);
            index[i] = i;
        }
        BubbleSort(pi, index);
        System.out.println();
        System.out.println("排序之后权重输出");
        for (int i = 0; i < weightArr.length; i++) {
            System.out.print(pi[i] + " ");
        }
        System.out.println();
        //将排序好的重量和价值分别保存到数组
        int[] w1 = new int[n];
        int[] v1 = new int[n];
        for (int i = 0; i < n; i++) {
            w1[i] = weightArr[index[i]];
            v1[i] = valueArr[index[i]];
        }
        //将物品装入背包
        //记录哪些物品已经被装入背包       0 没有装入背包    1 代表已经装入背包
        int[] x = new int[n];
        int maxValue = 0;
        for (int i = 0; i < n; i++) {
            if (w1[i] <= beibaocapacity) {
                //还可以装的下
                x[i] = 1;  //表示将该物品装入背包
                System.out.println("物品:" + w1[i] + " 被放进了");
                maxValue += v1[i];
                beibaocapacity -= w1[i];
            }
        }
        System.out.println("总共放下的物品的数量为:" + Arrays.toString(x));
        System.out.println("最大价值为:" + maxValue);
    }


    public static void BubbleSort(float arr[], int[] index) {
        int i = 0;
        int j = 0;
        //判断进行多少趟比较
        for (i = 0; i < arr.length - 1; i++) {
            //判断进行多少次比较
            for (j = 0; j < arr.length - i - 1; j++) {
                //判断大小进行交换
                if (arr[j] < arr[j + 1]) {
                    float tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
                    //将排序后性价比的下标更新为性价比排序后的位置
                    int tmp1 = index[j];
                    index[j] = index[j + 1];
                    index[j + 1] = tmp1;
                    System.out.println(index[j] + " ");
                }
            }
        }
        System.out.println("index排序之后,对应原index");
        for (int k = 0; k < arr.length; k++) {
            System.out.println(index[k] + " ");
        }
    }

    public static void main(String[] args) {
        System.out.println("请输入背包可承受重量(kg),数字:");
        Scanner input = new Scanner(System.in);
        String W = input.nextLine();
        String regex = "[1-9]{1}[0-9]{1,12}";
        boolean flag = W.matches(regex);
        if (flag) {
            beibaocapacity = Integer.parseInt(W);
        } else {
            System.err.println(W + " 不合法,需要输入全部是数字");
        }
        System.out.println("请输入有几个物品:");
        Scanner input1 = new Scanner(System.in);
        n = input1.nextInt();
        int[] Warray1 = new int[n];
        int[] Varray2 = new int[n];
        for (int i = 0; i < n; i++) {
            System.out.println("请依次输入第" + (i + 1) + "个物品重量和价值,用逗号隔开:");
            Scanner input2 = new Scanner(System.in);
            String WandV = input.nextLine();
            int mid = WandV.indexOf(",");
            String weight = WandV.substring(0, mid);
            Warray1[i] = Integer.parseInt(weight);
            String value = WandV.substring(mid + 1, WandV.length());
            Varray2[i] = Integer.parseInt(value);
        }
        for (int i = 0; i < n; i++) {
            System.out.print(Warray1[i] + " ");
        }
        System.out.println();
        for (int i = 0; i < n; i++) {
            System.out.print(Varray2[i] + " ");
        }
        System.out.println();
        BeiBao.bG(beibaocapacity, n, Warray1, Varray2);
    }

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值