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

这一部分是整个问题的第一大难点!适应度嘛,简单点来说就是时间越少适应越好。那么具体如果去完成2*3,一共6条个车间的处理呢?我们可以对其进行抽象,流水线的本质就是工件在车间上被加工处理,我们只需要知道每个车间上正在处理的工件处理工件的剩余时间就可以进行推演了,于是,我们定义了“工作状态矩阵”和“剩余时间矩阵”分别表式上面的两个量。
流程开始,每隔一秒(假设的最小时间单位),我们检擦一遍“工作状态矩阵”work_state上的工件流程的剩余时间temp_maxtr[ ][ ],如果剩余时间没了,那么他就可以进行下一个流程。等到所有工件的每一个流程剩余时间都小于等于0时,即可结束。
内存调试真实效果

调试真实效果


甘特图模拟效果

在这里插入图片描述

那么进行下一个流程如果表示呢?只要更改work_state改变以下车间里的原件就好。

var work_state = new Array(PROCESS_NUM * WORKSHOP_NUM); // 存储流水线状态,用于保存每条流水线上正在加工的工件id var temp_maxtr = new Array(PROCESS_NUM); // 用于存储每个工件在加工过程中的剩余时间 for(var i=0; i<PROCESS_NUM; i++) { temp_maxtr[i] = new Array(WORKPIECE_NUM); } var scores = new Array(POOR_SIZE); // 存储分数(每个顺序下的时间) for(var j=i==0?0:SUVIVAL_SIZE-1; j<POOR_SIZE; j++){ // 前SUVIVAL_SIZE组为SUVIVAL区,上一次已经记录过分数 // 将work_state, 和 temp_maxtr 做归零处理 resetTimeAndState(work_state, PROCESS_NUM, WORKSHOP_NUM, T_MAXTR, temp_maxtr); // 把得分存到scores里 scores[j] = calcTime(work_state, temp_maxtr, PROCESS_NUM, WORKSHOP_NUM, WORKPIECE_NUM, poor[j]); } /** 重置流水线状态和时间记录矩阵 * @param work_state 要复位的工作状态矩阵 * @param c 流程数目 * @param m 每一个流程下可以同时运行的生产线数目 * @param t_maxtr 每一个工件在每个工序上所要消耗的时间 * @param temp_maxtr t_maxtr => temp_maxtr * @returns temp_maxtr每个工件各个流程的剩余时间记录矩阵 */ function resetTimeAndState(work_state, c, m, t_maxtr, temp_maxtr) { var n = t_maxtr[0].length; // 将每一个机床都复位 for (var i = 0; i < c * m; i++) { work_state[i] = n; // 用n来表示空闲状态 } for(var i=0; i<c ;i++){ for(var j=0; j<t_maxtr[0].length; j++){ temp_maxtr[i][j] = t_maxtr[i][j]; } } } /** 计算一个状态量所耗费的时间 * @param {Int16List} work_state 工作状态矩阵 * @param {二维矩阵} temp_maxtr 每个工件各个流程的剩余时间记录矩阵 * @param {Int} c 流程数目 * @param {Int} m 每一个流程下可以同时运行的生产线数目 * @param {Int} n 工件的总数目 * @param {Int16List} arr 工件的加工顺序矩阵 * @returns {Int16List} 返回所用的时间 */ function calcTime(work_state, temp_maxtr, c, m, n, arr, record) { var tim = 0; // 使用的总时间 var parts_id = 0; while (true) { // 检测是否可以补货 if (parts_id != n) { for (var i = 0; i < m; i++) { if (work_state[i] == n) { work_state[i] = arr[parts_id++]; } } } // 仅当进入测试模式下if条件成立,记录每次一运行时各条流水线上的状态 if(record != null){ var a = new Array(6); for(var i =0; i<6; i++){ a[i] = work_state[i]; } record.push(a.map(item => item)); } // 每个车间开始工作 for (var i = c * m - 1; i >= 0; i--) { // 每次循环让所有车间进行一单位的时间 temp_maxtr[Math.floor(i / m)][work_state[i]] = temp_maxtr[Math.floor(i / m)][work_state[i]] - 1; if (work_state[i] != n) { // 如果这个车间有物品的话 if (temp_maxtr[Math.floor(i / m)][work_state[i]] <= 0) { // 如果这个车间上的东西已经加工完了 if (i >= c * m - m) { // 如果时最后一个车间了 work_state[i] = n; // 就可以把状态设置为空闲了 } else for (var j = 0; j < m; j++) { // 否则就去判断 下一个流程上的车间是否有空闲 if (work_state[(Math.floor(i / m) + 1) * m + j] == n) { // 如果找到空闲了 work_state[(Math.floor(i / m) + 1) * m + j] = work_state[i]; // 就把当前进程放到下一个流水线上 work_state[i] = n; // 并且把状态置成空闲 } } } } } // 增加一次时间 tim++; // 检测是否结束 var is_end = true; for(var i=0; i<n; i++){ if(temp_maxtr[c - 1][i]){ is_end = false; break; } } if(is_end){ return tim; } } }
5、选择

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

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