1. 程式人生 > >4】動態分割槽分配演算法

4】動態分割槽分配演算法

// 作業系統_實驗四(動態分割槽分配演算法).cpp : 定義控制檯應用程式的入口點。
//

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

#define MAXNUMBER 100
static int PartitionNum;  //記憶體中空閒分割槽的個數
static int ProcessNum; //需要分配的程序個數
static int FreePartition[MAXNUMBER];  //空閒分割槽對應的記憶體
static int ProcessNeed[MAXNUMBER];  //需要分配的程序大小

static int LeftFreePartition[MAXNUMBER];
static int LeftProcessNeed[MAXNUMBER];

static char ProcessName[MAXNUMBER];
static char NameProcessToPartition[MAXNUMBER][MAXNUMBER];

typedef struct
{
	int partitionSize;
	int id;
}sortNeed;

void readDataFunction();
void display();
void FirstFit();
void NextFit();
void BestFit();
void WorstFit();
void selectAlgorithm(int chooceAlgorithm);
void display();

void readDataFunction()
{
	ifstream readData;
	readData.open("data.txt");

	readData>>PartitionNum;
	for (int i=0;i<PartitionNum;i++)
	{
		readData>>FreePartition[i];
	}

	readData>>ProcessNum;
	for (int i=0;i<ProcessNum;i++)
	{
		readData>>ProcessName[i];
	}
	for (int i=0;i<ProcessNum;i++)
	{
		readData>>ProcessNeed[i];
	}
}

void initial()
{
	readDataFunction();   //讀取原始資料
	for (int i=0;i<ProcessNum;i++)
	{	
		for (int j =0;j<PartitionNum;j++)
		{
			NameProcessToPartition[i][j] =NULL;
			LeftFreePartition[j] = FreePartition[j];
		}
	}
	for (int i = 0;i<ProcessNum;i++)
	{
		LeftProcessNeed[i] = ProcessNeed[i];
	}
}


void FirstFit()
{
	cout<<"***********首次適應演算法***********"<<endl;
	initial();

	int i,j;
	for (i = 0;i<ProcessNum;i++)   //逐個遍歷每個程序
	{
		for (j = 0;j<PartitionNum;j++)   //每次都從分割槽的首地址開始查詢
		{
			if (LeftProcessNeed[i] <= LeftFreePartition[j] && LeftFreePartition!=0)  //當系統記憶體分割槽足夠大的時候,即分配給程序資源
			{
				LeftFreePartition[j] -= LeftProcessNeed[i];   //扣除分配給程序的資源
				LeftProcessNeed[i] = 0;  //當且僅當系統記憶體分割槽足夠時才執行,即當前程序大小置0

				NameProcessToPartition[i][j] = ProcessName[i];  //儲存各個程序所在的分割槽位置

				break;   //!!!很重要,一個程序分割槽完後,應該立即break,進行下一個程序的判斷
			}
		}
	}

	display();
	
}

void NextFit()
{
	cout<<"***********迴圈首次適應演算法***********"<<endl;
	initial();
	int i,nextPoint = 0;
	bool isWhile;
	for (i = 0;i<ProcessNum;i++)
	{
		isWhile = true;
		while(isWhile)     //每次都從當前分割槽的下一個分割槽開始查詢
		{
			if (LeftFreePartition[nextPoint] >= LeftProcessNeed[i])
			{
				LeftFreePartition[nextPoint] -= LeftProcessNeed[i];
				LeftProcessNeed[i] = 0;
				NameProcessToPartition[i][nextPoint] = ProcessName[i];
				nextPoint++;
				if (nextPoint > PartitionNum - 1)
				{
					nextPoint = 0;  //當j遍歷到分割槽末尾的時候,返回首位置
				}
				isWhile = false;
			}
			else
				nextPoint++;
		}
	}
	display();
}

void BestFit()
{
	//思想:利用氣泡排序對分割槽大小進行排序,但不改變原分割槽的位置
	//建立一個結構體,包括分割槽大小和所對應的id,排序過程中,每改變順序一次,id隨著改變
	//關鍵:每次分配完一個程序的記憶體大小後,都要重新排序
	cout<<"***********最佳適應演算法***********"<<endl;
	initial();
	int i,j,temp,tempID;

	sortNeed best[MAXNUMBER];
	for (i = 0;i<PartitionNum;i++)
	{
		//初始化結構體
		best[i].partitionSize = FreePartition[i];
		best[i].id = i;
	}

	//int count2 = 0;

	for (i = 0;i<ProcessNum;i++)
	{
		for (int s = PartitionNum - 1;s > 0;s--)   //氣泡排序(每次分配完一個程序後,都需要重新排序)
		{
			for (int t = 0;t < s;t++)
			{
				if (best[s].partitionSize < best[t].partitionSize)
				{
					temp = best[s].partitionSize;
					best[s].partitionSize = best[t].partitionSize;
					best[t].partitionSize = temp;

					tempID = best[s].id;
					best[s].id = best[t].id;
					best[t].id = tempID;
				}
			}
		}

		for (j = 0;j<PartitionNum;j++)
		{
			if (LeftProcessNeed[i] <= best[j].partitionSize)
			{
				best[j].partitionSize -= LeftProcessNeed[i];
				LeftProcessNeed[i] = 0;			

				NameProcessToPartition[i][best[j].id] = ProcessName[i];
				//count2++;
				break;
			}
		}
		LeftFreePartition[best[j].id] = best[j].partitionSize;
	}
	//cout<<count2<<endl;

	display();
}

