遗传算法改进代码

本文探讨了遗传算法中的关键算子——交叉和变异,包括POX交叉和均匀交叉两种策略,以及机器号变异和工序变异两种变异方法。通过这些改进,算法能更好地避免局部最优解,提升全局搜索能力。同时,还介绍了局部邻域搜索策略,以优化解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

遗传算法改进

交叉

交叉算子是遗传算法中最为重要的部分。

POX交叉

第一步,现任意在DNA上取到需要交叉工序基因的片段,然后父代P1,取到的片段复制给C1,同理P2也是一样的操作
第二步:在P1中取出包含J2中的工件,将剩余的工件安原来的顺序复制给C2;在P2中去掉包含J1中的工件,将剩余工件安原顺序复制给C1
如下图所示:
在这里插入图片描述

    def POX_improve(self, Father_1, Father_2):
        """先选折一部分种群进行pox交叉操作,看看结果
        Father_1,Father_2父代的DNA序列
        """
        Father_1 = Father_1[0:self.WNumber].copy()
        Father_2 = Father_2[0:self.WNumber].copy()
        children_1= np.zeros(self.WNumber, dtype=int)
        children_2 = np.zeros(self.WNumber, dtype=int)
        #建立工件集合
        Job_set = [i_+1 for i_ in range(10)]#有10个工件
        J_set_1 = np.random.choice(Job_set, 2, replace=False)
        J_set_2 = np.random.choice(Job_set, 2, replace=False)
        index_J2_of_F1_set=[]
        index_J1_of_F2_set=[]
        for i in range(len(J_set_1)):
            index_J1_of_F1 = np.where(Father_1 == J_set_1[i])[0]
            index_J1_of_F2 = np.where(Father_2 == J_set_1[i])[0]
            index_J2_of_F1 = np.where(Father_1 == J_set_2[i])[0]
            index_J2_of_F2 = np.where(Father_2 == J_set_2[i])[0]
            index_J2_of_F1_set.append(index_J2_of_F1)
            index_J1_of_F2_set.append(index_J1_of_F2)
            for i_1 in range(np.size(index_J1_of_F1)):
                a_1 = index_J1_of_F1[i_1]
                a_2 = index_J2_of_F2[i_1]
                children_1[a_1] = Father_1[a_1]
                children_2[a_2] = Father_2[a_2]
                #第二部将F1的转接到C2
        #将二维数组转化为一维数组
        index_delet_1 = list(chain.from_iterable(index_J2_of_F1_set))
        index_delet_2 = list(chain.from_iterable(index_J1_of_F2_set))
        Father_1_deleted = np.delete(Father_1, index_delet_1)
        Father_2_deleted = np.delete(Father_2, index_delet_2)
        index_0_insert_1 = np.where(children_2 == 0)[0]
        index_0_insert_2 = np.where(children_1 == 0)[0]
        for j in range(np.size(Father_1_deleted)):
            a_3 = index_0_insert_1[j]
            a_4 = index_0_insert_2[j]
            children_2[a_3] = Father_1_deleted[j]
            children_1[a_4] = Father_2_deleted[j]
        children_1 = CODE.en_code_3(children_1)
        children_2 = CODE.en_code_3(children_2)
        return children_1, children_2

均匀交叉

