用python实现基于压缩时窗的柔性作业车间调度问题

策略流程

代码如下:

注:仅有部分代码,提供思路。

import decimal
from Jobs import Job
from Machines import Machine_Time_window
import numpy as np
import random
import matplotlib.pyplot as plt


class Scheduling:
    def __init__(self, M_num, Processing_time,J):
        self.Processing_time = Processing_time
        self.Scheduled = []                 #已经排产过的工序
        self.M_num = M_num
        self.Machines = []  # 存储机器类
        self.fitness=0
        for j in range(M_num):
            self.Machines.append(Machine_Time_window(j))
        self.Machine_State = np.zeros(M_num, dtype=int)  # 在机器上加工的工件是哪个
        self.Jobs = []
        for k, v in J.items():
            self.Jobs.append(Job(k, v))

    def Earliest_Start(self,Job,O_num,Machine):
        P_t=self.Processing_time[Job][O_num][Machine]
        last_O_end = self.Jobs[Job].Last_Processing_end_time  # 上道工序结束时间
        Selected_Machine=Machine
        M_window = self.Machines[Selected_Machine].Empty_time_window()
        M_Tstart = M_window[0]
        M_Tend = M_window[1]
        M_Tlen = M_window[2]
        Machine_end_time = self.Machines[Selected_Machine].End_time
        ealiest_start = max(last_O_end, Machine_end_time)
        Forced_Insertion=0
        if M_Tlen is not None:  # 此处为全插入时窗
            for le_i in range(len(M_Tlen)):
                if M_Tlen[le_i] >= P_t:
                    if M_Tstart[le_i] >= last_O_end:
                        ealiest_start=M_Tstart[le_i]
                        break
                    if M_Tstart[le_i] < last_O_end and M_Tend[le_i] - last_O_end >= P_t:
                        ealiest_start = last_O_end
                        break
                    if M_Tstart[le_i]<last_O_end and M_Tend[le_i]-last_O_end>=P_t*0.6 and M_Tlen[le_i]-last_O_end<P_t :
                        ealiest_start=last_O_end
                        Forced_Insertion=1
                        break
                    break
                if M_Tlen[le_i]>=P_t*0.6 and M_Tlen[le_i]<P_t:
                    if M_Tstart[le_i]>=last_O_end :
                        ealiest_start = M_Tstart[le_i]
                        Forced_Insertion = 1
                        break
                    if M_Tstart[le_i]<last_O_end and M_Tend[le_i]-last_O_end>=P_t*0.6:
                        ealiest_start = last_O_end
                        Forced_Insertion = 1
                        break
                    break
        M_Ealiest = ealiest_start
        End_work_time = M_Ealiest + P_t
        return M_Ealiest, Selected_Machine, P_t, O_num, End_work_time,Forced_Insertion,last_O_end

    #判断强迫插入影响到的工序
    def Influenced_Operation(self,Machine,Job,P_t,O_num,ealiest_start,last_o_end):
        End_time=self.Machines[Machine].O_end
        Start_time=self.Machines[Machine].O_start
        Influend=[]
        for i in range(len(Start_time)):
            if ealiest_start<Start_time[i]:
                back_off = ealiest_start + P_t - Start_time[i ]
                for j in range(i,len(Start_time)-1):
                        Influend.append(self.Machines[Machine].assigned_task[j])
                        Start_time[j]+=back_off
                        End_time[j]+=back_off
                # self.Machines[Machine].O_end=End_time
                # self.Machines[Machine].O_start=Start_time
                # self.Machines[Machine]._Input(Job, ealiest_start, P_t, O_num)
                # End=ealiest_start+P_t
                # self.Jobs[Job]._Input(ealiest_start, End, Machine)
                break
        for k in range(len(Influend)):
            J_num=Influend[k][0]-1
            J=self.Jobs[Influend[k][0]-1]
            O_i=J.Current_Processed()
            if O_i==Influend[k][1]:
                pass
            else:
                for k_1 in range(Influend[k][1],O_i):
                    # print(k_1)
                    Machine_J=J.J_machine[k_1]
                    if Machine_J==Machine:
                        pass
                    else:
                        Site=self.Machines[Machine_J].assigned_task.index([Influend[k][0],k_1+1])
                        for S_i in range(Site,len(self.Machines[Machine_J].O_start)):
                            self.Machines[Machine_J].O_start[S_i]+=back_off
                            self.Machines[Machine_J].O_end[S_i] += back_off
                    self.Jobs[Influend[k][0] - 1].J_start[k_1]+=back_off
                    self.Jobs[Influend[k][0]-1].J_end[k_1]+=back_off
        self.Machines[Machine].O_end = End_time
        self.Machines[Machine].O_start = Start_time
        self.Machines[Machine]._Input(Job, ealiest_start, P_t, O_num)
        End = ealiest_start + P_t
        self.Jobs[Job]._Input(ealiest_start, End, Machine)

    def add_job(self,Job,M_Ealiest,Selected_Machine,P_t,O_num,Force_Insertion,last_o_end):
        if Force_Insertion==0:
            self.Scheduled.append([Job,O_num])
            self.Machines[Selected_Machine]._Input(Job,M_Ealiest,P_t,O_num)
            End_time=M_Ealiest+P_t
            self.Jobs[Job]._Input(M_Ealiest,End_time,Selected_Machine)
            if self.fitness<End_time:
                self.fitness=End_time
        else:
            try:
                self.Influenced_Operation(Selected_Machine,Job,P_t,O_num,M_Ealiest,last_o_end)
            except:
                self.Gantt(self.Machines)
                print(Job,M_Ealiest,P_t,O_num)

    def Gantt(self,Machines):
        M = ['red', 'blue', 'yellow', 'orange', 'green', 'palegoldenrod', 'purple', 'pink', 'Thistle', 'Magenta',
             'SlateBlue', 'RoyalBlue', 'Cyan', 'Aqua', 'floralwhite', 'ghostwhite', 'goldenrod', 'mediumslateblue',
             'navajowhite',
             'navy', 'sandybrown', 'moccasin']
        for i in range(len(Machines)):
            Machine=Machines[i]
            Start_time=Machine.O_start
            End_time=Machine.O_end
            for i_1 in range(len(End_time)):
                # plt.barh(i,width=End_time[i_1]-Start_time[i_1],height=0.8,left=Start_time[i_1],\
                #          color=M[Machine.assigned_task[i_1][0]],edgecolor='black')
                # plt.text(x=Start_time[i_1]+0.1,y=i,s=Machine.assigned_task[i_1])
                plt.barh(i, width=End_time[i_1] - Start_time[i_1], height=0.8, left=Start_time[i_1], \
                         color='white', edgecolor='black')
                s = Machine.assigned_task[i_1]
                plt.text(x=Start_time[i_1] + (End_time[i_1] - Start_time[i_1])/2-0.5, y=i, s=Machine.assigned_task[i_1])
        plt.yticks(np.arange(i + 1), np.arange(1, i + 2))
        plt.title('Scheduling Gantt chart')
        plt.ylabel('Machines')
        plt.xlabel('Time(s)')
        plt.show()

