2022年华为杯数学建模竞赛B题论文和代码

news2024/10/22 8:11:30

基于整数规划的方形件排样和组批优化问题研究

常见的板式产品如玻璃,PCB板,铝合金门窗等产品因其结构定制化程度高的特点,相关生产制造的企业往往采用“多品种小批量”的个性化生产模式。通过对客户订单的组批,预先规划好各个产品的排样方式,由于所有的产品均由原板材切割生成,因此这种生产模式直接引起生产效率同生产成本之间的矛盾,若能协调好生产订单组批与排样优化难题可以为企业计划排产的顺利进行提供有效的决策支持。针对此类问题,本文从组批与排样过程中的实际约束入手,建立了整数规划模型,合理配置原材料资源和订单组批,从时间和空间两个维度提高原材料利用率和生产效率。

对问题一,首先在满足各个子集生产订单需求和三阶段齐头切等约束的条件下建立排样整数规划模型,在尽可能少的母板上切割出要求的产品。基于所建模型,设计了一种三阶段启发式搜索树算法(3-Stage Heuristic Search Tree,3-SHST )对模型进行求解。基于宽度非递增原则,采用贪婪式排列算法对原始数据进行排列组合,在FFDH算法的基础上利用后序遍历查找产品项可能插入的位置节点,并生成切割树,遍历所有树节点找到最优插入位置。最后在所给数据集 dataA1~dataA4 进行算法验证,最终求得四个数据集上所需原板材的个数分别为89块、89块、8987,板材利用率分别为93.87%93.12%94.08%94.08%,排样算法运行时间分别为0.1064s0.0917s0.1289s0.1112s,所有数据集的排样示意图和相关排样信息表格分别以.jpg.csv文件格式输出。

对问题二,首先在问题一所建整数规划模型的基础上,增加对每个批次产品项总数和面积总和的约束及相关决策变量,建立组批整数规划模型,在材料利用率最大化的优化目标下平衡生产效率和材料利用率的关系。设计了一种基于生产条件约束的订单层次聚类算法,以生产条件约束为前提,利用杰卡德距离定义各个订单簇之间材料种类的区别,最后利用凝聚层次聚类算法得到最优的组批结果。针对各个批次的排样问题,采用问题一中的排样优化算法得到最优的组批排样方案。最后在所给数据集 dataB1~dataB5 中进行算法验证,最终求得五个数据集上组批次个数分别为 5541个、51 个、44 70,使用板材个数分别为37262498块、2497块、25654004板材利用率分别为79.93%77.14%77.44%79.15%77.17%组批算法运行时间分别为33.441s13.2627s13.7917s11.3077s47.0652s所有数据集的排样示意图和相关组批信息表格分别以.jpg.csv文件格式输出。

键词:二维库存切割;排样优化;组批优化;整数规划

一、问题背景与重述

1.1问题背景

