贪心_01背包

package agrisom;

import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * 贪心算法求背包问题
 */
/**
 * 物品类
 */
class Good{
    public int weight;     //重量
    public int value;      //价值
    public int status;     //选中标志
    public String name;    //货品名称
    public float rate;     //单价
}
public class BackPackGreedy {
    public Good [] goods;
    /**
     * 物品初始化
     */
    public void init(int [] weights,int [] values){
        int length=weights.length;
        this.goods=new Good[length];
        for(int i=0;i<length;i++){
            Good good=new Good();
            goods[i]=good;
            good.weight=weights[i];
            good.value=values[i];
            good.status=0;
            good.name=(i+1)+"";
            good.rate=(values[i]+0f)/weights[i];
        }
        this.print();
    }
    
    /**
     * 打印物品状态
     */
    public void print(){
        String formatStr="            ";
        DecimalFormat df=new DecimalFormat("##0.000");
        for(int i=0;i<this.goods.length;i++){
            Good good=goods[i];
            System.out.print(good.name+formatStr);
            System.out.print(good.weight+formatStr);
            System.out.print(good.value+formatStr);
            System.out.print(df.format(good.rate)+formatStr);
            System.out.println(good.status+formatStr);
        }
        System.out.println();
    }
    /**
     * 贪心策略:每次选取单位容量价值最大的物品
     */
    public void greedy(int maxWeight){
        int packWeight=0;  //当前背包重量
        int packValue=0;   //当前背包价值
        float maxRate=0f;  //当前最大货品单价
        int j=0,n=0;
        String [] names=new String [this.goods.length];  //选择的物品数组
        while(packWeight<maxWeight)
        {
              for(int i=0;i<this.goods.length;i++)
              {
                      if(goods[i].rate>maxRate && goods[i].status==0)
                      {
                          maxRate=goods[i].rate;
                          j=i;
                      }
              }
              names[n++]=goods[j].name;
              maxRate=0.0f;
              goods[j].status=1;
              if(packWeight+goods[j].weight<maxWeight){
                  packWeight=packWeight+goods[j].weight;
                  packValue=packValue+goods[j].value;
              }else{
                  break;
              }
        }
        this.print();
        System.out.println("packWeight: "+packWeight+" packValue: "+packValue);
        System.out.print("selected goods list: ");
        for(int i=0;i<names.length;i++){
            if(names[i]!=null){
                System.out.print(names[i] + "  ");
            }
        }
    }
    
    public static void main(String [] args){
        int [] weights=new int[]{35,30,60,50,40,10,25};
        int [] values=new int[]{10,40,30,50,35,40,30};
        BackPackGreedy bpg=new BackPackGreedy();
        bpg.init(weights, values);
        bpg.greedy(150);
    }
}

/**
运行结果:
1            35            10            0.286            0            
2            30            40            1.333            0            
3            60            30            0.500            0            
4            50            50            1.000            0            
5            40            35            0.875            0            
6            10            40            4.000            0            
7            25            30            1.200            0            

1            35            10            0.286            0            
2            30            40            1.333            1            
3            60            30            0.500            0            
4            50            50            1.000            1            
5            40            35            0.875            1            
6            10            40            4.000            1            
7            25            30            1.200            1            

packWeight: 115 packValue: 160
selected goods list: 6  2  7  4  5  
*/
### 使用贪心算法解决01背包问题 对于01背包问题而言,通常推荐采用动态规划而非贪心算法来获得全局最优解[^1]。然而,在特定条件下,也可以尝试应用贪心策略处理简化版的01背包问题。 当面对严格定义下的01背包问题时——即每种物品仅能选取一次且不可分割的情况下,直接运用标准贪心法则往往无法保证找到全局最优解。这是因为贪心法倾向于每次都作出局部最优的选择,这可能导致最终未能达到整体最佳效果。不过,如果允许对物品进行切割或存在其他特殊条件,则可以通过调整后的贪心方法近似解决问题。 为了更好地理解这一点,下面给出一段基于贪心思路的伪代码示例,用于说明如何在假设可分物品的前提下模拟01背包问题: ```python def fractional_knapsack(value, weight, capacity): """Fractional Knapsack using Greedy Approach""" index = list(range(len(value))) # 物品索引列表 ratio = [v/w for v, w in zip(value, weight)] # 计算单位重量的价值比率 # 将物品按照价值密度降序排列 index.sort(key=lambda i: ratio[i], reverse=True) max_value = 0 fractions = [0] * len(value) for i in index: if weight[i] <= capacity: fractions[i] = 1 max_value += value[i] capacity -= weight[i] else: fractions[i] = capacity / weight[i] max_value += value[i] * capacity / weight[i] break return max_value, fractions ``` 需要注意的是,上述代码适用于分数背包问题而不是严格的01背包问题。对于后者来说,由于其特性决定了每次只能取整件商品或者完全放弃该商品,因此更适宜通过构建状态转移方程的方式利用动态规划求得精确解答[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值