开源算法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;
    }
}
相关推荐
程序员码歌12 小时前
明年35岁了,如何破局?说说心里话
android·前端·后端
橙*^O^*安12 小时前
Go 语言基础:变量与常量
运维·开发语言·后端·golang·kubernetes
工程师小星星12 小时前
Golang语言的文件组织方式
开发语言·后端·golang
哈喽姥爷13 小时前
Spring Boot---自动配置原理和自定义Starter
java·spring boot·后端·自定义starter·自动配置原理
舒一笑14 小时前
为什么where=Version就是乐观锁了?
后端·mysql·程序员
GoGeekBaird14 小时前
关于垂类AI应用落地行业的方法论思考
后端·github·agent
小宁爱Python15 小时前
Django 基础入门:命令、结构与核心配置全解析
后端·python·django
你的人类朋友15 小时前
认识一下Bcrypt哈希算法
后端·安全·程序员
tangweiguo0305198716 小时前
基于 Django 与 Bootstrap 构建的现代化设备管理平台
后端·django·bootstrap
IT果果日记16 小时前
详解DataX开发达梦数据库插件
大数据·数据库·后端