「达摩院MindOpt」优化形状切割问题(MILP)

1. 形状切割问题

在制造业,高效地利用材料不仅是节约成本的重要环节,也是可持续发展的关键因素。无论是在金属加工、家具制造还是纺织品生产中,原材料的有效利用都直接影响了整体效率和环境影响。

形状切割问题(Shape Cutting or Cutting Stock Problem),以其多变的问题形式和实际应用的广泛性,成为了运筹学和优化领域中一个非常有趣且具有挑战性的研究课题。简单来说,这个问题要求我们从一块给定尺寸的材料中切割出一系列预定形状的物品,目的是最大化材料的使用效率,同时最小化浪费。虽然表述看似直白,但实际解决过程却充满了复杂性。

一维切割、二维切割、三维切割,对应的需要考虑的约束会指数升级,对应的解决方案可能会不一致。比如一维控制量只有长度,二维就有坐标x,y和转角,三维就对应x,y,z,和Roll, Pitch, Yaw三种选择角度。切割的形状不能重叠的表达也会变得非常的复杂。

本文先仅探讨一维切割问题。

image.png

一维切割的思路,扩展一下,在实际中也有很多应用,如:

  • 钢筋切割,将统一的长钢筋原材料,根据需求切割成不同长度小尺寸,如何切割能最小化使用的原材料数。
  • 木材加工,从长度不一的原材料木材中,切割出多种长度的小段,如何切割能最大化成品总长度数,提高原木材利用率。
  • 计算资源分配,将不同规格的机器,容器化成多个虚拟计算资源,如何划分能满足用户的使用需求,提高在使用机器的利用率。
  • 时间管理,将完整的工作日或项目周期分配给多个任务,使得每个任务都有足够的时间完成,同任务尽量连续时间,避免频繁切换导致时间浪费。
  • 货运装箱,在物流运输中,如何将一堆不同大小的货物合理地分配给不同的货车或者集装箱,有效提高装载效率,降低货运成本。此问题在有些场景可以用一维问题来表示,还有很多厂家是需要3维装箱问题来表达。

2. 一个具体的问题示例

假设我们有一批长度统一为100单位的水管原材料,需要切割出不同的长度,需求为

  • 14单位长度的小段 5个
  • 50单位长度的小段 7个
  • 70单位长度的小段 3个
    请问,如何安排切割,使用的原材料数目最少?

3. 数学建模和数据整理

这个问题我们用数学规划的方式建模如下:

image.png

汇总的数学模型为:


min ⁡ f u s e d s.t. f u s e d = ∑ i ∈ R b i ∑ i ∈ R x i , j ≥ d j , N u m , ∀ j ∈ D ∑ j ∈ D x i , j ⋅ d j , S i z e ≤ L ⋅ b i , ∀ i ∈ R b i ∈ { 0 , 1 } , ∀ i ∈ R x i , j 是整数 , ∀ k , i ∈ I \begin{array}{rll} \min & f_{used} & \\ \text{s.t.} & f_{used} = \sum_{i \in R}b_{i} &\\ & \sum_{i \in R} x_{i,j} \geq d_{j,Num}, & \forall j \in D \\ & \sum_{j \in D} x_{i,j} \cdot d_{j,Size} \leq L \cdot b_{i}, & \forall i \in R \\ & b_{i} \in \{0,1\}, & \forall i \in R\\ & x_{i,j} 是整数, & \forall k,i \in I \end{array} mins.t.fusedfused=iRbiiRxi,jdj,Num,jDxi,jdj,SizeLbi,bi{0,1},xi,j是整数,jDiRiRk,iI


4. MindOpt APL 建模和求解

MindOpt APL 简称(MAPL),是一款代数建模语言。更适合数学优化模型开发者的语言。建模更高效,可调用多款优化求解器。

代码解析

决策变量
  1. 变量x_pipeUsed,表示在满足所有需求后总共被使用的管道(水管原材料)数量。这是一个连续变量,但实际应用中通常会被当作整数处理,因为你不能使用部分水管。
  2. 变量var x_cuts[rawPipe] >= 0 binary; 定义了一个索引为 rawPipe(原材料水管编号集合)的二元变量数组 x_cuts。每个元素 x_cuts[i] 表示编号为 i 的原材料水管是否被切割使用:1 表示被切割使用,0 表示未被使用。由于这是一个二元变量,所以其值被限定为 0 或 1。
  3. 变量var x_cutNum[rawPipe,Demand] >= 0 integer; 定义了一个整数变量数组 x_cutNum,其索引为 rawPipe(原材料水管编号集合)和 Demand(需求序号集合)的笛卡尔积。每个元素 x_cutNum[i,j] 表示在编号为 i 的原材料水管中,编号为 j 的需求长度被切割出来的数量。整数变量意味着这些变量的值必须为非负整数。