if __name__=='__main__':
    M=3
    J={1:3,2:4,3:3}
    Processing_time=[[
        [1,2,3],
        [1.3,4],
        [3,2,5]
    ],
    [
        [1,3,4],
        [2,3,4],
        [2,5,3],
        [4,3,5]
    ],
    [
        [1,3,4],
        [4,4,5],
        [3,2,5]
    ]]
    S=Scheduling(M,Processing_time,J)
    S.Jobs[1].J_start=[0]
    S.Jobs[1].J_end=[1]

    S.Jobs[0]._Input(0, 1, 0)
    S.Machines[0]._Input(0,0,1,0)

    S.Jobs[1]._Input(1, 2, 0)
    S.Machines[0]._Input(1, 1, 1, 0)

    S.Jobs[1]._Input(2, 5, 1)
    S.Machines[1]._Input(1, 2, 3, 1)

    S.Jobs[1]._Input(5, 7, 0)
    S.Machines[0]._Input(1, 5, 2, 2)

    S.Jobs[0]._Input(7, 8, 0)
    S.Machines[0]._Input(0, 7, 1, 1)

    S.Jobs[0]._Input(8, 10, 1)
    S.Machines[1]._Input(0, 8, 2, 2)

    S.Gantt(S.Machines)
    P=S.Earliest_Start(2,0,1)
    S.add_job(2,P[0],P[1],P[2],P[3],P[5],P[6])
    S.Gantt(S.Machines)

    P = S.Earliest_Start(2, 1, 0)
    S.add_job(2, P[0], P[1], P[2], P[3], P[5], P[6])
    S.Gantt(S.Machines)

结果

未插入前的工序排序:

插入[3,1]后:

插入[3,2]后:

mk07测试结果:

猜你喜欢

转载自blog.csdn.net/crazy_girl_me/article/details/114642059