栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

通过0-1背包问题看穷举法、贪心算法、启发式算法(JAVA)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

通过0-1背包问题看穷举法、贪心算法、启发式算法(JAVA)

用最简单的0-1背包问题(1-0 knapsack problem)来说明穷举法、贪心算法、启发式算法。

0-1背包问题简述:

有一个背包,背包能装的物品重量是有限的,只能装C kg的物品。
现在有N个物品,每个物品都有自己的重量w和价值v。
现在要你决策:选哪些物品装进背包,才能使得不超过背包容量情况下,装的物品价值最大?

一、穷举法

穷举法是一种暴力求解方式。首先穷举所以可能的情况,也就是找到解空间,然后遍历解空间找到最好的方案。
通过穷举生成解空间(n个物品):对每个物品要么选择(1),要么不选择(0);生成一个长度为n的数组,数组的每个元素表示每个物品,元素的值为0或1,得到的每个数组就是一种可能的解;所有的数组放一起就是解空间。n个物品,解空间中有2^n种可能(每个物品要么选择要么不选择)。

1.1.代码实现

算例:背包能装载的最大重量为100,商品数量4个,重量分别是:18,42,88,3,价值分别是:141,136,192,223

package com.wuxiaolong.algorithm.knapsackProblem;

import java.util.ArrayList;
import java.util.List;


public class KnapsackProblem {

    public static void main(String[] args) {
        // 启动
        exhaustAlgorithm();
    }

    
    public static void  exhaustAlgorithm(){

        // 1.算例定义:背包限制重量100  有4个物品 每个物品的重量和价值
        double knapsackLimit = 100;
        int goodsNum = 4;
        double[] weights = {18,42,88,3};
        double[] values ={141,136,192,223};

        // 2.根据商品数量生成解空间(递归+回溯)
        List> solutionSpace = getSolutionSpace(goodsNum);

        // 3.评价每个解
        double maxVal = 0;
        List solve = null;
        for(int i=0; i curr = solutionSpace.get(i);
            double w = 0;
            double v = 0;
            for(int j=0; j=maxVal){
                    maxVal = v;
                    solve = curr;
                }
            }
        }

        // 4.输出最优解
        System.out.println("最大价值:"+ maxVal + "  最优方案:"+solve);
    }

    
    public static List> getSolutionSpace(int goodsNum){

        List> result = new ArrayList<>();
        List path = new ArrayList<>();

        // 递归的层数 相当于每个物品就是一层for
        Integer index = 1;
        Integer length = goodsNum;

        // 递归
        dfs(result,path,length,index);

        System.out.println("解空间元素个数: "+result.size());
        System.out.println("解空间详情:");
        result.forEach(System.out::println);

        return result;
    }

    public static void dfs(List> result,List path, int length, int index){

        // 终止条件
        if(index>length){
            // 获取一个解
            result.add(new ArrayList<>(path));
            return;
        }

        // 每个物品有两种选择方式 1:选   0:不选
        for(int i=0; i<2; i++){
            path.add(i);
            dfs(result,path,length,index+1);
            // 回溯
            path.remove(index-1);
        }
    }
}
1.2.运行结果

上面的背包问题,通过穷举法我们找到了最优解;上面有4个商品时,解空间有24=16种可能。当商品数为50个时,解空间中需要验证的解就是250=1125899906842624种可能,假如一秒钟可以计算10亿次,需要1125899秒=312小时。这在时间生活生产中是不能接受的。可见穷举法求解时间随问题规模增长而呈爆炸式增长,这也是穷举法的最大问题。

1.3.总结

穷举法的特点:

  1. 通过比较解空间中的所有解(可行的和不可行的),穷举法一定能找到问题的最优解。穷举法简单粗暴,结果还是最优。
  2. 在问题规模较小时,是一种比较好的解决问题的方式
  3. 当问题规模过大时,求解所消耗的资源是不能接受的,需要寻找其他方式解决问题。
二、贪心算法

贪心算法是将一个问题差分成多个子问题,找到每个子问题的最优解就找到了全局的最优解。比如需要分别从10个箱子中取一张钞票(假如每个箱子中都有各种面额的钞票),要求取得的钞票加起来总面额最高,这时就可以从每个箱子中取最大面额的钞票就会使整个金额最大。对于某些问题贪心是一种很好的方式,但是对于某些情况,贪心就不能满足要求。贪心是一种目光短浅的做法,因为它只关注当前的最优性,而对于最后总体会变成什么样子就不管不顾了。

2.1.代码实现

使用上面相同的算例,用贪心算法编码:

算例:背包能装载的最大重量为100,商品数量4个,重量分别是:18,42,88,3,价值分别是:141,136,192,223

package com.wuxiaolong.algorithm.knapsackProblem;

import java.util.*;


public class KnapsackProblem1 {

    public static void main(String[] args) {
        greedyAlgorithm();
    }

    
    public static void  greedyAlgorithm(){

        // 1.算例定义:背包限制 10个物品 每个物品的重量和价值
        double knapsackLimt = 100;
        int goodsNum = 4;
        double[] weights = {18,42,88,3};
        double[] values ={141,136,192,223};

        // 2.商品信息放入item对象
        List goodsList = new ArrayList<>();
        for(int i=0; i(){
            @Override
            public int compare(Item o1, Item o2) {
                return o2.getValWghtRate().compareTo(o1.getValWghtRate());
            }
        });
        System.out.println("按照价值重量比排序后的结果:{}"+goodsList);

        // 4.每次找满足条件的最大的商品,每个商品找一次
        List selectedGoods = new ArrayList<>();
        double currSumWeight = 0;
        double maxVal = 0;
        for(int i=0; i
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328071.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号