决策目标
minimize Totalpipes: x_pipeUsed;

最小化变量 x_pipeUsed 的值,即最小化总共被使用的管道数。

约束
  1. constraint_0 (管道使用总数约束): 这个约束确保变量 x_pipeUsed(被使用的管道总数)等于所有被切割的原材料管道数量的合计。换句话说,每个被切割使用的原材料管道都被计算在内。
subto constraint_0:
     sum {i in rawPipe} x_cuts[i] == x_pipeUsed;

这里,x_cuts[i] 是一个二元变量,表示原材料管道 i 是否被切割使用。如果被切割使用,则 x_cuts[i] 为 1,否则为 0。所有这些值加起来应该等于 x_pipeUsed。


  1. constraint_1_DemandFulfillment (需求满足约束): 这个约束确保每个需求的数量 demandNum[j](需求 j 的数量)都不超过通过切割原材料管道得到的对应尺寸的数量。
subto constraint_1_DemandFulfillment:
    forall { j in Demand}
        demandNum[j] <= sum{i in rawPipe} x_cutNum[i,j];

这里,x_cutNum[i,j] 表示从原材料管道 i 切割出的满足需求 j 的数量。所有原材料管道对该需求的贡献加起来,应该至少等于需求的数量。


  1. constraint_1_CuttingLimit (切割限制约束): 这个约束确保每个被使用的原材料管道 i 切割出的产品总长度不超过该原材料管道的实际长度。
subto constraint_1_CuttingLimit:
    forall { i in rawPipe}
        sum{j in Demand} x_cutNum[i,j] * demandSize[j] <= pipe_length * x_cuts[i];

这里,demandSize[j] 是需求 j 的尺寸,pipe_length 是原材料管道的长度,x_cutNum[i,j] 是从原材料管道 i 切割出的满足需求 j 的数量。对所有的需求尺寸的切割长度求和,得到的总长度不应超过原材料管道的长度乘以该管道是否被使用的标志(如果管道未被使用,x_cuts[i] 为 0,因此等式右侧为 0,满足约束)。


完整源代码

完整代码如下:

clear model;
option modelname cutting_01; #定义存储文件名

# ----------建模--------Start----
# cutting_01.mapl

# 标准水管长度
param pipe_length = 100; 

# 需要切割的小段尺寸和对应的数量

param fileDir = "data/";
set Demand = {read fileDir+"Demand.csv" as "<1n>" skip 1}; # 读取需求序号
param demandSize[Demand] = read fileDir+"Demand.csv" as "<1n> 2n" skip 1; # 读取需求长度
param demandNum[Demand]  = read fileDir+"Demand.csv" as "<1n> 3n" skip 1; # 读取需求个数


# 假设总共有15根原材料
param pipe_Num = 15;
set rawPipe = {1..pipe_Num};

## 决策变量:
var x_pipeUsed; #总共被使用的管道数

# 各个原材料是否被切割
var x_cuts[rawPipe] >= 0 binary; 

# 每个原材料中,各种demandSize的需求被切割生产出来的数量
var x_cutNum[rawPipe,Demand] >= 0 integer; 


# 目标函数:最小化使用的水管原材料数量
minimize Totalpipes: x_pipeUsed;


## 约束条件:
# pipes_used 等于被切割原材料的求和。
subto constraint_0:
     sum {i in rawPipe} x_cuts[i] == x_pipeUsed;

# 切割后,各个尺寸的需求得到满足
subto constraint_1_DemandFulfillment:
    forall { j in Demand}
        demandNum[j] <= sum{i in rawPipe} x_cutNum[i,j];
        
# 每个原材料的切割方式,不超过总长度*被使用
subto constraint_1_CuttingLimit:
    forall { i in rawPipe}
        sum{j in Demand} x_cutNum[i,j] * demandSize[j] <= pipe_length * x_cuts[i] ;
        

#求解
option solver mindopt;     # (可选)指定求解用的求解器,默认是MindOpt
#option mindopt_options 'max_time=600'; #设置求解器参数
option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印
solve;         # 求解

# 结果打印和检查结果
print "----------------结果打印和存文件--------------";
#display; 
print "最小原材料耗费数 = ",x_pipeUsed;
print "原材料长度,需求1长度,需求1切割数,需求2长度,需求2切割数,需求3长度,需求3切割数,……";
forall { i in rawPipe with x_cuts[i] >= 0.5}
    print "{},|{},{},|{},{},|{},{},……"
        %pipe_length,demandSize[1],x_cutNum[i,1] ,demandSize[2],x_cutNum[i,2] ,demandSize[3],x_cutNum[i,3];


