1. 程式人生 > >Java簡單實現程序排程演算法 FCFS和SJF

Java簡單實現程序排程演算法 FCFS和SJF

import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class experiment1 {
	public static void main(String[] args) {
		Scanner in= new Scanner(System.in); 
		
		System.out.println("請輸入程序個數:");
		int n=in.nextInt();
		
		Process[] p=new Process[n];
		
		System.out.println("請輸入每個程序的到達時間和服務時間和程序ID:");
		
		//初始化程序資料
		for(int i=0;i<n;i++){
			int arrTime=in.nextInt();
			int serTime=in.nextInt();
			String pid=in.nextLine();
			p[i]=new Process(arrTime, serTime,pid);
		}
		
		while(true){
			System.out.println("請選擇程序排程演算法,1:FCFS 2:SJF 其他鍵:quit");
			int select=in.nextInt();
			if(select==1){
				System.out.println("----------------您選擇了FCFS-------------------");
				FCFS(p);
				Out(p);
				
			}
			else if(select==2){
				System.out.println("----------------您選擇了SJF-------------------");
				Process[] processes=SJF(p);
				Out(processes);
			}
			else{
				break;
			}
		}
		
	}
	
	//輸出
	public static void Out(Process[] p){
		DecimalFormat df = new DecimalFormat("#.00");   
		float sumWT=0;
		float sumWWT=0;
		float AverageWT;
		float AverageWWT;
		for(int i=0;i<p.length;i++){
			System.out.println("時刻"+p[i].startTime+": 程序"+p[i].pid+"開始執行,完成時間為:"+p[i].finishTime+",週轉時間為:"+p[i].WholeTime+",帶權週轉時間為:"+df.format(p[i].weightWholeTime));
			sumWT+=p[i].WholeTime;
			sumWWT+=p[i].weightWholeTime;
		}
		AverageWT=sumWT/p.length;
		AverageWWT=sumWWT/p.length;
		
		System.out.println("平均週轉時間為:"+df.format(AverageWT));
		System.out.println("平均帶權週轉時間為:"+df.format(AverageWWT));
		System.out.println("---------------------------------------------------------");
	}
	
	//找出下一個處理的程序
	public static Process FindNextPro(List<Process> list,int now){
		Process pro=list.get(0);
		int index=0;
		for(int i=1;i<list.size();i++){
			if(list.get(i).serviceTime<pro.serviceTime&&list.get(i).arrivalTime<now){
				pro=list.get(i);
				index=i;
			}
		}
		list.remove(index);
		return pro;
	}
	
	//插入排序
	public static void InsertSort(Process[] array)
	{
	    int i, j;
	    int n = array.length;
	    Process target;
	    for (i = 1; i < n; i++)
	    {
	        j = i;
	        target = array[i]; 
	        while (j > 0 && target.arrivalTime < array[j - 1].arrivalTime)
	        {
	            array[j] = array[j - 1];
	            j--;
	        } 
	        array[j] = target;
	    }
	}
	
	//先來先服務演算法
	public static void FCFS(Process[] p){
		
		//按到達時間對程序進行排序
		InsertSort(p);
				
		for(int i=0;i<p.length;i++){
			//計算完成時間
			if(i==0){
				p[i].finishTime=p[i].arrivalTime+p[i].serviceTime;
			}else{
				if(p[i].arrivalTime>p[i-1].finishTime){
					p[i].finishTime=p[i].arrivalTime+p[i].serviceTime;
					p[i].startTime=p[i].arrivalTime;
				}
				else{
					p[i].finishTime=p[i].serviceTime+p[i-1].finishTime;
					p[i].startTime=p[i-1].finishTime;
				}
			}
			
			//計算週轉時間和帶權週轉時間
			p[i].WholeTime=p[i].finishTime-p[i].arrivalTime;
			p[i].weightWholeTime=(double)p[i].WholeTime/(double)p[i].serviceTime;
			
		}
	}
	
	//短作業優先演算法
	public static Process[] SJF(Process[] p){
		
		//當前時間
		int now=0;
		//待處理list
		List<Process> list=new LinkedList<>();
		//結果list
		List<Process> res=new LinkedList<>();
		//按時間對程序進行排序
		InsertSort(p);
		
		//處理第一個程序
		p[0].finishTime=p[0].arrivalTime+p[0].serviceTime;
		p[0].WholeTime=p[0].finishTime-p[0].arrivalTime;
		p[0].weightWholeTime=p[0].WholeTime/p[0].serviceTime;
		res.add(p[0]);
		
		now=p[0].finishTime;
		
		//將剩餘程序新增進待處理list
		for(int i=1;i<p.length;i++){
			list.add(p[i]);
		}
		
		while(list.size()!=0){
			Process next=FindNextPro(list, now);
			if(next.arrivalTime>now){
				next.finishTime=next.arrivalTime+next.serviceTime;
				next.startTime=next.arrivalTime;
			}else{
				next.finishTime=now+next.serviceTime;
				next.startTime=now;
			}
			now=next.finishTime;
			next.WholeTime=next.finishTime-next.arrivalTime;
			next.weightWholeTime=(double)next.WholeTime/(double)next.serviceTime;
			res.add(next);
		}	
			
		return res.toArray(new Process[0]);
		
	}
	

}

//程序的資料結構
class Process{
	public int arrivalTime;
	public int serviceTime;
	public int finishTime;
	public int startTime;
	public int WholeTime;
	public double weightWholeTime;
	public String pid;
	
	Process(int x,int y,String id){
		arrivalTime=x;
		serviceTime=y;
		pid=id;
	}
}