2019年MathorCup数学建模C题汽配件制造业中的生产排程问题解题全过程文档及程序

news2024/11/18 13:26:22

2019年第九届MathorCup高校数学建模挑战赛

C题 汽配件制造业中的生产排程问题

原题再现:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

整体求解过程概述(摘要)

  随着市场竞争日趋激烈,企业开始更加注重低费高效,因此生产排程问题成为众多制造企业关注的热点之一。其中,制造行业的喷漆生产排程问题是长久以来的业界难题,本文欲解决之。
  针对问题一,我们以最小化换色次数以及最小化未满足产品需求零件个数为目标,引入满足支架数量限制、滑橇数量限制、面漆换色限制、颜色前后摆放限制等约束,并将各变量、约束之间的隐形限制条件也引入约束中,建立了双目标非线性整数规划模型。在算法设计中,首先设计基于规则以及颜色优先级的基本算法求得初始解,得出平均每圈的换色次数为 4,未满足生产需求的零件个数为 71。接着基于此运用遗传算法求出一组基于初始解的双目标帕累托最优解。我们以较为平衡的一组为例展示,其平均每圈的换色次数(考虑了不同圈首尾衔接的换色情况)为 3.5,未满足生产需求的零件个数为40。
  针对问题二,我们在问题一已有优化目标的基础上引入最小化更换滑撬次数这一目标。为了调节各目标关系,首先引入不同圈之间产品喷涂结构相似度指标,根据问题一的解,分析发现各圈产品之间喷涂结构相似度差异不大且大多在 50%左右,同时结合生产需求和换色次数在企业制造的重要性,将支架更换次数置于较低优先级。算法设计分为两部分,首先在尽量保证问题一最优解的情况下,以相似度和首尾颜色的可衔接性作为关键因素调整各圈之间的生产顺序。接着以调整后的第一圈为基准,依序调整此后各圈的产品喷涂结构,使之与其前一圈结构尽量相似。求得平均每圈的换色次数小幅增长为 3.6 以及未满足生产需求的零件个数不变为 40,平均每圈支架更换次数由 275 优化至180。观察结果发现,支架更换次数优化的情况受限于各圈生产顺序的选取策略,因此对于该策略的改进可作为后续研究的方向。

模型假设:

  假设 1:不考虑设备的故障问题
  假设 2:人工更换滑橇只是人力方面的影响,不对具体生产流程产生影响。
  假设 3:企业不会因为更换次数频繁而增加对人员的雇佣

问题分析(部分):

  支架的更换与不同圈之间的产品结构的情况息息相关,因此我们首先定义产品喷涂结构相似度。对与不同圈之间的产品喷涂相似性,我们以其共同生产的产品种类数为标准。具体表达如下:
在这里插入图片描述
  第m圈和第n圈的相似度为他们相同的产品种类数与他们总共生产的产品种类数之比。越接近 1 则说明他们喷涂的产品结构越类似,进行适当的圈内调整之后,对更换支架次数的优化情况也会较好

模型的建立与求解整体论文缩略图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可

程序代码:(代码和文档not free)

The actual procedure is shown in the screenshot

