用python实现改进遗传算法求解FJSP问题的完整编码

学习目标:

上两篇内容写了遗传算法求解FJSP算法的编码和初始化以及解码方式,今天把完整的算法代码放上来,与大家一块学习。

完整研究可参考:基于遗传算法求解柔性作业车间调度问题代码实现(包括标准算例准换、编码、解码的详细讲述)_crazy_girl_me的博客-CSDN博客


算法的基本步骤:

1

2


代码:

import numpy as np
import matplotlib.pyplot as plt
import random
import itertools

#全局初始化
def Global_initial(T0,O,GS,MS,n,M,OS_list,OS):
    Machine_time = np.zeros(M,dtype=int)          # 机器时间初始化
    for i in range(GS):
        random.shuffle(OS_list)  # 生成工序排序部分
        OS[i] = np.array(OS_list)
        GJ_list=[]
        for GJ_Num in range(n):         #工件集
            GJ_list.append(GJ_Num)
        random.shuffle(GJ_list)
        for g in GJ_list:    # 随机选择工件集的第一个工件,从工件集中剔除这个工件
            h = np.array(O[g])  # 第一个工件含有的工序
            for j in range(len(h)):  # 从工件的第一个工序开始选择机器
                D = np.array(h[j])
                List_Machine_weizhi = []
                for k in range(len(D)):  # 每道工序可使用的机器以及机器的加工时间
                    Useing_Machine = D[k]
                    if Useing_Machine == 9999:  # 确定可加工该工序的机器
                        continue
                    else:
                        List_Machine_weizhi.append(k)
                Machine_Select = []
                for Machine_add in List_Machine_weizhi:  # 将这道工序的可用机器时间和以前积累的机器时间相加
                    Machine_time[Machine_add] = Machine_time[Machine_add] + D[
                        Machine_add]  # 比较可用机器的时间加上以前累计的机器时间的时间值,并选出时间最小
                    Machine_Select.append(Machine_time[Machine_add])
                Min_time=min(Machine_Select)
                Machine_Index_add = Machine_Select.index(Min_time)
                MS[i][g*3+j] =Machine_Index_add + 1

    CHS1=np.hstack((MS,OS))
    return CHS1
#局部选择
def Local_initial(T0,O,LS,MS,n,M,OS_list,OS):
    for i in range(LS):
        random.shuffle(OS_list)  # 生成工序排序部分
        OS_gongxu = OS_list
        OS[i] = np.array(OS_gongxu)
        GJ_list=[]
        for GJ_Num in range(n):         #工件集
            GJ_list.append(GJ_Num)
        A=0
        for gon in GJ_list:
            Machine_time = np.zeros(M)          # 机器时间初始化
            g = gon                      # 随机选择工件集的第一个工件   #从工件集中剔除这个工件
            h = np.array(O[g])  # 第一个工件及其对应工序的加工时间
            for j in range(len(h)):  # 从工件的第一个工序开始选择机器
                D = np.array(h[j])
                List_Machine_weizhi = []
                for k in range(len(D)):  # 每道工序可使用的机器以及机器的加工时间
                    Useing_Machine = D[k]
                    if Useing_Machine == 9999:  # 确定可加工该工序的机器
                        continue
                    else:
                        List_Machine_weizhi.append(k)
                Machine_Select = []
                for Machine_add in List_Machine_weizhi:  # 将这道工序的可用机器时间和以前积累的机器时间相加
                    Machine_time[Machine_add] = Machine_time[Machine_add] + D[Machine_add]  # 比较可用机器的时间加上以前累计的机器时间的时间值,并选出时间最小
                    Machine_Select.append(Machine_time[Machine_add])
                Machine_Index_add = Machine_Select.index(min(Machine_Select))
                MS[i][g*3+j] = MS[i][g*3+j] + Machine_Index_add + 1
                A+=1
    CHS1=np.hstack((MS,OS))
    return CHS1
#随机选择
def Random_initial(T0,O,RS,MS,n,M,OS_list,OS):
    for i in range(RS):
        random.shuffle(OS_list)  # 生成工序排序部分
        OS_gongxu = OS_list
        OS[i] = np.array(OS_gongxu)
        GJ_list=[]
        for GJ_Num in range(n):         #工件集
            GJ_list.append(GJ_Num)
        A=0
        for gon in GJ_list:
            Machine_time = np.zeros(M)          # 机器时间初始化
            g = gon                      # 随机选择工件集的第一个工件   #从工件集中剔除这个工件
            h = np.array(O[g])  # 第一个工件及其对应工序的加工时间
            for j in range(len(h)):  # 从工件的第一个工序开始选择机器
                D = np.array(h[j])
                List_Machine_weizhi = []
                for k in range(len(D)):  # 每道工序可使用的机器以及机器的加工时间
                    Useing_Machine = D[k]
                    if Useing_Machine == 9999:  # 确定可加工该工序的机器
                        continue
                    else:
                        List_Machine_weizhi.append(k)
                Machine_Select = []
                for Machine_add in List_Machine_weizhi:  # 将这道工序的可用机器时间和以前积累的机器时间相加
                    Machine_time[Machine_add] = Machine_time[Machine_add] + D[
                        Machine_add]  # 比较可用机器的时间加上以前累计的机器时间的时间值,并选出时间最小
                    Machine_Select.append(Machine_time[Machine_add])
                Machine_Index_add = Machine_Select.index(random.choice(Machine_Select))

                MS[i][A] = MS[i][A] + Machine_Index_add + 1
                A+=1
    CHS1=np.hstack((MS,OS))
    return CHS1
