多机调度问题(Java实现)

多机调度问题(贪心算法)
问题:
设有n个独立的作业{1, 2, …, n},由m台相同的机器{M1, M2, …, Mm}进行加工处理,作业i所需的处理时间为ti(1≤i≤n),每个作业均可在任何一台机器上加工处理,但不可间断、拆分。多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
思想:
贪心法求解多机调度问题的贪心策略是最长处理时间作业优先,即把处理时间最长的作业分配给最先空闲的机器,这样可以保证处理时间长的作业优先处理,从而在整体上获得尽可能短的处理时间。按照最长处理时间作业优先的贪心策略,当m≥n时,只要将机器i的[0, ti)时间区间分配给作业i即可;当m<n时,首先将n个作业依其所需的处理时间从大到小排序,然后依此顺序将作业分配给空闲的处理机。
代码:

package 贪心法解决多机调度问题;

import java.util.Arrays;
import java.util.Scanner;

public class HomeworkTest {

	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner scanner=new Scanner(System.in);
		
		int M;//机器的数量
		int N;//作业的数量
			
		System.out.print("机器的数量:");
		M=scanner.nextInt();		
		//machine(机器)
		int machines[]=new int[M];//机器的编号
		for(int i=0;i<machines.length;i++) {//为机器编号
			machines[i]=i+1;
		}
		System.out.print("机器的编号为:");
		System.out.println(Arrays.toString(machines));
			
		System.out.print("作业的数量:");
		N=scanner.nextInt();		
		int id[]=new int[N];//作业的编号
		for(int i=0;i<id.length;i++) {//为作业编号
			id[i]=i+1;
		}
		System.out.print("作业的编号为:");
		System.out.println(Arrays.toString(id));

		int time[]=new int[N];//N作业的处理时间
		System.out.print("请输入作业的时间:");
		for(int i=0;i<time.length;i++) {
			time[i]=scanner.nextInt();
		}
		System.out.println("作业的时间为:");
		for(int i=0;i<time.length;i++) {
			System.out.print("作业 "+id[i]+" 的时间为 :"+time[i]+"   ");
			if((i+1)%3==0)
				System.out.println();			
		}
		
		System.out.println("****************");
		GreedyHomework.greedyhomework(time, id, machines, M, N);
	}
}

上面为测试方法,以3个机器,6个作业,作业的时间量为34,22,67,51,10,90.
具体算法如下:

package 贪心法解决多机调度问题;

import java.util.Arrays;

public class GreedyHomework {
	/**
	 * 
	 * @param time 处理作业的时间数组
	 * @param id 作业的编号数组
	 * @param machines 机器的编号数组
	 * @param M 机器的数量
	 * @param N 作业的数量
	 */
	public static void greedyhomework(int time[],int id[],int machines[],int M,int N) {
		//用冒泡排序将作业的时间和编号按时间的降序重新排序
		for(int i=0;i<time.length-1;i++) {
			for(int j=i+1;j<time.length;j++) {
				int temp=0;
				if(time[i]<time[j]) {
					temp=time[i];
					time[i]=time[j];
					time[j]=temp;
					
					temp=id[i];
					id[i]=id[j];
					id[j]=temp;
				}
			}
		}
		//输出重新排序后的作业的时间数组和编号数组
		System.out.println(Arrays.toString(time));
		System.out.println(Arrays.toString(id));
		
		System.out.println("****************");		
		int alltime[]=new int[M];//每台机器工作的时间总和
		int plan[]=new int[N];//机器的分配的作业数和时间

		//首先将M个作业分配个M个机器,若作业数小于等于机器数,此步完成则结束
		for(int i=0;i<M;i++) {
			alltime[i]=time[i];
			plan[i]=alltime[i];
			System.out.println("机器"+(i+1)+"从0到"+alltime[i]+"的时间分给作业"+(i+1));
		}
		//作业数大于机器数执行此步骤	
		for(int i=M;i<N;i++) {
			int j=min(alltime);	//将最先空闲的机器的下标赋给j		
			plan[j]=alltime[j]+time[i];//将机器[j+1]的时间更新,获得机器赋予那个作业的时间段
			System.out.println("机器"+(j+1)+"从"+alltime[j]+"到"+plan[j]+"的时间分给作业"+(i+1));
			alltime[j]+=time[i];//将机器alltime[j]更新
		}
		for(int i=0;i<M;i++) {
			System.out.println("机器"+(i+1)+"的工作总时间为:"+alltime[i]);
		}
		
		System.out.println("****************");	
		int max=Max(alltime);
		System.out.println("最短的工作时间为:"+max);
	}	
	//返回时间最小的下标
	public static int min(int arr[]) {
		int min=(arr[0]<arr[1])?0:1;
		min=(arr[min]<arr[2])?min:2;
		return min;
	}
	//返回时间最大的值
	public static int Max(int arr[]) {
		Arrays.sort(arr);
		return arr[arr.length-1];
	}
}

测试结果为:
在这里插入图片描述
总结:
此算法存在不足,以上例子的机器数只能是三个,如果机器数有改变,则需要修改

//返回时间最小的下标
	public static int min(int arr[]) {
		int min=(arr[0]<arr[1])?0:1;
		min=(arr[min]<arr[2])?min:2;
		return min;
	}

,如果机器数过大,此方法就会代码量冗余,可通过递归修改。
欢迎大家指出不足,一起进步,谢谢大家。

  • 8
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值