经典算法问题:流水作业调度(java实现)

1.问题模型:

n个作业{0,1,2,…,n}在2台机器M1和M2组成的流水线上完成加工。每个作业加工的顺序都是先在M1上加工,后在M2上加工。在两台机器上加工的时间分别为ai和bi,确定这n个作业的加工顺序,使得从第一台作业开始加工,到最后一个作业完成加工所需要的时间最少。

2.流水作业调度问题的Johnson算法:

(1)令N1={i|ai<bi},N2={i|ai>=bi};
(2)将N1中作业依ai的非减序排序;N2中作业依bi的非增序排序;
(3)N1中作业接N2中作业构成满足Johnson法则的最优调度。

3.思路

(1) a[i]和b[i]分别存储第i个作业在M1、M2上的加工时间,c[i]存储作业的最优加工顺序;
(2) 将a[i],b[i]中较小的那个放到数组d的key值并通过Arrays.sort()方法按key值进行排序;
(3)d[i].job为true的属于N1保存在c[i]前面,d[i].job为false的属于N2保存在c[i]后面,以此得出最优加工顺序和最短加工时间。

4.代码

package flowshop;
public class Johnson {
	private static class Element implements Comparable<Object>{
		int key;
		int index;
		boolean job;
		public Element(int kk,int ii,boolean jj){
			key = kk;
			index = ii;
			job = jj;
		}
		public int compareTo(Object x) {
			int xkey =((Element)x).key;
			if(key<xkey) return -1;
			if(key==xkey) return 0;
			return 1;
		}
	}
	public static int flowShop(int[] a,int[] b,int[] c){
		int n = a.length;
		Element[] d = new Element[n];
		for(int i=0;i<n;i++){
			int key=a[i]>b[i]? b[i]:a[i];//按Johnson法则分别取对应的b[i]或a[i]值作为关键字
			boolean job = a[i]<=b[i];//给符合条件a[i]<b[i]的放入到N1子集标记为true
			d[i] = new Element(key,i,job);
		}
		java.util.Arrays.sort(d);//对数组d按关键字升序进行排序
		int j=0,k=n-1;
		for(int i=0;i<n;i++){
			if(d[i].job)
				c[j++]=d[i].index;//将排过序的数组d,属于N1的从前面进插入 
			else
				c[k--]=d[i].index;//属于N2的从后面进入
		}
		j=a[c[0]];
		k=j+b[c[0]]; 
		for(int i=1;i<n;i++){
			j+=a[c[i]]; 
			k=j<k?k+b[c[i]]:j+b[c[i]];//计算最优加工时间  
		}
		System.out.println("作业的最优加工顺序为(编号从0开始):");
		for(int i=0;i<c.length;i++){
			System.out.print(c[i]+"  ");
		}
		System.out.println();
		return k;
	}
	public static void main(String[] args) {
		int[] a=new int[6];
	    int[] b=new int[6];
	    int[] c=new int[6];
	    for(int i=0;i<a.length;i++){
	        a[i]=(int) (Math.random()*10+1);
	        b[i]=(int) (Math.random()*10+1);
	        System.out.println("第"+i+"个作业在M1,M2上的加工时间为:"+a[i]+" "+b[i]);
	    }
		int k = flowShop(a, b, c);
		System.out.println("完成作业的最短时间为:"+k);
	}
}

5.结果

示例

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值