電梯控制算法(1)單電梯場景——簡單掃描算法

電梯系列,自然要從最簡單的單電梯場景開始。

 

1,電梯狀態

電梯狀態可以分爲空閒、開門、上下移動三個狀態,爲了便於理解,我們可以忽略開門狀態。

也就是說,電梯分爲空閒狀態和移動狀態。

 

2,樓層

一般有2種,一種是1~n層,沒有地下,一種是1~n層和-1~-m層,有地下m層。

在不影響核心研究內容的前提下,默認只考慮第一種,1~n層,沒有地下。

 

3,電梯輸入

電梯外輸入一般有2種,一種是上下按鈕,一種是樓層數值按鈕。

電梯內輸入都是直接按樓層。

 

4,比較容易想到的控制算法

先來先服務算法(FCFS)、最短尋找時間優先算法(SSTF)、掃描算法(SCAN)

這三個都是和操作系統的調度算法相通的,我就不解釋含義了。

先來先服務算法會造成效率很低,最短尋找時間優先算法會造成飢餓等待,都是不可取的。

所以電梯都是基於掃描算法進行優化的。

 

5,簡單掃描算法

如何模擬呢?

可以抽象爲2個函數,一個是輸入,包括外部輸入和內部輸入,一個是輸出,顯示電梯實時狀態。

利用多線程,可以實時控制輸入和輸出函數同時運行。

本來是構思2個輸入函數的,因爲多線程不熟,避免輸入流的麻煩,就合到一起了,用控制字來描述。

每次輸入lev和fla,如果fla爲0,表示內部輸入要去lev樓,如果fla爲1,2,3,表示lev樓有乘客按了上下行

注意:

(1)代碼健壯性很弱,需要嚴格按照預定方式輸入。

(2)外部輸入的方式是直接覆蓋式的,測試的時候需要人工避免一些奇怪的值。

(3)需要人工控制輸入時間,並不是一開始就全部把數據粘貼進去

#include <thread>
#include<time.h>

#define LEVEL 6
int flag[LEVEL + 1];  //1到Level層的外部輸入,取值爲0,1,2,3,其中0表示無乘客,1表示有乘客上行,2表示有乘客下行,3表示既有上行又有下行
int dest[LEVEL + 1];  //目的樓層的記錄,取值爲0,1,其中0表示不是目的地,1表示是目的地

void input()
{
	int lev, fla;
	while (cin >> lev >> fla) if (lev > 0 && lev <= LEVEL)
	{
		if(fla>0 && fla<=3)flag[lev] = fla; //外部輸入
		else dest[lev] = 1;//內部輸入
	}
}
void upPull(int loc)//上行接客
{
	flag[loc]--;
	cout << "上行接客"<<loc<<endl;
}
void downPull(int loc)//下行接客
{
	flag[loc] -= 2;
	cout << "下行接客" << loc << endl;
}
void push(int loc)//送客
{
	dest[loc] = 0;
	cout << "送客" << loc << endl;
}

void run()
{
	int loc = 1;
	while (1)
	{
		for (loc = 1; loc <= LEVEL; loc++)
		{
			cout << "    當前樓層" << loc << endl;
			if (flag[loc] == 1 || flag[loc] == 3)upPull(loc);
			if (dest[loc])push(loc);
			Sleep(1000);
		}
		for (loc = LEVEL; loc>0; loc--)
		{
			cout << "    當前樓層" << loc << endl;
			if (flag[loc] == 2 || flag[loc] == 3)downPull(loc);
			if (dest[loc])push(loc);
			Sleep(1000);
		}
	}
}

int main()
{
	thread t1(input);
	thread t2(run);
	t1.join();
	t2.join();
	return 0;
}

模擬示例:

示例1

示例2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章