标签:
2.交叉
交叉是遗传算法中的一个重要操作,它的目的是从两条染色体中各自取出一部分来组合成一条新的染色体这里,在车间调度中一种常见的交叉方法叫Generalized Order Crossover方法(GOX),假设有三个工件A,B,C, 每个工件下面包含三道工序,根据这一信息我们可以利用上一节介绍的编码技术随机生成两条染色体如下:
我们可以用一个list来存储一条染色体,
这个list中的每个元素是一个有序偶,有序偶的第一个元素是工件号,第二个元素是工序号。
Parent1用list可以表示为[(B,1),(A,1),(B,2),(B,3),(C,1),(A,2),(C,2),(C,3),(B,1),(A,3))]
有序偶的图示为
GOX交叉就是从Parent2中随机抽取其中的一部分把它移植到Parent1中生成新的染色体,比如,我们选取 “(A,2)(C,1)(A,3)(B,3)” 这个片段
我们首先随机选取Parent1中的一个位置,把这个“(A,2)(C,1)(A,3)(B,3)”片段插到该位置之后
同时,我们把原Parent1中与从Parent2中移植过来的部分中重复的有序偶删掉,即可以得到新的交叉后的染色体:
上述过程的实现代码如下:
1 def Crossover(p1, p2, I)://p1,p2是两条待交叉的染色体,I存放工序和工件的信息(见编码部分) 2 """Crossover operation for the GA. Generalized Order Crossover (GOX).""" 3 def Index(p1, I)://Index(p1,I)//这个函数接收两个参数p1和I,返回p1对应的有序偶list 4 ct = [0 for j in xrange(I.n)] 5 s = [] 6 for i in p1: 7 s.append((i, ct[i])) 8 ct[i] = ct[i] + 1 9 return s 10 idx_p1 = Index(p1, I) //p1的有序偶list,p1即上文的Parent2 11 idx_p2 = Index(p2, I) //p2的有序偶list,p2即上文的Parent1 12 nt = len(idx_p1) //p1的长度 13 i = randint(1, nt)//1到nt间的随机数 14 j = randint(0, nt-1)//0 到nt间的随机数 15 k = randint(0, nt)//k为插入Parent1时的插入点
//implant 相当于上面的“(A,2)(C,1)(A,3)(B,3)”即从Parent2抽取的片段 16 implant = idx_p1[j:min(j+i,nt)] + idx_p1[:i - min(j+i,nt) + j]17 18 lft_child = idx_p2[:k] 19 rgt_child = idx_p2[k:] 20 for jt in implant://从Parent1删除与插入片段重复的有序偶 21 if jt in lft_child: lft_child.remove(jt) 22 if jt in rgt_child: rgt_child.remove(jt) 23 //Child:即相当于BABACABCCB 24 child = [ job for (job, task) in lft_child + implant + rgt_child ] 25 return child
标签:
原文地址:http://www.cnblogs.com/zhaogeatdlnu/p/5676399.html