import numpy as np
import xlwt
import math
import copy
import xlrd
'''商品是商品大类根据颜色的细分''' #商品类,原始的不同类型不同颜色的商品为一个对象
class com:
name = None
color = None
num = 0
sled_num = 0 #商品需要的总的滑橇数
circle_num = 0 #商品需要生产的圈数
#如果圈数大于 1,假设生产圈数为 n,则保证前 n-1 生产量为 6 的倍数
pro_num = 0
def __init__(self, tname, tcolor,tnum):
self.name = tname
self.color = tcolor
self.num = tnum
#商品段类,排产圈中每个不同类型不同颜色的商品段为一个对象
class com_seg:
name = None
color = None
position = 0
num = 0
sled_num = 0
circle_balance = 0 #在加入该商品段前本圈的 balance
def __init__(self,tname,tcolor,tposition,tnum,sled_num,balance):
self.name = tname
self.color = tcolor
self.position = tposition
self.num = tnum
self.sled_num = sled_num
self.circle_balance = balance
com_info_list = [] #保存各个商品大类信息的列表
#示例:[name,color,num]
com_list = [] #保存所有商品对象
bracket_num = {} #支架数目字典,由商品大类名字为键
com_seg_list = [] #保存所有的商品段对象,由排产时生成
bracket_num_copy = {} #支架数目字典副本,排产时使用
''' 颜色序列与各颜色对应的数目
4068 曜岩黑 3854 极地白 1746 钻石白 1100 光耀蓝 935 宝石红 704 铱
银
551 米兰银 429 宝石蓝 43 宇宙黑 15 牛仔蓝
''' #颜色序列与颜色商品字典
color_series = ['曜岩黑','极地白','钻石白','光耀蓝','宝石红',
'铱银' ,'米兰银','宝石蓝', '宇宙黑','牛仔蓝']
color_com_dict = {'曜岩黑':[],'极地白':[],'钻石白':[],'光耀蓝':[],'宝石红':[],
'铱银':[],'米兰银':[],'宝石蓝':[], '宇宙黑':[],'牛仔蓝':[]}
def read_com_list(com_info_list):
workbook = xlrd.open_workbook("C 题附件.xlsx")
sheet1 = workbook.sheet_by_name("生产需求量表")
for i in range(1,84):
one_com_info = []
for j in range(3):
one_cell = sheet1.cell(i,j).value
one_com_info.append(one_cell)
#print(one_com_info)
com_info_list.append(one_com_info)
def read_brackrt_info(bracket_num):
workbook = xlrd.open_workbook("C 题附件.xlsx")
sheet1 = workbook.sheet_by_name("支架数量上限")
for i in range(1, 32):
one_cell = sheet1.cell(i,0).value
two_cell = sheet1.cell(i,1).value
bracket_num[one_cell] = int(two_cell)
#根据商品信息列表,生成商品对象列表
def cre_com_list(com_info_list,com_list):
for one_com_info in com_info_list:
temp = com(one_com_info[0],one_com_info[1],int(one_com_info[2]))
com_list.append(temp)
'''按照尽量多生产原则,计算各个商品需要的总滑撬数''' def cacu_sled(com_list):
for com in com_list:
if bracket_num[com.name] >= 6:
sleds = com.num // 6
if com.num % 6 > 0:
sleds += 1
com.sled_num = sleds
else:
sleds = com.num // bracket_num[com.name]
com.sled_num = sleds
#根据 com_list 中的商品对象,计算各个商品对象要排产的圈数
def cacu_circle(com_list):
for com in com_list:
circle_num = math.ceil(com.num / bracket_num[com.name])
if circle_num > 1:
if bracket_num[com.name] > 6:
com.pro_num = (bracket_num[com.name] // 6) * 6
com.circle_num = math.ceil(com.num / com.pro_num)
else:
com.pro_num = bracket_num[com.name]
com.circle_num = math.ceil(com.num /
bracket_num[com.name])
else:
com.circle_num = 1
#根据各个商品的颜色,生成以颜色划分的商品字典
def cre_color_dict(com_list):
for com in com_list:
color_com_dict[com.color].append(com)
#生成一个排产列表
pre_series = []
def cre_one_series(pre_series,color_series,bracket_num):
'''初始化总的滑橇数目,商品排产位置,要维护的每一圈滑橇数目,支架数目字典''' balance = 2250 #总的滑橇数目
position = 1 #记录商品排产的位置
one_balance = 303 #要维护的每一圈滑橇数目
bracket_num_copy = copy.deepcopy(bracket_num) #排产过程中用到的支架
数目字典
while(balance > 0):
for color in color_series:
for com in color_com_dict[color]:
#还剩一圈的产品与多余一圈的产品之间的差别是排产的数量
与排产的滑橇数量
#print(com.name,com.color,com.circle_num)
#print(balance)
if balance < 0:
return pre_series
if com.circle_num > 1:
once_sled = com.pro_num // 6
if once_sled <= 0:
once_sled += 1
append_num = com.pro_num
#print(com.name,com.color,com.circle_num,com.pro_num)
#print("append_num",append_num)
elif com.circle_num > 0:
once_sled = com.sled_num
append_num = com.num
#print(com.name, com.color, com.circle_num, com.num)
#print("append_num", append_num)
else:
continue
#判断是否加入本商品后就超出了本圈,若是则对支架数
字典
#滑橇数目的更新方式不同,如果加入后超出了本圈则
#print(one_balance)
#print(once_sled)
if one_balance - once_sled <= 0:
#print('是末尾')
#print(one_balance,once_sled)
# 这里要改,应该改成>,把下面的放在 else
#print('是末尾')
if bracket_num_copy[com.name] >= once_sled * 6:
a = com_seg(com.name, com.color, position, append_num,once_sled,one_balance)
com.num -= append_num #无论是否在末尾,
对该商品的更新方式相同
com.circle_num -= 1 #维护余下需要的圈数
com.sled_num -= once_sled #维护余下需要的滑橇
数
position += 1 #无论是否在末尾,对
位置的更新相同
pre_series.append(a)
#在末尾对滑橇数和支架数的更新不同
ex_sled = once_sled - one_balance
ex_bracket = bracket_num_copy[com.name] - one_balance * 6
bracket_num_copy = copy.deepcopy(bracket_num)
bracket_num_copy[com.name] -= ex_bracket
one_balance = 303 - ex_sled
balance -= once_sled
else:
continue
else:
#print('append_num',append_num)
#print(bracket_num_copy[com.name])
#print(one_balance, once_sled)
#print(com.name)
if append_num <= bracket_num_copy[com.name]:
#print('不是末尾')
a =
com_seg(com.name,com.color,position,append_num,once_sled,one_balance)
com.num -= append_num
com.circle_num -= 1
com.sled_num -= once_sled
position += 1
pre_series.append(a)
balance -= once_sled
one_balance -= once_sled
bracket_num_copy[com.name] -= append_num
#print(balance)
if balance < 0:
print(com.name,'balance < 0 ')
else:
continue
#pre_series.append("换色")
#one_balance -= 1
#balance -= 1
#print(balance)
read_com_list(com_info_list) #读入商品数据
cre_com_list(com_info_list,com_list) #创建商品列表
read_brackrt_info(bracket_num) #创建支架词典
cacu_sled(com_list) #按照多生产原则计算需要的滑橇
数量
cacu_circle(com_list) #计算各商品需要的生产圈数
cre_color_dict(com_list)
#for com in com_list:
#
print(com.name,com.color,com.sled_num,com.circle_num,com.num,com.pro_num)
pre_series = cre_one_series(pre_series,color_series,bracket_num)
count = 0
all = 0
for com_seg in pre_series:
if com_seg == '换色':
count += 1
print('换色')
else:
print(com_seg.name,com_seg.color,' 商 品 数 ',com_seg.num,' 滑 橇 数
',com_seg.sled_num,'加入之前本圈剩余滑橇数',com_seg.circle_balance)
all += com_seg.sled_num
def write_solution(pre_series):
f = xlwt.Workbook(encoding='utf-8')
sheet1 = f.add_sheet(u'sheet1', cell_overwrite_ok=True) # 创建 sheet
# 将数据写入第 i 行,第 j 列
i = 0
for com_seg in pre_series:
sheet1.write(i, 1, com_seg.name)
sheet1.write(i, 2, com_seg.color)
sheet1.write(i, 3, com_seg.num)
sheet1.write(i, 4, com_seg.sled_num)
sheet1.write(i, 5, com_seg.circle_balance)
i = i + 1
f.save('初始解.xls') # 保存文件

全部论文请见下方“ 只会建模 QQ名片” 点击QQ名片即可

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

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

相关文章

源码剖析Spring MVC如何将请求映射到Controller?

文章目录一、前言二、核心链路分析1、确定请求映射的入口1&#xff09;HandlerMapping注入Spring容器2&#xff09;HandlerMethod注册到MappingRegistry1> 判断Class是否为一个Handler2> 解析Class中的所有HandlerMethod 并注册到MappingRegistry中2、请求路径匹配1&…

【JavaScript速成之路】JavaScript函数

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言1&#xff0c;函数基础1.1&#xff0c;函数概念1.2&#xff0c;函数使用1.3&…

sHMIctrl 曲线控件使用

目录 效果 官方介绍 ​编辑 名词解释 使用方法 显示点 点在X轴位置 点在Y轴位置 量程 单位 如何设置自动标尺数据 设置量程 设置单位 效果 官方介绍 名词解释 四条曲线&#xff1a;同时最多使用4条曲线。 每条条曲线最多512点&#xff1a;X2-X1-Xn&#xff1b; 数据自定…

认识CSS值如何提高写前端代码的效率

&#x1f31f;所属专栏&#xff1a;前端只因变凤凰之路&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该系列将持续更新前端的相关学习笔记&#xff0c;欢迎和我一样的小白订阅&#xff0c;一起学习共同进步~&#x1f449;文章简…

Spring注解开发之组件注册(一)

Spring注解开发 Spring注解开发之组件注册下半篇 IOC&#xff0c;中文名为控制反转&#xff0c;是将Java的bean对象存储在容器中&#xff0c;当需要使用时&#xff0c;通过名字获取该对象。而不是通过new关键字去创建。 1.Configuration & Bean给容器中注册组件 第一种&…

K_A16_003 基于STM32等单片机采集薄膜压力传感器参数串口与OLED0.96双显示

K_A16_003 基于STM32等单片机采集薄膜压力传感器参数串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明对应程序:四、部分代码说明1、接线引脚定义STM32F103C8T6薄膜压力传感器模块五、基础知识学习与相关资料下载六、视频效果展示与程序资料获取七、注意…

Allegro如何在PCB中添加层面操作指导

Allegro如何在PCB中添加层面操作指导 在用Allegro做PCB设计的时候,根据需要,会在PCB中额外添加一些额外的层面,如下图 如何添加,具体操作如下 点击Setup点击Subclasses

实在智能RPA入选中国信通院《高质量数字化转型产品及服务全景图》

近日&#xff0c;中国信息通信研究院“高质量数字化转型创新发展大会暨中国信通院‘铸基计划’年度峰会”在北京召开&#xff0c;大会上信通院揭晓了《高质量数字化转型产品及服务全景图&#xff08;2022&#xff09;》&#xff08;以下称“全景图”&#xff09;。实在智能凭借…

自己定义typescript的类型声明文件xx.d.ts

****内容预警***菜鸟新手内容&#xff0c;大佬请绕道&#xff0c;不对的请指出我们在使用typescript的使用&#xff0c;如果安装一个包没有相应的类型声明文件&#xff0c;ts的类型检查就会报错&#xff0c;所以我们经常会安装npm包对应的types类型声明包&#xff0c;比如uuid …

手把手教你安装Linux!!!

文章目录Linux简述它们的区别安装CentOS①下载CentOS②安装Linux有两种方式③下载模拟软件④安装vmware⑤创建虚拟机⑥安装操作系统Linux简述 在国内比较流行的两款Linux发行版本CentOS和ubuntu 它们的区别 ubuntu&#xff1a;页面更加的华丽比较漂亮&#xff0c;它对计算机…

【bioinfo】融合检测软件FusionMap分析流程和报告结果

文章目录写在前面FusionMap融合检测原理FusionMap与其他软比较FusionMap分析流程FusionMap结果文件说明FusionMap mono CUP设置图片来源: https://en.wikipedia.org/wiki/Fusion_gene写在前面 下面主要内容是关于RNA-seq数据分析融合&#xff0c;用到软件是FusionMap 【Fusion…

连接微信群、Slack 和 GitHub:社区开放沟通的基础设施搭建

NebulaGraph 社区如何构建工具让 Slack、WeChat 中宝贵的群聊讨论同步到公共领域。 要开放&#xff0c;不要封闭 在开源社区中&#xff0c;开放的一个重要意义是社区内的沟通、讨论应该是透明、包容并且方便所有成员访问的。这意味着社区中的任何人都应该能够参与讨论和决策过…

编写程序:有92号和95号汽油可以选择,选择你需要的汽油,并输入需要加油的升数,点击按钮“`计算总价钱`“在div中可以得到你所需要支付的价格

需求&#xff1a; 有92号汽油和95号可以选择&#xff0c;选择你需要的汽油&#xff0c;并输入需要加油的升数&#xff0c;点击按钮"计算总价钱"在div中可以得到你所需要支付的价格。结构如下图所示&#xff1a; 详细代码如下&#xff1a; <!DOCTYPE html> &l…

图像识别技术OpenCV | C++版本

基础入门 图像与信号 图像 图像是人对视觉感知的物质再现。图像可以由光学设备获取&#xff0c;也可以人为创作。随着数字采集技术和信号处理理论的发展&#xff0c;越来越多的图像以数字形式存储。因而&#xff0c;有些情况下”图像“一词实际上是指数字图像。图像相关的话…

YOLOv8初体验:检测、跟踪、模型部署

安装 YOLOv8有两种安装方式&#xff0c;一种是直接用pip命令安装&#xff1a; pip install ultralytics另外一种是通过源码安装&#xff1a; git clone https://github.com/ultralytics/ultralytics cd ultralytics pip install -e .[dev]安装完成后就可以通过yolo命令在命令…

JavaScript的错误类型数据

在使用JavaScript开发过程中&#xff0c;当我们遇见浏览器控制台中出现的报错时&#xff0c;如何从这些错误类型快速定位到问题代码是一种必不可少的技能&#xff0c;下面我们来看看JavaScript的7种错误类型&#xff08;卷起来…&#xff09; 1、SyntaxError&#xff1a;语法错…

IP地址、网段处理模块IPy

【小白从小学Python、C、Java】【计算机等级考试500强双证书】【Python-数据分析】IP地址、网段处理模块IPy选择题以下关于python代码表述错误的一项是?from IPy import IPprint("【执行】IP(192.168.0.0/24).len()")print(IP(192.168.0.0/24).len())print("【…

realman——使用Moveit控制Gazebo中的机械臂

文章目录 概述新建工作区配置说明MoveIt端的配置机器人端的配置关节轨迹控制器关节状态控制器运行效果可能存在的问题概述 MoveIt!与 Gazebo 的联合仿真,其主要思路为搭建 ros_control 和 MoveIt!的桥梁。先在 MoveIt!端配置关节和传感器接口 yaml 文件,将其加载到 rviz 端;…

Java 某厂面试题真题合集

哈喽~大家好&#xff0c;这篇来看看Java 某厂面试题真题合集。 &#x1f947;个人主页&#xff1a;个人主页​​​​​ &#x1f948; 系列专栏&#xff1a;【日常学习上的分享】 &#x1f949;与这篇相关的文章&#xff1a; Spr…

leetcode-70 爬楼梯(java实现)

爬楼梯题目分析1 递归写法动态规划解法题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 分析1 递归写法 如果要爬上第n阶&#xff0c;要么是从第n-1上面再爬1阶上去的&#xff0c;要么是从…