电梯控制算法(5)单电梯场景——屏蔽较近楼层进梯请求
电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615
我们会遇到这样一种场景:
电梯在下行的时候,5楼乘客在外面按钮下行按钮,如果此时电梯在8楼及以上,到了5楼会开门接客,
但是如果此时电梯在7楼或者6楼,电梯就会跳过5楼,等到了1楼再回来接5楼乘客。
但是如果7楼停靠了,刚离开7楼的时候5楼乘客在外面按钮下行按钮,这时电梯又会停靠5楼开门。
我推测,这是因为加速度的限制,电梯为了保证平稳运行加速度不能过大。
关于电梯平稳控制,据悉有多种不同的算法,并不统一。
为了简化问题,我假设平稳控制的逻辑如下:
如果电梯从x楼开始下行,当处于x和x-1之间时就屏蔽x-1楼层的进梯请求,当x越过x-1之后处于y和y-1之间时,就屏蔽y-2楼层的进梯请求。一旦电梯在某层停靠(无论是因为有出电梯的,还是因为有进电梯的),x就刷新了值,屏蔽楼层情况重新计算。
上行同理。
那么屏蔽之后,什么时候取消屏蔽呢?
只要电梯在任意楼层停靠,那么此前的所有屏蔽都会立刻取消。
所以,在之前的代码基础上,我们还需要一个额外的量,实时记录当前电梯运动的起点,还需要给每个楼层加一个标签,记录是否被屏蔽。
这里,我的做法是把flag数组进行含义扩充,最后2个比特位仍然是之前的含义,第三个比特位用来表示是否被屏蔽。
代码:
#include<iostream>
#include<windows.h>
#include <thread>
#include<time.h>
#include<math.h>
using namespace std;#define LEVEL 16
#define PARK 1 //空闲停靠楼层
int flag[LEVEL + 1]; //1到Level层的外部输入,取值为0,1,2,3,其中0表示无乘客,1表示有乘客上行,2表示有乘客下行,3表示既有上行又有下行//取值为4-7的话,对应0-3的状态,但是是处于屏蔽状态
int dest[LEVEL + 1]; //目的楼层的记录,取值为0,1,其中0表示不是目的地,1表示是目的地
int levelMax, levelMin; //levelMax是进出电梯最大楼层,levelMin是进出电梯最小楼层
int avail[LEVEL + 1]; //可达楼层,取值为0,1,其中0表示不是可达楼层,1表示是可达楼层
int loc = 1; //当前楼层
int sta;//当前电梯运动的起点bool getBlock(int lev)//查询该楼层是否被屏蔽
{return ((flag[lev]) & 4);
}
void setBlock(int lev)//设置输入楼层是否被屏蔽的状态
{if (getBlock(lev))return;if (loc == sta && abs(lev - sta) <= 1)flag[lev] += 4;if(abs(loc-sta)==1 && abs(lev-sta)<=2)flag[lev] += 4;
}
void clearBlock()
{for (int i = 1; i <= LEVEL; i++){if (getBlock(i))flag[i] -= 4;}
}
void input()//输入楼层和标志,标志1-3是外部输入上下行,其他标志是内部输入目标楼层
{int lev, fla;while (cin >> lev >> fla) if (lev > 0 && lev <= LEVEL){if (avail[lev] == 0)continue;if (fla > 0 && fla <= 3){flag[lev] = fla; //外部输入setBlock(lev);}else dest[lev] = 1;//内部输入}
}
void upPull(int loc)//上行接客
{flag[loc]--;cout << "上行接客" << loc << endl;sta = loc;clearBlock();
}
void downPull(int loc)//下行接客
{flag[loc] -= 2;cout << "下行接客" << loc << endl;sta = loc;clearBlock();
}
void push(int loc)//送客
{dest[loc] = 0;cout << "送客" << loc << endl;sta = loc;clearBlock();
}
int getMax()//进出电梯最大楼层
{levelMax = 0;for (int loc = 1; loc <= LEVEL; loc++){if (flag[loc] && !getBlock(loc) || dest[loc])levelMax = max(levelMax, loc);}return levelMax;
}
int getMin()//进出电梯最小楼层
{levelMin = LEVEL + 1;for (int loc = 1; loc <= LEVEL; loc++){if (flag[loc] && !getBlock(loc) || dest[loc])levelMin = min(levelMin, loc);}return levelMin;
}
bool isPark()//是否为空闲状态
{return getMax() <= 0 || getMax() > LEVEL;
}
int getMax2()//进出电梯最大楼层
{if (isPark())return PARK;return getMax();
}
int getMin2()//进出电梯最小楼层
{if (isPark())return PARK;return getMin();
}
void initAvail()//初始化可达楼层设定
{for (int i = 1; i <= LEVEL; i++){avail[i] = 1;}
}
void run()//电梯运行主控逻辑
{initAvail(); cout << " 当前楼层" << loc << endl;while (1){while (loc <= getMax2()){if ((flag[loc]&1) && !getBlock(loc))upPull(loc);if (dest[loc])push(loc);Sleep(1000);if (loc < getMax2())loc++;else break;cout << " 当前楼层" << loc << endl;}while (loc >= getMin2()){if ((flag[loc]&2) && !getBlock(loc))downPull(loc);if (dest[loc])push(loc);Sleep(1000);if (loc > getMin2())loc--;else break;cout << " 当前楼层" << loc << endl;}}
}int main()
{thread t1(input);thread t2(run);t1.join();t2.join();return 0;
}
2个示例:
电梯控制算法(5)单电梯场景——屏蔽较近楼层进梯请求相关推荐
- 电梯控制算法(1)单电梯场景——简单扫描算法
坐电梯小技巧 https://blog.csdn.net/nameofcsdn/article/details/106044619 电梯控制算法(1)单电梯场景--简单扫描算法 https:/ ...
- 电梯控制算法(4)单电梯场景——限层策略
电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 电梯很多都有限层策略,主要是定差限层和高中低限层2种. 单电梯一般不 ...
- 电梯控制算法(2)单电梯场景——优化扫描算法
电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 在实际情况下,电梯并不需要扫描所有的楼层,只需要扫描有乘客进出电梯的 ...
- 电梯控制算法(7)多电梯场景——两个等价电梯——动态指派
电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 两个电梯是等价的,都是全部楼层可达的. 当有乘客在外面按电梯时,哪个 ...
- 电梯控制算法(8)多电梯场景——双电梯的空闲停靠
电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 如果,两个电梯是等价的,那么,2个电梯的空闲停靠楼层是多少呢? 假设 ...
- 电梯控制算法(6)多电梯场景——两个等价电梯——静态指派
电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 对于多电梯场景,首先我们考虑最简单的情况,即两个电梯是等价的,都是全 ...
- plc四层单电梯课程设计
四层单电梯的PLC 控制 摘要:电梯作为我们日常生活中最常见也最必不可少的生活工具,它极大地方便了我们的生活.现代电梯主要由曳引机(绞车).导轨.对重装置.安全装置(如限速器.安全钳和缓冲器等).信号 ...
- STM32F4单电梯调度系统(扫描算法)
这是第一次做嵌入式相关的东西,使用了STM32F401VE芯片,由于没有板子,只能用Proteus进行仿真,在实现过程中遇到了很多困难. 修改了定时器中断内容,把调度算法放到主函数中,定时器中断只是简 ...
- 基于TransformerFusion的单目场景重构
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨贝塔 来源丨韦心雕AI 今天小伙伴贝塔来给大家分享一下关于Transformer的单目场景重构的 ...
最新文章
- 数据结构---线段树
- linux 内核编译详解
- android SDK manager 无法获取更新版本列表
- [react] react中可以在render访问refs吗?为什么?
- QMessageBox改变大小
- python3哪个版本稳定-python的哪个版本稳定
- 计算机不能打开管理员用户输入窗口,win10系统管理员账户无法打开某些程序的设置技巧...
- 基于Python-turtle库绘图(汇总)
- anaconda下载
- 夜深人静写算法(十四)- 基数估计 (Cardinality Estimation)
- Java整型变量举例_java 整型常量和整型变量的问题
- 从2D图片生成3D点云
- 倾斜摄影超大场景的三维模型轻量化与三维展示效果的关系浅析
- 查看网络交换机光口的光功率
- jcp jsr_JCP EC 2011年特别选举候选人宣布
- 如何解决前后端token过期问题
- 扫拖一体洗地机哪个品牌好、家用洗地机品牌介绍
- hihocoder#1054之滑动解锁
- python对数函数定义域如何为一切实数_函数的定义域为一切实数
- Oracle开发者性能课第6课(如何创建物化视图)实验