优化电梯调度1:实现高效优先级队列算法

概述:

写作原由:

今天早上上班时候,等电梯等了快十分钟,故此猜想这个电梯运行的算法到底是啥,当年面试工作时候,给出笔试题也是有这个电梯算法的,故此需要坐下来慢慢想想。

随着高层建筑的增多,电梯作为连接各层的重要交通工具,其调度系统的效率直接影响到人们的日常生活和工作效率。一个优秀的电梯调度算法不仅能够减少乘客的等待时间,还能提高电梯系统的整体运行效率。本文将探讨如何通过实现一个基于优先级队列的电梯调度算法来优化电梯服务。

简单轮询算法(Round Robin)

在电梯系统中意味着电梯会按照固定的顺序访问每一层,不论该层是否有乘客请求。以下是一个用Java实现的简单轮询电梯调度算法的示例:

 

java

复制代码

public class RoundRobinElevator { private int currentFloor; // 当前电梯所在楼层 private final int topFloor; // 电梯系统的最高楼层 private final int bottomFloor; // 电梯系统的最底楼层 private boolean movingUp; // 电梯移动方向,true为向上,false为向下 public RoundRobinElevator(int bottomFloor, int topFloor) { this.bottomFloor = bottomFloor; this.topFloor = topFloor; this.currentFloor = bottomFloor; // 假设电梯初始在最底层 this.movingUp = true; // 初始向上移动 } // 电梯开始运行 public void startElevator() { while (true) { // 电梯持续运行 visitFloor(currentFloor); if (movingUp) { if (currentFloor < topFloor) { currentFloor++; } else { movingUp = false; // 到达顶层,改变方向 } } else { if (currentFloor > bottomFloor) { currentFloor--; } else { movingUp = true; // 到达底层,改变方向 } } // 模拟电梯在楼层间移动的时间 try { Thread.sleep(1000); } catch(InterruptedException e) { e.printStackTrace(); } } } // 电梯访问楼层 private void visitFloor(int floor) { System.out.println("电梯到达楼层: " + floor); // 在这里可以添加开门、关门的逻辑 // 以及乘客进出电梯的逻辑 } public static void main(String[] args) { RoundRobinElevator elevator = new RoundRobinElevator(1, 10); elevator.startElevator(); } }

电梯从最底层开始,逐层向上移动,直到顶层,然后改变方向向下移动,直到底层,如此循环。每到一层,就调用visitFloor方法模拟电梯到达该层的行为。这种实现是是最简单暴力的实现。

响应轮询

 

java

复制代码

import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; /** * @Author derek_smart * @Date 2024/6/5 9:01 * @Description * <p> 响应轮询 */ public class RealWorldElevator implements Runnable { //表示电梯当前所在的楼层 private int currentFloor; // 电梯可以到达的最高楼层。 private final int topFloor; // 一个 `AtomicBoolean` 实例,用于控制电梯运行的状态。由于它是原子操作,可以确保线程安全 private final AtomicBoolean running = new AtomicBoolean(true); // 一个线程安全的 `ConcurrentLinkedQueue` 队列,用于存储电梯的呼叫请求。 private final ConcurrentLinkedQueue<Integer> requests = new ConcurrentLinkedQueue<>(); public RealWorldElevator(int currentFloor, int topFloor) { this.currentFloor = currentFloor; this.topFloor = topFloor; } /** * 允许外部调用电梯到指定楼层。如果楼层在电梯服务范围内,请求会被添加到请求队列中 * @param floor */ public void callElevator(int floor) { if (floor >= 0 && floor <= topFloor) { requests.add(floor); } } /** * 允许外部停止电梯运行。它将 `running` 标志设置为 `false`, * 使得电梯在完成当前操作后停止运行。 */ public void stopElevator() { running.set(false); } @Override public void run() { while (running.get()) { //只要 `running` 为 `true`, // 电梯就会处理请求队列中的下一个请求。 if (!requests.isEmpty()) { Integer nextFloor = requests.poll(); moveToFloor(nextFloor); } // Sleep for a short time to simulate waiting for the next request try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } /** * 控制电梯移动到目标楼层的方法。它会逐层移动电梯,直到到达目标楼层,并在每层停留一段时间模拟乘客进出。 * @param destinationFloor */ private void moveToFloor(int destinationFloor) { while (currentFloor != destinationFloor && running.get()) { if (currentFloor < destinationFloor) { // Move up currentFloor++; } else { // Move down currentFloor--; } // Simulate the time it takes to move between floors try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("Elevator is at floor: " + currentFloor); } // Simulate stopping at the floor if (running.get()) { openDoors(); // Simulate time for passengers to enter/exit try { Thread.sleep(3000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } closeDoors(); } } /** * 模拟电梯在楼层开门 */ private void openDoors() { System.out.println("Opening doors at floor: " + currentFloor); } /** * 模拟电梯在楼层关门。 */ private void closeDoors() { System.out.println("Closing doors at floor: " + currentFloor); } public static void main(String[] args) throws InterruptedException { RealWorldElevator elevator = new RealWorldElevator(0, 10); Thread elevatorThread = new Thread(elevator); elevatorThread.start(); // Simulate some calls to the elevator elevator.callElevator(3); elevator.callElevator(7); elevator.callElevator(5); // Allow the elevator to process the calls Thread.sleep(20000); // Stop the elevator elevator.stopElevator(); elevatorThread.join(); } }

企业微信截图_17175530746839.png

创建了一个RealWorldElevator类,它实现了Runnable接口,使得电梯可以在自己的线程中运行。 电梯接受楼层的请求并将它们添加到一个线程安全的队列中。 当运行标志runningtrue时,电梯会处理队列中的请求,移动到相应的楼层,并模拟开关门以及乘客进出的时间。

使用了AtomicBoolean来控制电梯的运行状态,并提供了一个stopElevator方法来优雅地停止电梯。 电梯在移动到目标楼层时会检查running的状态,以确保在电梯被停止时能够立即响应。此外,通过捕获InterruptedException来正确处理线程中断。

优先级轮询:

在传统的电梯调度系统中,电梯可能会按照简单的先来先服务(FCFS)原则或是固定的轮询方式响应乘客的请求,这些方法在乘客流量较低时表现尚可,但在高峰时段或特殊情况下,可能无法高效地处理乘客的需求。为了解决这一问题,提出了一种高级电梯调度算法,该算法采用优先级队列来管理请求,根据请求的紧急程度和乘客的目的楼层智能地调度电梯。

 

java

复制代码

import java.util.PriorityQueue; import java.util.Comparator; import java.util.concurrent.atomic.AtomicBoolean; /** * @Author derek_smart * @Date 2024/6/5 9:41 * @Description * <p> 带优先级轮询 */ public class AdvancedElevator implements Runnable { private int currentFloor; private final int topFloor; private final AtomicBoolean running = new AtomicBoolean(true); private final PriorityQueue<ElevatorRequest> requestQueue; public AdvancedElevator(int currentFloor, int topFloor) { this.currentFloor = currentFloor; this.topFloor = topFloor; // Define the comparator for the priority queue based on priority and distance Comparator<ElevatorRequest> requestComparator = Comparator .comparingInt(ElevatorRequest::getPriority) .thenComparingInt(req -> Math.abs(req.getFloor() - currentFloor)); this.requestQueue = new PriorityQueue<>(requestComparator); } public void callElevator(int floor, int priority) { if (floor >= 0 && floor <= topFloor) { requestQueue.add(new ElevatorRequest(floor, priority)); } } public void stopElevator() { running.set(false); } @Override public void run() { while (running.get()) { ElevatorRequest nextRequest = requestQueue.poll(); if (nextRequest != null) { moveToFloor(nextRequest.getFloor()); } // Sleep for a short time to simulate waiting for the next request try { Thread.sleep(500); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } // Existing methods: moveToFloor, openDoors, closeDoors private static class ElevatorRequest { private final int floor; private final int priority; public ElevatorRequest(int floor, int priority) { this.floor = floor; this.priority = priority; } public int getFloor() { return floor; } public int getPriority() { return priority; } } /** * 控制电梯移动到目标楼层的方法。它会逐层移动电梯,直到到达目标楼层,并在每层停留一段时间模拟乘客进出。 * @param destinationFloor */ private void moveToFloor(int destinationFloor) { while (currentFloor != destinationFloor && running.get()) { if (currentFloor < destinationFloor) { // Move up currentFloor++; } else { // Move down currentFloor--; } // Simulate the time it takes to move between floors try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("Elevator is at floor: " + currentFloor); } // Simulate stopping at the floor if (running.get()) { openDoors(); // Simulate time for passengers to enter/exit try { Thread.sleep(3000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } closeDoors(); } } /** * 模拟电梯在楼层开门 */ private void openDoors() { System.out.println("Opening doors at floor: " + currentFloor); } /** * 模拟电梯在楼层关门。 */ private void closeDoors() { System.out.println("Closing doors at floor: " + currentFloor); } public static void main(String[] args) throws InterruptedException { AdvancedElevator elevator = new AdvancedElevator(0, 10); Thread elevatorThread = new Thread(elevator); elevatorThread.start(); // Simulate some calls to the elevator elevator.callElevator(3,3); elevator.callElevator(7,1); elevator.callElevator(5,10); // Allow the elevator to process the calls Thread.sleep(20000); // Stop the elevator elevator.stopElevator(); elevatorThread.join(); } }

image.png

 首先定义了一个 ElevatorRequest 类来表示电梯的请求,它包含请求的楼层和一个优先级属性。优先级可以根据不同的标准来设定,例如乘客的特殊需求、请求发出的时间,或者是基于预测模型的高峰时段流量。接着,使用一个优先级队列 requestQueue 来存储和排序这些请求。队列中的请求会根据优先级以及与电梯当前楼层的距离进行排序,确保电梯总是首先响应最紧迫的请求。

电梯的运行逻辑被封装在 run 方法中,它会循环检查优先级队列,取出并处理最高优先级的请求。通过调用 moveToFloor 方法,电梯会移动到请求的楼层,并执行开门和关门操作。这个过程模拟了电梯响应请求并搭载乘客的行为。为了优雅地停止电梯,引入了一个原子布尔标志 running,它可以安全地控制电梯的启动和停止。

此外,为了应对高峰时段的乘客流量,可以进一步扩展此算法,结合历史数据和流量预测模型来动态调整请求的优先级。例如,在上班高峰时段,可以提高通往办公室楼层的请求优先级,而在下班高峰时段,则优先响应通往地面层的请求。

总结:

总结来说,通过实施基于优先级队列的电梯调度算法,可以显著提高电梯系统的响应速度和乘客满意度,特别是在高峰时段和紧急情况下。这种智能化的调度方法为现代建筑中的电梯运输提供了一种高效、可靠的解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/684795.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

matrix-breakout-2-morpheus vulnhub靶场

端口扫描 80 81 需要用户名密码登录 目录扫描 robots.txt 妹用 找不到利用点&#xff0c;换个扫描器再扫 发现新的文件 graffiti.txt graffiti.php 输入的数据Post后会回显到页面上 抓包看看&#xff0c;居然直接传文件路径 发现我们post的数据被写入了graffiti.…

一种简单的借助微信扫码登录

公司内部登录一些网页、小工具&#xff0c;使用微信登录&#xff0c;可以保证安全又减少了输密码的麻烦。 需要使用两个码 左边的码是固定的&#xff0c;右边的是动态生成的 左边码&#xff1a;小程序后台生成的带参数的小程序码&#xff0c;带了一个自定义的参数fromscan1 流…

芒果YOLOv8改进169:即插即用 | 秩引导的块设计核心CIB结构,设计一种秩引导的块设计方案,旨在通过紧凑型架构设计减少被显示为冗余的阶段的复杂性

💡🚀🚀🚀本博客 秩引导的块设计,设计了一种秩引导的块设计方案,旨在通过紧凑型架构设计减少被显示为冗余的阶段的复杂性 :内含源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 文章目录 即插即用|秩引导的块设计|最新改进 YOLOv8 代码改进论文理论YOLO…

探索ChatGPT-4在解决化学知识问题上的研究与应用

1. 概述 近年来&#xff0c;人工智能的发展主要集中在 GPT-4 等大型语言模型上。2023 年 3 月发布的这一先进模型展示了利用广泛知识应对从化学研究到日常问题解决等复杂挑战的能力。也开始进行研究&#xff0c;对化学的各个领域&#xff0c;从化学键到有机化学和物理化学&…

单轴测径仪和双轴测径仪的区别

关键字&#xff1a;单轴测径仪、双轴测径仪、单轴双轴的结构差异、功能区别、应用场景、测量精度、测头、外径尺寸检测、 单轴测径仪和双轴测径仪在多个方面存在显著的区别&#xff0c;这些区别主要体现在其结构、功能、应用场景以及测量精度上。 首先&#xff0c;从结构上来…

Zookeeper复习

一、入门 1、概念 zookeeper文件系统通知机制 2.特点 1&#xff09;、一个领导者&#xff0c;多个跟随者组成的集群。 2&#xff09;、集群中只要有半数以上存活机制&#xff0c;zookeeper集群能正产服务。zk适合安装奇数台。 3&#xff09;、全局数据一致&#xff1a;每…

【智能算法】大蔗鼠算法(GCRA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;JO Agushaka受到自然界中大蔗鼠在交配季节和非交配季节觅食行为启发&#xff0c;提出了大蔗鼠算法&#xff08;Greater Cane Rat Algorithm, GCRA&#xff09;。 2.算法…

Covalent迁移以太坊并最大化倍数后,委托质押空间以创纪录速度填满

Covalent Network&#xff08;CQT&#xff09;&#xff0c;作为领先的模块化数据基础设施服务商&#xff0c;自豪地宣布在其质押生态系统中达成了一项重要里程碑。在完成质押最大奖励倍数变更仅一周内&#xff0c;质押空间的质押率已达成 96.74%。这一显著成就&#xff0c;突显…

PaaS平台未来发展的新篇章

中国云计算行业保持快速发展态势。根据中国信通院数据预测&#xff0c;伴随着经济回暖&#xff0c;全球云计算市场增长率将出现反弹&#xff0c;到2025年市场规模将超过6000亿美元。 在这个数字化时代的大背景下&#xff0c;企业不断探索将PaaS、SaaS、AI以及可组装的理念相互…

下载安装node.js,查看node.js版本

目录 一、下载安装node.js 二、查看node.js版本 三、使用nvm管理node.js版本 一、下载安装node.js 文档 nodejs中文网•学习教程•入门•如何安装 Nodejshttps://nodejs.cn/en/learn/getting-started/how-to-install-nodejs 步骤 1.进入node.js官网 nodejshttps://nodejs.…

原来Stable Diffusion是这样工作的

stable diffusion是一种潜在扩散模型&#xff0c;可以从文本生成人工智能图像。为什么叫做潜在扩散模型呢&#xff1f;这是因为与在高维图像空间中操作不同&#xff0c;它首先将图像压缩到潜在空间中&#xff0c;然后再进行操作。 在这篇文章中&#xff0c;我们将深入了解它到…

【Python】教你彻底了解Python中的正则表达式

​​​​ 文章目录 一、正则表达式的基本概念1. 元字符2. 特殊序列 二、Python中正则表达式的使用方法1. 导入re模块2. 匹配&#xff08;match&#xff09;3. 搜索&#xff08;search&#xff09;4. 查找所有匹配&#xff08;findall&#xff09;5. 替换&#xff08;sub&#…

新零售智能售卖教学实训沙盘内容介绍

新零售智能售卖教学实训沙盘是服务数据分析的教学工具。通过该沙盘&#xff0c;能够让学生了解数据分析在新零售行业智能售卖业务场景的应用流程。使用新零售智能售卖教学实训沙盘进行教学&#xff0c;一方面能够让老师的教学内容更加贴近实际应用&#xff0c;将教学场景具象化…

达摩院重大“遗产”!fluxonium量子比特初始化300纳秒且保真度超过99%

通用量子计算机开发的主要挑战之一是制备量子比特。十多年来&#xff0c;研究人员在构建量子计算机的过程中主要使用了transmon量子比特&#xff0c;这也是迄今为止商业上最成功的超导量子比特。 但与业界多数选择transmon量子比特不同&#xff0c;&#xff08;前&#xff09;…

C语言:详解gcc驱动程序完成编译、汇编、链接的过程

相关阅读 C语言https://blog.csdn.net/weixin_45791458/category_12423166.html?spm1001.2014.3001.5482 gcc是一个命令&#xff0c;严格意义上说&#xff0c;它只是一个驱动程序&#xff0c;而不是一个编译器。gcc负责调用GNU工具链中的预处理器、编译器、汇编器、链接器等工…

X-Caps

用于对视觉属性进行编码的胶囊 补充信息 数据集太大&#xff0c;不建议复现

机器学习笔记 - 本地windows 11 + PyCharm运行stable diffusion流程简述

一、环境说明 硬件:本地电脑windows11、32.0 GB内存、2060的6G的卡。 软件:本地有一个python环境,主要是torch 2.2.2+cu118 二、准备工作 1、下载模型 https://huggingface.co/CompVishttps://huggingface.co/CompVis 进入上面的网址,我这里下载的是这个里面的 …

el-input添加clearable属性 输入内容时会直接撑开

<el-inputclearablev-if"item.type number || item.type text":type"item.type":placeholder"item.placeholder":prefix-icon"item.icon || "v-model.trim"searchform[item.prop]"></el-input>解决方案 添加c…

LLM的基础模型6:注意力机制

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

DVWA-XSS(Stored)

Low 观察后端代码&#xff0c;对输入进行了一些过滤和转义。trim(string,charlist) 函数用于移除字符串两侧的空白字符或其他预定义字符&#xff0c;charlist 参数可以规定从字符串中删除哪些字符。stripslashes() 函数用于删除反斜杠。mysqli_real_escape_string() 函数用于对…