贪心算法

贪心算法基本原理

贪心算法的核心就是贪,就是总是做出当前看来最优的选择,因此可知,贪心算法不从整体去考虑,它做出的选择也是局部最优选择,从而达到全局优化选择。虽然贪心算法不一定能得到最优解,但是对很多问题,它是能够得到整体最优解的,因此贪心算法是否能到最优解,需要严格证明。

贪心算法产生有化解的条件

  1. 贪心选择性质: 
    若一个问题的全局最优解可以通过局部最优解来得到,则说明该问题具有贪心选择性质。
  2. 优化子结构: 
    当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。

贪心算法和动态规划的区别

  1. 贪心算法是自顶向下的,而动态规划则是自底向上的。
  2. 动态规划是自底向上求出各子问题的有化解,最后汇集有化解从而得出问题的全局最优解(可以想象成各个小河流入大海) 
    这里写图片描述 
    贪心算法是自顶下向下,以迭代的方式一步一步做出贪心选择,从而把问题简化成规模更小的问题 
    这里写图片描述

贪心算法的基本思路

从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。 
该算法存在问题: 
1. 不能保证求得的最后解是最佳的; 
2. 不能用来求最大或最小解问题; 
3. 只能求满足某些约束条件的可行解的范围。 
实现该算法的过程: 
从问题的某一初始解出发; 
while 能朝给定总目标前进一步 do 
   求出可行解的一个解元素; 
由所有解元素组合成问题的一个可行解;

背包问题:

private int  MAX_WEIGHT = 20;
private int[] weights = new int[]{35,30,60,50,40,10,25};
private int[] values = new int[]{10,40,30,50,35,40,30};

private void packageGreedy(int capacity,int weights[],int[] values) {
    int n = weights.length;
    double[] r = new double[n];//性价比数组
    int [] index = new int[n];//按性价比排序物品的下标
    for(int i = 0;i<n;i++){
        r[i] = (double)values[i]/weights[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] = index[x];
            }
        }
    }
    //排序好的重量和价值分别存到数组
    int[] w1 = new int[n];
    int[] v1 = new int[n];
    for(int i = 0;i<n;i++){
        w1[i] = weights[index[i]];
        v1[i] = values[index[i]];
    }
    int[] x = new int[n];
    int maxValue = 0;
    for(int i = 0;i<n;i++){
        if(w1[i]<capacity){
            //还可以装得下
            x[i] = 1;//表示该物品被装了
            maxValue+=v1[i];
            System.out.println("物品"+w1[i]+"被放进包包");
            capacity = capacity - w1[i];
        }
    }
    System.out.println("总共放下的物品数量:"+ Arrays.toString(x));
    System.out.println("最大价值:"+maxValue);


}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值