• 算法-经典趣题-窃贼问题


    一、问题

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

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

    物品1:6公斤,48元。

    物品2:5公斤,40元。

    物品3:2公斤,12元。

    物品4:1公斤,8元。

    物品5:1公斤,7元。

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

    二、分析

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

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

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

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

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

     

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

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

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

    三、编程

    package com.joshua317;
    
    import java.util.Arrays;
    import java.util.Scanner;
    import java.util.logging.SocketHandler;
    
    public class Main {
        static double maxPrice;//最大的价值
        static double totalPrice;//物品的总价值
        static double maxWeight;//最大限制的重量
        static  int goodsNum;//可选物品的数量
        static char[] selectTemp;//临时数组
    
        public static void main(String[] args) {
    
            System.out.println("窃贼问题-最优化问题");
            System.out.println("请输入窃贼可以装入物品的最大重量");
            Scanner scanner = new Scanner(System.in);
            maxWeight = scanner.nextDouble();
            System.out.println("请输入窃贼可选物品的数量");
            goodsNum = scanner.nextInt();
    
            Goods[] goods = new Goods[goodsNum];
            totalPrice = 0;
    
            for (int i = 0; i < goodsNum; i++) {
                Goods temp = new Goods();
                System.out.println("请输入第"+(i+1)+"件物品的重量和价格");
                temp.weight = scanner.nextDouble();
                temp.price = scanner.nextDouble();
                totalPrice += temp.price;
                goods[i] = temp;
            }
    
            //打印初始化信息
            System.out.println("背包可以装入物品的最大重量为" + maxWeight);
            for (int i = 0; i < goodsNum; i++) {
                System.out.println("第" + (i+1) + "号物品的重量为:"+goods[i].weight + "  价格为:" + goods[i].price);
            }
    
            //初始化被选择信息
            selectTemp = new char[goodsNum];
            for (int i = 0; i < goodsNum; i++) {
                selectTemp[i] = 0;
            }
            maxPrice = 0;
            //求解
            backPack(goods, 0, 0.0, totalPrice);
    
            double totalWeight = 0;//总重量
            //打印最佳方案
            System.out.println("可以装入以下物品,使得获取的价值最大");
            for (int i = 0; i < goodsNum; i++) {
                if (goods[i].isSelect == 1) {
                    System.out.println("第" + (i+1) + "号物品,其中:重量为:"+goods[i].weight + "  价格为:" + goods[i].price);
                    totalWeight += goods[i].weight;
                }
            }
            System.out.println("总重量为:" + totalWeight + "总价值为:" + maxPrice);
        }
    
        public static void backPack(Goods[] goods, int i, double weight, double tp) {
            int k;
            //将物品i包含在当前方案中,判断重量是否小于等于最大限制的重量
            if (weight + goods[i].weight <= maxWeight) {
                selectTemp[i] = 1;//选择第i个物品
                if (i < goodsNum - 1) {//如果物品i不是最后一个物品
                    backPack(goods, i+1, weight + goods[i].weight, tp);
                } else {
                    for (k = 0; k < goodsNum; k++) {
                        goods[k].isSelect = selectTemp[k];
                    }
                    maxPrice = tp;//保存方案的最大价值
                }
            }
    
            selectTemp[i] = 0;//取消物品i的选择状态
            //判断是否超重,还可以继续添加物品
            if (tp - goods[i].price > maxPrice) {
                if (i < goodsNum - 1) {//如果物品i不是最后一个物品
                    backPack(goods, i+1, weight,tp - goods[i].price);
                } else {
                    for (k = 0; k < goodsNum; k++) {
                        goods[k].isSelect = selectTemp[k];
                    }
                    maxPrice = tp - goods[i].price;//保存方案的最大价值
                }
            }
        }
    
    
    }
    
    class Goods {
        double price;//价钱
        double weight;//重量
        char isSelect;//是否选中到方案里面
    }
     
     

     

     
  • 相关阅读:
    MVC中单用户登录
    用CheckBox做删除时请不要使用@Html.CheckBoxFor
    MVC3"不允许启动新事务,因为有其他线程正在该会话中运行"错误解决方法
    下拉菜单DropDwon实现方法
    MVC3中Ajax.ActionLink用法
    删除时显示确认对话框
    民航指令学习(一)
    CentOS常用命令
    CentOS手动分区步骤
    CentOS下安装JDK和Tomcat
  • 原文地址:https://www.cnblogs.com/joshua317/p/15244266.html
Copyright © 2020-2023  润新知