您的位置:首页 > Web前端 > JavaScript

基于JavaScript实现流水作业调度问题

2018-01-10 16:35 232 查看

题记:

今天来给大家讲解一下关于流水作业的调度问题,如何用JavaScript来实现。

正文:

问题描述:

n个作业{0,1,2,…,n}在2台机器上M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工,后在M2上加工。在两台机器上加工的时间分别为ai和bi。

目标:确定这n个作业的加工顺序,使得从第一台作业开始加工,到最后一个作业完成加工所需要的时间最少。

算法描述:

令N1={t|t[t,1]< t[i,2]},N2={t[i,1]>=t[i,2]};

将N1 中作业依t[i,1]的非减序排列;将N2中作业依t[i,2]的非增序排列;

解释:

其实,我们仔细看看,可以把任务简单的划分一下。

首先,我们将这些作业分为2组:

一组是先执行的:在m1上执行的时间<在m2上执行的时间,有利于我们保证m2机器上没有等待

一组是后执行的:在m2上执行时间>在m1上执行的时间,这些不利于m2机器没有等待,所有后执行

然后,我们再对这两组任务进行划分:

先执行的一组任务中的任务,按照在m1上执行时间非减序来排列,也就是哪个时间短先执行哪个

再将后执行的一组任务中的任务,按照在m2上执行时间非增序来排列,也是哪个时间长先执行哪个

这样来看,我们的任务就十分简单了,然后我们用代码来实现。

代码实现:

1.首先我们构造两个机器上执行作业的时间数组,和最基本的函数,分别如下:

var m1 = [2,7,6,4,6,8], // 表示在机器1上所用的时间
m2 = [5,3,2,7,9,2]; // 表示在机器2上所用的时间
function assemblyLine(a,b) {
var arr1 = [], // 表示先执行的一部分
arr2 = [], // 表示后执行的一部分
finalArr = []; // 表示最后的次序
}


2.然后呢,我们就要思考一下,如何把这组任务分成先执行后执行

/*首先先选出来先执行的一部分和后执行的一部分,
满足的条件如下:
1.arr1存放在m1上的时间 < 在m2上的时间的作业,保证m2机器上没有等待,为先执行
2.arr2存放 m1上的时间 > 在m2上的时间的作业,为后执行
*/
for (var i = 0; i < a.length; i++) { // a,b为之前的形参
if (a[i]<b[i]) { // 先执行的
arr1.push({index:i+1,m1:a[i],m2:b[i]}); // i表示作业的序号
}
else{ // 后执行的
arr2.push({index:i+1,m1:a[i],m2:b[i]}); // i表示作业的序号
}
}


3.我们两组任务选出来了,分别是arr1先执行,arr2后执行,我们就要对这两个数组进行排序了

/*现在来排序,先执行的部分和后执行的部分,
排序规则如下:
1.在arr1里选择m1上执行时间较短的,来保证m2等待时间最短,所以是按m1增序排列
2.在arr2里,要保证最后一个作业在m2上执行的时间最短,所以是按m2时间非增序排
*/
/*我们先来定义2个函数,一个是按照数组属性增序排序,一个是按照数组属性减序排序*/
function upCompare(property){ // 增序
return function(a,b){
var value1 = a[property];
var value2 = b[property];
return value1 - value2;
}
}
function downCompare(property){ // 减序
return function(a,b){
var value1 = a[property];
var value2 = b[property];
return value2 - value1;
}
}
finalArr = arr1.sort(upCompare('m1')).concat(arr2.sort(downCompare('m2'))); // 把这两组任务排好序后拼接起来
return finalArr; // 最后,返回这个数组


完整代码如下:

var m1 = [2,7,6,4,6,8], // 表示在机器1上所用的时间
m2 = [5,3,2,7,9,2]; // 表示在机器2上所用的时间
function assemblyLine(a,b) {
var arr1 = [], // 表示先执行的一部分
arr2 = [], // 表示后执行的一部分
finalArr = [], // 表示最后的次序
time = 0; // 总共所花费的时间

/*首先先选出来先执行的一部分和后执行的一部分,
满足的条件如下:
1.arr1存放在m1上的时间 < 在m2上的时间的作业,保证m2机器上没有等待,为先执行
2.arr2存放 m1上的时间 > 在m2上的时间的作业,为后执行
*/
for (var i = 0; i < a.length; i++) {
if (a[i]<b[i]) { // 先执行的
arr1.push({index:i+1,m1:a[i],m2:b[i]}); // i表示作业的序号
}
else{ // 后执行的
arr2.push({index:i+1,m1:a[i],m2:b[i]}); // i表示作业的序号
}
}
/*现在来排序,先执行的部分和后执行的部分,
排序规则如下:
1.在arr1里选择m1上执行时间较短的,来保证m2等待时间最短,所以是按m1增序排列
2.在arr2里,要保证最后一个作业在m2上执行的时间最短,所以是按m2时间非增序排
*/
/*我们先来定义2个函数,一个是按照数组属性增序排序,一个是按照数组属性减序排序*/
function upCompare(property){ // 增序
return function(a,b){
var value1 = a[property];

b4c9
var value2 = b[property];
return value1 - value2;
}
}
function downCompare(property){ // 减序
return function(a,b){
var value1 = a[property];
var value2 = b[property];
return value2 - value1;
}
}
finalArr = arr1.sort(upCompare('m1')).concat(arr2.sort(downCompare('m2')));
return finalArr;
}
console.log(assemblyLine(m1,m2));


顺序如下图红框内:



有兴趣的同学还可以想想,怎么来计算总共花费的时间。

之后再补充计算总时间的代码~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 算法