电梯控制算法 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. 电梯控制算法(1)单电梯场景——简单扫描算法

    坐电梯小技巧   https://blog.csdn.net/nameofcsdn/article/details/106044619 电梯控制算法(1)单电梯场景--简单扫描算法   https:/ ...

  2. 电梯控制算法(4)单电梯场景——限层策略

    电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 电梯很多都有限层策略,主要是定差限层和高中低限层2种. 单电梯一般不 ...

  3. 电梯控制算法(2)单电梯场景——优化扫描算法

    电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 在实际情况下,电梯并不需要扫描所有的楼层,只需要扫描有乘客进出电梯的 ...

  4. 电梯控制算法(7)多电梯场景——两个等价电梯——动态指派

    电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 两个电梯是等价的,都是全部楼层可达的. 当有乘客在外面按电梯时,哪个 ...

  5. 电梯控制算法(8)多电梯场景——双电梯的空闲停靠

    电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 如果,两个电梯是等价的,那么,2个电梯的空闲停靠楼层是多少呢? 假设 ...

  6. 电梯控制算法(6)多电梯场景——两个等价电梯——静态指派

    电梯控制算法 https://blog.csdn.net/nameofcsdn/article/details/106874615 对于多电梯场景,首先我们考虑最简单的情况,即两个电梯是等价的,都是全 ...

  7. plc四层单电梯课程设计

    四层单电梯的PLC 控制 摘要:电梯作为我们日常生活中最常见也最必不可少的生活工具,它极大地方便了我们的生活.现代电梯主要由曳引机(绞车).导轨.对重装置.安全装置(如限速器.安全钳和缓冲器等).信号 ...

  8. STM32F4单电梯调度系统(扫描算法)

    这是第一次做嵌入式相关的东西,使用了STM32F401VE芯片,由于没有板子,只能用Proteus进行仿真,在实现过程中遇到了很多困难. 修改了定时器中断内容,把调度算法放到主函数中,定时器中断只是简 ...

  9. 基于TransformerFusion的单目场景重构

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨贝塔 来源丨韦心雕AI 今天小伙伴贝塔来给大家分享一下关于Transformer的单目场景重构的 ...

最新文章

  1. 数据结构---线段树
  2. linux 内核编译详解
  3. android SDK manager 无法获取更新版本列表
  4. [react] react中可以在render访问refs吗?为什么?
  5. QMessageBox改变大小
  6. python3哪个版本稳定-python的哪个版本稳定
  7. 计算机不能打开管理员用户输入窗口,win10系统管理员账户无法打开某些程序的设置技巧...
  8. 基于Python-turtle库绘图(汇总)
  9. anaconda下载
  10. 夜深人静写算法(十四)- 基数估计 (Cardinality Estimation)
  11. Java整型变量举例_java 整型常量和整型变量的问题
  12. 从2D图片生成3D点云
  13. 倾斜摄影超大场景的三维模型轻量化与三维展示效果的关系浅析
  14. 查看网络交换机光口的光功率
  15. jcp jsr_JCP EC 2011年特别选举候选人宣布
  16. 如何解决前后端token过期问题
  17. 扫拖一体洗地机哪个品牌好、家用洗地机品牌介绍
  18. hihocoder#1054之滑动解锁
  19. python对数函数定义域如何为一切实数_函数的定义域为一切实数
  20. Oracle开发者性能课第6课(如何创建物化视图)实验

热门文章

  1. 数据库函数依赖与候选码求解
  2. jquery给lable赋值
  3. Phoenix重磅 | Phoenix核心功能原理及应用场景介绍
  4. JavaWeb实现登录验证码
  5. python批处理文件编写_求大神用python写个批处理程序?
  6. M1安装gradle查看版本后失败的解决办法
  7. 关于PhotoShop中保存CMYK格式TIFF文件在GDI+错误地显示颜色的问题解决方法
  8. 浏览器被强制修改成 桔梗网—Google, Firefox
  9. 008-我的博友不锈钢钥匙扣上的随身金属外壳可启动U盘-20190413
  10. loghouse介绍