当前位置: 首页 > news >正文

OR-TOOL 背包算法

起因:最近公司要发票自动匹配,

比如财务输入10000W块,找到发票中能凑10000的。然后可以快速核销。

废话不多,

一 官方文档

https://developers.google.cn/optimization/pack/knapsack?hl=zh-cn

二 POM文件

        <!--google 算法包--><dependency><groupId>com.google.ortools</groupId><artifactId>ortools-java</artifactId><version>9.9.3963</version></dependency><!--google 算法包-->

三 代码

1 查询业务数据

说明:根据条件查询List<FsBill>,

由于发票金额的匹配,只有一个维度,所以设置values=amount,

然后调用knapsackSolver_invoice背包核心算法。

    @Overridepublic List<FsBill> solverBill(CheckingBill_Req req) {List<FsBill> fsBills = findCheckingBill(req);//背包算法只支持Long,所以amount*1000转换//由于不需要考虑价值因素,所以设置values=amount.这样可以匹配正好的金额。long[] values = fsBills.stream().mapToLong(x -> x.getTotalRateAmount().multiply(new BigDecimal(1000)).longValue()).toArray();//金额:小数*1000,作整数处理。long[][] amount = {values};//总金额*1000,作整数处理。long[] capacities = {req.getTotalAmount().multiply(new BigDecimal(1000)).longValue()};List<Integer> fsBillIndexs = knapsackSolver_invoice(values, amount, capacities);List<FsBill> solverBill = new ArrayList<>();if (!CollectionUtils.isEmpty(fsBillIndexs)) {for (Integer i : fsBillIndexs) {solverBill.add(fsBills.get(i));}}return solverBill;}

2 背包核心算法

说明:

values:代表物品价值(发票只有一个金额维度,所以values=weights)

weights:物品重量(此处可以传递发票金额amount)

返回的是List<Integer>数组下标,可以对应到List<FsBill>的对象。

@Overridepublic List<Integer> knapsackSolver_invoice(long[] values, long[][] weights, long[] capacities) {//加载OR-TOOL本地库Loader.loadNativeLibraries();//开始业务System.out.println("=========Begin : 匹配发票");KnapsackSolver solver = new KnapsackSolver(KnapsackSolver.SolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, "test");solver.init(values, weights, capacities);final long computedValue = solver.solve();ArrayList<Integer> packedItems = new ArrayList<>();ArrayList<Long> packedWeights = new ArrayList<>();int totalWeight = 0;for (int i = 0; i < values.length; i++) {if (solver.bestSolutionContains(i)) {packedItems.add(i);packedWeights.add(weights[0][i]);totalWeight = (int) (totalWeight + weights[0][i]);}}//匹配金额System.out.println("Target amounts: " + capacities[0]);//总价值System.out.println("Total values: " + computedValue);//总重量System.out.println("Total amounts: " + totalWeight);//装载项的下标,可对应List<发票>的下标System.out.println("Packed items: " + packedItems);//装载项的重量System.out.println("Packed amounts: " + packedWeights);System.out.println("=========End : 匹配发票");//如果没有完全匹配金额,则清空packedItemsif (capacities[0] != totalWeight) {packedItems.clear();}return packedItems;}

 

http://www.lryc.cn/news/337581.html

相关文章:

  • 前端h5录音
  • Android Studio 使用Flutter开发第一个Web页面(进行中)
  • Vue.js组件精讲 第2章 基础:Vue.js组件的三个API:prop、event、slot
  • npm install 报 ERESOLVE unable to resolve dependency tree 异常解决方法
  • RPC还是HTTP
  • Conda 常用命令总结
  • Spring MVC 文件上传和下载
  • WSL访问adb usb device
  • CDF与PDF(描述随机变量的分布情况)
  • react项目中需要条形码功能,安装react-barcode使用时报错
  • ES6基础(JavaScript基础)
  • [蓝桥杯] 纸张尺寸(C语言)
  • AI推介-多模态视觉语言模型VLMs论文速览(arXiv方向):2024.04.05-2024.04.10
  • 【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos
  • kubeadm k8s 1.24之后版本安装,带cri-dockerd
  • 13-pyspark的共享变量用法总结
  • BI数据分析软件:行业趋势与功能特点剖析
  • centos7上docker搭建vulhub靶场
  • Flutter入门指南
  • keepalived脑裂问题
  • 【Linux笔记】编mysql库
  • vscode远程免密登录ssh
  • 2024年MathorCup数模竞赛C题详解
  • 【简单讲解如何安装与配置Composer】
  • 深入理解Apache ZooKeeper与Kafka的协同工作原理
  • js解密心得,记录一次抓包vue解密过程
  • redis-哨兵模式
  • 自动化测试中的SOLID原则
  • tencentcloud-sdk-python-iotexplorer和tencent-iot-device有什么区别
  • Spring day1