#染色体解码
#JM与T的关系是一一对应的
def Chromosome_decoding(CHS,O,T0,n):
    JM = np.zeros((4, 3), dtype=int)  # JM(j,h)表示工件Ji的工序Oh的机器号
    T = np.zeros((4, 3), dtype=int)  # T(j,h)表示工件Jj的工序Oh的加工时间

    # 步骤1:对机器选择部分进行解码,从左到右依次读取并转换成机器顺序矩阵JM和时间顺序矩阵T
    MS = CHS[0:12]
    OS = CHS[12:24]
    GX_num = 0
    for J_j in MS:  # 将机器选择部分转换成机器顺序矩阵和时间顺序矩阵
        GX_num += 1
        JM_j = int((GX_num-1) / 3)  #机器顺序矩阵的横坐标
        JM_h = int((GX_num-1) % 3)       #机器顺序矩阵的纵坐标
        O_j =np.array(O[JM_j][JM_h])
        Mac_using = []
        Mac_time = []
        for Mac_num in range(len(O_j)):  # 寻找MS对应部分的机器时间和机器顺序
            if O_j[Mac_num] != 9999:
                Mac_using.append(Mac_num)
                Mac_time.append(O_j[Mac_num])
            else:
                continue
        JM[JM_j][JM_h] += Mac_using[J_j-1]  # 机器顺序矩阵
        T[JM_j][JM_h] += Mac_time[J_j-1]  # 时间顺序矩阵

    # 步骤2:按照步骤1对应的T和JM依次得到每个工件工序对应的加工机器和加工时间
    Start_time=np.zeros((6,12),dtype=int)   #机器开始加工的时间
    End_time=np.zeros((6,12),dtype=int)     #机器结束加工的时间
    Opearation = np.zeros((6, 12), dtype=int)

    Counter_List=[]
    T_count=0
    for OS_j in OS:  # 通过机器顺序矩阵和时间顺序矩阵的到工序的加工机器和加工时间
        T_count+=1
        Counter_List.append(OS_j)
        M_i_h=Counter_List.count(OS_j)      #该工件的第几道工序
        M_i = JM[OS_j-1][M_i_h-1]         #这道工序使用的机器
        P_ij=T[OS_j-1][M_i_h-1]             #这道工序的加工时间
        M_n_list=[]
        for M_n in End_time[M_i]:     #确定工序为机器M_i的第几道加工工序
            if M_n!=0:
                M_n_list.append(M_n)
        # 工件O_jh是机器M_i的第一道加工工序,直接从机器M_i的零时刻进行加工
        if M_i_h==1 and len(M_n_list)==0 :
            Start_time[M_i][T_count-1]=0
            End_time[M_i][T_count-1]+=P_ij
            Opearation[M_i][T_count-1]=OS_j
        # 工序O_jh是机器M_i的第一道工序
        elif len(M_n_list)==0 and M_i_h>1:
            #寻找该工件上一道工序的完工时间:
            SD_Machine=JM[OS_j-1][M_i_h-2]
            SD_count=0
            SD_c=0
            for SD_i in OS:
                SD_count+=1
                if SD_i==OS_j:
                    SD_c+=1
                    if SD_c==M_i_h-1:
                        break

            S=End_time[SD_Machine][SD_count-1]
            Start_time[M_i][T_count - 1] =S
            End_time[M_i][T_count - 1] = S+ P_ij
            Opearation[M_i][T_count - 1] = OS_j

        elif len(M_n_list)!=0 and M_i_h==1:
            List_start_0=[]
            List_end_0=[]
            List_index_0=[]
            for L_i in range(len(End_time[M_i])):
                if End_time[M_i][L_i]!=0:
                    List_start_0.append(Start_time[M_i][L_i])
                    List_end_0.append(End_time[M_i][L_i])
                    List_index_0.append(L_i)
            disp = zip(List_index_0,List_end_0)
            disp_1=zip(List_index_0,List_start_0)
            Disp_1 = dict(disp)
            Disp_2 = dict(disp_1)
            A = sorted(Disp_1.items(), key=lambda item: item[1])
            B = sorted(Disp_2.items(), key=lambda item: item[1])
            D_1= dict(A)
            D_2=dict(B)
            List_start=[]
            List_end=[]
            List_index=[]
            for k in D_1:
                List_end.append(D_1[k])
                List_index.append(k)
            for k_1 in D_2:
                List_start.append(D_2[k_1])
            Lst=[]
            Lst_index=[]
            for L_j in range(len(List_end)-1):
                if List_start[L_j+1]-List_end[L_j]>=P_ij:
                    Lst.append(List_start[L_j+1]-List_end[L_j])
                    Lst_index.append(List_index[L_j])
            if len(Lst)!=0:
                L_m_list = []
                for L_m in Lst:
                    L_m_list.append(L_m)
                    if L_m>=P_ij:
                        L_P=Lst_index[Lst.index(L_m)]
                        Start_time[M_i][T_count - 1]=End_time[M_i][L_P]
                        break
                    while len(L_m_list)==len(Lst):
                        Start_time[M_i][T_count - 1] = max(End_time[M_i])
                        break
            else:
                Start_time[M_i][T_count - 1] = max(End_time[M_i])
            End_time[M_i][T_count-1]=Start_time[M_i][T_count-1]+P_ij
            Opearation[M_i][T_count - 1] = OS_j

        #加工工序不是机器和工件的第一道工序
        else:
            SC_Machine = JM[OS_j - 1][M_i_h - 2]  # 这个工件上一道工序的使用机器
            CO_er = 0
            CON_er = 0
            for Max_i in OS:
                CO_er += 1
                if Max_i == OS_j:
                    CON_er += 1
                    if CON_er == M_i_h - 1:
                        break
            SC_endtime = End_time[SC_Machine][CO_er - 1]  # 这个工件的上一道工序的结束时间
            SD_S=[]
            SD_E=[]
            SD_index=[]
            for SD_i in range(len(End_time[M_i])):
                if End_time[M_i][SD_i]!=0:
                    SD_E.append(End_time[M_i][SD_i])
                    SD_S.append(Start_time[M_i][SD_i])
                    SD_index.append(SD_i)
            disp_2 = zip(SD_index, SD_E)
            disp_3 = zip(SD_index, SD_S)
            Disp_3 = dict(disp_2)
            Disp_4 = dict(disp_3)
            C_1 = sorted(Disp_3.items(), key=lambda item: item[1])
            D_4 = sorted(Disp_4.items(), key=lambda item: item[1])
            D_5 = dict(C_1)
            D_6 = dict(D_4)
            List_start_1 = []
            List_end_1 = []
            List_index_1 = []
            for k_2 in D_5:
                List_end_1.append(D_5[k_2])
                List_index_1.append(k_2)
            for k_3 in D_6:
                List_start_1.append(D_6[k_3])
            Lst_1 = []
            Lst_index_1=[]
            for L_j_1 in range(len(List_end_1) - 1):
                if List_start_1[L_j_1 + 1] - List_end_1[L_j_1]>=P_ij:
                    Lst_1.append(List_start_1[L_j_1 + 1] - List_end_1[L_j_1])
                    Lst_index_1.append(List_index_1[L_j_1])
            if len(Lst_1)!=0:
                L_M_1_list=[]
                for L_M_1 in Lst_1:
                    L_M_1_list.append(L_M_1)
                    if L_M_1 >= P_ij:
                        List_Count_1 = Lst_index_1[Lst_1.index(L_M_1)]
                        L_M= List_index_1[List_index_1.index(List_Count_1)+1]
                        if End_time[M_i][List_Count_1]>=SC_endtime or Start_time[M_i][L_M]-SC_endtime>=P_ij:
                            Start_time[M_i][T_count-1]=End_time[M_i][List_Count_1]
                            break
                    while len(L_M_1_list)==len(Lst_1):
                        if max(End_time[M_i]) >= SC_endtime:
                            Start_time[M_i][T_count - 1] = max(End_time[M_i])
                        else:
                            Start_time[M_i][T_count - 1] = SC_endtime
                        break

            else:
                if max(End_time[M_i])>=SC_endtime:
                    Start_time[M_i][T_count - 1] = max(End_time[M_i])
                else:
                    Start_time[M_i][T_count - 1]=SC_endtime
            End_time[M_i][T_count-1]=Start_time[M_i][T_count-1]+P_ij
            Opearation[M_i][T_count - 1] = OS_j
    return Start_time,End_time,Opearation

