开源算法or-tools运用之背包问题

今天发现了一个可以很好解决背包问题的方法。

首先简要说明一下背包问题:给定一组物品,每个物品都有相应的价值以及总量,我们有一个背包,容量有限,如何在有限的容量中选择物品,让总价值最大。

通常我们的解决办法是使用动态规划来解决,具体如何解决这里就不阐述了,下面我给大家介绍一种更简单的方法:那就是or-tools!(免费、开源、支持java8)
首先定义物品信息:

在使用时需要创建模型:

ini 复制代码
CpModel model = new CpModel();

然后创建线性表达式来合计重量和价值:

ini 复制代码
LinearExprBuilder weightVar = LinearExpr.newBuilder();
```
LinearExprBuilder allPriceVar = LinearExpr.newBuilder();
 ```

接下来就是关键步骤,将每个物品信息(重量、价格)添加进来

接下就是添加约束条件

//总的重量必须小于背包允许的重量(maxWeight) 复制代码
model.addLessOrEqual(weightVar,maxWeight);

再设定我们的求解目标(价值最大)

ini 复制代码
model.maximize(LinearExpr.sum(new LinearArgument[]{allPriceVar}));

最后进行求解

scss 复制代码
CpSolver solver = new CpSolver();
solver.getParameters().setMaxTimeInSeconds(60); // 60秒超时
solver.getParameters().setEnumerateAllSolutions(true);//找出所有的可行解
CpSolverStatus status = solver.solve(model);

是不是感觉很简单,我们不用再自己写循环进行来求解了,or-tools会不断的进行尝试找到最优的解。 以下是某次运行的结果

下面是完整的代码,有兴趣的小伙伴可以试着调整用不同的参数运行看看效果。

ini 复制代码
import com.google.ortools.Loader;
import com.google.ortools.sat.*;

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

public class BagProblemDemo {
    static {
        Loader.loadNativeLibraries();
    }
    public static void main(String[] args) {
        //背包允许的最大重量
        Integer maxWeight=100;
        List<GoodInfo> goodsInfoList=getGoods();
        // 2. 创建模型
        CpModel model = new CpModel();
        //目标,在有限的重量下,让价值最大
        //创建重量的变量
        LinearExprBuilder weightVar = LinearExpr.newBuilder();
        //价值
        LinearExprBuilder allPriceVar = LinearExpr.newBuilder();
        for (GoodInfo goodInfo : goodsInfoList) {
            //创建变量
            BoolVar isPickVar = model.newBoolVar("is_pick_"+goodInfo.getGoodId());
            goodInfo.setPickBool(isPickVar);
            Integer price = goodInfo.getPrice();
            Integer weight = goodInfo.getWeight();
            Integer signelPrice=price*weight;
            //添加价值信息
            allPriceVar.addTerm(isPickVar,signelPrice);
            //添加重量信息
            weightVar.addTerm(isPickVar,weight);
        }
        model.addLessOrEqual(weightVar,maxWeight);
        model.maximize(LinearExpr.sum(new LinearArgument[]{allPriceVar}));
        CpSolver solver = new CpSolver();
        solver.getParameters().setMaxTimeInSeconds(60); // 60秒超时
        solver.getParameters().setEnumerateAllSolutions(true);//找出所有的可行解
        CpSolverStatus status = solver.solve(model);
        if (status == CpSolverStatus.OPTIMAL || status == CpSolverStatus.FEASIBLE) {
            System.out.printf("求解状态: %s\n", status);
            System.out.printf("重量: %d\n", solver.value(weightVar));
            System.out.printf("价值: %d\n", solver.value(allPriceVar));
            for (GoodInfo goodInfo : goodsInfoList) {
                System.out.println(goodInfo.toString());
                if (solver.booleanValue(goodInfo.getPickBool())){
                    System.out.println("选中了"+goodInfo.getGoodName());
                }
            }
        }else{
            System.out.printf("无解");
        }
    }
    private static List<GoodInfo> getGoods(){
        List<GoodInfo> bagInfoList=new ArrayList<GoodInfo>();
        for(int i=1;i<=10;i++){
            GoodInfo goodInfo = new GoodInfo();
            Integer wehgith=new Random().nextInt(50);
            goodInfo.setWeight(wehgith);
            Integer price=new Random().nextInt(60);
            goodInfo.setPrice(price);
            goodInfo.setGoodName("bag"+i);
            goodInfo.setGoodId(i);
            bagInfoList.add(goodInfo);
        }
        return bagInfoList;
    }
}
相关推荐
H5css�海秀3 小时前
今天是自学大模型的第一天(sanjose)
后端·python·node.js·php
SuniaWang3 小时前
《Spring AI + 大模型全栈实战》学习手册系列 · 专题六:《Vue3 前端开发实战:打造企业级 RAG 问答界面》
java·前端·人工智能·spring boot·后端·spring·架构
韩立学长3 小时前
Springboot校园跑腿业务系统0b7amk02(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
sheji34163 小时前
【开题答辩全过程】以 基于springboot的扶贫系统为例,包含答辩的问题和答案
java·spring boot·后端
代码栈上的思考4 小时前
消息队列:内存与磁盘数据中心设计与实现
后端·spring
程序员小假5 小时前
我们来说一下 b+ 树与 b 树的区别
java·后端
Meepo_haha5 小时前
Spring Boot 条件注解:@ConditionalOnProperty 完全解析
java·spring boot·后端
sheji34166 小时前
【开题答辩全过程】以 基于springboot的房屋租赁系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
Victor3566 小时前
MongoDB(57)如何优化MongoDB的查询性能?
后端
Victor3567 小时前
MongoDB(58)如何使用索引优化查询?
后端