高響應比優先排程演算法(HRRN)
阿新 • • 發佈:2019-01-02
BOOM,困到不行,這個寫完就睡覺了,今天好像有點感冒 ,翹了晚上的課一直睡到10點起來,睡不著在寫程式碼,現在又困了
高響應比演算法,是一種動態調整優先順序的演算法,在上面介紹的PSA演算法中,給每個作業安排一個優先順序後,始終這個優先順序不再改變,這有些不合理。
因為可能造成一個低優先順序作業始終得不到執行。
為了解決這個問題,HRRN演算法每次都計算作業的優先順序,隨著作業等待時間的變長,優先順序不斷的提高,所以能夠得到更快的執行。
這個優先順序可以描述為: 優先順序 = (作業已等待時間 + 作業的服務時間) / 作業的服務時間
從上式可以看到,作業的服務時間是固定的, 優先順序隨著已等待時間的提高而變大
//main.cpp #include "HRRN.h" int main() { std::vector<PCB> PCBList; //輸入作業資訊 InputPCB(PCBList); //HRRN演算法 HRRN(PCBList); //顯示結果 show(PCBList); return 0; } //HRRN.h #ifndef HRRN_H_ #define HRRN_H_ #include <iostream> #include <algorithm> #include <iomanip> #include <vector> //作業結構體 typedef struct PCB { int ID; //識別符號 double Level; //優先順序 int ComeTime; //到達時間 int ServerTime; //服務時間 int FinishTime; //完成時間 int TurnoverTime; //週轉時間 double WeightedTurnoverTime; //帶權週轉時間 }PCB; /* 函式功能:輸入作業資訊 引數說明: PCBList std::vector<PCB>& PCB鏈 */ void InputPCB(std::vector<PCB> &PCBList); /* 函式功能:HRRN演算法 引數說明: PCBList std::vector<PCB>& PCB鏈 */ void HRRN(std::vector<PCB> &PCBList); /* 函式功能:計算優先順序 引數說明: b std::vector<PCB>::iterator 起始位置 e std::vector<PCB>::iterator 結束位置 CurTime int 當前時間 */ void CalPriority(std::vector<PCB>::iterator b, std::vector<PCB>::iterator e, int CurTime); /* 函式功能:顯示結果 引數說明: PCBList std::vector<PCB>& PCB鏈 */ void show(std::vector<PCB> &PCBList); /* 函式功能:比較函式,用於sort(),按ComeTime升序排列 引數說明: p1 const PCB& PCB p2 const PCB& PCB */ bool CmpByComeTime(const PCB &p1, const PCB &p2); /* 函式功能:比較函式,用於sort(),按Level降序排列 引數說明: p1 const PCB& PCB p2 const PCB& PCB */ bool CmpByLevel(const PCB &p1, const PCB &p2); #endif //HRRN.cpp #include "HRRN.h" //輸入作業資訊 void InputPCB(std::vector<PCB> &PCBList) { do { PCB temp; std::cout << "輸入識別符號: "; std::cin >> temp.ID; std::cout << "輸入到達時間: "; std::cin >> temp.ComeTime; std::cout << "輸入服務時間: "; std::cin >> temp.ServerTime; PCBList.push_back(temp); std::cout << "繼續輸入?Y/N: "; char ans; std::cin >> ans; if ('Y' == ans || 'y' == ans) continue; else break; } while (true); } //HRRN演算法 void HRRN(std::vector<PCB> &PCBList) { std::sort(PCBList.begin(), PCBList.end(), CmpByComeTime); //按到達時間排序 //同時到達的按優先順序降序排序,決定首先執行的作業 int i = 1; std::vector<PCB>::iterator it = PCBList.begin() + 1; while ((*it).ComeTime == (*(it - 1)).ComeTime) { ++i; ++it; } CalPriority(PCBList.begin(), PCBList.begin() + i, 0); //計算優先順序 std::sort(PCBList.begin(), PCBList.begin() + i, CmpByLevel); int FinishTime = -1; for (it = PCBList.begin(); it < PCBList.end(); ++it) { if ((*it).ComeTime >= FinishTime) //沒有作業正在執行,取隊首作業執行 (*it).FinishTime = (*it).ComeTime + (*it).ServerTime; else //有作業正在執行,等待作業完畢,此作業再執行 (*it).FinishTime = FinishTime + (*it).ServerTime; (*it).TurnoverTime = (*it).FinishTime - (*it).ComeTime; (*it).WeightedTurnoverTime = (double)(*it).TurnoverTime / (*it).ServerTime; FinishTime = (*it).FinishTime; //在一個作業執行期間,如果有其他作業到達,將他們按照優先順序降序排列 i = 1; while ((it + i) < PCBList.end() && (*(it + i)).ComeTime <= FinishTime) ++i; CalPriority(it + 1, it + i, FinishTime); std::sort(it + 1, it + i, CmpByLevel); } std::sort(PCBList.begin(), PCBList.end(), CmpByComeTime); //重新排列,用於顯示結果 } //計算優先順序 void CalPriority(std::vector<PCB>::iterator b, std::vector<PCB>::iterator e, int CurTime) { while (b < e) { (*b).Level = (double)((*b).ServerTime + (CurTime - (*b).ComeTime)) / (*b).ServerTime; ++b; } } //顯示結果 void show(std::vector<PCB> &PCBList) { int SumTurnoverTime = 0; double SumWeightedTurnoverTime = 0; std::cout.setf(std::ios::left); std::cout << std::setw(20) << "識別符號"; for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it) std::cout << std::setw(5) << (*it).ID; std::cout << std::endl; std::cout << std::setw(20) << "到達時間"; for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it) std::cout << std::setw(5) << (*it).ComeTime; std::cout << std::endl; std::cout << std::setw(20) << "服務時間"; for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it) std::cout << std::setw(5) << (*it).ServerTime; std::cout << std::endl; std::cout << std::setw(20) << "完成時間"; for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it) std::cout << std::setw(5) << (*it).FinishTime; std::cout << std::endl; std::cout << std::setw(20) << "週轉時間"; for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it) { std::cout << std::setw(5) << (*it).TurnoverTime; SumTurnoverTime += (*it).TurnoverTime;; } std::cout << std::endl; std::cout << std::setw(20) << "帶權週轉時間"; for (std::vector<PCB>::iterator it = PCBList.begin(); it < PCBList.end(); ++it) { std::cout << std::setw(5) << (*it).WeightedTurnoverTime; SumWeightedTurnoverTime += (*it).WeightedTurnoverTime;; } std::cout << std::endl; std::cout << "平均週轉時間: " << (double)SumTurnoverTime / PCBList.size() << std::endl; std::cout << "平均帶權週轉時間: " << SumWeightedTurnoverTime / PCBList.size() << std::endl; } //比較函式,按ComeTime升序排列 bool CmpByComeTime(const PCB &p1, const PCB &p2) { return p1.ComeTime < p2.ComeTime; } //比較函式,按Level降序排列 bool CmpByLevel(const PCB &p1, const PCB &p2) { return p1.Level > p2.Level; }