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輸送生料(未加工的物料);左邊爲下料傳送帶,負責將成料(加工並清洗完成的物料)送出系統。其他爲保證系統正常運行的輔助設備。

 

 

 

附圖1RGVCNC車間佈局圖

 

    2:帶機械手臂和清洗槽的RGV實物圖

 

 

附圖2是RGV的實物圖,包括車體、機械臂、機械手爪和物料清洗槽等。

 

 

附圖3RGV機械手臂前端的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條下料傳送帶等附屬設備構成。

1CNC在上料傳送帶和下料傳送帶的兩側各安裝4臺CNC,等距排列,每臺CNC同一時間只能安裝1種刀具加工1個物料。

如果物料的加工過程需要兩道工序,則需要有不同的CNC安裝不同的刀具分別加工完成,在加工過程中不能更換刀具。第一和第二道工序需要在不同的CNC上依次加工完成,完成時間也不同,每臺CNC只能完成其中的一道工序。

2RGVRGV帶有智能控制功能,能夠接收和發送指令信號。根據指令能在直線軌道上移動和停止等待,可連續移動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 = 1000000000
    add=(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 = 0
    T_CNC_even = 0
    T_cost = 0
    T_change = [31,28]
    T_clean = 25
    T_move = [0,20,33,46]
    T_process = 560
    T_process_1 = 400
    T_process_2 = 378
    for 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_clean
    print(T_CNC_matrix)
    add = find_martrix_min_value(T_CNC_matrix,State_CNC)
    (a,b) = add
    T_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) - 1
    if a == 0:
        T_RGV = T_RGV + T_change[0]
    elif a == 1:
        T_RGV = T_RGV + T_change[1]
    State_CNC[a][b] = 1
    T_down[a][b] = T_process + T_RGV
    if T_down[a][b] + T_change[a] + T_clean > T_total:
        break
    Answer_CSV.append([]) 
    Answer_CSV[times].append(times+1)
    Answer_CSV[times].append('CNC{}#'.format(Num))
    T_up = T_RGV
    Answer_CSV[times].append(T_up)
    Answer_CSV[times].append(T_down[a][b])
    
    if times > 7:
        T_RGV = T_RGV + T_clean
    State_RGV = b
    if 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 = d
        T_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 = 1000000000
    add=(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 add

def find_free_min_add(data_matrix,State_CNC,p,q,r,s):
    '''''
    功能:找到矩陣State_CNC一定條件下最小值
    '''
    min_data = 1000000000
    add=(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] = 0
            NUM_CNC[i][j] = 0
            counts_CNC[i][j] = 0
            State_CNC[0][i][j] = 0
            State_CNC[1][i][j] = 0
            T_CNC_matrix[i][j] = 0
            counts_CNC[i][j] = 0
    NUM_1 = 0
    NUM_2 = 0
    NUM = '{: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_change
                if 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_2
                T_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_process_2[Group]

#                T_clean
                T_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_clean[Group]
#    print(T_CNC_matrix)


    Answer_CSV.append([])
    T_RGV = 0
    counts = 0
    counts_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 = 5
        
        for i in range (2):
            for j in range (4):
                if State_CNC[1][i][j] == 0:               # 攜帶1類刀具CNC
#                    T_change
                    if 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_1
                    T_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] = 0
        if(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) - 1
        State_CNC[0][c][d] = 1
        counts = 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] = 1
            State_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] + 1
            T_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_RGV
            Answer_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] + 1
        T_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_RGV
        Answer_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] = 0
    counts_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 = 2

def find_martrix_min_value(data_matrix,State_CNC):
    '''''
    功能:找到矩陣State_CNC爲0下的data_matrix最小值
    '''
    min_data = 1000000000
    add=(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

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
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) - 1
    if 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] = 1
    NUM_CNC[a][b] = times + 1
    T_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_RGV
    Answer_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] = 1
        T_down[e][f] = g + T_RGV
        State_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) - 1
        Answer_CSV_Break[Count_break].append('CNC{}#'.format(Num_Break))
        T_up = T_RGV
        Answer_CSV_Break[Count_break].append(T_up)
        Answer_CSV_Break[Count_break].append(T_down[e][f])
        Count_break = Count_break + 1
    for 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] = 0
                State_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 = d
        T_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 = 1000000000
    add=(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 add

def find_free_min_add(data_matrix,State_CNC,State_CNC_Break,p,q,r,s):
    '''''
    功能:找到矩陣State_CNC一定條件下最小值
    '''
    min_data = 1000000000
    add=(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] = 0
            NUM_CNC[i][j] = 0
            counts_CNC[i][j] = 0
            State_CNC[0][i][j] = 0
            State_CNC[1][i][j] = 0
            T_CNC_matrix[i][j] = 0
            counts_CNC[i][j] = 0
    NUM_1 = 0
    NUM_2 = 0
    Count_break = 0
    NUM = '{: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_change
                if 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_2
                T_CNC_matrix[i][j] = T_CNC_matrix[i][j] + T_process_2[Group]

#                T_clean
                T_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 = 0
    counts = 0
    counts_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 = 5
        
        for i in range (2):
            for j in range (4):
                if State_CNC[1][i][j] == 0:               # 攜帶1類刀具CNC
#                    T_change
                    if 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_1
                    T_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)] + 1200
                    else:
                        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] = 0
        if(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] = 1
            T_down[e][f] = g + T_RGV
            State_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) - 1
            Answer_CSV_Break[loop][Count_break].append('CNC{}#'.format(Num_Break))
            T_up = T_RGV
            Answer_CSV_Break[loop][Count_break].append(T_up)
            Answer_CSV_Break[loop][Count_break].append(T_down[e][f])
            Count_break = Count_break + 1
        for 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] = 0
                    State_CNC[0][i][j] = 0
#        print('T_down',T_down)
        if c == 0:
            Num = 2 * (d + 1)
        elif c == 1:
            Num = 2 * (d + 1) - 1
        State_CNC[0][c][d] = 1
        counts = 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] + 1200
                else:
                    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] = 1
            State_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] + 1
            T_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_RGV
            Answer_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] + 1
        T_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_RGV
        Answer_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] = 0
    counts_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)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章