print "原材料长度,需求1长度,需求1切割数,需求2长度,需求2切割数,需求3长度,需求3切割数,……"
    : "切割方案.csv";
close "切割方案.csv";

forall { i in rawPipe with x_cuts[i] >= 0.5}
    print "{},{},{},{},{},{},{},……"
        %pipe_length,demandSize[1],x_cutNum[i,1] ,demandSize[2],x_cutNum[i,2] ,demandSize[3],x_cutNum[i,3] >> "切割方案.csv";
close "切割方案.csv";

运行上述代码结果如下:

Running mindoptampl
wantsol=1
print=0
MindOpt Version 1.0.1 (Build date: 20231114)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 29-DEC-2023 17:46:36).
License validation terminated. Time : 0.007s


OPTIMAL; objective 7.00

Completed.
----------------结果打印和存文件--------------
最小原材料耗费数 = 7
原材料长度,需求1长度,需求1切割数,需求2长度,需求2切割数,需求3长度,需求3切割数,……
100,|14,2,|50,0,|70,1,……
100,|14,1,|50,0,|70,1,……
100,|14,2,|50,0,|70,1,……
100,|14,0,|50,2,|70,0,……
100,|14,0,|50,2,|70,0,……
100,|14,0,|50,1,|70,0,……
100,|14,0,|50,2,|70,0,……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/333703.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

区域入侵检测AI边缘计算智能分析网关V4如何通过ssh进行服务器远程运维

智能分析网关V4是一款高性能、低功耗的AI边缘计算硬件设备&#xff0c;它采用了BM1684芯片&#xff0c;集成高性能8核ARM A53&#xff0c;主频高达2.3GHz&#xff0c;并且INT8峰值算力高达17.6Tops&#xff0c;FB32高精度算力达到2.2T&#xff0c;每个摄像头可同时配置3种算法&…

万户 ezOFFICE wf_printnum.jsp SQL注入漏洞复现

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…

VUE--插槽slot(将父级的模块片段插入到子级中)

组件可以接收任意类型的JS值作为props&#xff0c;但我们想要为子组件传递一些模板片段&#xff0c;并在子组件中进行渲染时&#xff0c;此时可以采用插槽slot来实现 简单来说&#xff0c;插槽时组件内留一个或多个插槽的位置&#xff0c;供组件传递对应的模板代码&#xff08;…

深入解析与实践:Ajax异步请求在Web开发中的应用指南

一、概述 1、定义 ​ Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;异步请求是现代Web开发中不可或缺的技术组件&#xff0c;它允许网页在不刷新整个页面的情况下从服务器获取并更新数据&#xff0c;从而实现动态、流畅的交互体验。 2、异步和同步 浏览器访…

目标文献分析方法

如何正确选题&#xff1f; 不仅仅是题目&#xff0c;而是研究工作的起步选题步骤&#xff1f; 发现问题选择方向调查研究分析论证确定选题 中国知网 深度学习方向词 1检索&#xff1a;深度学习 医疗影像 1 发表时间要最新 2 显示50个&#xff0c;全选 3 导出文献格式Ref 4 导…

无法打开浏览器开发者工具的可能解决方法

网页地址: https://jx.xyflv.cc/?url视频地址url 我在抖音里面抓了一个视频地址, 获取到响应的json数据, 找到里面的视频地址信息 这个网站很好用: https://www.jsont.run/ 可以使用js语法对json对象操作, 找到所有视频的url地址 打开网页: https://jx.xyflv.cc/?urlhttps:…

最推荐的视频播放器——PotPlayer

PotPlayer&#xff0c;是The KMPlayer的原作者姜勇囍进入Daum公司后的新一代作品&#xff0c;目前仍有更新。由于采用Delphi编译程式的KMPlayer有一些弊端&#xff0c;姜勇囍为改进播放器本身的一些效能而重新用VC进行构架。 除了支持3D视频外&#xff0c;PotPlayer还覆盖支持…

MetaGPT-打卡-day2,MetaGPT框架组件学习

文章目录 Agent组件实现一个单动作的Agent实现一个多动作的Agent技术文档生成助手其他尝试 今天是第二天的打卡~昨天是关于一些概念的大杂烩&#xff0c;今天的话&#xff0c;就来到了Hello World环节。 从单个Agnet到多个Agent&#xff0c;再到组合更复杂的工作流来解决问题。…

