电梯调度的改进

说明:

由于时间的问题,上一篇博客中的电梯调度程序还不够很完善。利用星期日上午的时间做了部分的调整和改进。

改进部分说明:

改进的地方主要有两个部分:

1、接受多个用户同时输入请求;

2、多个用户可以同时进入电梯,并选择自己的目的楼层。

3、关于电梯运行状态的更改,由于多处用到这个部分,此处改为函数,避免重复,使代码精简。

具体实现说明:

1、多用户同时输入

其实当初在这个方面多做思考,程序的查找功能、电梯需要停靠楼层和电梯状态的更新都是用独立的函数实现的。所以想支持多个用户的输入也很简单,只需在原有的基础上加一个循环。循环调用用户的输入函数、电梯查找函数、以及电梯停靠标记。

cout << "几人输入";
cin >> c;
if (c > 0)
{
	for (int i = 0; i < c;i++)
		Inset();
}
change();

 2、多个用户同时进入电梯

此处的实现和多个用户同时输入基本一样,也是利用加循环的办法,只是此处需要更改的地方较多。

(1)乘客进电梯部分(函数void geiIn(int i))

首先需要用户输入几人进入电梯,然后再用for循环控制,循环体包括用户输入目的楼层,判断电梯是否到达目的楼层,如果到达标记为停靠。同时也要改变电梯里的人数,控制超重。

cout << "请输入几人进入电梯";
cin >> num;
for (int m = 0; m < num && a[i].ifFloor == 0; m++)
{
	int f;
        cout << "输入目的层数";
	cin >> f;
	if (f % 2 == a[i].serveFloor || a[i].serveFloor == 3)//此电梯是否到目的层
	{
		a[i].nowPeople++;
                ifFull(i);
		if (a[i].staut == 0)//电梯如果是暂停状态,更改目的状态
		{
			if (a[i].floor > f)
				a[i].staut = -1;
			if (a[i].floor < f)
				a[i].staut = 1;
		}
		a[i].inPeople[f] = 1;//标记目的层数
	}
	else
	{
		cout << "此电梯不到目的层";
	}
}
	

(2)乘客出电梯部分(函数void getOut(int i))

首先需要用户输入几人出电梯,然后再用for循环控制,循环体包括恢复电梯此楼层不需停靠(a[i].inPeople[a[i].floor] = -1),同时也要改变电梯里的人数。

cout << "请输入几人出电梯";
cin >> num;
for (int m = 0; m < num; m++)
{
	a[i].nowPeople--;
	ifFull(i);
	a[i].inPeople[a[i].floor] = -1;
}

 (3)电梯状态控制封装为函数

函数原型为:int ifRun(int i)。返回值为int类型,返回1表示电梯还需以现在的状态继续运行,返回0表示电梯更改为静止状态。实现方法主要是,判断电梯的是否外部响应和内部响应,也就是说要同时满足,电梯外没有用户需要,电梯内没有用户。即,数组inPeople[21]和outPeople[21]的值全部为-1.

int ifRun(int i)
{
	int flag1, flag2;
	flag1 = 1;
	flag2 = 1;
	for (int j = 0; j < 21; j++)//电梯是否需要继续运行
	{
		if (flag1 == 1 && a[i].inPeople[j] == -1)
			continue;
		else
		{
			flag1 = 0;
			break;
		}
	}
	for (int j = 0; j < 21; j++)
	{
		if (flag2 == 1 && a[i].outPeople[j] == -1)
			continue;
		else
		{
			flag2 = 0;
			break;
		}
	}
	if (flag1 == 1 && flag2 == 1)
	{
		a[i].staut = 0;
		return 0;
	}
	else
		return 1;
}

 程序调试及结果分析:

首先先对输入的数据进行说明以及结果预测:

4个用户输入->1)8 -1(8楼用户下楼请求)-> 3号电梯响应 -> 1人进入电梯 -> 目的楼层0 -> 1人出电梯

                    2)19 -1(19楼用户下楼请求)-> 1号电梯响应 -> 11人进入电梯(1号电梯最大载重为10,最后一人不能上电梯) -> 目的楼层全部为0 -> 1人出电梯

                    3)3 1(3楼用户上楼请求)-> 4号电梯响应 -> 2人进入电梯 -> 目的楼层5 -> 1人出电梯

                                                                                                    -> 目的楼层8-> 1人出电梯

                    4)7 1(3楼用户上楼请求)-> 2号电梯响应 -> 2人进入电梯 -> 目的楼层11 -> 1人出电梯

                                                                                                    -> 目的楼层12-> 此电梯不到目的层(2号电梯为单数电梯)

1、用户输入

2、电梯做出响应

3、19楼到了11人进入电梯,最后一人无法进入

4、7楼到了用户进入电梯,输入目的楼层,此电梯为单层服务

5、8楼到了,请输入几人进入电梯

6、5楼到了,请输入几人出电梯

7、电梯运行完整,恢复暂停状态,等待用户输入

总结:

这次主要对上次不完善的地方做了点改进,我也会和队友继续讨论,找到程序还存在的问题,并且找到解决办法,不断的完善。

源代码:

 

#include<iostream>
#include<Windows.h>
#include <conio.h>
using namespace std;
struct elevator
{
	int maxPeople;//电梯最大载重量
	int nowPeople;//电梯目前装载4人数
	int ifFloor;//是否超载(已满1、未满0)
	int serveFloor;//电梯服务楼层(全部3、单层1、双层0)
	int outPeople[21];//外部人按电梯请求楼层(数组下标表示楼层,数值值表示是否停靠。停靠1、不停靠-1)
	int inPeople[21];//电梯内部人按电梯请求楼层
	int staut;//上升1、下降-1、停止0
	int floor;//电梯目前楼层
};
struct elevator a[4];
int ifRun(int i)
{
	int flag1, flag2;
	flag1 = 1;
	flag2 = 1;
	for (int j = 0; j < 21; j++)//电梯是否需要继续运行
	{
		if (flag1 == 1 && a[i].inPeople[j] == -1)
			continue;
		else
		{
			flag1 = 0;
			break;
		}
	}
	for (int j = 0; j < 21; j++)
	{
		if (flag2 == 1 && a[i].outPeople[j] == -1)
			continue;
		else
		{
			flag2 = 0;
			break;
		}
	}
	if (flag1 == 1 && flag2 == 1)
	{
		a[i].staut = 0;
		return 0;
	}
	else
		return 1;
}
int number(int x)//取绝对值
{
	if (x < 0)
		return -x;
	else
		return x;
}
void Iint()//各个电梯初始化
{
	for (int i=0; i < 4; i++)
	{
		for (int j = 0; j < 21; j++)
		{
			a[i].inPeople[j] = -1;
			a[i].outPeople[j] = -1;
		}
		a[i].nowPeople = 0;
		a[i].ifFloor = 0;
	}
	a[0].maxPeople = 10;
	a[0].serveFloor = 3;
	a[0].staut = 0;
	a[0].floor = 20;
	a[1].maxPeople = 10;
	a[1].serveFloor = 1;
	a[1].staut = 0;
	a[1].floor = 9;
	a[2].maxPeople = 20;
	a[2].serveFloor = 0;
	a[2].staut = 0;
	a[2].floor = 10;
	a[3].maxPeople = 20;
	a[3].serveFloor = 3;
	a[3].staut = 0;
	a[3].floor = 1;
}
void gotoxy(HANDLE hOut, int x, int y)//光标移到指定位置
{
	COORD pos;
	pos.X = x;             //横坐标
	pos.Y = y;            //纵坐标
	SetConsoleCursorPosition(hOut, pos);
}
void ifFull(int i)//判断电梯是否超载
{
	if (a[i].maxPeople < a[i].nowPeople)
	{
		HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
		gotoxy(hOut, 0, 4);
		cout << "电梯已满!" << endl;
		Sleep(1000);
		gotoxy(hOut, 0, 4);
		cout << "                                                      ";
		a[i].ifFloor = 1;
		return;
	}
	else
	{
		a[i].ifFloor = 0;
		return;
	}
}
void getIn(int i)//进入电梯
{
	a[i].outPeople[a[i].floor] = -1;
	ifRun(i);
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
	gotoxy(hOut, 0, 5);
	int num;
	cout << "请输入几人进入电梯";
	cin >> num;
	gotoxy(hOut, 0, 5);
	cout << "                                                      ";
	for (int m = 0; m < num && a[i].ifFloor == 0; m++)
	{
		int f;
		gotoxy(hOut, 0, 3);
		cout << "输入目的层数";
		cin >> f;
		gotoxy(hOut, 0, 3);
		cout << "                                                      ";
		if (f % 2 == a[i].serveFloor || a[i].serveFloor == 3)//此电梯是否到目的层
		{
			a[i].nowPeople++;
            ifFull(i);
			if (a[i].staut == 0)//电梯如果是暂停状态,更改目的状态
			{
				if (a[i].floor > f)
					a[i].staut = -1;
				if (a[i].floor < f)
					a[i].staut = 1;
			}
			a[i].inPeople[f] = 1;//标记目的层数
		}
		else
		{
			HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
			gotoxy(hOut, 0, 4);
			cout << "此电梯不到目的层";
			Sleep(1000);
			gotoxy(hOut, 0, 4);
			cout << "                                                      ";
		}
	}
}
void getOut(int i)//出电梯
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
	int num;
	gotoxy(hOut, 0, 5);
	cout << "请输入几人出电梯";
	cin >> num;
	gotoxy(hOut, 0, 5);
	cout << "                                                      ";
	for (int m = 0; m < num; m++)
	{
		a[i].nowPeople--;
		ifFull(i);
		a[i].inPeople[a[i].floor] = -1;
	}
}
void display()//结果显示
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
	for (int i = 0, j = 0; i < 4; i++,j=j+6)
	{
		gotoxy(hOut, j, 0);
		if (a[i].staut == 1)
		{
			if (a[i].floor>=10)
				cout << "↑" << a[i].floor;
			else
				cout << "↑0" << a[i].floor;
		}
		if (a[i].staut == 0)
		{
			if (a[i].floor >= 10)
				cout << "__" << a[i].floor;
			else
				cout << "__0" << a[i].floor;
		}
		if (a[i].staut == -1)
		{
			if (a[i].floor >= 10)
				cout << "↓" << a[i].floor;
			else
				cout << "↓0" << a[i].floor;
		}
	}
}
void change()//更新电梯状态
{
	int flag, i;
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
	for (i = 0; i < 4; i++)
	{
		if (a[i].staut == 1)//上升状态的电梯
		{
			if (a[i].inPeople[a[i].floor] == 1)
			{
				gotoxy(hOut, 0, 4);
				cout << a[i].floor << "到了! 乘客出电梯";
				Sleep(1000);
				gotoxy(hOut, 0, 4);
				cout << "                                                      ";
				getOut(i);
			}
			if (a[i].outPeople[a[i].floor] == 1)
			{
				gotoxy(hOut, 0, 4);
				cout << a[i].floor << "到了! 乘客进入电梯";
				Sleep(1000);
				gotoxy(hOut, 0, 4);
				cout << "                                                      ";
				getIn(i);
			}
			flag = ifRun(i);
			if (flag==1)
				a[i].floor++;//电梯继续上行
		}
		if (a[i].staut == -1)//下降状态的电梯
		{
			if (a[i].inPeople[a[i].floor] == 1)
			{
				gotoxy(hOut, 0, 4);
				cout << a[i].floor << "到了! 乘客出电梯";
				Sleep(1000);
				gotoxy(hOut, 0, 4);
				cout << "                                                      ";
				getOut(i);
			}
			if (a[i].outPeople[a[i].floor] == 1)
			{
				gotoxy(hOut, 0, 4);
				cout << a[i].floor << "到了! 乘客进入电梯";
				Sleep(1000);
				gotoxy(hOut, 0, 4);
				cout << "                                                      ";
				getIn(i);
			}
			flag = ifRun(i);
			if (flag == 1)
				a[i].floor--;//电梯继续下降
		}
	}
	display();
}
int ifSever(int floor, int direction, int elevator)//判断电梯是否相应此用户
{
	if (a[elevator].ifFloor == 0)//不超载
	{
		if (a[elevator].serveFloor == 3 || floor % 2 == a[elevator].serveFloor)//全部和双层
		{
			if (a[elevator].staut == 0)//停止状态
				return 1;
			if (a[elevator].staut == 1 && a[elevator].staut == direction)//上升且用户也上升
			{
				if (a[elevator].floor <= floor)
					return 1;
				else
					return 0;
			}
			if (a[elevator].staut == -1 && a[elevator].staut == direction)//下降且用户也下降
			{
				if (a[elevator].floor >= floor)
					return 1;
				else
					return 0;
			}
			return 0;
		}
		else
			return 0;
	}
	else
		return 0;
}
int search(int floor,int direction)//查询哪个电梯为用户服务
{
	int min[4] = { 100, 100, 100, 100 };
	int flag;
	int x;
	for (int i = 0; i < 4; i++)
	{
		flag = ifSever(floor, direction, i);
		if (flag==1)//计算电梯运行距离
		{
			x = a[i].floor - floor;
			min[i] = number(x);
		}
		else
			continue;
	}
	int temp, num;
	temp = min[0];
	num = 0;//标记电梯号
	for (int i = 1; i < 4; i++)//计算最近楼层
	{
		if (min[i] < temp)
		{
			temp = min[i];
			num = i;
		}
	}
	if (temp != 100)
	{
		a[num].outPeople[floor] = 1;
		if (a[num].staut==0)
		{
			if (a[num].floor > floor)
				a[num].staut = -1;
			if (a[num].floor < floor)
				a[num].staut = 1;
			if (a[num].floor == floor)
				a[num].staut = direction;
		}
		return 1;
	}
	return 0;
}
void Inset()//用户输入
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//定义显示器句柄变量
	int peopleFloor, peopleDirection, flag;
	gotoxy(hOut, 0, 2);
	cout << "输入请求的楼层数和方向(1为向上,-1为向下)";
	cin >> peopleFloor;
	cin >> peopleDirection;
	gotoxy(hOut, 0, 2);
	cout << "                                                      ";
	flag = search(peopleFloor, peopleDirection);
	if (flag == 1)//如果查询到服务的电梯
		return;
	else
	{
		while (flag == 0)
		{
			change();
			flag = search(peopleFloor, peopleDirection);
		}
	}
}
void main()
{
	Iint();
	display();
	int c;
	while (1)
	{
		HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
		gotoxy(hOut, 0, 1);
		cout << "几人输入";
		cin >> c;
		if (c > 0)
		{
			for (int i = 0; i < c;i++)
				Inset();
		}
		change();
	}
	system("pause");
}

 

posted on 2016-04-10 13:19  w11w  阅读(314)  评论(1编辑  收藏  举报