作業系統課程設計--磁碟排程演算法的模擬實現及對比
阿新 • • 發佈:2018-12-26
本來已經做好了個課程設計是銀行家演算法的,不過由於借給同學抄,被老師發現了,要重做...就選了磁碟高度演算法的題目。
實驗要求及提示
1 、首先假設磁碟磁軌數為 1500 ,磁頭初始停止於 0 磁軌。
2 、用隨機數生成函式產生“磁軌號”序列(即磁碟請求的位置),共產生 100 個。其中 50% 位於 0 ~ 499 , 25% 分佈在 500 ~ 999 , 25% 分佈在 1000 ~ 1499 。
3 、計算每種磁碟排程演算法下的磁頭移動道數
本程式主要是模擬實現,還有很多改進的地方,還請大家提出。
以下是為滿足要求2的隨機數生成程式碼,主要參照網上的方法:
package chow.app; import java.util.HashSet; import java.util.Iterator; import java.util.Random; /** * 用隨機數生成函式產生“磁軌號”序列(即磁碟請求的位置),共產生100個。其中50%位於0~499,25%分佈在500~999,25%分佈在1000~1499。 * @author Administrator */ public class DiskScheduleUtil { public static int count = 0;// 需要生成隨機數的個數 public int[] createDiskRequest() { int[] tmpRequest = new int[100]; HashSet<Integer> s = new HashSet<Integer>(); // 50%位於0~499的序列 count = 50; genRadoms(0, 499, count, s); Iterator<Integer> it; it = s.iterator(); int i = 0; while (it.hasNext()) { tmpRequest[i] = it.next(); i++; } // 25%分佈在500~999的序列 count = 25; s.clear(); genRadoms(500, 999, count, s); it = s.iterator(); i = 50; while (it.hasNext()) { tmpRequest[i] = it.next(); i++; } //25%分佈在1000~1499的序列 count = 25; s.clear(); genRadoms(1000, 1499, count, s); it = s.iterator(); i = 75; while (it.hasNext()) { tmpRequest[i] = it.next(); i++; } //用來打亂tmpRequest的順序 int[] tmpRequestReturn = new int[100]; int[] nosortSeq = random2(); for(int j = 0; j < 100; j++){ tmpRequestReturn[j] = tmpRequest[nosortSeq[j]]; System.out.print("[" + j + "]:" + tmpRequestReturn[j] + " "); if (j % 10 == 0) { System.out.println(); } } return tmpRequestReturn; } // 生成【begin,end】區間內num個隨機數 public void genRadoms(int begin, int end, int num, HashSet<Integer> set) { if (num > (end - begin + 1) || end < begin) { return; } for (int i = 0; i < num; i++) {// 生成num個隨機數 // 呼叫Math.random()方法 int temp = (int) (Math.random() * (end - begin + 1)) + begin; set.add(temp);// 將不同的數存入HashSet中 } int setLen = set.size(); // 如果存入的數小於指定生成的個數,則呼叫遞迴再生成剩餘個數的隨機數,如此迴圈,直到達到指定大小 if (setLen < count) { genRadoms(begin, end, count - setLen, set);// 遞迴 } } public static int[] random2() { int send[] = new int[100]; for(int i = 0; i < send.length; i++){ send[i] = i; } int temp1, temp2, temp3; Random r = new Random(); for (int i = 0; i < send.length; i++) // 隨機交換send.length次 { temp1 = Math.abs(r.nextInt()) % (send.length - 1); // 隨機產生一個位置 temp2 = Math.abs(r.nextInt()) % (send.length - 1); // 隨機產生另一個位置 if (temp1 != temp2) { temp3 = send[temp1]; send[temp1] = send[temp2]; send[temp2] = temp3; } } return send; } }
以下是FCFS,SSTF,SCAN,C-SCAN各演算法的程式碼,每個演算法都返回磁碟移動的磁軌數。
FCFS演算法,first come first service.
package chow.app; /** * first come, first service * @author Administrator */ public class DiskScheduleFCFS extends DiskScheduleAlgorithm{ @Override public int getCount(final int[] diskReq, int varIndex){ count = 0; curIndex = varIndex; for(int i = 0; i < diskReq.length; i++){ count += Math.abs(diskReq[i] - curIndex); curIndex = diskReq[i]; } return count; } }
SSTF演算法,shortest seek time first
package chow.app; /** * shortest seek time first 最短尋道時間優先演算法 * @author Administrator */ public class DiskScheduleSSTF extends DiskScheduleAlgorithm { @Override public int getCount(final int[] diskReq, int varIndex) { count = 0; curIndex = varIndex; int[] tmpDiskReq = new int[diskReq.length]; for(int tInt = 0; tInt < diskReq.length; tInt++){ tmpDiskReq[tInt] = diskReq[tInt]; } for (int i = 0; i < tmpDiskReq.length; i++) { int index = getNearestIndex(curIndex,tmpDiskReq); count += Math.abs(curIndex - tmpDiskReq[index]); System.out.print(tmpDiskReq[index]+" "); if(i%10==0) System.out.println(); curIndex = tmpDiskReq[index]; tmpDiskReq[index] = -1; } return count; } //返回距離當前最近的索引 public int getNearestIndex(int tmpIndex,final int[] tdiskReq) { int min = 1500; int temp = 0; int index = -1; for (int i = 0; i < tdiskReq.length; i++) { if (tdiskReq[i] != -1) { temp = Math.abs(tmpIndex - tdiskReq[i]); if (temp < min) { min = temp; index = i; } } } return index; } }
SCAN演算法,又叫做“電梯演算法”,我是處理完最遠一個請求就返回另一方向繼續處理。也有教材上是一直移動到末端才轉方向的。
/**
* SCAN 電梯演算法,先不斷移到一端(盡頭),再移到另一端(另一盡頭)
* 簡化:預設為先大數端後向0端;不移到末端,只移到最外一個請求就轉向
* @author Administrator
*/
public class DiskScheduleSCAN extends DiskScheduleAlgorithm{
@Override
public int getCount(final int[] diskReq, int varIndex) {
count = 0;
curIndex = varIndex;
int leftMin = curIndex, rightMax = curIndex;
for(int i = 0; i < diskReq.length; i++){
if(diskReq[i] > curIndex && diskReq[i] > rightMax){
rightMax = diskReq[i];
}else if(diskReq[i] < curIndex && diskReq[i] < leftMin){ // 小於等於curIndex
leftMin = diskReq[i];
}
}
if(curIndex==leftMin){
count = rightMax - curIndex;
}else{
count = (rightMax - curIndex) + (rightMax - leftMin);
}
return count;
}
}
C-SCAN演算法,SCAN演算法的變種
package chow.app;
/**
* C-SCAN, 是SCAN的變種,當碰頭移到另一端時,馬上返回到磁碟開始,返回時不處理請求
* @author Administrator
*/
public class DiskScheduleC_SCAN extends DiskScheduleAlgorithm{
@Override
public int getCount(final int[] diskReq, int varIndex) {
count = 0;
curIndex = varIndex;
int leftMax = lowIndex, rightMax = curIndex;
for(int i = 0; i < diskReq.length; i++){
if(diskReq[i] > curIndex && diskReq[i] > rightMax){
rightMax = diskReq[i];
}else if(diskReq[i] < curIndex && diskReq[i] > leftMax){ // 小於curIndex
leftMax = diskReq[i];
}
}
if(curIndex==leftMax){
count = rightMax - curIndex;
}else{
count = (rightMax - curIndex) + (highIndex - lowIndex) + leftMax;
}
return count;
}
}
以上是關鍵程式碼,其它的介面是在netbeans6.7上完成的。下面上傳最終生成的jar檔案。