这学期刚开始学习操作系统,收到一个作业,百度关于高响应比优先(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 ", 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 ... ", 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(" ----平均周转时间: %.2f --平均带权周转时间: %.2f ... 作业结束..", ave_aroundTime*1.0/order, ave_prior_aroundTime/order); 96 97 return 0; 98 }
加油( ̄▽ ̄)"