1. 程式人生 > >高響應比優先排程演算法(HRRN)

高響應比優先排程演算法(HRRN)

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;
}