简介基于Java实现的摩天大楼电梯类型与调度算法仿真项目模拟真实电梯运行覆盖单向、双向、观光、高速、消防等电梯建模并实现FCFS、最近楼层优先、最少行程时间、预调度和群控算法。通过随机生成乘客流量可对比不同调度策略下的响应效率适合学习Java面向对象编程、多线程并发及算法设计的开发者实战练习也可用于课程设计或毕业课题。压缩包共75个文件体积约70KB以25个Java源文件为核心包含Elevator、Call、TrafficGenerator等关键类另附XML配置、Eclipse元数据及README文档便于导入IDE运行修改。目前已有402人浏览学习。阅读源码可完整理解从乘客请求生成、电梯状态更新到调度决策的仿真链路并可在现有框架上扩展新算法或调整模拟参数进一步研究智能电梯群控和等待时间优化。1. 摩天大楼电梯仿真为什么先跑起来的是“模型”而不是“算法”第一次接触电梯仿真的人往往上来就钻进调度算法里盯着一堆电梯曲线画得天花乱坠。但真给一栋摩天大楼做电梯运量评估时最先卡住你的不是算法而是“模型”——轿厢类型没定、客流没建、仿真时钟都不知道怎么推算法再好也只是一段没有落点的代码。ElevatorSimulation 这类仿真项目要解决的正是把“电梯类型、楼宇客流、调度策略”三者缝在一起的问题它不产出唯一正确答案而是给你一台可以反复改参的“黑匣子”让峰值运力、平均候梯时间、区间停靠次数这些指标在代码里现出原形。适合的人群是那些要做写字楼、酒店、商办综合体方案比选的开发者和顾问工程师——你们缺的不是电梯曲线而是一个能快速验证“某某类型轿厢某调度策略”组合的仿真底座。这篇笔记就把我从模型到调度再到排坑的完整路径讲透。2. 建模先行客流、轿厢类型与仿真事件驱动怎么写在动手写调度策略之前得先想清楚一个前提电梯仿真到底在仿什么你仿的不是电梯按钮逻辑而是“乘客在特定时间出现在特定楼层、按目的地按键、被某台轿厢接走、到达目标楼层”这件事。这个主体一旦搞错后面所有指标都会失真。我把这一章拆成三层先选电梯类型再建客流最后才落地事件驱动骨架。2.1 选型先于编码单轿厢、双轿厢、双层轿厢怎么定常见做法是把轿厢类型看成“运能上限”把调度看成“运能利用率”。摩天大楼里你实际面对的无非这几种普通单轿厢、双轿厢同一井道内两个独立轿厢上下错位运行、双层轿厢一个轿厢内分上下两层停靠时同时服务相邻两层、以及配空中大堂的区间穿梭模式。先别急着写代码先用一张小表把这几种类型放进“运能/成本/复杂度”坐标系里。轿厢类型适用楼层区段运能特点调度复杂度单轿厢全高度均可弹性最大但高峰期容易扎堆入门双轿厢高中区两个轿厢独立响应请求运能接近翻倍需处理碰撞与错位双层轿厢低中区为主一次停靠服务两层高峰吞吐大需映射目标楼层到上下层区间穿梭空中大堂超高区段分段运输换乘在固定楼层完成需设计换乘路径和指示系统如果你的楼在 60 层以上我一般会先跑双轿厢或“低区空中大堂”的组合如果楼只有 20 层且层高低单轿厢加一个分区就够。选型逻辑一句话上下班峰值时段的五分钟后进楼人数决定了轿厢数量和类型。这个数字是楼宇运营方给的仿真代码里的building.peak_5min_flow就是它的落点。选型一旦定了代码里的轿厢对象就要跟着定。不要试图写一个“万能轿厢”类然后靠布尔开关区分类型那样到后面每个策略都要判断一堆标志位整段代码会变成没人敢动的泥潭。我习惯把轿厢拆成Car基类和一种叫“轿厢能力描述”的配置对象类型差异全部收在配置里# car_config.py from dataclasses import dataclass dataclass class CarConfig: car_count: int 6 # 井道数量 capacity: int 16 # 单轿厢载客人数 speed_mps: float 4.0 # 额定速度米/秒 accel_mps2: float 1.0 # 加速度 door_open_s: float 2.5 # 单次开门停留 board_time_s: float 0.8 # 每人平均进出时间 type: str single # single / double_deck / twin # 实际使用低区6台高区4台各配各的参数 low_zone CarConfig(car_count6, capacity16, typesingle) high_zone CarConfig(car_count4, capacity16, typedouble_deck)这段配置解决的是“改参不碰逻辑”的问题。所有电梯类型差异都体现在参数上type只影响停靠时的楼层映射规则而不会把整个调度器写成四份。参数里面的board_time_s是最容易被忽略的真实乘客不是一次全上完高峰期开门后前 8 个乘客挤进去和后 5 个慢悠悠走进去节奏完全不同所以如果你在代码里用整段“开门→上客→关门”的死时间片算出来的候梯时间普遍偏乐观。选型定完下一步就是客流。2.2 客流模型写字楼的三个时段决定仿真结果是否可信很多人拿泊松过程生成乘客就开跑结果仿真出来的高峰和实际大楼差一大截。原因很简单写字楼客流有明显的时段结构。早高峰是“进楼潮”上午九点前大量乘客从 1 层出发分散到各楼层晚高峰是“出楼潮”大量乘客从各楼层涌向 1 层或停车场层午间则是一小波双向混合。这不是随随便便一个泊松过程能覆盖的。我的做法是把乘客生成器做成三段时间曲线。早高峰用“高到达率目标楼层集中在高层”晚高峰用“高出发率目的地集中在大堂”午间则调低强度。目标楼层怎么分布也有讲究用一个带偏置的幂律分布。这样做的原因是真实楼宇里低区是餐饮和会议、高区是核心办公楼层到访概率并不均匀。代码里可以用一个floor_weights数组直接手动指定也可以用分布函数生成。# passenger_stream.py import random class Passenger: def __init__(self, pid, src, dst, t): self.pid pid self.src src self.dst dst self.arrival_t t def generate_morning_rush(total, highest_floor, peak_floor40): 早高峰客流目标楼层偏向peak_floor以上 weights [] for f in range(2, highest_floor 1): base 1.0 if f peak_floor: base 3.0 # 高区访问更密集 weights.append(base) total_w sum(weights) for pid in range(total): dst_floor 2 random.choices( range(0, highest_floor - 1), weightsweights, k1 )[0] yield Passenger( pidpid, src1, # 早高峰全部从大堂进 dstdst_floor, t8.0 * 3600 pid * 1.8 # 时间从8点开始单位秒 )这段代码的t8.0*3600 pid*1.8看起来是偷懒实际上是在控制仿真时长假设 600 个乘客在 18 分钟内陆续到达也就是平均每 1.8 秒来一个。真实早高峰并不是从第 0 秒到第 600 秒匀速的它会有一个“从稀疏到密集再到稀疏”的驼峰。真要追求准确就在外层再加一组“到达率倍率数组”按每 5 分钟一个倍率给生成器加权。先把均匀版本跑通再在参数敏感性那一章推曲线。你还会发现一个问题src1是硬编码。写死楼层在大楼改造时就是灾难。后来我把源头来源楼层做成了配置项因为在很多综合体里早高峰并不一定从 1 楼进地下车库层有时客流比 1 楼还猛。把src1替换成source_floor_list就能同时支持地下车库层只是后面统计等候时间时要分清是从哪一层进的否则对比结果会打架。2.3 仿真骨架事件循环与电梯状态机不能各写各的有了轿厢参数和乘客流下一步是搭一个“事件驱动”的仿真骨架。为什么不用简单的时间步长扫描摩天大楼楼高、电梯速度快时间步长设小了吧跑到一天要循环几百万次设大了吧电梯加减速和开关门的时间对不齐。事件驱动更容易精确描述“轿厢这一刻到站”这种离散瞬间。事件驱动的核心是一个有序事件队列和一个不断把事件弹出的主循环。电梯本身应该是一个状态机停止、加速运行、匀速运行、减速停靠、开关门、上下客。事件队列里的事件则对应状态转移的触发点。我最精简的实现长这样# sim_engine.py import heapq class Event: def __init__(self, t, priority, callback): self.t t self.priority priority self.callback callback def __lt__(self, other): return (self.t, self.priority) (other.t, other.priority) class Sim: def __init__(self): self.now 0.0 self.queue [] self.passengers [] # 候梯乘客 self.cars [] # 所有轿厢 def schedule(self, delay, callback): heapq.heappush(self.queue, Event(self.now delay, 0, callback)) def run(self, until): while self.queue: ev heapq.heappop(self.queue) if ev.t until: break self.now ev.t ev.callback()这段代码的核心来自系统仿真里常见的“未来事件表”结构。priority字段用来处理同一个时间发生多个事件的顺序比如电梯到站和乘客到达同时发生时我习惯先处理乘客到达把排队状态更新了再处理轿厢停靠这样后续调度才能基于完整状态决策。队列用heapq实现系统仿真和操作系统的定时器调度在数据结构层面上几乎一样这个点很容易被教科书忽略。初步跑起来后你会发现仿真里的“时钟”和“现实时间”不等价Sim.now里一个早上 8 点的早高峰可能只有仿真里短短的 3 分钟因为生成器把时间压缩了。要得到真实的候梯时间曲线整个仿真时长必须乘以乘客生成器的时间跨度别在这个地方位移了。这是新手最容易困惑的“仿真时钟 vs 真实时钟”问题后面避坑章节再展开一次。电梯状态机的具体动作包括什么时候加速、什么时候开始减速可以用一个简单的时间函数算出来从当前楼层到目标楼层加速段距离v^2 / (2a)如果距离不够那就直接跑一个“三角速度曲线”。下面这段逻辑不是每个仿真都要做得一模一样但对结果影响很大# motion.py import math def travel_time(car, target_floor): 计算轿厢从当前位置到目标楼层所需时间考虑加减速 dist abs(target_floor - car.floor) v car.speed_mps a car.accel_mps2 # 如果距离不足以加到全速则走三角速度曲线 d_accel v * v / (2 * a) if dist 2 * d_accel: return 2 * math.sqrt(dist / a) return v / a (dist - 2 * d_accel) / v这里最容易搞错的就是“把电梯当成瞬时到达”的做法。很多早期仿真为了跑得快直接让电梯从一个楼层瞬间跳到另一个楼层结果是候梯时间被严重低估。加了加减速模型后一天的仿真运行时间从毫秒级涨到秒级但数据的可信度完全是两回事。如果你觉得这个模型还不够细可以在car.floor之外再加一个“运行方向”和“运行状态”字段用于后续调度算法判断顺路方向这为第 3 章的调度器铺好了路。3. 调度策略落代码SCAN、LOOK、分区群控的参数与边界模型跑通之后重头戏才刚开始调度算法。仿真项目的最终目的是对比不同调度策略在相同客流、相同楼型下的表现。这一章从最常见的电梯调度算法讲到如何把它们实现成可替换的策略模块最后落到群控分区的编码上。3.1 先看四种策略的适用边界再谈代码策略核心思想典型场景最大弱点FCFS按请求先后顺序响应乘客少楼层低的楼电梯频繁折返效率最低SCAN像电梯“扫描”一样沿一个方向走到底再换向早高峰进楼潮回扫时高区乘客等太久LOOKSCAN 的改良只走到当前方向最远请求就回头上下行不均时更灵活边界方向可能反复感死分区群控每组轿厢固定服务某个楼层段区内用 SCO60 层以上超高层跨区乘客需换乘设计复杂FCFS 在仿真里最容易实现但很少用在现代摩天大楼因为它的电梯轨迹是一堆乱麻。SCAN 和 LOOK 才是绝大多数电梯控制器的底层逻辑。你卖参数时也常看到“目的地呼叫系统”那是另一个层面乘客在候梯厅输入目标楼层系统分组派梯本质上是在请求产生阶段就做了调度决策而不是轿厢到了才选方向。仿真的时候两种都值得做但第一版先跑 LOOK 就够了因为参数最少基线最干净。要实现 LOOK核心是把电梯的“前进方向”和“沿路请求”维护成两个独立的数据状态。请求不是全局队列而是挂在每一层上的“向上叫梯/向下叫梯”两个标志。3.2 调度核心代码LOOK 与 SCAN 在仿真里的差异少了哪个条件就翻车我用一个最直接的实现来看 LOOK 和 SCAN 的差别。两者的共同前提是轿厢当前方向上有请求就继续没有请求再看反方向。差别只在于 SCAN 会一直跑到物理边界楼层再回头LOOK 则跑到当前方向最远的一个请求楼层就回头。下面这段代码展示的是电梯每到一个楼层时调度器怎么重新决策方向# scheduler.py def next_stop(car, up_requests, down_requests): LOOK策略先看当前方向是否有更远请求没有就回头 cur car.floor if car.direction 1: # 上行 forward [f for f in up_requests if f cur] if forward: return min(forward) down_forward [f for f in down_requests if f cur] if down_forward: return max(down_forward) # 换向前先接完当前方向上所有下行请求 car.direction -1 return max([f for f in up_requests down_requests], defaultcur) else: # 下行 forward [f for f in down_requests if f cur] if forward: return max(forward) down_forward [f for f in up_requests if f cur] if down_forward: return min(down_forward) car.direction 1 return min([f for f in up_requests down_requests], defaultcur)这段代码故意没有写成花哨的数学版而是用最朴素的列表推导式目的是让人一眼看清“方向”和“请求列表”之间怎么联动。注意down_forward那个分支很多实现到这里只判断了同方向请求忘了轿厢在上行途中还可能遇到一个在下行方向的乘客想在同一方向顺路搭一段于是导致本该顺路接的人被留到下一轮。还有一个容易被忽略的细节return min(forward)是 LOOKreturn highest_floor是 SCAN。把min(forward)换成“当前方向的物理边界楼层”就是纯 SCAN。这行代码的差别就是你调节奏的关键。SCAN 在低峰期会浪费一大段空跑因为它总要扫到边界才能回头LOOK 在边界层附近可能出现“感死”——只有一层请求时电梯来回横跳。实际产品里往往还有一层“空闲停靠”策略比如没请求时电梯自动回到大堂待命而不是停在最后服务的那一层。3.3 分区与群控让六台电梯不再一窝蜂冲向顶楼单台电梯的调度是基础摩天楼真正难的是群控。六台电梯如果都执行 LOOK 且从同一位置出发早高峰时大概率全部挤向同一个高楼层造成大厅运力瞬间真空。分区是最简单可靠的方案把 1 层到 60 层切成三个区每区两台电梯同区内再用 LOOK。分区配置我会做成一张表而不是写死在代码里# zoning.py ZONES [ {id: low, floor_start: 1, floor_end: 20, cars: [0, 1]}, {id: mid, floor_start: 20, floor_end: 40, cars: [2, 3]}, {id: high, floor_start: 40, floor_end: 60, cars: [4, 5]}, ] def assign_car(passenger, zones): 根据乘客目标楼层分配电梯组 for zone in zones: if zone[floor_start] passenger.dst zone[floor_end]: return zone[cars] return zones[-1][cars] # 兜底分区之后一个过墙的问题是 1 层大厅的乘客要去 45 层只能坐高区电梯但高区电梯来回一次要好久乘客在大堂排到最远的队伍最慢。所以很多超高楼会加“空中大堂”低区电梯把人送到 30 层再换乘高区电梯。仿真里这个换乘动作需要在客流模型中显式建模一个乘客到达目标楼层应分成两个行程段第一段的终点是空中大堂第二段的起点是大堂。这一步不做直接把 45 层当目标仿真的候梯时间会虚高很多。群控代码到这一步其实还没真正接触“动态指派”只是用了静态分区。真正让算法效果飞起来的是“空闲电梯预指派”当一台轿厢空闲时不是原地待命而是根据当前各层请求密度提前移动到预测楼层。预测逻辑可以很简单比如当前候梯人数最多的楼层优先停靠。这种启发式很粗糙但效果明显后续第 6 章的方向性仿真会用到它。4. 用实验说话电梯仿真的指标设计、对照试验与参数敏感性调度器能跑起来以后项目真正的价值来自“实验对比”。这一章讲清楚怎么设计指标、怎么跑对照实验、怎么通过参数敏感性找到系统的瓶颈。4.1 先定指标再谈实验平均候梯时间为什么不够用电梯仿真的输出如果只有“平均候梯时间”等于看病只看体温。真实工程里这一堆指标必须全部看到指标计算方式反映的问题平均候梯时间 AWT全部乘客候梯时长之和 / 乘客数整体用户体验95 分位候梯时间候梯时间排序后第 95% 位长尾风险反映最差体验平均行程时间 ART进入轿厢到到达目标楼层的时间轿厢效率与停靠次数每趟平均停靠次数总停站次数 / 总运行趟次调度策略的聚合效率运能余量峰值时段实际运能 / 需求运能系统是否逼近上限平均候梯时间短不代表系统健康有可能 95% 的人候梯 20 秒另有 5% 的人等了 10 分钟AWT 依然很好看。你在给运营方汇报时最容易被挑战的问题就是“你们说平均 40 秒为什么我看到有人站了一刻钟”所以 95 分位这个指标必须和 AWT 一起出现。指标不能只在程序内存里算建议把每次乘客的完整事件流导出成 CSV然后统一在离线分析里统计。这样不仅方便复查也能画出候梯时间随时间的分布曲线。# metrics.py import csv def dump_trip_log(sim, filenametrip_log.csv): with open(filename, w, newline) as f: writer csv.writer(f) writer.writerow([pid, src, dst, arrival_t, board_t, arrive_t]) for p in sim.passengers: writer.writerow([p.pid, p.src, p.dst, p.arrival_t, p.board_t, p.arrive_t])这一步看起来只是多写一个文件但它对项目的价值远超想象。没有这段日志你会发现每次换参数后只能看着一堆新数字发呆不知道差异到底是什么环节造成的。有了 CSV之后做任何对比实验都能用同一套 Python 脚本分析而不是反复改仿真主程序。4.2 对照实验怎么设计同客流下改策略而不是同日期下改策略对比调度策略的前提是“严格复用同一批乘客”。这个原则听起来简单执行上却经常翻车有人习惯每次仿真都重新生成客流结果发现 A 策略比 B 策略好实际上是又一次随机波动。正确做法是把乘客流一次性生成后缓存成文件或者固定一个随机种子。整个实验结构我通常写成# experiment.py import random SEED 42 random.seed(SEED) passengers list(generate_morning_rush(600, highest_floor60)) def evaluate(strategy, cars_config, passengers): sim Sim() sim.load(cars_config) sim.seed_passengers(passengers) sim.attach_scheduler(strategy) sim.run(until10800) return summarize(sim) results { look: evaluate(look, low_zone_cars, passengers), scan: evaluate(scan, low_zone_cars, passengers), zone: evaluate(zone, zone_cars, passengers), }这种设计把客流生成和策略评估完全解耦任何策略跑的都是同一串 PID 完全相同的乘客。实验做完你会发现结果可能和自己预想的不一样SCAN 在高楼层多、请求跨度大的场景下未必比 LOOK 好因为 SCAN 虽然少折返但空跑距离大而分区虽然让电梯各管一段却让区域间请求的等待时间剧烈恶化。这些都是仿真给你的“反直觉结论”比任何经验法则都更有说服力。4.3 参数敏感性轿厢数量、容量和开门时间哪个最“值钱”仿真跑顺之后下一步不是急着加算法而是做参数敏感性分析。所有参数里轿厢数量和单次容量对候梯时间的影响是压倒性的但这俩是硬成本不到万不得已不会改。软参数里最被低估的是door_open_s和board_time_s一栋 60 层楼每台电梯高峰期每趟至少停 8 次每次开门省 0.5 秒一个高峰时段 20 趟下来能省 80 秒。这个优化空间可以接近白嫖。敏感性实验可以很简单固定其他值只让某个参数从 baseline 偏移正负 20%看指标波动幅度。参数baseline20%-20%AWT 波动轿厢数量675明显改善 / 明显恶化轿厢容量161913低谷期不敏感高峰敏感开门时间2.5s3.0s2.0s中等影响乘客进出时间0.8s0.96s0.64s长距离高区影响大如果你发现某个参数对结果的影响小到在 1 秒以内那说明当前系统瓶颈不在这里。此时与其继续调参数不如回头换电梯类型或改分区方案。这就是仿真项目的哲学它帮你把精力导向真正的杠杆点而不是让你在无关参数上自嗨。很多人在这一步会陷入“参数调优玄学”觉得多试几组总能更好实际上在随机客流下AWT 差 0.3 秒根本不构成策略级差异。5. 避坑与排查电梯仿真里最容易翻车的五处细节这一章的素材来自血泪经验。电梯仿真跑起来容易跑得“可信”难。以下六个细节每一个都能让你的结论完全反转。5.1 仿真时钟跳变乘客凭空瞬移现象候梯时间曲线像锯齿一样跳某些乘客的候梯时间为负或者同一秒内出现了十几个操作顺序对不上的事件。原因事件循环里某个回调函数直接修改了sim.now而不是通过schedule推迟事件。常见误用是在乘客到达事件里顺手把轿厢开门事件也提前了导致同一仿真时刻下状态不一致。另一个常见原因是生成器的时间t直接当成了sim.now但真实仿真应当以事件队列为准。解决彻底禁止在回调里写sim.now ...所有未来的状态变更都必须通过schedule表达。生产环境里可以在Sim类里加断言检测到时间回退就抛异常宁可慢一点也绝不让黑匣子产出不可复现的数字。5.2 满载跳站引发“大厅瘫痪”现象高峰期候梯人数暴涨但轿厢频繁过站不停有些楼层完全等不到电梯。原因轿厢满载之后会越过所有楼层即使有请求也直接跳过。高峰期这种跳站策略如果写了“满载直接回大堂”中间楼层的乘客会等到来回几趟才上得去。这个现象在低区常见一批人冲进电梯去 10 楼开会满载后直接忽略 2 楼的请求2 楼的人只能等下一趟。解决满载跳站不是错但需要加一个“满载顺路续载”的阈值。比如轿厢一旦低于 80% 载客率遇到顺路方向请求仍然停靠高于 100% 时确实只能跳站但要记录跳站次数作为指标。跳站次数一旦超标说明轿厢容量或数量不足该加车了。5.3 LOOK 回扫让高区乘客“饿死”现象高区乘客长时间等不到电梯但低区电梯一直忙碌。原因LOOK 策略下轿厢永远在低区和中区之间来回高区很少有人叫梯于是电梯永远不往高区走——这叫“饿死”。很多人以为 LOOK 自动覆盖所有楼层实际上它只覆盖“最近被请求的方向”而不是“所有可能被请求的楼层”。解决给每个分区加一个“最小扫楼间隔”即使当前方向没有请求每隔一段时间强制轿厢往高区边界跑一次。实现上就是在调度器里加一个time_since_last_high_zone_visit的判断。这种启发式的本质是以牺牲少量空跑距离换取长尾候梯时长的大幅改善。5.4 开门时间被计入两次现象同一个 2.5 秒的开门时间在某些跑批数据里导致电梯平均行程时间比其他批次莫名多出好几十秒。原因事件流里轿厢到站后先安排开门开门结束后又额外安排一次“到达”事件导致每次停靠都被统计成两个停靠时间片。这种重复计算极隐蔽因为它只会在最终指标里体现为“莫名变大”不会报任何错误。解决给停站事件统一命名例如door_open_start和door_open_end。在绘制时间轴图时确保用手工小型数据集核对首尾事件是否一一对应。大数据量下靠肉眼看不出但你能在一个只有 3 台电梯 10 个乘客的小用例里逐一核对事件序列把每个动作的时间戳手动加一遍等于预期值再放大规模。5.5 随机种子没固定实验结果不可复现现象同样的策略和参数跑两次结果差 20%无法判断策略差异是真实还是噪声。原因乘客生成和调度器内部随机决策都依赖同一个random但每次运行前没有重新seed()。更隐蔽的是Python 的random是全局的在一个文件里seed()了另一个模块如果调用random.sample顺序就变了。解决所有仿真入口统一在最开始执行random.seed(SEED)并且在实验脚本里用pytest或简单断言把SEED写死。更进一步把客流生成放一个独立模块生成后序列化落地实验时直接加载同一份数据。这样每个策略拿到的乘客顺序、目标楼层完全相同指标差异才可信。5.6 物理楼层与逻辑楼层没有对齐现象明明配置了 60 层楼某些策略的候梯时间却异常低后来发现电梯“穿越”了中间楼层。原因空中大堂、地下车库层、设备层这些物理楼层在真实楼宇里存在但仿真里可能被压缩成了一维数字。如果代码里用floor_delta target - current来计算楼层间距且楼层间隔是 3.6 米那么让轿厢从 1 层到 60 层和从 1 层到 3 层用的时间差别会被错误计算。解决在楼宇模型里维护一张floor_height_map每层的高度可以不同比如大堂 5 米标准层 3.6 米。所有运动模型按物理距离计算而不是按楼层序号计算。这一步对大堂、空中大堂、底层商业裙楼组合的复杂楼型尤其重要否则你的仿真永远无法回答“从大堂到 40 层空中大堂要多久”。6. 从仿真到设计参考导出日志、校验运能与扩展直达方案仿真跑出结论后别急着交付一摞数字下一件事是让这些数字能被楼宇设计方直接校验。我习惯把仿真结果里每个轿厢的运动轨迹导出成可视化曲线并计算“五分钟尖峰运能”这是高层楼宇电梯设计里的关键指标在 5 分钟高峰内电梯系统能把多少人从大堂送离或从各层送抵大堂。运能校验公式很简单将仿真里最后一个 5 分钟窗口内完成运输的人数除以 5 乘以 60得到“人/分钟”吞吐量。如果这个数值低于楼宇运营方给出的预期高峰流量说明电梯数量或分组策略必须调整。公式只是结果校验真正推导出问题所在的是每个轿厢的“空跑距离”统计。空跑次数多说明调度策略的“顺路判断”还有优化空间而不是立刻加轿厢。仿真数据导出后一个值得做的扩展是“目标楼层直达”方案在低区到空中大堂的分段运输中让某台轿厢只服务一趟“起终点固定”的区间路线。实现上给轿厢加一个dedicated_mode标志调度器对该轿厢跳过传统 LOOK 判断直接返回固定端点。这个模式的仿真意义在于验证“专车式直达”是否真的比分段随叫随停快很多时候你会惊奇地发现直达虽减少了停靠次数却因为脱离实时调度造成电梯空跑比例上升反而更糟。这种反直觉结论就是仿真的价值所在。我现在的习惯是每做一个电梯仿真项目第一件事不是打开代码编辑器而是先把楼型和客流参数画成一张“时钟-楼层”二维表然后才开始写事件循环。这习惯帮我在很多方案比选时提前劝退客户换电梯类型省下的调试时间足够多跑几轮参数。希望这篇笔记里的模型骨架、调度代码和避坑记录能帮你少走点弯路让下一次摩天大楼电梯仿真方案从“能跑”直接跨到“能信”。本文还有配套的精品资源点击获取