這學期剛開始學習操作系統,收到一個作業,百度關於高響應比優先(HRRN,Highest Response Ratio Next)的CPU進程調度模擬演算法,基本思想:短作業優先調度演算法 + 動態優先權機制;既考慮作業的執行時間也考慮作業的等待時間,綜合了先來先服務(FCFS,First Come Fi ...
這學期剛開始學習操作系統,收到一個作業,百度關於高響應比優先(HRRN,Highest Response Ratio Next)的CPU進程調度模擬演算法,基本思想:短作業優先調度演算法 + 動態優先權機制;既考慮作業的執行時間也考慮作業的等待時間,綜合了先來先服務(FCFS,First Come First Served)和最短作業優先(SJF,Shortest Job First)兩種演算法的特點。
之後經過多番揣摩... ...決定界面用命令行算了,反正啥也不會...
關於響應比:
RR = (預計運行時間 + 等待時間) / 預計運行時間 = 1 + 等待時間/預計運行時間;
響應比高者優先進行調度;
關於要求中的周轉時間、帶權周轉時間、平均周轉時間和平均帶權周轉時間:
周轉時間 =(作業完成的時間 - 作業提交時間);
帶權周轉時間 = 作業周轉時間 / 作業運行時間;
平均周轉時間 = (周轉時間1+周轉時間2+...+周轉時間n)/ n;
平均帶權周轉時間 = (帶權周轉時間1+帶權周轉時間2+...+帶權周轉時間n)/ n;
開始,用vector存儲提交的作業結構體指針,自己設置一個系統時間,畢竟模擬不可能時間流速一毛一樣,接下來就是毫無技術含量的選擇了,關於測試數據,想了想好難輸,還得自己編,於是用隨機函數產生數據;再在主函數參數中提供一個傳遞生成數據數量的參數。
說到這裡得說一下,關於java老師(沒錯,java老師)說的關於main()的一些情況:
1 int main(int argc, char** argv){ ////argc為參數個數, argv為接下來傳的參數 2 ... 3 return 0; 4 }
比如在命令行中調用該函數,***.exe 100,此時有兩個參數,一個為"***.exe", 另一個就是"100"了,分別在argv[0]和argv[1]中。
首先是數據生成,用為要求格式,所以要小處理一下,感覺這種方法可以在刷ACM題被題目玄學時使用,一個為標準代碼,一個為自己的代碼,目前未試過:
1 #include "bits/stdc++.h" 2 using namespace std; 3 4 int ch_to_int(char* s){ 5 int ans = 0, len = strlen(s); 6 for(int i = 0; i < len; i++) ans = ans*10 + s[i]-'0'; 7 return ans; 8 } 9 int main(int argc, char** argv){ 10 int k, N, tj/*0~23*/, ys/*0~59*/, tmp; 11 freopen("test.txt", "w", stdout); 12 srand(time(NULL)); //以系統時間為種子生成真正的隨機數 13 N = k = ch_to_int(argv[1]); 14 while(k--){ 15 tmp = (rand() + 24)%24 * 100 + (rand() + 6)%6*10 + (rand() + 10)%10; 16 printf("%04d %d\n", tmp, (rand() + N)%N + 1); 17 } 18 return 0; 19 }
調度演算法:
1 #include "bits/stdc++.h" 2 #include "windows.h" 3 using namespace std; 4 typedef long long ll; 5 6 //(所有時間以分鐘為單位存儲,需要時轉化) 7 8 ll systemTime; //自定義系統當前時間 9 10 struct Task{ 11 int Tij; //提交時間 12 int Ysi; //預計運行時間 13 ll waitingTime; //等待時間 14 int id; //作業號 15 16 ll prior(){ 17 return 1 + waitingTime*1.0/Ysi; 18 } 19 20 Task(int T, int Y){ 21 Tij = T; 22 Ysi = Y; 23 waitingTime = 0; 24 } 25 ll aroundTime(){ 26 return systemTime - Tij + Ysi; 27 } 28 29 double priorTime(){ 30 return aroundTime()*1.0/Ysi; 31 } 32 void disp(int ord){ 33 printf("--調度次序: %d --作業號: %04d --調度時間:%02d%02d --周轉時間: %d min(s) --帶權周轉時間%.2f ...\n", 34 ord, id, (systemTime/100 + systemTime/60)%24, systemTime%60, aroundTime(), priorTime()); 35 } 36 }; 37 38 int cmp1(const Task* a, const Task* b){ 39 return (a->Tij) < (b->Tij); 40 } 41 42 int main(){ 43 vector<Task*> taskArr; ///以不定長數組存儲作業隊列 44 45 int Tij, Ysi, order; 46 ll ave_aroundTime = 0; 47 double ave_prior_aroundTime = 0; 48 49 freopen("test.txt", "r", stdin); 50 system(".\\生成測試數據.exe 1024"); //調用測試數據生成程式 51 52 while(cin>>Tij>>Ysi) taskArr.push_back(new Task(Tij%100 + Tij/100*60, Ysi)); 53 54 ////按提交時間進行排序並編號 55 sort(taskArr.begin(), taskArr.end(), cmp1); 56 std::vector<Task*>::iterator pos; 57 for(pos = taskArr.begin(); pos != taskArr.end(); pos++){ 58 (*pos)->id = pos - taskArr.begin(); 59 } 60 61 std::vector<Task*>::iterator willRun; //指向即將運行程式 62 systemTime = (*taskArr.begin())->Tij; ///將系統當前時間設置為最早提交的作業時間 63 order = -1; 64 while(!taskArr.empty()){ 65 bool flag = false; ///判定是否有新的程式提交 66 willRun = taskArr.begin(); 67 for(pos = taskArr.begin(); pos != taskArr.end(); pos++){ 68 if((*pos)->Tij > systemTime) break; 69 willRun = (*willRun)->prior() < (*pos)->prior() ? pos : willRun; 70 flag = true; 71 } 72 if(!flag){ 73 willRun = taskArr.begin(); 74 systemTime = (*willRun)->Tij; 75 } 76 77 (*willRun)->disp(++order); 78 79 ave_aroundTime += (*willRun)->aroundTime(); //總周轉 80 ave_prior_aroundTime += (*willRun)->priorTime(); //總帶權周轉 81 82 for(pos = taskArr.begin(); pos != taskArr.end(); pos++){ //更新等待時間 83 if((*pos)->Tij < systemTime){ 84 (*pos)->waitingTime += (*willRun)->Ysi; 85 } 86 } 87 88 systemTime += (*willRun)->Ysi; //系統時間增加 89 90 taskArr.erase(willRun); //結束則刪除 91 92 //Sleep(10); 93 } 94 cout<<ave_aroundTime<<' '<<ave_prior_aroundTime<<endl; 95 printf("\n----平均周轉時間: %.2f --平均帶權周轉時間: %.2f ...\n作業結束..", ave_aroundTime*1.0/order, ave_prior_aroundTime/order); 96 97 return 0; 98 }
加油( ̄▽ ̄)"