随着数字化、网络化、智能化的工业浪潮席卷全球,“智能制造”已被列为“中国制造2025的主攻方向。在机械制造、纺织加工、印刷作业等领域经常会遇到这样的问题:从一组大的矩形原料上按需求切割下一定尺寸一定需求量的小矩形,按照最朴素的节约资源降低生产成本的想法,希望在使用原材料最少的前提下完成订单需求,这就是典型的二维切削库存(2DCStwo-dimensional cutting stock问题[1]其变体问题为二维装箱(2DBPtwo-dimensional bin packing问题[2]题干中介绍的三阶段的齐头切模式常被用于作为解决上述问题的限制条件之一,这是因为这种切割方式在材料利用率和切割过程的复杂性之间取得了很好的平衡[3]整数线性规划(ILPInteger linear programming常被用于二阶段和三阶段的齐头切2DCS2DBP问题[4][2]Lodi等人的混合整数规划(MILPThe Mixed-Integer  Linear  Programming)模型[5]展到三阶段模式并用于列生成以解决2DBP问题。同时若在原材料利用率最大的要求上加上生产批次与交货时间约束、切割次数最少约束等附加条件则会使优化目标增多,约束条件也更加复杂,求解也变得更为困难。本赛题正是在此背景下要解决小批次多种类的订单的二维切削库存问题的排样优化和订单组批问题。

批量订单数据

订单组批优化

成订单分批方案

组批

批方

订单排样优化

成订单排样方案

排样

样方

输出排样结果

 1组批与排样流程

3

1.2问题重述

          基于上述研究背景,题目提供了两个独立的数据集AB分别包含产品项数量、需求、尺寸、产品id、订单号等信息,本文需要解决以下两个问题:
          问题1:排样优化问题。对数据集A中的每个子集,在满足各子集生产订单需求和三阶段齐头切约束条件下,建立相关的模型并设计求解算法,使用最少的相同尺寸的原板材

来完成订单生产需求,使板材利用率达到最大化,并按格式输出排样图和排样信息表格。

此问题中未对订单号作相关要求,且同一子集中产品的材料也相同,因此这两项数据可以不做考虑。这是一个典型的三阶段齐头切2DCS2DBP问题。

          问题2:订单组批问题。对数据集B中的每个子集,在问题一约束的基础上,增加以下进一步约束:

          1)  每份订单当且仅当出现在一个批次中;
          2)  每个批次中的相同材质的产品项(item才能使用同一块板材原片进行排样;           3)  为保证加工环节快速流转,每个批次产品项(item)总数不能超过1000           4)  因工厂产能限制,每个批次产品项(item)的面积总和不能超过250m 2
          要根据上述所有条件,建立规划模型并设计相应的求解算法,对数据集B中的全部订单进行组批,然后对每个批次进行独立排样,使得板材原片的用量最少。本问题虽然最终的优化目标与问题一相同,但由于加上了同批次 item 数量,同批次 item 面积和以及同材质item排样三个条件,实质上是在问题一的基础上上升了一个维度,提出了一个子问题,即如何组批才能平衡生产效率和材料利用率的关系,使得材料利用率最大化。同时数据集B的数据量比A要大的多,这也就对模型和算法的求解效率提出了需求。

1.3技术路线图

问题一:方形件排样优化问题

生成订单分批方案

 2本文技术路线图

二、基本假设和符号说明

2.1基本假设

基于题干和实际求解中可能考虑到的因素,在求解之前我们需做出以下假设以保证模

型和算法的逻辑完备:

          1)本次赛题所有订单的交货期均相同,不做区分;
          2只考切的切割方(直线切割方垂直材一条边,证每次直线切割板材可分离成两块);
          3)切割阶段数不超过3,同一个阶段切割方向相同;
          4)排样方式为精确排样;

5)假定板材原片仅有一种规格且数量充足;
6)排样方案不用考虑锯缝宽度(即切割的缝隙宽度)影响; 7)数据集AB中的各子集数据是独立的,应分别处理。

2.2符号说明

针对贯穿全文的一些主要变量及其符号含义列表如下。

 1符号及变量定义说明

符号

符号含义

单位

Area  

i

数据集Aiitem面积总和

L

所使用板材原片的长

mm

W

所使用板材原片的宽

mm

il  

item的长

mm

iw  

item的宽

mm

d

所有stripe的尺寸类别数

t

能生成stripestack的个数

m

所有stripe的最大顺序编号

kq  

a

0/1变量,顺序编号为kstack是否可以被编号为astripe包含

aiy  

0/1变量,顺序编号为iitem是否可以被编号为astack包含

ax  

正整数变量,在顺序编号为astack中包含item的个数

az  

正整数变量,在顺序编号为astripe中包含stack的个数

J A B  

杰卡德相似系数

J ( , ) A B

杰卡德距离

三、问题一:方形件排样优化问题求解

3.1数据分析与思考

          首先对给出的 dataA1-dataA4 四组数据进行粗略的观察和分析,可分别计算出每组数据中item的面积之和,以dataA1数据为例,item面积之和为:

Area

1

=

752

i = 0

length

i

*

width

i

=

2.4868561455 10 (

m

2

)

(3.1)