Step 1:随机生成长度为L的二进制编码串R
Step 2:将父代染色体中Pi中所有对应R中值为1的基因复制给子代C1,在P2中去掉复制给C1的基因后将剩余基因按顺序复制给C1
Step 3:将父代染色体中几中所有对应R中为1的基因赋值给子代C2,在P1中将复制给Cz的基因去掉后将剩余基因按顺序复制给C2
如图所示:
在这里插入图片描述

    def Cross_evenly(self, DNA_1, DNA_2):
        """第二组采用均匀交叉的方式,通过加入二进制码进行交叉"""
        F_1 = DNA_1[0:self.WNumber].copy()
        F_2 = DNA_2[0:self.WNumber].copy()
        #第一步随机生成二进制编码
        R = np.random.randint(2, size=self.WNumber)#产生二进制码
        c_1 = F_1*R
        c_2 = F_2*R
        for i in range(self.WNumber):#这里要将c_2在p_1中的值赋值为0
            a_1 = c_2[i]
            b_1 = c_1[i]
            if a_1 > 0:
                index_of_f_1_of_c_2 = np.where(F_1 == a_1)[0]
                F_1[index_of_f_1_of_c_2[0]] = 0
            if b_1 > 0:
                index_of_f_2_of_c_1 = np.where(F_2 == b_1)[0]
                F_2[index_of_f_2_of_c_1[0]] = 0
        index_of_f_1 = np.where(F_1 > 0)[0]
        index_of_c_2 = np.where(c_2 == 0)[0]
        index_of_f_2 = np.where(F_2 > 0)[0]
        index_of_c_1 = np.where(c_1 == 0)[0]
        for j in range(np.size(index_of_f_1)):
            a_2 = index_of_f_1[j]
            a_3 = index_of_c_2[j]
            b_2 = index_of_f_2[j]
            b_3 = index_of_c_1[j]
            c_2[a_3] = F_1[a_2]
            c_1[b_3] = F_2[b_2]
        c_1 = CODE.en_code_3(c_1)
        c_2 = CODE.en_code_3(c_2)
        return c_1, c_2

变异

变异是为了保证让遗传算法在进行搜素时,避免陷入局部最优解的情况。

机器号变异

按照变异概率Pm选定一个父代染色体进行变异操作,选择其中一个加工工序口,由于每道工序可以在多台机器上加工完成,所以每一工序都有其可选的加工机器集,在可以的加工机器集中随机选择一个机器完成变异操作。

    def mut_mechine(self,DNA):
        """通过对DNA的工序重新解码,得到机器,这样就产生了机器变异"""
        DNA = DNA[:self.WNumber]
        mut_mechine_DNA = CODE.en_code_3(DNA)
        return mut_mechine_DNA

工序变异

在工序基因段中随机选一个基因,然后再随机插入到这个DNA的工序基因片段中。
如图所示:
在这里插入图片描述

    def mut_job(self, DNA):
        """这个变异是基于工件层面的变异,相当于单点自交叉"""
        DNA = DNA[:self.WNumber]
        DNA_1 = DNA[:self.WNumber].copy()
        mut_two_of_position = np.random.choice([i_ for i_ in range(self.WNumber)], 2, replace=False)
        a = mut_two_of_position[0]
        b = mut_two_of_position[1]
        DNA[b] = DNA_1[a]
        DNA[a] = DNA_1[b]
        mut_job_DNA = CODE.en_code_3(DNA)
        return mut_job_DNA

局部邻域搜素

本遗传算法采用的邻域搜索,是通过选择加工时间最小的机器号,来进行邻域搜索

    def Local_search_1(self, DNA):
        """第一中局部搜索,改变机器的选择"""
        job_position_mechine = np.random.choice([i_ for i_ in range(self.WNumber)], 3, replace=False)
        P = CODE.en_code_4(DNA)
        for i in range(np.size(job_position_mechine)):
            a = job_position_mechine[i]
            b_m = a + self.WNumber
            if P[a] == 206 and 306 and 406 and 706 and 806:
                continue
            M_num = []
            T_M = []
            for i_1 in range(self.MNumber):
                Time = Jm_T.loc[P[a]][i_1]
                if np.isnan(Time):
                    pass
                else:
                    M_num.append(i_1 + 1)
                    T_M.append(Time)
            if np.size(T_M) == 0:
                continue
            M_num_np = np.array(M_num)#这个位置是有问题的哈
            T_M_np = np.array(T_M)
            index_older = np.where(DNA[b_m] == M_num_np)[0]
            min_t_index = np.argmin(T_M_np)
            if T_M_np[index_older] > T_M_np[min_t_index]:
                DNA[b_m] = M_num_np[min_t_index].copy()
        return DNA

遗传算法的整体结构,流程图

请添加图片描述

实验结果

请添加图片描述
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

self.键盘上的钢琴师.LX

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

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

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

打赏作者

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

抵扣说明:

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

余额充值