• 窃贼问题


    窃贼问题是一个典型的最优化问题。窃贼问题的大意如下:

    有一个窃贼带着一个背包去偷东西,房屋中共有5件物品,其重量和价值如下:

    物品1: 6公斤,48元

    物品2: 5公斤,40元

    物品3: 2公斤,12元

    物品4: 1公斤,8元

    物品5: 1公斤,7元。

    窃贼希望能够拿最大价值的东西,而窃贼的背包最多可装重量为8公斤的物品。那么窃贼应该装上述哪些物品才能达到要求呢?

     1. 窃贼问题算法

    首先来分析一下窃贼问题。窃贼问题是关于最优化的问题,可使用动态规划的思想来解最优化问题。窃贼问题求解的操作过程如下:

    (1)首先创建一个空集合。

    (2)然后向空集合中增加元素,每增加一个元素就先求出该阶段最优解。

    (3)继续添加元素,直到所有的元素都添加到集合中,最后得到的就是最优解。

    采用上述思路,窃贼问题的求解算法如下:

    (1)首先,窃贼将物品i试着添加到方案中。

    (2)然后判断是否超重,若未超重,则继续添加下一个物品,重复第一步。

    (3)若超重,则将该物品排除在方案之外,并判断此时所有未排除物品的价值是否小于已有最大值;如果满足,则不必再尝试后续物品了。

     可以按照此思路来编写相应的窃贼问题的求解算法,代码示例如下:

        static class GType{    //物品数据结构
            double value;    //价值
            double weight;    //重量
            char isSelect;    //是否选中到方案
        }
        
        static double maxvalue;    //方案最大价值
        static double totalvalue;    //物品总价值
        static double maxwt;    //窃贼能拿的最大重量
        static int num;        //物品数量
        static char[] seltemp;    //临时数组
        /**
         * 算法
         * @param goods 物品
         * @param i    下一个待选物品
         * @param wt 盗贼现拿物品重量
         * @param vt 可选物品总价值
         */
        static void backpack(GType[] goods,int i,double wt,double vt){
            int k;
            if(wt+goods[i].weight<=maxwt){    //将物品i包含在当前方案,判断重量小于等于限制重量
                seltemp[i]=1;    //选中第i个物品
                if(i<num-1){        //如果物品i不是最后一个物品
                    backpack(goods,i+1,wt+goods[i].weight,vt);    //递归调用,继续添加物品
                }else{
                    for(k=0;k<num;++k){
                        goods[k].isSelect=seltemp[k];
                    }
                    maxvalue=vt;    //保存当前方案的最大价值
                }
            }
            seltemp[i]=0;    //取消物品i的选择状态
            if(vt-goods[i].value>maxvalue){    //还可以继续添加物品
                if(i<num-1){
                    backpack(goods,i+1,wt,vt-goods[i].value);    //递归调用
                }else{
                    for(k=0;k<num;++k){
                        goods[k].isSelect=seltemp[k];
                    }
                    maxvalue=vt-goods[i].value;
                }
            }
        }

    2. 窃贼问题求解

    求解窃贼问题的完整代码如下:

    package com.cn.suanfaquti;
    
    import java.util.Scanner;
    
    public class QieZeiQuestion {
        static class GType{    //物品数据结构
            double value;    //价值
            double weight;    //重量
            char isSelect;    //是否选中到方案
        }
        
        static double maxvalue;    //方案最大价值
        static double totalvalue;    //物品总价值
        static double maxwt;    //窃贼能拿的最大重量
        static int num;        //物品数量
        static char[] seltemp;    //临时数组
        /**
         * 算法
         * @param goods 物品
         * @param i    下一个待选物品
         * @param wt 盗贼现拿物品重量
         * @param vt 可选物品总价值
         */
        static void backpack(GType[] goods,int i,double wt,double vt){
            int k;
            if(wt+goods[i].weight<=maxwt){    //将物品i包含在当前方案,判断重量小于等于限制重量
                seltemp[i]=1;    //选中第i个物品
                if(i<num-1){        //如果物品i不是最后一个物品
                    backpack(goods,i+1,wt+goods[i].weight,vt);    //递归调用,继续添加物品
                }else{
                    for(k=0;k<num;++k){
                        goods[k].isSelect=seltemp[k];
                    }
                    maxvalue=vt;    //保存当前方案的最大价值
                }
            }
            seltemp[i]=0;    //取消物品i的选择状态
            if(vt-goods[i].value>maxvalue){    //还可以继续添加物品
                if(i<num-1){
                    backpack(goods,i+1,wt,vt-goods[i].value);    //递归调用
                }else{
                    for(k=0;k<num;++k){
                        goods[k].isSelect=seltemp[k];
                    }
                    maxvalue=vt-goods[i].value;
                }
            }
        }
        
        public static void main(String[] args) {
            double sumweight;
            int i;
            System.out.println("窃贼问题求解!");
            System.out.print("窃贼背包能容纳的最大重量:");
            Scanner input = new Scanner(System.in);
            maxwt=input.nextDouble();    //窃贼背包能容纳的最大重量
            System.out.print("可选物品数量:");
            num = input.nextInt();     //可选物品的数量
            GType[] goods=new GType[num];
            seltemp = new char[num];
            totalvalue=0;    //初始化总价值
            for(i=0;i<num;i++){
                GType t = new GType();
                System.out.print("输入第"+(i+1)+"号物品的重量和价值:");
                t.weight=input.nextDouble();
                t.value = input.nextDouble();
                totalvalue+=t.value;
                goods[i]=t;
            }
            System.out.print("
    背包最大能装的重量为:"+maxwt+"
    
    ");
            for(i=0;i<num;i++){
                System.out.println("第"+(i+1)+"号物品重:"+goods[i].weight+",价值:"+goods[i].value);
                seltemp[i]=0;
            }
            maxvalue=0;
            backpack(goods,0,0.0,totalvalue);    //求解
            sumweight=0;
            System.out.println("
    可将以下物品装入背包,使背包的物品价值最大:");
            for(i=0;i<num;++i){
                if(goods[i].isSelect==1){
                    System.out.println("第"+(i+1)+"号物品,重量:"+goods[i].weight+",价值:"+goods[i].value);
                    sumweight+=goods[i].weight;
                }
            }
            System.out.println("
    总重量为:"+sumweight+",总价值为:"+maxvalue);
        }
    
    }

    程序运行结果如下:

    窃贼问题求解!
    窃贼背包能容纳的最大重量:8
    可选物品数量:5
    输入第1号物品的重量和价值:6 48
    输入第2号物品的重量和价值:5 40
    输入第3号物品的重量和价值:2 12
    输入第4号物品的重量和价值:1 8
    输入第5号物品的重量和价值:1 7
    
    背包最大能装的重量为:8.0
    
    第1号物品重:6.0,价值:48.0
    第2号物品重:5.0,价值:40.0
    第3号物品重:2.0,价值:12.0
    第4号物品重:1.0,价值:8.0
    第5号物品重:1.0,价值:7.0
    
    可将以下物品装入背包,使背包的物品价值最大:
    第1号物品,重量:6.0,价值:48.0
    第4号物品,重量:1.0,价值:8.0
    第5号物品,重量:1.0,价值:7.0
    
    总重量为:8.0,总价值为:63.0
  • 相关阅读:
    Vue的style与class
    position记录
    JS 原型模式创建对象
    Js 栈和堆的实现
    slice深拷贝数组
    Vue路由query传参
    Object.prototype.toString.call(value)
    Node里面的对象创建问题
    Django模板语言 标签整理
    JavaScript基础
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4510530.html
Copyright © 2020-2023  润新知