用面积除以原板材面积可得极限情况下最小使用的板材数:

Area

1

(1220

2440 10 )

=

83.54

84

(3.2)

          item 面积之和除以极限情况下使用板材面积之和可得 dataA1 提供数据的原材料极限利用率:

Area 1 / (84*2440*1220 10 )

=

99.45%

(3.3)

当然,由于题干中给出的不能拼接等条件以及三阶段齐头切方式所带来的必然的材料

浪费,实际的原材料利用率不肯可能达到以上计算值,同样的,如果模型及算法的计算结

果显示利用率超过此值那说明结果也是错误的。对其他三组数据进行同样的处理得出的结果如表2所示:

 2极限情况下材料利用率分析

数据集

dataA1

dataA2

dataA3

dataA4

极限情况下所需

84

83

84

82

原材料块数

极限利用率

99.45%

98.66%

99.68%

97.44%

继续对数据进行观察,发现每个数据集中的方形件的需求量都是1且很少有长宽完全一样的两个方形件,但是若以长度或者宽度来进行排序,可以发现有不少的方形件具有同样的长度或者宽度,这也符合题干中所说的同一个 stack item 的长或宽需相等的条件。为了更加直观的看出方形件的外观尺寸分布情况,利用数据集中的数据在 origin 软件中画出如图3所示散点频数统计图,XY坐标分别是方形件的长和宽,XY平面内是方形件的长宽散点图,在 XZ YZ 平面内我们作出了某一长度或宽度区间段内方形件的频数统计直方图,可以看出在某些区间内方形件的长或宽特征体现出高度集中的特征。

6

1)在相同栈(stack)里的产品项(item)的宽度(或长度)应该相同; 2)最终切割生成的产品项是完整的,非拼接而成。

        优化的目标是要满足尽可能少的板材原片数量,由于本问题为典型的 NP-hard 问题,一般没有polynomal复杂度的算法,算法复杂度随着变量的增加呈指数级增长(指数爆炸),因此在上述题干约束的基础上引申做出以下约束:
        1)切割方式固定为第 1 阶段采用横向切割生成 stripe(条带),第 2 阶段采用纵向切割生成stack(栈),第三阶段采用横向切割生成item(产品项);
        2)每个stack中的第一个(最上面)元素是stack中最宽的元素;
        3)每个stripe中的第一个(最左边)元素是stripe中最宽的元素;
        4)所有被选择的item的宽度按照不递减排列;
        为解释模型需要,对问题一涉及的符号作进一步说明:

2假设最终可能会产生d种不同尺寸的stripe对于每一个stripe都可以通过他们

3最终产生的stack个数为m每个stack产生都源于最初插入了一个顺序编号为i item,记此 stack 顺序编号为a;与此类似,假定最终可能会产生m stripe,每一个stripe的产生都源于最初插入了一个顺序编号为kstack,记此stripe的顺序编号为a。这里符号不进行区分只用来表明元素的产生与其组成之间存在上述关系。

基于上述所有约束条件,我们选择通过整数规划对该问题进行建模,模型如下: 一)决策变量:

代码

1. class TreeNode():   

2.     def __init__(self, length, width, depth = 0, sum = 0, item = None) -> None:   

3.         self.length = length # 节点长度信息   

4.         self.width = width # 节点宽度信息   

5.         self.depth = depth # 节点所处树的位置,root-1   

6.         self.sum = sum # 节点长度或宽度和 依据所处位置   

7.         self.item = item # 只有叶子节点有该属性,表示处于叶子节点处的实际item   

8.         self.childs = list()   

9.        

10.     def insert_node(self, node):   

11.         for child in self.childs:   

12.             if child.insert_node(node):   

13.                 return True   

14.         if self.depth == 3:   

15.             return False   

# 当节点深度为2时候,子节点的切法是横着切,只在当前节点下方加一个新节点   

18.         elif self.depth == 2:   

19.             cur_pos = self.childs[len(self.childs) - 1].sum + node.width   

