最近又看了韩老师的Java基础视频,然后讲到了“扫描对象”,又恰逢算法要求编写多机调度的算法,就想自己来编一编动态的。
多机调度的官方描述如下:
设有n个独立的作业{1, 2, …, n}, 由m台相同的机器进行加工处理,作业i所需时间为ti。
约定:任何作业可以在任何一台机器上加工处理, 但未完工前不允许中断处理,任何作业不能拆分成更小的子作业。 要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
当然,按照贪心算法,应该先处理作业时间长的作业(所以你得先编个排序算法)。
上述题用人话来说就是,你随便给几台机器和一个作业需要处理时间的数组,让机器来处理这一组作业。情况一是需要处理的作业的数量刚好小于或等于机器的数量,这时候就随便处理了,如果一号作业需要处理的时间最长,那么这就是最短时间。情况二是作业数量大于机器的数量,这时候你就要降序来选择处理时间长的作业。举个小栗子吧:
7个独立作业{1, 2, 3, 4, 5, 6, 7}由M1,M2和M3来加工处理各作业所需时间间分别为{2, 14, 4, 16, 6, 5, 3}。调度结果如下:
将以上作业处理时间排序后16分给机器一;14分给机器二;6分给机器三;接下来调用排序方法选出最小的处理时间,也就是三号机器肯定是最先空闲的,把还未处理的作业中最大的再分给三号机器,这时候又要进行排序,再次选择最先空闲的机器,然后再分配。直到作业都处理完为止。
接下来上代码
import java.util.Scanner;
public class Expriment02ofalgorithm {
static int MACHINE_ID;//机器数
static int[] WORK_TIME;//作业需要处理时间数组
static int[] PROCESS_TIME;//机器执行作业时间数组
public int getId() {//动态获取机器的数量
System.out.println("请输入机器台数:");
Scanner myscanner=new Scanner(System.in);
MACHINE_ID=myscanner.nextInt();
return MACHINE_ID;
}
public int[] getWorkTime() {//动态获取作业的工作时间
System.out.println("请输入作业工作时间:");
Scanner my=new Scanner(System.in);
WORK_TIME=new int[1];
WORK_TIME[0]=my.nextInt();
char BANNER;
do {
System.out.println("是否继续添加工作时间,请选择T/F:");
BANNER=my.next().charAt(0);
if(BANNER=='T') {
System.out.println("请继续输入工作时间:");
//接下来创建动态变化的数组
int gettime=my.nextInt();
int[]newtime=new int[WORK_TIME.length+1];
for(int i=0;i<WORK_TIME.length;i++) {
newtime[i]=WORK_TIME[i];
}
newtime[newtime.length-1]=gettime;
WORK_TIME=newtime;
}else {
return WORK_TIME;
}
}while(true);
}
public void BubbleSortingReverse(int[]WORK_TIME) {//冒泡逆排序
for(int i=0;i<WORK_TIME.length-1;i++) {
for(int j=0;j<WORK_TIME.length-1-i;j++) {
if(WORK_TIME[j]<WORK_TIME[j+1]) {
int temp=WORK_TIME[j];
WORK_TIME[j]=WORK_TIME[j+1];
WORK_TIME[j+1]=temp;
}
}
}
}
public void Greedy(int MACHINE_ID,int[] WORK_TIME) {//贪心算法处理
PROCESS_TIME=new int[MACHINE_ID];//动态创建机器执行时间数组
int count=0;//一个计数器
if(MACHINE_ID>=WORK_TIME.length) {
for(int i=0;i<WORK_TIME.length-1;i++) {
PROCESS_TIME[i]=WORK_TIME[i];
}
BubbleSortingReverse(PROCESS_TIME);
System.out.println("此情况为机器数大于等于作业数。");
System.out.println("此时作业号与机器一一对应,最大花费时间为:"+PROCESS_TIME[0]);
}else {
BubbleSortingReverse(WORK_TIME);
System.out.println("第一次分配:");
for(int i=0;i<PROCESS_TIME.length;i++) {
PROCESS_TIME[i]=WORK_TIME[i];
System.out.println("Machine"+i+"机器处理时长为"+PROCESS_TIME[i]+"秒的作业");
}
do {
int i=PROCESS_TIME.length;
while(i<WORK_TIME.length) {
BubbleSortingReverse(PROCESS_TIME);
PROCESS_TIME[PROCESS_TIME.length-1]+=WORK_TIME[i];
count++;
i++;
}
if(count+PROCESS_TIME.length==WORK_TIME.length) {
break;
}
}while(true);
// for(int i=0;i<PROCESS_TIME.length;i++) {
// System.out.println("Machine"+i+"处理时常为"+PROCESS_TIME[i]+"秒的作业");
// }
BubbleSortingReverse(PROCESS_TIME);
System.out.println("最大花费时间为:"+PROCESS_TIME[0]);
}
}
public static void main(String[] args) {
Expriment02ofalgorithm e=new Expriment02ofalgorithm();
e.getId();
e.getWorkTime();
e.BubbleSortingReverse(WORK_TIME);
e.Greedy(MACHINE_ID, WORK_TIME);
// for(int i=0;i<WORK_TIME.length;i++) {
// System.out.printf("%d\t",WORK_TIME[i]);
// }
}
}
现成的虽好,但同学们看代码的时候还是要动一动脑筋哦。