短作業優先排程演算法(SJF)——Java實現
阿新 • • 發佈:2018-12-26
短作業優先排程演算法(SJF)
短作業優先排程演算法(Short Job First)用於程序排程時又被稱為短程序優先排程演算法(Short Process First),該演算法既可以用於作業排程,又可以用於程序排程。
在作業排程中,該演算法每次從後備作業佇列中挑選估計服務時間最短的一個或幾個作業,將他們調入記憶體,分配必要的資源,建立程序並放入就緒佇列。在程序排程中的原理類似。
題目:
每個任務請求都以其請求時間(向系統提交請求的時間)和 其持續時間(即完成任務所需要的時間)為特徵。
當前任務完成後,SJF 策略選擇具有最短持續時間的任務作為下一個要執行的任務。如果多個任務都有最短持續時間,則選擇請求時間最早的那個任務,任務的的等待時間為請求時間和時間開始時間的差值(即,等待系統執行任務所花的時間)。假設任務到達時系統時鐘處於執行任務的狀態,且永遠不會關閉。
給定的一個請求時間和任務持續時間的列表,計算使用最短作業優先(SJF)演算法排程時的平均等待時間。
所給出的請求時間和持續時間都是按照請求時間的升序排序的。
ShortFirstJob類,有一個方法minAgerageWaitTime(int[] requestTime, int[] durationTime) requestTime是n個任務的請求時間,durationTime是n個任務的持續時間。該方法返回一個表示平均等待時間(使用非搶佔式SJF排程演算法)的浮點數。
(假定0 <= 到達時間 < 100.0 < 突發時間 < 100)
注:優先選擇持續時間小的,如果持續時間相同,則選擇請求時間早的。
- 提交時間 = 請求時間
- 服務時間 = 作業需要執行的時間,即持續時間
- 開始時間 = task == 0 ? 0 : 上個優選任務 完成時間
- 完成時間 = 開始時間 + 服務時間
- 等待時間 = 開始時間 - 提交時間
- 週轉時間 = 完成時間 - 提交時間
- 帶權週轉時間 = 週轉時間 / 服務時間
- 響應比 = (等待時間 + 服務時間) / 服務時間 = 等待時間/服務時間 + 1
public class ShortJobFirst { public static float minAgerageWaitTime(int[] requestTime, int[] durationTime){ int length = requestTime.length; int[] serviceTime = new int[length]; //服務時間 即是持續時間 for(int i=0; i<length; i++){ serviceTime[i] = durationTime[i]; } int[] task = new int[length]; //任務號 for(int i=0; i<length; i++){ task[i] = i+1; } int[] waitTime = new int[length]; //等待時間 int[] startTime = new int[length]; //開始時間 int[] finishTime = new int[length]; //完成時間 int[] turnTime = new int[length]; //週轉時間 float[] rightTurnTime = new float[length]; //帶權週轉時間 startTime[0] = requestTime[0]; finishTime[0] = startTime[0] + durationTime[0]; waitTime[0] = startTime[0] - requestTime[0]; turnTime[0] = finishTime[0] - requestTime[0]; rightTurnTime[0] =(float) turnTime[0] / durationTime[0]; System.out.println("11111:"+rightTurnTime[0]); int minIndex = 0; int lastIndex = 0; int[] durations = getMin( requestTime,serviceTime); //得到任務調動的順序 for(int i=1; i<length; i++){ minIndex = durations[i-1]+1; startTime[minIndex] = finishTime[lastIndex]; //開始時間 = task == 0 ? 0 : 上個優選任務的完成時間 finishTime[minIndex] = startTime[minIndex] + durationTime[minIndex]; //完成時間 = 開始時間 + 服務時間 waitTime[minIndex] = startTime[minIndex] - requestTime[minIndex]; //等待時間 = 開始時間 - 提交時間 turnTime[minIndex] = finishTime[minIndex] - requestTime[minIndex]; //週轉時間 = 完成時間 - 提交時間 rightTurnTime[minIndex] = (float)turnTime[minIndex] / durationTime[minIndex]; //帶權週轉時間 = 週轉時間 / 服務時間 lastIndex = minIndex; //將當前索引記為上一個任務索引 } int add = 0; float result; for(int i=0; i< length; i++){ add += waitTime[i]; } result = (float)add/length; //求平均等待時間 return result; } /** * 得到任務調動的順序 * @param requstTime * @param durationTime * @return */ private static int[] getMin(int[] requstTime, int[] durationTime) { int length = durationTime.length; int[] arr = new int[length-1]; //去除第一個任務,剩下的任務的服務時間 int[] arr1 = new int[length-1]; //存放剩下任務的開始順序索引 int[] arr2 = new int[length-1]; //存放剩下任務的開始順序值 for(int i=0; i<arr.length ; i++){ arr[i] = durationTime[i+1]; } int minIndex =0; for(int i=0; i<arr.length; i++){ //趟數 for(int j=0 ; j<arr.length; j++){ //冒泡比較法,但是不交換位置 if(arr[j] < arr[minIndex]){ minIndex = j; } } arr1[i] = minIndex; arr2[i] = arr[minIndex]; arr[minIndex] = Integer.MAX_VALUE; } return arr1; } public static void main(String[] args) { int[] requestTime = {0,1,2,3,4}; int[] durationTime = {4,3,5,2,4}; float averageWaitTime = ShortJobFirst.minAgerageWaitTime(requestTime, durationTime); System.out.println("平均等待時間:" + averageWaitTime ); }