20.             if  cur_pos <= self.width and node.length == self.length:  # 查看是否有空间      放置(暂时不考虑旋转)   

21.                 node.sum = cur_pos   

22.                 node.depth = 3   

23.                 self.add_child(node)   

24.                 return True   

25.         # 当节点深度为1时候, 子节点的切法是竖着切,在当前节点下方要加两个新节点(一个  stack和一个item)   

26.         elif self.depth == 1:   

27.             cur_pos = self.childs[len(self.childs) - 1].sum + node.length   

28.             if node.width <= self.width and cur_pos <= self.length:   

29.                 stack = TreeNode(node.length, self.width, depth = 2 ,sum = cur_pos)   

30.                 self.add_child(stack)   

31.                 node.sum = node.width   

32.                 node.depth = 3   

33.                 stack.add_child(node)   

34.                 return True   

35.         # 当处理节点深度为0,即该块是某个原件,子节点的切法是横着切,在当前节点下方要加入三个   新节点(一个strip,一个stack和一个item)   

36.         elif self.depth == 0:   

37.             cur_pos = self.childs[len(self.childs) - 1].sum + node.width   

38.             if cur_pos <= self.width:   

39.                 strip = TreeNode(self.length, node.width, depth = 1, sum = cur_pos)   

40.                 self.add_child(strip)   

41.                 stack = TreeNode(node.length, strip.width, depth = 2, sum = node.lengt

h)   

42.                 strip.add_child(stack)   

43.                 node.sum = node.width   

44.                 node.depth = 3   

45.                 stack.add_child(node)   

46.                 return True   

47.         # 当处理节点深度为-1时,即当前无原件可以放置当前块,则要拿一块新原件放置该块,在根节点下方要加入四个新节点(一个sheet 一个strip,一个stack和一个item)   

48.         else:   

49.             sheet = TreeNode(self.length, self.width, depth = 0)   

50.             self.add_child(sheet)   

51.             strip = TreeNode(sheet.length, node.width, depth = 1, sum = node.width)   

52.             sheet.add_child(strip)   

53.             stack = TreeNode(node.length, strip.width, depth = 2, sum = node.length)   

54.             strip.add_child(stack)   

5.             node.sum = node.width   

56.             node.depth = 3   

57.             stack.add_child(node)   

58.             return True   

59.        

60.         return False   

61.    

62.     def add_child(self, node):   

63.         self.childs.append(node)   

64.         # sorted(self.childs)   

65.        

66.     def __str__(self):   

