01背包问题 动态规划

介绍:这个算法自己本有比较深刻的了解,也有很多人从专业的角度去解释了这个算法,而我主要是针对01背包问题而用代码的方式实现了它。

题目场景是这样子的:
假设有一个重量为 totalWeight 的背包
* 现有物品a1,a2,….an,他们的重量为w1,w2,w3….wn 价值为v1,v2,v3….vn.(w1+w2+w3….>totalWeight)
* 请问如何将物品放入背包中才能让物品价值最大化
这个题目拿到的话,反正我是没想到什么方法解决。但是看了分析才焕然大悟。

import java.util.List;

public class ZuiYouJie {

    int totalWeight;
    int currentWeight;

    List<Zone>zoneAllList;
    int zuiYouValue [][] = new  int[100][100];

    public ZuiYouJie(int totalWeight,List<Zone> zoneAllList){
        this.totalWeight = totalWeight;
        this.zoneAllList = zoneAllList;
    }

    public  void getZuiYou(){

        int size = zoneAllList.size();
        //当i=0的时候
        for(int i=0;i<totalWeight;i++){
            zuiYouValue[0][i] = 0;
        }

        for(int i=0;i<size;i++){
            zuiYouValue[i][0] = 0;
        }

        for(int currentWeight=1;currentWeight<=totalWeight;currentWeight++){
            for(int i=1;i<=size;i++){
                 Zone currentZone = zoneAllList.get(i-1);
                 if(currentWeight<zoneAllList.get(i-1).getWeight()){
                     zuiYouValue[i][currentWeight]=zuiYouValue[i-1][currentWeight];
                 }
                 else{
                     //如果
                     if(zuiYouValue[i-1][currentWeight-currentZone.getWeight()]+currentZone.getValue()>zuiYouValue[i-1][currentWeight]){
                         zuiYouValue[i][currentWeight] =  zuiYouValue[i-1][currentWeight-currentZone.getWeight()]+currentZone.getValue();
                     }else{
                         zuiYouValue[i][currentWeight] = zuiYouValue[i-1][currentWeight];
                     }
                 }
            }
        }
         int currentWeightForCompare = totalWeight; 
         for(int k = size;k>0;k--){
             if(zuiYouValue[k][currentWeightForCompare]>zuiYouValue[k-1][currentWeightForCompare]){
                 zoneAllList.get(k-1).setForZuiYou(true);
                 currentWeightForCompare = currentWeightForCompare-zoneAllList.get(k-1).getWeight();
             }
             if(currentWeightForCompare==0){
                 break;
             }
         }
    }

}
public class Zone {
    int id;
    int value;
    int weight;
    boolean isForZuiYou = false;


    public boolean isForZuiYou() {
        return isForZuiYou;
    }
    public void setForZuiYou(boolean isForZuiYou) {
        this.isForZuiYou = isForZuiYou;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    public int getWeight() {
        return weight;
    }
    public void setWeight(int weight) {
        this.weight = weight;
    }

}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class DynamicProgramming {
    /**
     * 动态规划 01背包问题
     * 假设有一个重量为 totalWeight 的背包
     * 现有物品a1,a2,....an,他们的重量为w1,w2,w3....wn 价值为v1,v2,v3....vn.(w1+w2+w3....>totalWeight)
     * 请问如何将物品放入背包中才能让物品价值最大化
     * 可以肯定的是要将这n个中的物品选择其中 m个放入背包
     * 那么那些要放那些不要放呢?
     * 
     * 可以想象一下场景
     * 1.若放的下一个物品大于totalWeight
     *  2.1 若是wm>currentWeight那么显然就是
     *    当 wm>currentWeight  V(m-1,currentWeight)=V(m,currentWeight) 
     *  
     *  2.2 若是currentWeight>wm那么就比较复杂了这里的话可以直接判断出第m个能否成为最优解的一员
     *  即V(m,currentWeight)=max{V(m-1,currentWeight) ,V(m-1,currentWeight-wm)+vm } 
     */

    public static void main(String[] args) {
        List<Zone>allList = new ArrayList<Zone>();
        for(int i=0;i<10;i++){
            Zone zone = new Zone();
            zone.setId(i);
            zone.setWeight(getRandome(10,5));
            zone.setValue(getRandome(20,10));
            System.out.println("第"+i+"物品重量为:"+zone.getWeight()+"价值为:"+zone.getValue());
            allList.add(zone);
        }
        int sumValue = 0;
        int sumWeight = 0;
        ZuiYouJie zuiYouJie = new ZuiYouJie(50,allList);
        zuiYouJie.getZuiYou();
        for(int i=0;i<allList.size();i++){
            Zone zone = allList.get(i);
            if(allList.get(i).isForZuiYou){
                System.out.println("最优解 第"+zone.getId()+"物品重量为:"+zone.getWeight()+"价值为:"+zone.getValue());
                sumValue += zone.getValue();
                sumWeight += zone.getWeight();
            }
        }
        System.out.println("最优解总价值:"+sumValue);
        System.out.println("最优解总重量:"+sumWeight);
    }

    public static int getRandome(int max,int min){
        Random random = new Random();
        int s = random.nextInt(max)%(max-min+1) + min;
        return s;
    }
}

没怎么做详细的解释,下次理解更加透彻了,再加上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值