#交叉操作
#机器选择部分
def Crossover_Machine(T0,T_r,CHS1,CHS2):



    r=random.randint(0,T0)    #在区间[1,T0]内产生一个整数r
    random.shuffle(T_r)
    R=T_r[0:r]                  #按照随机数r产生r个互不相等的整数
    #将父代的染色体复制到子代中去,保持他们的顺序和位置
    C_1=CHS2
    C_2=CHS1
    for i in R:
        K=CHS1[i]
        K_2=CHS2[i]
        C_1[i]=K
        C_2[i]=K_2
    return C_1,C_2
#工序排序部分
def Crossover_Operation(O_set,CHS1,CHS2):
    r=2
    random.shuffle(O_set)
    O_1=O_set[0:r]      #将工件集划分为Jobset1和Jobset2
    O_2=O_set[r:4]
    C_1=np.zeros(12,dtype=int)
    C_2=np.zeros(12,dtype=int)
    Count_i=0
    Count=0
    C_index1=[]
    C_index2=[]
    for j in CHS1:      #复制父代染色体P1、P2中包含工件集Jobset1/Jobset2中的工件复制到C1/C2中,保持他们的顺序
        Count_i+=1
        for i in O_1:
            if j==i:
                C_1[Count_i-1]=j
    for j_1 in CHS2:
        Count+=1
        for i_1 in O_2:
            if j_1==i_1:
                C_2[Count-1]=j_1
    Count_2=0
    for j_2 in CHS1:
        Count_2+=1
        for i_2 in O_2:
            if j_2==i_2:
                C_index1.append(Count_2-1)
    Count_3=0
    for j_3 in CHS2:
        Count_3+=1
        for i_3 in O_1:
            if j_3==i_3:
                C_index2.append(Count_3-1)
    new_CHS1 = np.delete(CHS1, C_index1)
    new_CHS2 = np.delete(CHS2, C_index2)
    Count_4=0
    for k in range(len(CHS1)):
        if C_1[k]==0:
            C_1[k]=new_CHS2[Count_4]
            Count_4+=1
    Count_5=0
    for k_1 in range(len(CHS2)):
        if C_2[k_1]==0:
            C_2[k_1]=new_CHS1[Count_5]
            Count_5+=1
    return C_1,C_2
