遗传算法解混合流水车间调度问题(注释很多)JavaScript (4)

在这里插入图片描述

交叉的是这道题里的第二个难点,由于序列交叉会导致一个工件在一个顺序中出现两次,而有的工件会没有被排序,导致顺序不存在。我们要设计算法去避免交叉带来的重复问题。

在这里插入图片描述

var FUSION_NUM = 3; // 发生交叉时,交换的序列数 fusion(poor, POOR_SIZE, SUVIVAL_SIZE, FUSION_NUM, WORKPIECE_NUM); /** 进行个体交叉 * @param {*} poor 种群池 * @param {*} poor_size 种群池的大小(自然环境的容量)(流程顺序方案数目) * @param {*} surival_size 自然选择下存活的方案数(最优的n种解决方案) * @param {*} fusion_num 发生交叉时,交换的序列数 * @param {*} workpiece_num 总共要完成的零件数目(也是每个个体的基因数) */ function fusion(poor, poor_size, surival_size, fusion_num, workpiece_num) { var poor_p = surival_size ; // 位置标记,要被修改的组的位置 // 将幸存区里的每两个进行交叉 for(var i=0; i<surival_size; i++){ for(var j=i+1; j<surival_size; j++){ // 随机生成一个位置,将两个个体的一段进行交换 var fusion_pos = random(workpiece_num-fusion_num+1); // 交叉生成两个新的个体 createNew(poor, workpiece_num, fusion_num, fusion_pos, i, j, poor_p); poor_p = poor_p+1; createNew(poor, workpiece_num, fusion_num, fusion_pos, j, i, poor_p); poor_p = poor_p+1; } } } /** 创建一个新的个体, 这个个体由 i 加入部分 j 构成 * @param {二维数组} poor 种群池 * @param {Int} fusion_pos 交叉标志位, 从交叉标记位开始,往后的n个会被替换,n为交换的序列数,是个常量 * @param {Int} workpiece_num 一个体的所拥有的基因数(工件的数目) * @param {Int} i 初始个体i, i是一个int * @param {Int} j 初始个体i, j是一个int * @param {Int} poor_p 目标个体poor_p,新产生的个体数据会被放到这个个体中 */ function createNew(poor,workpiece_num, fusion_num, fusion_pos, i, j, poor_p){ var kk_p = fusion_pos; // 记录这个位置,用于更高效的完成循环 // 构建第一个新的数组(个体) for(var ii=0; ii<workpiece_num; ii++){ if(ii<fusion_pos || ii>= fusion_pos + fusion_num){ // 如果是非交换的位置 var is_repeat = false; // 数据重复标志位 for(var jj= fusion_pos; jj< fusion_num+fusion_pos; jj++){ if(poor[i][ii] == poor[j][jj]){ // 如果要交换的位置检查出了重复 is_repeat = true; for(var kk=kk_p; kk< fusion_num+fusion_pos; kk++){ // 就从要交换过去的位置里去找一个替换部分不一样的,用这个数来消除重复 var is_repeat2 = false; // 数据重复标志位 for(var iii = fusion_pos; iii< fusion_num+fusion_pos; iii++){ if(poor[i][kk] == poor[j][iii]){ // 如果在交替部分发生重复就不用考虑这一位了 is_repeat2 = true; kk_p ++; break; } } if(!is_repeat2){ // 如果不是重复的, poor[poor_p][ii] = poor[i][kk]; // 我们就将这个基因赋值给新的个体 kk_p ++;break; // kk的起始位置 +1 } } } } if(!is_repeat){ // 两个交换的部分没有重复,代表这个数会在原数列的非交换部分出现。 poor[poor_p][ii] = poor[i][ii]; } }else{ // 如果是两序列相互交换的位置就直接交换 poor[poor_p][ii] = poor[j][ii]; } } }
7、变异

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgyssg.html