AnyLogic如何统计指定节点区域内的行人数量及相关指标
AnyLogic指定矩形节点行人指标统计实现方案
核心判定逻辑
要实现仅统计蓝色矩形节点内、非服务状态的行人,直接用内置API组合判断即可,不需要额外做空间碰撞检测,单行人的判定条件代码如下:
// 先将蓝色矩形节点的元素名修改为targetArea(可在元素属性面板自定义名称) // ped为遍历得到的单个行人类实例 boolean validForStats = targetArea.contains(ped.getX(), ped.getY()) && !ped.isInService();
代码说明:
contains(x,y)是所有矩形空间标记元素的内置方法,可直接判断传入坐标是否落在区域范围内isInService()是行人库Pedestrian类的内置状态方法,可直接判定行人当前是否处于服务模块的占用状态,自动排除服务区域内的行人,无需额外划定服务区域做范围判断
各指标的具体统计实现
建议添加1个循环触发的事件(触发间隔设置为1秒,触发模式选择Cyclic),每次事件触发时执行统计逻辑,即可拿到每秒的对应指标:
- 区域内符合条件的行人总数
遍历模型内所有行人,通过上述判定条件筛选计数即可:int currentPedNum = 0; double speedSum = 0.0; // peds为行人库默认生成的全局行人集合,若你修改过集合名称请替换为自定义名称 for (Ped ped : peds) { if (targetArea.contains(ped.getX(), ped.getY()) && !ped.isInService()) { currentPedNum++; speedSum += ped.getSpeed(); } } - 区域每秒行人平均速度
基于遍历得到的总速度和有效行人数计算,增加除零判断避免运行报错:double avgSpeedPerSecond = currentPedNum == 0 ? 0 : speedSum / currentPedNum; - 区域行人密度
密度为单位面积内的有效行人数,直接调用矩形元素的内置面积方法计算即可:double area = targetArea.getArea(); double density = currentPedNum / area; // 单位:人/平方米
大规模场景优化方案
如果你的模型行人规模超过1000人,全量遍历所有行人会拖慢运行速度,可改用集合动态维护的方式降低计算量:
- 给蓝色矩形节点添加「进入时」触发动作:判断进入的行人不在服务状态时,将其加入自定义的
HashSet<Ped> validPeds统计集合 - 给蓝色矩形节点添加「离开时」触发动作:将离开的行人从
validPeds集合中移除 - 在服务模块的「进入服务时」动作中,判断当前行人在
validPeds集合内则将其移除;「离开服务时」动作中,判断行人当前坐标在蓝色矩形区域内则重新加入集合
后续统计时直接读取validPeds.size()即可获得实时人数,遍历该集合计算速度、密度即可,无需扫全量行人。
注意:不要使用
ped.getCurrentTargetNode()作为区域判定条件,行人跨节点移动时该值会提前切换为下一个目标节点,会导致统计漏算。
内容的提问来源于stack exchange,提问作者ruby zou
相关产品推荐
相关产品推荐

