• 电梯调度的改进


    说明:

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

    改进部分说明:

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

    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");
    }
    
  • 相关阅读:
    选择结构
    Java基本语法
    Java开发实战经典
    限时福利丨全网最全Java视频教程合集(java学习路线+视频+配套资料)
    入选《2021爱分析·区域性银行数字化厂商全景报告》,网易云信助力南京银行打造转型标杆
    资讯|WebRTC M94 更新
    网易云信的音频共享技术 | 体验共享专题
    网易云信 NERTC 高清画质体验之 H.265的工程实践 | 体验共享技术专题
    Jvm-Sandbox-Repeater 推送配置详解
    Jvm-Sandbox-Repeater 拉取配置详解
  • 原文地址:https://www.cnblogs.com/mww123/p/5373894.html
Copyright © 2020-2023  润新知