67.         return "length: {}, width: {}, depth: {}".format(self.length, self.width, self

.depth

可视化排样方案程序:

1. from PIL import Image, ImageDraw   

2. from cut_tree_node import Item, TreeNode   

3.    

4. def visualize_sheet(node, save_file, fill = (135, 206, 235), outline = "black", width =

 2):   

5.     # 可视化图,返回方形件被占面积以及方形件中所有被切割元件信息   

6.     # filloutlinewidth为矩形的填充,边框等信息   

7.     # 深度优先搜索   

8.     def dfs_node(node):   

9.         info = {}   

10.         node_index = 0   

11.         if node.depth == 2:   

12.             node_index = node.sum - node.length   

13.         elif node.depth == 1 or node.depth == 3:   

14.             node_index = node.sum - node.width   

15.         info[node_index] = list()   

16.         for child in node.childs:   

17.             info[node_index].append(dfs_node(child))   

18.    

19.         if node.depth == 3:   

20.             return {"y": node_index, "item": node.item}   

21.         return info   

22.        

23.     img = Image.new('RGB', (node.length, node.width), (255, 255, 255))   

24.     draw = ImageDraw.Draw(img)   

25.     info = dfs_node(node)[0] # 通过深度优先搜索遍历树来得到被切割块所处x, y坐标   

26.        

27.     # 返回值   

28.     sum_area = 0 # 当前方形件被占面积   

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2022统考真题】计算时间复杂度

目录 一、题目描述 二、思路分析 三、易错提醒 四、同级和嵌套的关系 一、题目描述 下列程序段的时间复杂度是&#xff08;&#xff09; int sum 0; for (int i 1; i < n; i * 2) for (int j 0; j < i; j) sum; A. O(logn) B. O(n) C. O(nlogn) D…

卡牌小程序开发,线上抽卡机的优势

今年以来&#xff0c;卡牌成为了一种新的潮玩方式&#xff0c;继盲盒后在度成为大众收藏娱乐的选择。卡牌的种类各异&#xff0c;以热门IP为原型&#xff0c;设计出了专属卡牌&#xff0c;具有较大的收藏价值&#xff0c;吸引了无数的消费者的关注。 随着互联网技术的发展&…

python常用的字符串方法

一、求字符串的长度 python最常用的内置函数 二、切片获取子串 获取前第5个字符 print(s[:5]) # wuzij 获取后6个字符 print(s[-6:]) # python 三、去掉多余空格 四、是否以某个串开头 五、是否包含某个子串 六、串联多串 七、分割多串 八、替换子串

施瓦辛格之女凯瑟琳和克里斯帕拉特的女儿养成了她们妈妈一个习惯

凯瑟琳施瓦辛格与克里斯帕拉特的长女莉拉和次女艾洛斯显然与其母亲极为相像&#xff0c;一张崭新且罕见的照片清晰地展露了这一情形&#xff01; 广告 10 月 13 日&#xff0c;施瓦辛格分享了一系列家人外出游玩的照片。她分享了这些甜蜜温馨的照片&#xff0c;并附上标题写道&…

链接伪类(:hover)CSS背景图片有闪动BUG的解决方法 vue3

现象&#xff1a; hover时候&#xff0c;图片还没加载出来&#xff0c;导致边框闪烁 在Vue 3中&#xff0c;如果你遇到了使用伪类(:hover)时背景图片出现闪烁的问题&#xff0c;可能是由于浏览器的渲染机制导致的。解决这个问题的方法可能包括&#xff1a; 使用background-pos…

【Go初阶】两万字快速入门Go语言

初见golang语法 package mainimport "fmt"func main() {/* 简单的程序 万能的hello world */fmt.Println("Hello Go")} 第一行代码package main定义了包名。你必须在源文件中非注释的第一行指明这个文件属于哪个包&#xff0c;如&#xff1a;package main…

中级课程RHCE

RHCE 一、复习RHCSA1.1 系统安装1.1.1 安装虚拟机1.1.2 第一个快照1.1.3 第二个快照vi编辑器1.1.4 看网关网卡 1.2 文件管理1.3 目录管理1.4 用户管理1.5 权限管理1.6 存储管理1.6.1 标准分区管理实验&#xff1a;1.6.2 逻辑卷管理实验&#xff1a;1.6.3 交换空间管理实验 …

MySQL-CRUD-基础-(详解) ┗( ▔, ▔ )┛

目录 ❄️一、新增&#xff08;Create&#xff09;&#xff1a; ☑ 1、单行数据 全列插入&#xff1a; ☑ 2、指定列插入&#xff1a; ☑ 3、多行插入&#xff1a; ❄️二、查询&#xff08;Retrieve&#xff09;&#xff1a; ☑ 1、全列查询&#xff1a; ☑ 2、指定列查询&a…

API项目3:API签名认证

问题引入 我们为开发者提供了接口&#xff0c;却对调用者一无所知 假设我们的服务器只能允许 100 个人同时调用接口。如果有攻击者疯狂地请求这个接口&#xff0c;那是很危险的。一方面这可能会损害安全性&#xff0c;另一方面耗尽服务器性能&#xff0c;影响正常用户的使用。…

Linux命令——ls

命令格式&#xff1a;命令本身选项命令的指向目标 1.ls命令作用为列出目录下的内容 #lls后的选项有[-a,-l,-h]##注意ls与选项间应用空格隔开. 如下图为&#xff08;ls命令体-l选项/根文件&#xff09;的命令行 # ls -a 为&#xff1a;列出所有文件&#xff08;包括隐藏文件&…

解析:ARM 工业计算机在光伏储能中的关键作用

在当今能源转型的大背景下&#xff0c;光伏储能作为一种可持续、高效的能源解决方案&#xff0c;正受到越来越广泛的关注。而在光伏储能系统中&#xff0c;ARM 工业计算机以其卓越的性能和特点&#xff0c;成为了理想的选择。 一、光伏储能的重要性与挑战 全球对清洁能源的需…

视图使用控制器模板分配变量

文章目录 控制器视图路由配置控制器视图 视图使用控制器模板分配变量控制器视图 控制器视图 路由配置 <?phpuse Illuminate\Support\Facades\Route;/* |-------------------------------------------------------------------------- | Web Routes |---------------------…

服务性能优化之mybatis-plus 开启与关闭 SQL 日志打印

Hello&#xff01;欢迎各位新老朋友来看小弟博客&#xff0c;祝大家事业顺利&#xff0c;财源广进&#xff01;&#xff01; 主题&#xff1a;mybatis-plus 开启与关闭 SQL 日志打印 第一&#xff1a;开启打印 Mybatis-plus 需要通过下面的方式开启控制台 SQL 日志打印 myba…

2024 Mathorcup高校数学建模挑战赛ABCD题和 LaTeX 模版

01 A题-移动通信网络中 PCI 规划问题 02 B题-甲骨文智能识别中原始拓片单字自动分割与识别研究 03 C题-物流网络分拣中心货量预测及人员排班 &#xff08;左右滑动查看完整赛题&#xff09; 04 D题-量子计算在矿山设备配置及运营中的建模应用 看完了赛题&#xff0c;同学们…

同三维T80003JEH 4K30 HDMI解码器

1路HDMI输出&#xff0c; 1路3.5音频输出&#xff0c; 1个USB2.0,带1个RS232串口&#xff0c;1个网口&#xff0c;支持1路4K或4路1080P或9路720P及以下分辨率同时实时解码&#xff1b;支持视频画面输出1-16分割显示 同三维T80003JEH 4K30 HDMI解码器 同三维T80003JEH是一款4K3…

低成本轻量化5G网络部署redcap技术

RedCap&#xff08;Reduced Capability&#xff09;轻量化5G路由器旨在提供低功耗、成本效益高、性能较5G完整版稍微降低的解决方案。用于满足工业物联网&#xff08;IoT&#xff09;、消费电子产品和轻量级5G设备的需求。通过对5G技术进行一定程度的“功能裁剪”&#xff0c;降…

美食抖音视频素材网站推荐

为美食类抖音视频寻找高质量的素材&#xff0c;不仅能让作品更加吸引人&#xff0c;还能帮助创作者展现出精美的烹饪过程和独特的美食文化。以下推荐的素材网站&#xff0c;提供多种美食视频资源&#xff0c;从食材准备到烹饪技巧&#xff0c;甚至精致摆盘&#xff0c;让你的视…

postgres 的使用

postgres的常用命令&#xff1a; 查看所有库&#xff1a; \l 进入库 &#xff1a;\c 查看所有表&#xff1a;\d 库名; 查看表结构&#xff1a;\d 表名; 查看所有用户&#xff1a;\du 显示当前库下schema信息&#xff1a; \dn postgres的防火墙配置&#xff1a; 在安装目录的/va…

【升华】人生苦短,我要学python

一、python进阶成熟度阶梯 二、python进阶路线 三、python基础 Python 是由 Guido van Rossum 在八十年代末和九十年代初&#xff0c;在荷兰国家数学和计算机科学研究所设计出来的。 Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C、Algol-68、SmallTa…

解决使用MobaXterm不能向Ubuntu上传下载文件的问题

如上图所示 解决方案 新建连接&#xff0c;使用root账户建立ssh会话&#xff0c;就是建立会话的时候&#xff0c;用户名使用root。ubuntu系统默认不允许远程root账户建立连接&#xff0c;表现就是你新建ssh会话&#xff0c;在第一步输入root密码的时候&#xff0c;密码正确会报…