开源算法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;
    }
}
相关推荐
程序员爱钓鱼1 分钟前
Go for 循环详解
后端·面试·go
程序员爱钓鱼1 分钟前
Rust impl详解:为Struct定义方法与关联函数
前端·后端·rust
weixin_4316004410 分钟前
NestJS 入门(9):连上数据库,SQL 写在哪?
数据库·后端·sql·学习·nest.js
qq_225891746624 分钟前
基于Flask的城市地铁客流量数据预测系统设计与实现
后端·python·flask
IT_陈寒26 分钟前
搞不定JavaScript的数组去重?你可能漏了这两个坑
前端·人工智能·后端
AINative软件工程1 小时前
AI Agent 证据仲裁工程实践:别让检索结果按自信程度撒谎
人工智能·后端·ai编程
卷无止境2 小时前
FastAPI 权限管理实战:从 ACL 到 RBAC 的那些门道
后端·python·fastapi
GreenTea10 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
风流 少年10 小时前
Spring AI 2.0:Memory
java·后端·spring
万少10 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端