void WorstFit()
{
	cout<<"***********最壞適應演算法***********"<<endl;
	initial();
	int i,j,s,t,tempSize,tempID;
	sortNeed Worst[MAXNUMBER];

	for (i = 0;i<PartitionNum;i++)
	{
		Worst[i].partitionSize = FreePartition[i];
		Worst[i].id = i;
	}

	for (i = 0;i<ProcessNum;i++)
	{
		for (s = PartitionNum - 1;s>0;s--)
		{
			for (t = 0; t<s;t++)
			{
				if (Worst[s].partitionSize > Worst[t].partitionSize)
				{
					tempSize = Worst[s].partitionSize;
					Worst[s].partitionSize = Worst[t].partitionSize;
					Worst[t].partitionSize = tempSize;

					tempID = Worst[s].id;
					Worst[s].id = Worst[t].id;
					Worst[t].id = tempID;
				}
			}
		}

		for (j = 0;j<PartitionNum;j++)
		{
			if (LeftProcessNeed[i] <= Worst[j].partitionSize)
			{
				Worst[j].partitionSize -= LeftProcessNeed[i];
				LeftProcessNeed[j] = 0;

				NameProcessToPartition[i][Worst[j].id] = ProcessName[i];
				break;
			}
		}
		LeftFreePartition[Worst[j].id] = Worst[j].partitionSize;
	}

	display();

}

void selectAlgorithm(int chooseAlgorithm)
{
	switch(chooseAlgorithm)
	{
		case 0:break;
		case 1:FirstFit();break;
		case 2:NextFit();break;
		case 3:BestFit();break;
		case 4:WorstFit();break;
		default:cout<<"請輸入正確的序號:"<<endl;
	}
}

void display()
{
	int i;
	cout<<"需要分配記憶體的程序名:"<<setw(10);
	for (i = 0;i<ProcessNum;i++)
	{
		cout<<ProcessName[i]<<setw(6);
	}
	cout<<endl;
	cout<<"需要分配記憶體的程序分割槽大小:"<<setw(4);
	for (i = 0;i<ProcessNum;i++)
	{
		cout<<ProcessNeed[i]<<setw(6);
	}
	cout<<endl;
	cout<<"分配結果:"<<endl;

	cout<<"分割槽序號:";
	for (i = 0;i<PartitionNum;i++)
	{
		cout<<"分割槽"<<i+1<<" ";
	}
	cout<<endl<<"分割槽大小:";
	for (i = 0;i<PartitionNum;i++)
	{  
		cout<<FreePartition[i]<<"     ";
	}
	cout<<endl<<"剩餘大小:";
	for (i = 0;i<PartitionNum;i++)
	{
		cout<<LeftFreePartition[i]<<"     ";
	}
	cout<<endl<<"分配程序情況:"<<endl;
	for (i = 0;i<PartitionNum;i++)
	{
		for (int j = 0;j<ProcessNum;j++)
		{
			if (NameProcessToPartition[j][i]!=NULL)
			{
				cout<<NameProcessToPartition[j][i]<<": (分割槽"<<i+1<<")"<<endl;
			}		
		}	
	}
	cout<<endl<<"********結束**********"<<endl;
}

int main()
{
	int chooseAlgorithm = 5;	
	while(chooseAlgorithm)
	{
		cout<<"請選擇實現的演算法:"<<endl;
		cout<<"*****  1 - 首次適應演算法     *****"<<endl;
		cout<<"*****  2 - 迴圈首次適應演算法 *****"<<endl;
		cout<<"*****  3 - 最佳適應演算法     *****"<<endl;
		cout<<"*****  4 - 最壞適應演算法     *****"<<endl;
		cout<<"*****  0 - 結束             *****"<<endl;

		cout<<"chooseAlgorithm = ";
		cin>>chooseAlgorithm;
		selectAlgorithm(chooseAlgorithm);
	}
	system("pause");
	return 0;
}