java实现 SPF短进程优先调度算法

前几天用java做了实现一下SPF短进程优先调度算法,在这里分享一下我的代码

算法描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pYlfogAv-1604578476121)(file:///C:\Users\DELL\AppData\Local\Temp\ksohtml10796\wps1.jpg)]

这是我的进程类

public class JCB implements Comparable<JCB>{
	public int name;          //进程名
	public double atime;         //进程提交时间
	public double time;       //进程执行时间
	public double rtime;          //进程开始时间
	public double otime;         //进程完成时间
	public double total;           //周转时间
	public double ptotal;        //带权周转时间(周转系数)

}

这是运行主类

我的实现思想就是,先判断有无进程到达,有的会就找执行时间最短的,没有的话就时间往后退,就是找到提交时间最短的未执行的进程,然后让时间等于它的提交时间,执行这个进程。我这边采用的是执行完进程就删除这个进程,当然也可以用一个属性表示是否完成,不过这样就要多加一些判断了。

public class Main02{
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);		
		System.out.println("请输入进程数");
		int cnt=sc.nextInt();
		List<JCB> jcbs=new ArrayList<JCB>();
		System.out.println("请一次输入"+cnt+"个提交时间和执行时间");//赋值
		for(int i=0;i<cnt;i++) {
			JCB jcb=new JCB();
			jcb.name=i+1;
			jcb.atime=sc.nextDouble();
			jcb.time=sc.nextDouble();
			jcbs.add(jcb);
		}		
		double now=0.0;double sum1=0.0;double sum2=0.0;
	    int flag=-1;int tag=0;
		System.out.println("进程名\t提交时间\t执行\t开始\t完成\t周转\t带权周转");				
		while(jcbs.size()>0) {
			for (int c = 0; c < jcbs.size(); c++) {//判断是否有到了的
				if (jcbs.get(c).atime <= now ) {
						// 如果满足条件
						flag = c; // 暂时记录当前作业的下标
				}
			}
			if(flag==-1) {
				tag=findMInFlag(jcbs);
				flag=-2;
				now = jcbs.get(tag).atime;
			}
			JCB temp =new JCB();
			int index;
			if(flag==-2) {
				index=tag;
			}else {
				index=findMin(jcbs,now);
			}
			flag=-1;
			jcbs.get(index).rtime=now;
			temp=jcbs.get(index);
			temp.otime=temp.rtime+temp.time;
			now =temp.otime;
	    	temp.total=temp.otime-temp.atime;
	        temp.ptotal=temp.total/temp.time;	
            //我这里用大数类BigDecimal去两位小数是为了在保持double的精度,顺便缩短数的长度
	        temp.atime=new BigDecimal(temp.atime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        temp.rtime=new BigDecimal(temp.rtime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();	        
	        temp.total = new BigDecimal(temp.total).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        temp.ptotal = new BigDecimal(temp.ptotal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        temp.otime = new BigDecimal(temp.otime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        sum1+=temp.total;
	        sum2+=temp.ptotal;
	        System.out.println(temp.name+"\t"+temp.atime+"\t"+temp.time+"\t"+temp.rtime+"\t"+temp.otime+"\t"+temp.total+"\t"+temp.ptotal);
            
	        jcbs.remove(index);//执行完后删除
            
	    }
	    sum1 = new BigDecimal(sum1).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	    sum2 = new BigDecimal(sum2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	   // System.out.println("平均周转时间"+sum1/cnt+"\t带权周转时间"+sum2/cnt);
	    sum1 = new BigDecimal(sum1/cnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	    sum2 = new BigDecimal(sum2/cnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	    System.out.println("取两位小数");
	    System.out.println("平均周转时间"+sum1+"\t平均带权周转时间"+sum2);		
	}
	public static int findMin(List<JCB> jcbs,double now) {//找到到达的进程中执行时间最短的进程编号
		int minIndex=0;
		for(int i=0;i<jcbs.size();i++) {
			if(jcbs.get(i).time<jcbs.get(minIndex).time && jcbs.get(i).atime<=now) {
				minIndex=i;
			}
		}
		return minIndex;
	}	
    //这是一个找最早提交时间的函数
	public static int findMInFlag(List<JCB> jcbs) {//找到提交时间最早的进程编号
		int minIndex=0;
		for(int i=0;i<jcbs.size();i++) {
			if(jcbs.get(i).atime<jcbs.get(minIndex).atime ) {
				minIndex=i;
			}
		}
		return minIndex;
	} 
}

还有另外的这个算法是用的先按提交时间排序,这样就不用再去找提交时间最早的进程了。

代码附上

public class Main{
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);		
		System.out.println("请输入进程数");
		int cnt=sc.nextInt();
		List<JCB> jcbs=new ArrayList<JCB>();
		System.out.println("请一次输入"+cnt+"个提交时间和执行时间");//赋值
		for(int i=0;i<cnt;i++) {
			JCB jcb=new JCB();
			jcb.name=i+1;
			jcb.atime=sc.nextDouble();
			jcb.time=sc.nextDouble();
			jcbs.add(jcb);
		}		
		Collections.sort(jcbs);		
		for (JCB jcb : jcbs) {
			System.out.println(jcb.atime+"   "+jcb.time);
		}
		double now=0.0;
		double sum1=0.0;
	    double sum2=0.0;
		System.out.println("作业名\t提交时间\t执行\t开始\t完成\t周转\t带权周转");		
		int flag=0;		
		while(jcbs.size()>0) {
			JCB temp =new JCB();
			if(jcbs.get(0).atime>now) {
				jcbs.get(0).rtime=jcbs.get(0).atime;
				temp=jcbs.get(0);
				temp.otime=temp.rtime+temp.time;
				now=temp.otime;
			}else {
				int index=findMin(jcbs,now);
				jcbs.get(index).rtime=now;				
				temp=jcbs.get(index);
				temp.otime=temp.rtime+temp.time;
				now =temp.otime;
				flag=index;
			}			
			temp.otime=temp.rtime+temp.time;	        
	    	temp.total=temp.otime-temp.atime;
	        temp.ptotal=(float)temp.total/(float)temp.time;	        
	        temp.atime=new BigDecimal(temp.atime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        temp.rtime=new BigDecimal(temp.rtime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();	        
	        temp.total = new BigDecimal(temp.total).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        temp.ptotal = new BigDecimal(temp.ptotal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        temp.otime = new BigDecimal(temp.otime).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	        sum1+=temp.total;
	        sum2+=temp.ptotal;	   	        
	        System.out.println(temp.name+"\t"+temp.atime+"\t"+temp.time+"\t"+temp.rtime+"\t"+temp.otime+"\t"+temp.total+"\t"+temp.ptotal);
	        jcbs.remove(flag);
	    }
	    sum1 = new BigDecimal(sum1).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	    sum2 = new BigDecimal(sum2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	    System.out.println("平均周转时间"+sum1/cnt+"\t带权周转时间"+sum2/cnt);
	    sum1 = new BigDecimal(sum1/cnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	    sum2 = new BigDecimal(sum2/cnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
	    System.out.println("取两位小数");
	    System.out.println("平均周转时间"+sum1+"\t带权周转时间"+sum2);		
	}
	public static int findMin(List<JCB> jcbs,double now) {
		int minIndex=0;
		for(int i=0;i<jcbs.size();i++) {
			if(jcbs.get(i).time<jcbs.get(minIndex).time && jcbs.get(i).atime<=now) {
				minIndex=i;
			}
		}
		return minIndex;
	}
}
```int minIndex=0;
		for(int i=0;i<jcbs.size();i++) {
			if(jcbs.get(i).time<jcbs.get(minIndex).time && jcbs.get(i).atime<=now) {
				minIndex=i;
			}
		}
		return minIndex;
	}
} 
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值