#变异操作
#机器变异部分
def Variation_Machine(Tr,O,MS):
    #机器选择部分
    r=random.randint(1,11)        #在变异染色体中选择r个位置
    random.shuffle(Tr)
    T_r=Tr[0:r]
    for i in T_r:
        O_i=int(i/3)
        O_j=i%3
        Machine_using=O[O_i][O_j]
        Machine_index=[]
        for j in Machine_using:
            if j!=9999:
                Machine_index.append(j)
        Min=Machine_index[0]
        Min_index=0
        for j_1 in range(len(Machine_index)):
            if Machine_index[j_1]0:                 #设定结束的约束条件
        Max_Itertions-=1
        S=Select(Fit,POP_SIZE)
        C_I=[]
        for j in S:
            C_I.append(C[j])
        C_J=np.array(C_I)
        P_c=random.uniform(0.6,0.8)     #确定交叉概率
        P_m=random.uniform(0.005,0.006) #确定变异概率
        P_C=int(P_c*(len(S)))
        P_M=int(P_m*(len(S)))
        S_list=np.random.permutation(range(len(S)))
        PC=S_list[0:P_C]
        for k in range(0,len(PC),2):
            CHS_1=C_J[PC[k]]
            if k+1

结果分析:

3

4


  • 16
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 19
    评论
遗传算法是一种模拟自然选择和遗传机制的搜索和优化方法,该方法通常用于解决复杂的优化问题。而Python是一种高级编程语言,具有简洁的语法和强大的库支持。因此,使用Python实现遗传算法可以方便地编写和调试算法,并且可以利用其丰富的库来加速算法的运行和优化。 在Python中,首先需要定义问题的适应度函数,它用于评估每个个体的适应程度。然后,定义一些遗传算法的基本操作,如选择、交叉和变异。选择操作根据个体的适应程度来保留一部分较优的个体。交叉操作随机选择两个个体,并通过交换部分遗传信息来产生新的个体。变异操作通过在个体中引入随机变化来增加多样性。 接下来,需要初始化一组个体作为初始种群,并迭代执行选择、交叉和变异操作直至满足停止准则。停止准则可以是达到一定迭代次数或达到问题的最优解。 为了实现这些操作,Python提供了许多功能强大的库,如NumPy用于处理数组和矩阵计算,Matplotlib用于绘制和可视化结果,以及其他一些优化库如DEAP等,可以方便地实现遗传算法的各个步骤。 总结来说,使用Python实现遗传算法可以方便地编写、调试和优化算法,同时利用丰富的库支持,可以快速地实现复杂的优化问题。这对于对遗传算法和优化问题感兴趣的研究人员和工程师来说,是一个非常有吸引力和有用的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码丽莲梦露

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值