分类预测 | Matlab实现CS-SVM布谷鸟算法优化支持向量机的数据分类预测

分类预测 | Matlab实现CS-SVM布谷鸟算法优化支持向量机的数据分类预测 目录 分类预测 | Matlab实现CS-SVM布谷鸟算法优化支持向量机的数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现CS-SVM布谷鸟算法优化支持向量机的数据分类预测。 2.自带数据…

均线和布林线这样的关系,WeTrade众汇实例这样使用

在后台经常有交易者咨询:“我可以用加权平均线或指数代替移动平均线吗?”理论上&#xff0c;任何平均值都适合绘制BB。在回答这个问题之前&#xff0c;为了稳妥起见&#xff0c;WeTrade众汇通过对各种均线对比分析&#xff0c;却得出这样结论:经典均线是构建参考点最简单、最准…

element-plus表格判断table中的数据是否换行展示,如果换行展示,替换为....

文章目录 需求分析 需求 element-plus表格判断table中的数据是否换行展示&#xff0c;如果换行展示&#xff0c;替换为… 分析 <style lang"less" scoped>::v-deep(.el-table .cell) {overflow: hidden; // 溢出隐藏text-overflow: ellipsis; // 溢出用省略号…

蓝桥杯(C++ 整数删除 优先队列 )

优先队列&#xff1a; 优先队列具有队列的所有特性&#xff0c;包括队列的基本操作&#xff0c;只是在这基础上添加了内部的一个排序&#xff0c;它本质是一个堆实现的。 1.头文件&定义 #include <queue> #include <functional> //greater<>// 定义 p…

如何使用@font-face

font-face css 提供的font-face可以让开发者自定义项目中的字体。字体可以从远程服务器获取&#xff0c;也可以从本地加载。 font-face {font-family: "Open Sans";src:url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2"),url(&qu…

鸿蒙开发实战-OpenHarmony沙箱文件

在openharmony文件管理模块中&#xff0c;按文件所有者分类分为应用文件和用户文件和系统文件。 1&#xff09;沙箱文件。也叫做应用文件&#xff0c;包括应用安装文件、应用资源文件、应用缓存文件 二.文件详解 在使用时首先需要导入包 import fs from “ohos.file.fs”&am…

某马头条——day05

文章定时发布 实现方案对比 实现方案 延迟队列服务实现 按照文档进行项目的导入并准备数据库表导入对应实体类和nacos配置中心 乐观锁集成 redis集成和测试 成功集成通过测试 添加任务 ①&#xff1a;拷贝mybatis-plus生成的文件&#xff0c;mapper ②&#xff1a;创建task类…

C++ 设计模式之观察者模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【设计模式大纲】 前面的文章介绍了创建型模式和结构型模式&#xff0c;今天开始介绍行为型模式。 【简介】什么是…

Google play 应用批量下架的可能原因及应对指南

想必大多数上架马甲包或矩阵式上架的开发者们&#xff0c;都遭遇过应用包批量被下架、账号被封的情况。这很令人苦恼&#xff0c;那造成这种情况的可能原因有哪些呢&#xff1f;以及如何降低这种情况发生&#xff1f; 1、代码问题 通常上架成功后被下架的应用&#xff0c;很可…

PyTorch入门之Tensor综合-含操作/运算、机器学习的关系、稠密张量与稀疏张量的定义等

PyTorch入门之Tensor综合-含操作/运算、机器学习的关系、稠密张量与稀疏张量的定义等 Tensor的理解 数学中有标量、向量和矩阵的概念&#xff0c;它们的维度分别是0、1、2。其中&#xff1a; 标量可以看成的一个数字&#xff0c;1&#xff0c;标量中元素的位置固定。向量可以…

014集:python访问互联网:网络爬虫实例—python基础入门实例

以pycharm环境为例&#xff1a; 首先需要安装各种库(urllib&#xff1a;requests&#xff1a;Openssl-python等) python爬虫中需要用到的库&#xff0c;大致可分为&#xff1a;1、实现 HTTP 请求操作的请求库&#xff1b;2、从网页中提取信息的解析库&#xff1b;3、Python与…

Gin 框架之Cookie与Session

文章目录 一、Cookie和Session的由来二、Cookie简介1. 什么是Cookie2. Cookie规范3. 安全性4. Cookie 关键配置 三、Session简介1. 什么是Session2. Session 安全性3. 如何让客户端携带 sess_id 四、使用 Gin 的 Session 插件4.1 介绍4.2 基本使用 五、 session与store5.1 会话…
最新文章