Java 模擬磁碟排程管理
阿新 • • 發佈:2018-12-26
老師佈置的實習題目如下:設計目的: 3.迴圈掃描演算法CSCAN:CSCAN演算法規定磁頭單向移動,例如,只是自裡向外移動,當磁頭移到最外的磁軌並訪問後,磁頭立即返回到最裡的欲訪問的磁軌,亦即將最小磁軌號緊接著最大磁軌號構成迴圈,進行迴圈掃描。程式碼如下:
如有不對,歡迎指出。
加深對請求磁碟排程管理實現原理的理解,掌握磁碟排程演算法。
設計內容:
通過程式設計實現不同磁碟排程演算法。
設定開始磁軌號尋道範圍,依據起始掃描磁軌號和最大磁軌號數,隨機產生要進行尋道的磁軌號序列。選擇磁碟排程演算法,顯示該演算法的磁軌訪問順序,計算出移動的磁軌總數和平均尋道總數。
常用的磁碟排程演算法簡介如下,請在以下演算法中任意選擇兩種實現,並對演算法效能進行分析對比。
1. 最短尋道優先演算法SSTF:該演算法選擇這樣的程序:其要求訪問的磁軌與當前磁頭所在的磁軌距離最近,以使每次的尋道時間最短。
2. 掃描演算法SCAN:該演算法不僅考慮到欲訪問的磁軌與當前磁軌間的距離,更優先考慮的是磁頭當前的移動方向。例如,當磁頭正在自裡向外移動時,SCAN演算法所考慮的下一個訪問物件,應是其欲訪問的磁軌既在當前磁軌之外,又是距離最近的。這樣自裡向外地訪問,直至再無更外的磁軌需要訪問時,才將磁臂換向為自外向裡移動。
import java.util.Scanner; import java.util.Arrays; class Cipandiaodu{ public static void main(String[] args){ /* 要用到的幾種演算法分別是 氣泡排序演算法 先來先服務排程演算法 最短尋道時間優先排程演算法 掃描排程演算法 迴圈掃描排程演算法 */ Cipandiaodu A=new Cipandiaodu(); int a; int now; int c; int[] cidao=new int[1000]; int i=0,count; int[] str=new int[100]; System.out.println("隨機產生一個磁軌序列(包含10個磁軌)\n"); for(i=0;i<10;i++){ str[i]=(int)(Math.random()*200); cidao[i]=str[i]; } count=i-1; System.out.println("得到的磁軌序列為:"); for(i=0;i<count;i++) { System.out.print(cidao[i]+" "); } System.out.println(); while(true) { System.out.println(); System.out.println("----------------------------------------------");System.out.println("------ 系統選單 ------"); System.out.println("--- ---"); System.out.println("-- 1. 先來先服務 --"); System.out.println("-- 2. 最短尋道時間優先 --"); System.out.println("-- 3. 掃描排程 --"); System.out.println("-- 4. 迴圈掃描 --"); System.out.println("-- 5. 退出 --"); System.out.print("請選擇演算法:"); Scanner w=new Scanner(System.in); c=w.nextInt(); if(c==5) break; switch(c) { case 1: //使用FCFS演算法 A.FCFS(cidao,count); break; case 2: //使用SSTF演算法 A.SSTF(cidao,count); break; case 3: //使用SCAN演算法 A.SCAN(cidao,count); break; case 4: //使用CSCAN演算法 A.CSCAN(cidao,count); break; } } } void FCFS(int cidao[],int m) //磁軌號陣列,個數為m { int now;//當前磁軌號 int sum=0; //總尋道長度 int j,i; int a; float ave=0; //平均尋道長度 System.out.println("磁碟請求序列為:"); for( i=0;i<m;i++) //按先來先服務的策略輸出磁碟請求序列 { System.out.print(cidao[i]+" "); } System.out.println(); System.out.print("請輸入當前的磁軌號:"); Scanner w=new Scanner(System.in); now=w.nextInt(); sum+=Math.abs(cidao[0]-now); System.out.println("磁碟掃描序列為:"); for( i=0;i<m;i++) //輸出磁碟掃描序列 { System.out.print(cidao[i]+" "); } for(i=0,j=1;j<m;i++,j++) //求平均尋道長度 { sum+=Math.abs(cidao[j]-cidao[i]); ave=(float)sum/m; } System.out.println(); System.out.println("平均尋道長度:"+ave); } void SSTF(int cidao[],int m) { int k=1; int now,l,r; int i,j,sum=0; int a; float ave; Arrays.sort(cidao); System.out.print("請輸入當前的磁軌號:"); Scanner w=new Scanner(System.in); now=w.nextInt(); if(cidao[m-1]<=now) //若當前磁軌號大於請求序列中最大者,則直接由外向內依次給予各請求服務 { System.out.println("磁碟掃描序列為:"); for(i=m-1;i>=0;i--) System.out.print(cidao[i]+" "); sum=now-cidao[0]; } if(cidao[0]>=now) //若當前磁軌號小於請求序列中最小者,則直接由內向外依次給予各請求服務 { System.out.println("磁碟掃描序列為:"); for(i=0;i<m;i++) System.out.print(cidao[i]+" "); sum=cidao[m-1]-now; } if(now>cidao[0]&&now<cidao[m-1]) //若當前磁軌號大於請求序列中最小者且小於最大者 { System.out.println("磁碟掃描序列為:"); while(cidao[k]<now) //確定當前磁軌在已排的序列中的位置,後面的演算法都用到了,可以直接複製後少量修改,節省時間。 { k++; } l=k-1; r=k; while((l>=0)&&(r<m)) //當前磁軌在請求序列範圍內 { if((now-cidao[l])<=(cidao[r]-now)) //選擇與當前磁軌最近的請求給予服務 { System.out.print(cidao[l]+" "); sum+=now-cidao[l]; now=cidao[l]; l=l-1; } else { System.out.print(cidao[r]+" "); sum+=cidao[r]-now; now=cidao[r]; r=r+1; } } if(l==-1) //磁頭移動到序列的最小號,返回外側掃描仍未掃描的磁軌 { for(j=r;j<m;j++) { System.out.print(cidao[j]+" "); } sum+=cidao[m-1]-cidao[0]; } else //磁頭移動到序列的最大號,返回內側掃描仍未掃描的磁軌 { for(j=l;j>=0;j--) { System.out.print(cidao[j]+" "); } sum+=cidao[m-1]-cidao[0]; } } ave=(float)(sum)/(float)(m); System.out.println(); System.out.println("平均尋道長度: "+ave); } void SCAN(int cidao[],int m) //先要給出當前磁軌號和移動臂的移動方向 { int k=1; int now,l,r,d; int i,j,sum=0; int a; float ave; Arrays.sort(cidao); System.out.print("請輸入當前的磁軌號:"); Scanner w=new Scanner(System.in); now=w.nextInt(); if(cidao[m-1]<=now) //若當前磁軌號大於請求序列中最大者,則直接由外向內依次給予各請求服務,此情況同最短尋道優先 { System.out.println("磁碟掃描序列為:"); for(i=m-1;i>=0;i--) System.out.print(cidao[i]+" "); sum=now-cidao[0]; } if(cidao[0]>=now) //若當前磁軌號小於請求序列中最小者,則直接由內向外依次給予各請求服務,此情況同最短尋道優先 { System.out.println("磁碟掃描序列為:"); for(i=0;i<m;i++) System.out.print(cidao[i]+" "); sum=cidao[m-1]-now; } if(now>cidao[0]&&now<cidao[m-1]) //若當前磁軌號大於請求序列中最小者且小於最大者 { while(cidao[k]<now) { k++; } l=k-1; r=k; System.out.println("請輸入當前移動臂的移動的方向 (1 表示向外 ,0表示向內) : "); Scanner x=new Scanner(System.in); d=x.nextInt(); if(d==0) //選擇移動臂方向向內,則先向內掃描 { System.out.println("磁碟掃描序列為:"); for(j=l;j>=0;j--) { System.out.print(cidao[j]+" "); } for(j=r;j<m;j++) //磁頭移動到最小號,則改變方向向外掃描未掃描的磁軌 { System.out.print(cidao[j]+" "); } sum=now-2*cidao[0]+cidao[m-1]; } else //選擇移動臂方向向外,則先向外掃描 { System.out.println("磁碟掃描序列為:"); for(j=r;j<m;j++) { System.out.print(cidao[j]+" "); } for(j=l;j>=0;j--) //磁頭移動到最大號,則改變方向向內掃描未掃描的磁軌 { System.out.print(cidao[j]+" "); } sum=-now-cidao[0]+2*cidao[m-1]; } } ave=(float)(sum)/(float)(m); System.out.println(); System.out.print("平均尋道長度: "); } void CSCAN(int cidao[],int m) { int k=1; int now,l,r; int i,j,sum=0; int a; float ave; Arrays.sort(cidao); System.out.print("請輸入當前的磁軌號:"); Scanner w=new Scanner(System.in); now=w.nextInt(); if(cidao[m-1]<=now) //若當前磁軌號大於請求序列中最大者,則直接將移動臂移動到最小號磁軌依次向外給予各請求服務 { System.out.println("磁碟掃描序列為:"); for(i=0;i<m;i++) System.out.print(cidao[i]+" "); sum=now-2*cidao[0]+cidao[m-1]; } if(cidao[0]>=now) //若當前磁軌號小於請求序列中最小者,則直接由內向外依次給予各請求服務,此情況同最短尋道優先 { System.out.println("磁碟掃描序列為:"); for(i=0;i<m;i++) System.out.print(cidao[i]+" "); sum=cidao[m-1]-now; } if(now>cidao[0]&&now<cidao[m-1]) //若當前磁軌號大於請求序列中最小者且小於最大者 { System.out.println("磁碟掃描序列為:"); while(cidao[k]<now) //單向反覆地從內向外掃描 { k++; } l=k-1; r=k; for(j=r;j<m;j++) { System.out.print(cidao[j]+" "); } for(j=0;j<r;j++) //當掃描完最大號磁軌,磁頭直接移動到最小號磁軌,再向外掃描未掃描的磁軌 { System.out.print(cidao[j]+" "); } sum=2*cidao[m-1]+cidao[l]-now-2*cidao[0]; } ave=(float)(sum)/(float)(m); System.out.println(); System.out.println("平均尋道長度: "); } }
如有不對,歡迎指出。