2018CUMCM(数学建模国赛)_B——智能RGV的动态调度策略
图1是一个智能加工系统的示意图,由8台计算机数控机床(Computer Number Controller,CNC)、1辆轨道式自动引导车(Rail Guide Vehicle,RGV)、1条RGV直线轨道、1条上料传送带、1条下料传送带等附属设备组成。RGV是一种无人驾驶、能在固定轨道上自由运行的智能车。它根据指令能自动控制移动方向和距离,并自带一个机械手臂、两只机械手爪和物料清洗槽,能够完成上下料及清洗物料等作业任务(参见附件1)。
图1:智能加工系统示意图
针对下面的三种具体情况:
(1)一道工序的物料加工作业情况,每台CNC安装同样的刀具,物料可以在任一台CNC上加工完成;
(2)两道工序的物料加工作业情况,每个物料的第一和第二道工序分别由两台不同的CNC依次加工完成;
(3)CNC在加工过程中可能发生故障(据统计:故障的发生概率约为1%)的情况,每次故障排除(人工处理,未完成的物料报废)时间介于10~20分钟之间,故障排除后即刻加入作业序列。要求分别考虑一道工序和两道工序的物料加工作业情况。
请你们团队完成下列两项任务:
任务1:对一般问题进行研究,给出RGV动态调度模型和相应的求解算法;
任务2:利用表1中系统作业参数的3组数据分别检验模型的实用性和算法的有效性,给出RGV的调度策略和系统的作业效率,并将具体的结果分别填入附件2的EXCEL表中。
表1:智能加工系统作业参数的3组数据表 时间单位:秒
系统作业参数 |
第1组 |
第2组 |
第3组 |
RGV移动1个单位所需时间 |
20 |
23 |
18 |
RGV移动2个单位所需时间 |
33 |
41 |
32 |
RGV移动3个单位所需时间 |
46 |
59 |
46 |
CNC加工完成一个一道工序的物料所需时间 |
560 |
580 |
545 |
CNC加工完成一个两道工序物料的第一道工序所需时间 |
400 |
280 |
455 |
CNC加工完成一个两道工序物料的第二道工序所需时间 |
378 |
500 |
182 |
RGV为CNC1#,3#,5#,7#一次上下料所需时间 |
28 |
30 |
27 |
RGV为CNC2#,4#,6#,8#一次上下料所需时间 |
31 |
35 |
32 |
RGV完成一个物料的清洗作业所需时间 |
25 |
30 |
25 |
注:每班次连续作业8小时。
1.系统的场景及实物图说明
在附图1中,中间设备是自带清洗槽和机械手的轨道式自动引导车RGV,清洗槽每次只能清洗1个物料,机械手臂前端有2个手爪,通过旋转可以先后各抓取1个物料,完成上下料作业。两边排列的是CNC,每台CNC前方各安装有一段物料传送带。右侧为上料传送带,负责为CNC输送生料(未加工的物料);左边为下料传送带,负责将成料(加工并清洗完成的物料)送出系统。其他为保证系统正常运行的辅助设备。
附图1:RGV—CNC车间布局图
附图2:带机械手臂和清洗槽的RGV实物图
附图2是RGV的实物图,包括车体、机械臂、机械手爪和物料清洗槽等。
附图3:RGV机械手臂前端的2个手爪实物图
在附图3左图中,机械臂前端上方手爪抓有1个生料A,CNC加工台上有1个熟料B。RGV机械臂移动到CNC加工台上方,机械臂下方空置的手爪准备抓取熟料B,在抓取了熟料B后即完成下料作业。
在附图3右图中,RGV机械臂下方手爪已抓取了CNC加工台上的熟料B抬高手臂,并旋转手爪,将生料A对准加工位置,安放到CNC加工台上,即完成上料作业。
2.系统的构成及说明
智能加工系统由8台CNC、1台带机械手和清洗槽的RGV、1条RGV直线轨道、1条上料传送带和1条下料传送带等附属设备构成。
(1)CNC:在上料传送带和下料传送带的两侧各安装4台CNC,等距排列,每台CNC同一时间只能安装1种刀具加工1个物料。
如果物料的加工过程需要两道工序,则需要有不同的CNC安装不同的刀具分别加工完成,在加工过程中不能更换刀具。第一和第二道工序需要在不同的CNC上依次加工完成,完成时间也不同,每台CNC只能完成其中的一道工序。
(2)RGV:RGV带有智能控制功能,能够接收和发送指令信号。根据指令能在直线轨道上移动和停止等待,可连续移动1个单位(两台相邻CNC间的距离)、2个单位(三台相邻CNC间的距离)和3个单位(四台相邻CNC间的距离)。RGV同一时间只能执行移动、停止等待、上下料和清洗作业中的一项。
(3)上料传送带:上料传送带由4段组成,在奇数编号CNC1#、3#、5#、7#前各有1段。由系统传感器控制,只能向一个方向传动,既能连动,也能独立运动。
(4)下料传送带:下料传送带由4段组成,在偶数编号CNC2#、4#、6#、8#前各有1段。由传感器控制,只能向同一个方向传动,既能连动,也能独立运动。
3. 系统的作业流程
(1)智能加工系统通电启动后,RGV在CNC1#和CNC2#正中间的初始位置,所有CNC都处于空闲状态。
(2)在工作正常情况下,如果某CNC处于空闲状态,则向RGV发出上料需求信号;否则,CNC处于加工作业状态,在加工作业完成即刻向RGV发出需求信号。
(3)RGV在收到某CNC的需求信号后,它会自行确定该CNC的上下料作业次序,并依次按顺序为其上下料作业。根据需求指令,RGV运行至需要作业的某CNC处,同时上料传送带将生料送到该CNC正前方,供RGV上料作业。
RGV为偶数编号CNC一次上下料所需时间要大于为奇数编号CNC一次上下料所需时间。
(4)在RGV为某CNC完成一次上下料作业后,就会转动机械臂,将一只机械手上的熟料移动到清洗槽上方,进行清洗作业(只清洗加工完成的熟料)。
具体过程:首先用另一只机械手抓取出清洗槽中的成料、转动手爪、放入熟料到清洗槽中,然后转动机械臂,将成料放到下料传送带上送出系统。这个作业过程所需要的时间称为RGV清洗作业时间,并且在这个过程中RGV不能移动。
熟料在清洗槽中的实际清洗时间是很短的,远小于机械手将成料放到下料传送带上的时间。
(5)RGV在完成一项作业任务后,立即判别执行下一个作业指令。此时,如果没有接到其他的作业指令,则RGV就在原地等待直到下一个作业指令。
某CNC完成一个物料的加工作业任务后,即刻向RGV发出需求信号。如果RGV没能即刻到达为其上下料,该CNC就会出现等待。
(6)系统周而复始地重复(3)至(5),直到系统停止作业,RGV回到初始位置。
解题思路:采用A*算法,计算各个CNC完成工件的期望时间矩阵,进而进行实时最优决策。
Case_1_1
# -*- coding: utf-8 -*-
"""
Created on Fri Sep 14 21:57:21 2018@author: LIUZhendong
"""
import csv
from itertools import chain
'''按照A*算法进行RGV分配加工所需时间模拟(第一组)======================================'''
def find_martrix_min_value(data_matrix,State_CNC):'''''功能:找到矩阵State_CNC为0下的data_matrix最小值'''min_data = 1000000000add=(0,0)for i in range(len(data_matrix)):for j in range (len(data_matrix[i])):if data_matrix[i][j] < min_data and State_CNC[i][j] == 0:min_data = data_matrix[i][j]add = (i,j)return add
T_total = 8 * 60 * 60
T_CNC_matrix = []
State_CNC = [] # 0表示完成工作进入等待 1 表示正在工作
State_RGV = 0 # 表示RGV的位置 其中0,1,2,3分别代表位于1#、2#,3#、4#,5#、6#,7#、8#之间
T_RGV = 0
T_G = []
T_H = []
T_down = []
Answer_CSV = []
for i in range (2):State_CNC.append([])T_CNC_matrix.append([])T_G.append([])T_down.append([])for j in range(4):State_CNC[i].append(0)T_CNC_matrix[i].append(0)T_G[i].append(0)T_down[i].append(0)
for times in range (1000):T_CNC_odd = 0T_CNC_even = 0T_cost = 0T_change = [31,28]T_clean = 25T_move = [0,20,33,46]T_process = 560T_process_1 = 400T_process_2 = 378for j in range (2):for k in range (4):if j == 0:T_G[j][k] = T_change[0]elif j == 1:T_G[j][k] = T_change[1]
# print(T_G)for i in range (2):if State_RGV == 0:T_G[i][1] = T_G[i][1] + T_move[1]T_G[i][2] = T_G[i][2] + T_move[2]T_G[i][3] = T_G[i][3] + T_move[3]elif State_RGV == 1:T_G[i][0] = T_G[i][0] + T_move[1]T_G[i][2] = T_G[i][2] + T_move[1]T_G[i][3] = T_G[i][3] + T_move[2]elif State_RGV == 2:T_G[i][0] = T_G[i][0] + T_move[2]T_G[i][1] = T_G[i][1] + T_move[1]T_G[i][3] = T_G[i][3] + T_move[1]elif State_RGV == 3:T_G[i][0] = T_G[i][0] + T_move[3]T_G[i][1] = T_G[i][1] + T_move[2]T_G[i][2] = T_G[i][2] + T_move[1]
# print(T_G)for j in range (2):T_H.append([])for k in range (4):T_H[j].append(T_process)
# print(T_H)
# print(type(T_G))
# print(type(T_H))for i in range (2):for j in range (4):T_CNC_matrix[i][j] = T_G[i][j] + T_H[i][j] + T_cleanprint(T_CNC_matrix)add = find_martrix_min_value(T_CNC_matrix,State_CNC)(a,b) = addT_RGV = T_RGV + T_move[abs(State_RGV-b)]
# print('{}:{}'.format(times,T_RGV))if a == 0:Num = 2 * (b + 1)elif a == 1:Num = 2 * (b + 1) - 1if a == 0:T_RGV = T_RGV + T_change[0]elif a == 1:T_RGV = T_RGV + T_change[1]State_CNC[a][b] = 1T_down[a][b] = T_process + T_RGVif T_down[a][b] + T_change[a] + T_clean > T_total:breakAnswer_CSV.append([]) Answer_CSV[times].append(times+1)Answer_CSV[times].append('CNC{}#'.format(Num))T_up = T_RGVAnswer_CSV[times].append(T_up)Answer_CSV[times].append(T_down[a][b])if times > 7:T_RGV = T_RGV + T_cleanState_RGV = bif len(set(list(chain.from_iterable(State_CNC)))) == 1:for i in range (2):for j in range (4):State_CNC[i][j] = 0(c,d)=find_martrix_min_value(T_down,State_CNC)T_RGV = T_RGV + T_move[abs(State_RGV-d)]State_RGV = dT_RGV = T_down[c][d]if T_down[a][b] + T_change[a] + T_clean > T_total:break
# print(State_CNC)
# print(T_RGV)
# print(State_RGV)
#print(Answer_CSV)
#writer = csv.writer(open("Case_1_1.csv",'w',newline=''))
#for item in Answer_CSV:
# writer.writerow(item)
Case_1_2
Case_1_3
同上,修改至不同组数据
Case_2
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 15 14:25:40 2018@author: LIU Zhendong
"""import csv
from itertools import chain
import random
'''穷举法--两道工序======================================'''
'''
算法规则:
RGV总共有三种工作要做
1、给1类刀具CNC上原件
2、把1类刀具CNC上原件给二类刀具
3、将2类刀具CNC上熟件卸下清洗存放
假设从1类刀具CNC上卸下的原件无处存放,需要RGV停止等待2类刀具
CNC结束工作再给其装上,期间RGV不能做其他事情
如果RGV遇到1类刀具CNC和2类刀具CNC同时请求时,优先选择2类刀具
CNC装件
'''Group = 1
Loop = 254
Times = 1024
def find_martrix_min_value(data_matrix,State_CNC,p,q):'''''功能:找到矩阵State_CNC[0]为0下的data_matrix最小值'''min_data = 1000000000add=(0,0)for i in range(len(data_matrix)):for j in range (len(data_matrix[i])):if data_matrix[i][j] < min_data and State_CNC[p][i][j] == q:min_data = data_matrix[i][j]add = (i,j)return adddef find_free_min_add(data_matrix,State_CNC,p,q,r,s):'''''功能:找到矩阵State_CNC一定条件下最小值'''min_data = 1000000000add=(2,2)for i in range(len(data_matrix)):for j in range (len(data_matrix[i])):if data_matrix[i][j] < min_data and State_CNC[p][i][j] == q and State_CNC[r][i][j] == s:min_data = data_matrix[i][j]add = (i,j)return add
def Breakdown_random():'''''功能:随机产生故障并返回故障机器编号和故障时间'''a = random.randint(1,800)b = random.randint(600,1200)if a > 8:return (2,0,0)elif a % 2 == 0:return (0 , int(a/2-1) , b)elif a % 2 == 1:return (1 , int((a-1)/2) , b)'''初始化变量==============================================='''
T_total = 8 * 60 * 60
MAX_OUTPUT = 0
T_CNC_matrix = []
# 表示CNC剩余工作时间列表
State_CNC = [[],[]]
'''
State_CNC[0] 为一张2 * 4 列表,表示CNC状态其中0表示完成工作进入等待 1 表示正在工作
State_CNC[1] 为一张2 * 4 列表, 表示CNC携带的刀具其中0表示携带第一类刀具 1 表示携带第二类刀具
'''
State_RGV = 0'''
State_RGV表示RGV的位置其中State_RGV = 0,1,2,3分别代表位于1#、2#,3#、4#,5#、6#,7#、8#之间'''
State_CNC_Break = [] # 存放故障结束时间 0 表示无故障
T_RGV = 0
T_G = []
T_H = []
counts_CSV = []
Count_break = 0
T_down = []
Answer_CSV = []
Answer_CSV_Break =[]
NUM_CNC = [] # 存放CNC上物品编号
counts_CNC = [] # 记录CNC处理产品数量
T_change = [[31,28],[35,30],[32,27]]
T_clean = [25,30,25]
T_move = [[0,20,33,46],[0,23,41,59],[0,18,32,46]]
T_process = [560,580,545]
T_process_1 = [400,280,455]
T_process_2 = [378,500,182]
for i in range (2):State_CNC[0].append([])State_CNC[1].append([])T_CNC_matrix.append([])T_G.append([])T_down.append([])State_CNC_Break.append([])NUM_CNC.append([])counts_CNC.append([])for j in range(4):State_CNC[0][i].append(0)State_CNC[1][i].append(0)T_CNC_matrix[i].append(0)T_G[i].append(0)T_down[i].append(0)State_CNC_Break[i].append(0)NUM_CNC[i].append(0)counts_CNC[i].append(0)
#print(State_CNC)'''穷举刀具各种情况主循环'''for loop in range (Loop):for i in range (2):for j in range (4):T_CNC_matrix[i][j] = 0NUM_CNC[i][j] = 0counts_CNC[i][j] = 0State_CNC[0][i][j] = 0State_CNC[1][i][j] = 0T_CNC_matrix[i][j] = 0counts_CNC[i][j] = 0NUM_1 = 0NUM_2 = 0NUM = '{:08b}'.format(loop + 1)list_NUM = list(str(NUM))State_CNC[1][1][0] = int(list_NUM[7])State_CNC[1][0][0] = int(list_NUM[6])State_CNC[1][1][1] = int(list_NUM[5])State_CNC[1][0][1] = int(list_NUM[4])State_CNC[1][1][2] = int(list_NUM[3])State_CNC[1][0][2] = int(list_NUM[2])State_CNC[1][1][3] = int(list_NUM[1])State_CNC[1][0][3] = int(list_NUM[0])
# State_CNC[1][1][0] = 0
# State_CNC[1][0][0] = 0
# State_CNC[1][1][1] = 0
# State_CNC[1][0][1] = 1
# State_CNC[1][1][2] = 1
# State_CNC[1][0][2] = 1
# State_CNC[1][1][3] = 1
# State_CNC[1][0][3] = 1
# print(State_CNC[1])for i in range (2):for j in range (4):if State_CNC[1][i][j] == 0:NUM_1 = NUM_1 + 1 #1类刀具CNC数目elif State_CNC[1][i][j] == 1:NUM_2 = NUM_2 + 1 #2类刀具CNC数目
# print(NUM_1)# 定义时间矩阵表示从目前位置到完成整件预估时间
# T_move + T_change + T_process_1 + T_change + T_move + T_change + T_process_2 + T_clean
# 预估时间矩阵T_CNC_matrix求解===============================================
# 2类刀具CNC预估时间矩阵for i in range (2):for j in range (4):if State_CNC[1][i][j] == 1: # 携带2类刀具CNC
# T_changeif i == 0:T_CNC_matrix[i][j] = 2 * T_change[Group][0]elif i == 1:T_CNC_matrix[i][j] = 2 * T_change[Group][1]# T_process_2T_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_process_2[Group]# T_cleanT_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_clean[Group]
# print(T_CNC_matrix)Answer_CSV.append([])T_RGV = 0counts = 0counts_1 = 0 # 计数:1类刀具CNC正在加工零件数目counts_2 = 0 # 计数:2类刀具CNC正在加工零件数目State_RGV = 0
#循环求解for times in range (Times):
# print(counts+1,'===================================================')
# for i in range (2):
# for j in range (4):
# State_CNC[0][i][j] = 0
# 1类刀具CNC预估时间矩阵
# State_CNC[1][1][0] = 0
# State_CNC[1][0][0] = 1
# State_CNC[1][1][1] = 1
# State_CNC[1][0][1] = 0
# State_CNC[1][1][2] = 1
# State_CNC[1][0][2] = 0
# State_CNC[1][1][3] = 0
# State_CNC[1][0][3] = 0
# NUM_1 = 5for i in range (2):for j in range (4):if State_CNC[1][i][j] == 0: # 携带1类刀具CNC
# T_changeif i == 0:T_CNC_matrix[i][j] = T_change[Group][0]elif i == 1:T_CNC_matrix[i][j] = T_change[Group][1]
# T_process_1T_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_process_1[Group]
# print(T_CNC_matrix)for i in range (2):for j in range (4):if State_CNC[1][i][j]== 0:for k in range (2):for l in range (4):if State_CNC[1][k][l] == 1:T_G[k][l] = T_CNC_matrix[i][j] + T_move[Group][abs(l-j)] + T_CNC_matrix[k][l](a,b) = find_martrix_min_value(T_G,State_CNC,1,1)T_CNC_matrix[i][j] = T_G[a][b] + T_move[Group][abs(State_RGV-j)](c,d) = find_martrix_min_value(T_CNC_matrix,State_CNC,1,0)for i in range (2):for j in range(4):T_G[i][j] = 0
# print(T_CNC_matrix)
# 预估时间矩阵T_CNC_matrix求解===============================================# =============================================================================
# NUM_1 1CNC数
# counts 零件标号
# counts_1 正在加工
# counts_1_free 加工完成空闲数
# counts_2 正在加工
# counts_2_free 加工完成空闲数# =============================================================================
#for i in range (2):for j in range (4):if T_RGV >= T_down[i][j]:State_CNC[0][i][j] = 0
# print(State_CNC[0])(c,d) = find_free_min_add(T_CNC_matrix,State_CNC,0,0,1,0)
# 移动至目标CNC
# print(c,d)for i in range (2):for j in range (4):if T_RGV >= T_down[i][j]:State_CNC[0][i][j] = 0if(c,d) == (2,2):(c,d) = find_martrix_min_value(T_down,State_CNC,1,0)T_RGV = max(T_RGV + T_move[Group][abs(State_RGV-d)],T_down[c][d])else:T_RGV = T_RGV + T_move[Group][abs(State_RGV-d)]State_RGV = d
# 上件if c == 0:T_RGV = T_RGV + T_change[Group][0]elif c == 1:T_RGV = T_RGV + T_change[Group][1]T_down[c][d] = T_RGV + T_process_1[Group]# print('T_down',T_down)if c == 0:Num = 2 * (d + 1)elif c == 1:Num = 2 * (d + 1) - 1State_CNC[0][c][d] = 1counts = counts + 1
# print(NUM_CNC)Answer_CSV[loop].append([])if counts_CNC[c][d] != 0:if find_free_min_add(T_CNC_matrix,State_CNC,0,0,1,1) == (2,2):(m,n) = find_martrix_min_value(T_down,State_CNC,1,1)T_RGV = max(T_RGV + T_move[Group][abs(State_RGV-n)],T_down[m][n])else:(m,n) = find_free_min_add(T_CNC_matrix,State_CNC,0,0,1,1)T_RGV = T_RGV + T_move[Group][abs(State_RGV-n)]
# 上件
# print(m,n)if m == 0:T_RGV = T_RGV + T_change[Group][0]elif m == 1:T_RGV = T_RGV + T_change[Group][1]State_CNC[0][m][n] = 1State_RGV = n
# print(counts_CNC)if counts_CNC[m][n] != 0:T_RGV = T_RGV + T_clean[Group]counts_CNC[m][n] = counts_CNC[m][n] + 1T_down[m][n] = T_process_2[Group] + T_RGV# print(NUM_CNC)NUM_CNC[m][n] = NUM_CNC[c][d]
# print(NUM_CNC[m][n])if m == 0:Num = 2 * (n + 1)elif m == 1:Num = 2 * (n + 1) - 1
# print(Answer_CSV[loop])
# print(NUM_CNC[m][n] - 1)Answer_CSV[loop][NUM_CNC[m][n] - 1].append('CNC{}#'.format(Num))T_up = T_RGVAnswer_CSV[loop][NUM_CNC[m][n] - 1].append(T_up)Answer_CSV[loop][NUM_CNC[m][n] - 1].append(T_down[m][n])NUM_CNC[c][d] = counts
# print(counts)counts_CNC[c][d] = counts_CNC[c][d] + 1T_down[c][d] = T_process_1[Group] + T_RGV
# 超过8小时即结束循环if T_down[c][d] + T_change[Group][c] + T_clean[Group] > T_total:break
# 将结果输出至CSV表格if c == 0:Num = 2 * (d + 1)elif c == 1:Num = 2 * (d + 1) - 1
# print(NUM_CNC[c][d])Answer_CSV[loop][NUM_CNC[c][d] - 1].append(NUM_CNC[c][d])Answer_CSV[loop][NUM_CNC[c][d] - 1].append('CNC{}#'.format(Num))T_up = T_RGVAnswer_CSV[loop][times].append(T_up)Answer_CSV[loop][times].append(T_down[c][d])for i in range (2):for j in range (4):if T_RGV >= T_down[i][j]:State_CNC[0][i][j] = 0counts_CSV.append(counts)
# print(Answer_CSV)
MAX_loop = 0
for loop in range (Loop):if MAX_OUTPUT < counts_CSV[loop]:MAX_OUTPUT = counts_CSV[loop]MAX_loop = loop
print(Answer_CSV[MAX_loop])
print(counts_CSV[MAX_loop])
writer = csv.writer(open("Case_2_2_2_2_test.csv",'w',newline=''))
for item in Answer_CSV[MAX_loop]:writer.writerow(item)
#
Case_3_1
# -*- coding: utf-8 -*-
"""
Created on Sat Sep 15 14:00:24 2018@author: LIU Zhendong
"""
import csv
from itertools import chain
import random
'''按照A*算法进行RGV分配加工所需时间模拟(模拟1%故障率)======================================'''Group = 2def find_martrix_min_value(data_matrix,State_CNC):'''''功能:找到矩阵State_CNC为0下的data_matrix最小值'''min_data = 1000000000add=(0,0)for i in range(len(data_matrix)):for j in range (len(data_matrix[i])):if data_matrix[i][j] < min_data and State_CNC[i][j] == 0:min_data = data_matrix[i][j]add = (i,j)return adddef Breakdown_random():'''''功能:随机产生故障并返回故障机器编号和故障时间'''a = random.randint(1,800)b = random.randint(600,1200)if a > 8:return (2,0,0)elif a % 2 == 0:return (0 , int(a/2-1) , b)elif a % 2 == 1:return (1 , int((a-1)/2) , b)'''初始化变量==============================================='''
T_total = 8 * 60 * 60
T_CNC_matrix = []
State_CNC = [] # 0表示完成工作进入等待 1 表示正在工作
State_RGV = 0 # 表示RGV的位置 其中0,1,2,3分别代表位于1#、2#,3#、4#,5#、6#,7#、8#之间
State_CNC_Break = [] # 存放故障结束时间 0 表示无故障
T_RGV = 0
Count_break = 0
T_G = []
T_H = []
T_down = []
Answer_CSV = []
Answer_CSV_Break =[]
NUM_CNC = [] # 存放CNC上物品编号
for i in range (2):State_CNC.append([])T_CNC_matrix.append([])T_G.append([])T_down.append([])State_CNC_Break.append([])NUM_CNC.append([])for j in range(4):State_CNC[i].append(0)T_CNC_matrix[i].append(0)T_G[i].append(0)T_down[i].append(0)State_CNC_Break[i].append(0)NUM_CNC[i].append(0)'''模拟主循环====================================================='''
for times in range (1000):
# 初始化T_change = [[31,28],[35,30],[32,27]]T_clean = [25,30,25]T_move = [[0,20,33,46],[0,23,41,59],[0,18,32,46]]T_process = [560,580,545]T_process_1 = [400,280,455]T_process_2 = [378,500,182]for j in range (2):for k in range (4):if j == 0:T_G[j][k] = T_change[Group][0]elif j == 1:T_G[j][k] = T_change[Group][1]
# print(T_G)for i in range (2):if State_RGV == 0:T_G[i][1] = T_G[i][1] + T_move[Group][1]T_G[i][2] = T_G[i][2] + T_move[Group][2]T_G[i][3] = T_G[i][3] + T_move[Group][3]elif State_RGV == 1:T_G[i][0] = T_G[i][0] + T_move[Group][1]T_G[i][2] = T_G[i][2] + T_move[Group][1]T_G[i][3] = T_G[i][3] + T_move[Group][2]elif State_RGV == 2:T_G[i][0] = T_G[i][0] + T_move[Group][2]T_G[i][1] = T_G[i][1] + T_move[Group][1]T_G[i][3] = T_G[i][3] + T_move[Group][1]elif State_RGV == 3:T_G[i][0] = T_G[i][0] + T_move[Group][3]T_G[i][1] = T_G[i][1] + T_move[Group][2]T_G[i][2] = T_G[i][2] + T_move[Group][1]
# print(T_G)for j in range (2):T_H.append([])for k in range (4):T_H[j].append(T_process[Group])for i in range (2):for j in range (4):T_CNC_matrix[i][j] = T_G[i][j] + T_H[i][j] + T_clean[Group]
# print(T_CNC_matrix)add = find_martrix_min_value(T_CNC_matrix,State_CNC)(a,b) = add
# print(add)T_RGV = T_RGV + T_move[Group][abs(State_RGV-b)]if a == 0:Num = 2 * (b + 1)elif a == 1:Num = 2 * (b + 1) - 1if a == 0:T_RGV = T_RGV + T_change[Group][0]elif a == 1:T_RGV = T_RGV + T_change[Group][1]State_CNC[a][b] = 1NUM_CNC[a][b] = times + 1T_down[a][b] = T_process[Group] + T_RGV# 超过8小时即结束循环if T_down[a][b] + T_change[Group][a] + T_clean[Group] > T_total:break
# 将结果输出至CSV表格Answer_CSV.append([]) Answer_CSV[times].append(times+1)Answer_CSV[times].append('CNC{}#'.format(Num))T_up = T_RGVAnswer_CSV[times].append(T_up)Answer_CSV[times].append(T_down[a][b])
# print(T_RGV)'''随机产生故障'''(e,f,g)= Breakdown_random()if times > 7 and e != 2:
# 存在故障State_CNC[e][f] = 1T_down[e][f] = g + T_RGVState_CNC_Break[e][f] = T_down[e][f]Answer_CSV_Break.append([])Answer_CSV_Break[Count_break].append(NUM_CNC[e][f])if e == 0:Num_Break = 2 * (f + 1)elif e == 1:Num_Break = 2 * (f + 1) - 1Answer_CSV_Break[Count_break].append('CNC{}#'.format(Num_Break))T_up = T_RGVAnswer_CSV_Break[Count_break].append(T_up)Answer_CSV_Break[Count_break].append(T_down[e][f])Count_break = Count_break + 1for i in range (2):for j in range (4):if T_RGV > State_CNC_Break[i][j] and State_CNC_Break[i][j] != 0:State_CNC_Break[i][j] = 0State_CNC[i][j] = 0# 清洗if times > 7:T_RGV = T_RGV + T_clean[Group]State_RGV = b# 全部CNC在工作或故障,没有CNC等待,RGV自动跳转至下一个最快结束的机器位if len(set(list(chain.from_iterable(State_CNC)))) == 1:for i in range (2):for j in range (4):if State_CNC_Break[i][j] == 0:State_CNC[i][j] = 0(c,d)=find_martrix_min_value(T_down,State_CNC)T_RGV = T_RGV + T_move[Group][abs(State_RGV-d)]State_RGV = dT_RGV = T_down[c][d]if T_down[a][b] + T_change[Group][a] + T_clean[Group] > T_total:break
# print(State_CNC)
# print(T_RGV)
# print(State_RGV)
print(Answer_CSV)
print(Answer_CSV_Break)
print(Count_break)
writer = csv.writer(open("Case_3_1_3.csv",'w',newline=''))
for item in Answer_CSV:writer.writerow(item)writer_1 = csv.writer(open("Case_3_1_Break_3.csv",'w',newline=''))
for item_1 in Answer_CSV_Break:writer_1.writerow(item_1)
Case_3_2
# -*- coding: utf-8 -*-
"""
Created on Sun Sep 16 17:06:37 2018@author: LIU Zhendong
"""
'''两道工序按照A*算法进行RGV分配加工所需时间模拟(模拟1%故障率)======================================'''
import csv
from itertools import chain
import random
'''穷举法--两道工序======================================'''
'''
算法规则:
RGV总共有三种工作要做
1、给1类刀具CNC上原件
2、把1类刀具CNC上原件给二类刀具
3、将2类刀具CNC上熟件卸下清洗存放
假设从1类刀具CNC上卸下的原件无处存放,需要RGV停止等待2类刀具
CNC结束工作再给其装上,期间RGV不能做其他事情
如果RGV遇到1类刀具CNC和2类刀具CNC同时请求时,优先选择2类刀具
CNC装件
'''Group = 2
Loop = 254
Times = 1024
def find_martrix_min_value(data_matrix,State_CNC,State_CNC_Break,p,q):'''''功能:找到矩阵State_CNC[0]为0下的data_matrix最小值'''min_data = 1000000000add=(2,2)for i in range(len(data_matrix)):for j in range (len(data_matrix[i])):if data_matrix[i][j] < min_data and State_CNC[p][i][j] == q and State_CNC_Break[i][j] == 0:min_data = data_matrix[i][j]add = (i,j)return adddef find_free_min_add(data_matrix,State_CNC,State_CNC_Break,p,q,r,s):'''''功能:找到矩阵State_CNC一定条件下最小值'''min_data = 1000000000add=(2,2)for i in range(len(data_matrix)):for j in range (len(data_matrix[i])):if data_matrix[i][j] < min_data and State_CNC[p][i][j] == q and State_CNC[r][i][j] == s and State_CNC_Break[i][j] == 0:min_data = data_matrix[i][j]add = (i,j)return add
def Breakdown_random():'''''功能:随机产生故障并返回故障机器编号和故障时间'''a = random.randint(1,800)b = random.randint(600,1200)if a > 8:return (2,0,0)elif a % 2 == 0:return (0 , int(a/2-1) , b)elif a % 2 == 1:return (1 , int((a-1)/2) , b)'''初始化变量==============================================='''
T_total = 8 * 60 * 60
MAX_OUTPUT = 0
T_CNC_matrix = []
# 表示CNC剩余工作时间列表
State_CNC = [[],[]]
'''
State_CNC[0] 为一张2 * 4 列表,表示CNC状态其中0表示完成工作进入等待 1 表示正在工作
State_CNC[1] 为一张2 * 4 列表, 表示CNC携带的刀具其中0表示携带第一类刀具 1 表示携带第二类刀具
'''
State_RGV = 0'''
State_RGV表示RGV的位置其中State_RGV = 0,1,2,3分别代表位于1#、2#,3#、4#,5#、6#,7#、8#之间'''
State_CNC_Break = [] # 存放故障结束时间 0 表示无故障
T_RGV = 0
T_G = []
T_H = []
counts_CSV = []
Count_break = 0
T_down = []
Answer_CSV = []
Answer_CSV_Break =[]
NUM_CNC = [] # 存放CNC上物品编号
counts_CNC = [] # 记录CNC处理产品数量
T_change = [[31,28],[35,30],[32,27]]
T_clean = [25,30,25]
T_move = [[0,20,33,46],[0,23,41,59],[0,18,32,46]]
T_process = [560,580,545]
T_process_1 = [400,280,455]
T_process_2 = [378,500,182]
for i in range (2):State_CNC[0].append([])State_CNC[1].append([])T_CNC_matrix.append([])T_G.append([])T_down.append([])State_CNC_Break.append([])NUM_CNC.append([])counts_CNC.append([])for j in range(4):State_CNC[0][i].append(0)State_CNC[1][i].append(0)T_CNC_matrix[i].append(0)T_G[i].append(0)T_down[i].append(0)State_CNC_Break[i].append(0)NUM_CNC[i].append(0)counts_CNC[i].append(0)
#print(State_CNC)'''穷举刀具各种情况主循环'''for loop in range (Loop):for i in range (2):for j in range (4):T_CNC_matrix[i][j] = 0NUM_CNC[i][j] = 0counts_CNC[i][j] = 0State_CNC[0][i][j] = 0State_CNC[1][i][j] = 0T_CNC_matrix[i][j] = 0counts_CNC[i][j] = 0NUM_1 = 0NUM_2 = 0Count_break = 0NUM = '{:08b}'.format(loop + 1)list_NUM = list(str(NUM))State_CNC[1][1][0] = int(list_NUM[7])State_CNC[1][0][0] = int(list_NUM[6])State_CNC[1][1][1] = int(list_NUM[5])State_CNC[1][0][1] = int(list_NUM[4])State_CNC[1][1][2] = int(list_NUM[3])State_CNC[1][0][2] = int(list_NUM[2])State_CNC[1][1][3] = int(list_NUM[1])State_CNC[1][0][3] = int(list_NUM[0])
# State_CNC[1][1][0] = 0
# State_CNC[1][0][0] = 0
# State_CNC[1][1][1] = 0
# State_CNC[1][0][1] = 1
# State_CNC[1][1][2] = 1
# State_CNC[1][0][2] = 1
# State_CNC[1][1][3] = 1
# State_CNC[1][0][3] = 1
# print(State_CNC[1])for i in range (2):for j in range (4):if State_CNC[1][i][j] == 0:NUM_1 = NUM_1 + 1 #1类刀具CNC数目elif State_CNC[1][i][j] == 1:NUM_2 = NUM_2 + 1 #2类刀具CNC数目
# print(NUM_1)# 定义时间矩阵表示从目前位置到完成整件预估时间
# T_move + T_change + T_process_1 + T_change + T_move + T_change + T_process_2 + T_clean
# 预估时间矩阵T_CNC_matrix求解===============================================
# 2类刀具CNC预估时间矩阵for i in range (2):for j in range (4):if State_CNC[1][i][j] == 1: # 携带2类刀具CNC
# T_changeif i == 0:T_CNC_matrix[i][j] = 2 * T_change[Group][0]elif i == 1:T_CNC_matrix[i][j] = 2 * T_change[Group][1]# T_process_2T_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_process_2[Group]# T_cleanT_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_clean[Group]
# print(T_CNC_matrix)Answer_CSV.append([])Answer_CSV_Break.append([])T_RGV = 0counts = 0counts_1 = 0 # 计数:1类刀具CNC正在加工零件数目counts_2 = 0 # 计数:2类刀具CNC正在加工零件数目State_RGV = 0
#循环求解for times in range (Times):
# print(counts+1,'===================================================')
# for i in range (2):
# for j in range (4):
# State_CNC[0][i][j] = 0
# 1类刀具CNC预估时间矩阵
# State_CNC[1][1][0] = 0
# State_CNC[1][0][0] = 1
# State_CNC[1][1][1] = 1
# State_CNC[1][0][1] = 0
# State_CNC[1][1][2] = 1
# State_CNC[1][0][2] = 0
# State_CNC[1][1][3] = 0
# State_CNC[1][0][3] = 0
# NUM_1 = 5for i in range (2):for j in range (4):if State_CNC[1][i][j] == 0: # 携带1类刀具CNC
# T_changeif i == 0:T_CNC_matrix[i][j] = T_change[Group][0]elif i == 1:T_CNC_matrix[i][j] = T_change[Group][1]
# T_process_1T_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_process_1[Group]
# print(T_CNC_matrix)for i in range (2):for j in range (4):if State_CNC[1][i][j]== 0:for k in range (2):for l in range (4):if State_CNC[1][k][l] == 1:T_G[k][l] = T_CNC_matrix[i][j] + T_move[Group][abs(l-j)] + T_CNC_matrix[k][l](a,b) = find_martrix_min_value(T_G,State_CNC,State_CNC_Break,1,1)if (a,b) == (2,2):T_CNC_matrix[i][j] = T_G[0][0] + T_move[Group][abs(State_RGV-j)] + 1200else:T_CNC_matrix[i][j] = T_G[a][b] + T_move[Group][abs(State_RGV-j)](c,d) = find_martrix_min_value(T_CNC_matrix,State_CNC,State_CNC_Break,1,0)for i in range (2):for j in range(4):T_G[i][j] = 0
# print(T_CNC_matrix)
# 预估时间矩阵T_CNC_matrix求解===============================================# =============================================================================
# NUM_1 1CNC数
# counts 零件标号
# counts_1 正在加工
# counts_1_free 加工完成空闲数
# counts_2 正在加工
# counts_2_free 加工完成空闲数# =============================================================================
#for i in range (2):for j in range (4):if T_RGV >= T_down[i][j]:State_CNC[0][i][j] = 0
# print(State_CNC[0])
# print(State_CNC_Break)(c,d) = find_free_min_add(T_CNC_matrix,State_CNC,State_CNC_Break,0,0,1,0)
# 移动至目标CNC
# print(c,d)for i in range (2):for j in range (4):if T_RGV >= T_down[i][j]:State_CNC[0][i][j] = 0if(c,d) == (2,2):(c,d) = find_martrix_min_value(T_down,State_CNC,State_CNC_Break,1,0)if (c,d) == (2,2):(h,o) = (0,0)T_RGV = T_down[0][0]else:T_RGV = max(T_RGV + T_move[Group][abs(State_RGV-d)],T_down[c][d])else:T_RGV = T_RGV + T_move[Group][abs(State_RGV-d)]State_RGV = d
# 上件if c == 0:T_RGV = T_RGV + T_change[Group][0]elif c == 1:T_RGV = T_RGV + T_change[Group][1]if (c,d) == (2,2):(c,d) = (0,0)T_RGV = T_down[0][0]T_down[c][d] = T_RGV + T_process_1[Group]
# 产生随机故障(e,f,g)= Breakdown_random()if times > NUM_1 and e != 2:
# 存在故障State_CNC[0][e][f] = 1T_down[e][f] = g + T_RGVState_CNC_Break[e][f] = T_down[e][f]Answer_CSV_Break[loop].append([])Answer_CSV_Break[loop][Count_break].append(NUM_CNC[e][f])if e == 0:Num_Break = 2 * (f + 1)elif e == 1:Num_Break = 2 * (f + 1) - 1Answer_CSV_Break[loop][Count_break].append('CNC{}#'.format(Num_Break))T_up = T_RGVAnswer_CSV_Break[loop][Count_break].append(T_up)Answer_CSV_Break[loop][Count_break].append(T_down[e][f])Count_break = Count_break + 1for i in range (2):for j in range (4):if T_RGV > State_CNC_Break[i][j] and State_CNC_Break[i][j] != 0:State_CNC_Break[i][j] = 0State_CNC[0][i][j] = 0
# print('T_down',T_down)if c == 0:Num = 2 * (d + 1)elif c == 1:Num = 2 * (d + 1) - 1State_CNC[0][c][d] = 1counts = counts + 1
# print(NUM_CNC)Answer_CSV[loop].append([])if counts_CNC[c][d] != 0:if find_free_min_add(T_CNC_matrix,State_CNC,State_CNC_Break,0,0,1,1) == (2,2):(m,n) = find_martrix_min_value(T_down,State_CNC,State_CNC_Break,1,1)if (m,n) == (2,2):(m,n) = (0,0)T_RGV = T_down[0][0] + 1200else:T_RGV = max(T_RGV + T_move[Group][abs(State_RGV-n)],T_down[m][n])else:(m,n) = find_free_min_add(T_CNC_matrix,State_CNC,State_CNC_Break,0,0,1,1)T_RGV = T_RGV + T_move[Group][abs(State_RGV-n)]
# 上件
# print(m,n)if m == 0:T_RGV = T_RGV + T_change[Group][0]elif m == 1:T_RGV = T_RGV + T_change[Group][1]if (m,n) == (2,2):(m,n) == (0,0)S_RGV = T_down[0][0]State_CNC[0][m][n] = 1State_RGV = n
# print(counts_CNC)if counts_CNC[m][n] != 0:T_RGV = T_RGV + T_clean[Group]counts_CNC[m][n] = counts_CNC[m][n] + 1T_down[m][n] = T_process_2[Group] + T_RGV# print(NUM_CNC)NUM_CNC[m][n] = NUM_CNC[c][d]
# print(NUM_CNC[m][n])if m == 0:Num = 2 * (n + 1)elif m == 1:Num = 2 * (n + 1) - 1
# print(Answer_CSV[loop])
# print(NUM_CNC[m][n] - 1)Answer_CSV[loop][NUM_CNC[m][n] - 1].append('CNC{}#'.format(Num))T_up = T_RGVAnswer_CSV[loop][NUM_CNC[m][n] - 1].append(T_up)Answer_CSV[loop][NUM_CNC[m][n] - 1].append(T_down[m][n])NUM_CNC[c][d] = counts
# print(counts)counts_CNC[c][d] = counts_CNC[c][d] + 1T_down[c][d] = T_process_1[Group] + T_RGV
# 超过8小时即结束循环if T_down[c][d] + T_change[Group][c] + T_clean[Group] > T_total:break
# 将结果输出至CSV表格if c == 0:Num = 2 * (d + 1)elif c == 1:Num = 2 * (d + 1) - 1
# print(NUM_CNC[c][d])Answer_CSV[loop][NUM_CNC[c][d] - 1].append(NUM_CNC[c][d])Answer_CSV[loop][NUM_CNC[c][d] - 1].append('CNC{}#'.format(Num))T_up = T_RGVAnswer_CSV[loop][times].append(T_up)Answer_CSV[loop][times].append(T_down[c][d])for i in range (2):for j in range (4):if T_RGV >= T_down[i][j]:State_CNC[0][i][j] = 0counts_CSV.append(counts)
# print(Answer_CSV)
MAX_loop = 0
for loop in range (Loop):if MAX_OUTPUT < counts_CSV[loop]:MAX_OUTPUT = counts_CSV[loop]MAX_loop = loop
print(Answer_CSV[MAX_loop])
print(counts_CSV[MAX_loop])
print(Answer_CSV_Break[MAX_loop])writer = csv.writer(open("Case_3_2_3.csv",'w',newline=''))
for item in Answer_CSV[MAX_loop]:writer.writerow(item)writer_1 = csv.writer(open("Case_3_2_3_Break.csv",'w',newline=''))
for item_1 in Answer_CSV_Break[MAX_loop]:writer_1.writerow(item_1)
2018CUMCM(数学建模国赛)_B——智能RGV的动态调度策略相关推荐
- 数学建模国赛2018B题RGV动态调度模型思路复述(这题也太硬了吧(啃不动
目录 一.问题分析 任务一 任务二 二.假设与符号说明 假设 变量 三.思路与模型 情况1:一道工序无故障作业调度 1. 关于RGV运行路径的分析 2. 关于RGV的作业调度方式 3. 调度模型的目标 ...
- 2018年数学建模国赛B题 智能RGV的动态调度策略
第一种情况大致思路: 每秒判断各个CNC的状态,若工作完成或者是出于空闲状态下则向RGV发出一个请求.同时,RGV每秒判断自己的状态(上下料.移动.闲置.清洗等),如果是处于闲置状态,则启用调度算法, ...
- 2018 数学建模 国赛(高教杯)-智能RGV的动态调度策略
2018 高教社杯全国大学生数学建模竞题 问题B 智能RGV的动态调度策略 Author:YXP Email:yxp189@protonmail.com 更多数模赛题: Amoiensis-CUMCU ...
- 2018数学建模国赛回顾(国一)
2018年数学建模国赛终于尘埃落定,第一次参赛,非常幸运地拿到了国一,在这里记录下这段难忘的经历,分享一些个人的看法心得. 其实严格来说,我从接触数模到参赛只有一个月左右的时间,我之所以能拿奖很大程度 ...
- 详解2020数学建模国赛A题炉温曲线
详解2020数学建模国赛A题炉温曲线 问题描述 在集成电路板等电子产品生产中,需要将安装有各种电子元件的印刷电路板放置在回焊炉中,通过加热,将电子元件自动焊接到电路板上.在这个生产过程中,让回焊炉的各 ...
- 备战数学建模国赛,快速搞定算法模型!
全世界只有3.14 % 的人关注了 青少年数学之旅 说到数学建模,大家的第一反应就是国赛.美赛等数学建模比赛,但这只是冰山一角,不过这个反应却也很正常,因为很多小伙伴接触数学建模的契机,大部分还是因为 ...
- 2022年数学建模国赛c题论文+代码(附详解)
古代玻璃制品化学成分的分析与研究 摘要 古代玻璃极易受埋藏环境的影响而风化,并且在风化过程中,内部元素与环境元素进行着大量交换,导致其成分比例会发生变化,从而会影响对其类别的正确判断.玻璃在炼制的过程 ...
- 2019 数学建模国赛 C 题思路
我最后一次数学建模国赛结束了. 今年选的C题,在这里讲一些关于我们的解题思路之类的东西. 今年看到题目以后果断选了C,但是中途想过要换B,因为找了一晚上C的数据,几乎找不到什么有用的,但最后还是继续做 ...
- 2019数学建模国赛C题
2019数学建模国赛C 运用模拟仿真的思想 附录1 在一定时间段内出租车在市区的平均空载率 zhs02.m clear; clc; data=xlsread('C:\Users\limaoli\Des ...
- 2020年数学建模国赛C题
2020年数学建模国赛C题题目: 后续会更新解题思路,在此可以看下面的一篇论文 基于贝叶斯神经网络的信贷策略规划研究
最新文章
- 开源医学图像数据集(资源整合)
- windows中端口号(port id)和port的区别,如何通过端口查看进程pid,如何通过pid查看程序,如何通过pid查看端口?
- python 可视化界面_给大家分享一些实用的Python库
- Mysql系列三:Centos6下安装Mysql和Mysql主从复制的搭建
- Java中基础数据类型分类
- mysql 5.7和8.0区别_SpringBoot 2.0 教程实战 MySQL 读写分离
- 点个外卖时间,我把「软中断」搞懂了
- roseMirrorHA5.0 for WindowsServer2008R2配合sqlserver2012|Oracle 11g的安装和配置
- 半个月使用rust语言的体验
- nodejs后台系列--第四篇--koa(四)
- css.ppt,CSS ppt.ppt
- 网络PPTP协议代理加速器的应用
- 计算机与网络期刊多少钱,《计算机与网络》是不是核心期刊
- 关于linux系统安装zabbix报错的解决方案
- Ubuntu系统中使用todesk设备ID不显示问题解决
- CTP 4097错误根源 / CTP程序运行没有反应/CTP版本说明
- 0x80073712_Win10更新提示0x80073712错误代码解决方法
- 摘自网眼的腾讯QQ微博(http://t.qq.com/zhangking)
- pandas 库前置知识
- 企业人物的百度百科怎么建立的,创建百度百科词条要交费吗