You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Simmer R中能否为每个到达实体设置独立超时时间?

问题描述

我正在开发车辆行驶路段的离散事件仿真,路段行驶时间取决于该路段上的已有车辆数量:前期进入的车辆应采用自由流速度,仅后期车辆会受到拥堵影响。但在示例代码中,vehicle0的活动时间采用了拥堵速度(120kph),而它本应使用自由流速度(60kph)。请问在simmer中能否为同一时间到达的每个实体设置独立的超时时间?

问题原因

问题出在调用get_server_count的时机:当100辆车同时到达时,第一个车辆seize资源后,服务器计数立刻变成1,但后续车辆会在同一仿真时刻依次执行seize操作;等到第一个车辆执行timeout时,服务器计数已经是100(所有车辆都完成了seize),所以计算出的是拥堵状态下的行驶时间,而非车辆进入时的实际车辆数。

解决方案

当然可以为同一时间到达的实体设置独立超时时间。核心是在车辆seize资源的瞬间记录当时的车辆数,而非等到执行timeout时再获取当前服务器计数。可以通过set_attribute为每个实体存储专属的行驶时间,后续timeout直接调用这个属性即可。

修改后的代码如下:

library(tidyverse)
library(magrittr)
library(simmer)
library(simmer.plot)
library(simmer.bricks)

rm(list = ls())

# Globals ----
limit_freeflow_segment1 <- 20 # 自由流最大车辆数(拥堵阈值)
limit_segment1 <- limit_freeflow_segment1 * 2 # 路段最大容纳车辆数
freeflow_speed_segment1 <- 60 # 自由流速度(km/h)
kms_segment1 <- 60 # 路段长度(km)

# Monitor object to collect results ----
mon <- monitor_csv()

road_sim <- simmer(mon = mon)

# Timeout functions ----
mins_segment1 <- function(vehicles) {
  if (vehicles < limit_freeflow_segment1) {
    speed <- freeflow_speed_segment1
  } else {
    speed <- (limit_freeflow_segment1 / vehicles) * freeflow_speed_segment1
  }
  mins <- kms_segment1 / speed * 60
  return(mins)
}

# Trajectory ----
vehicle_traj <- trajectory() %>%
  # 路段1行驶逻辑 ----
  seize("road_segment_1") %>%
  # 关键改动:在seize后立即记录当前服务器计数(即该车辆进入时的路段车辆数)
  set_attribute(
    "entry_vehicle_count",
    function() get_server_count(.env = road_sim, resources = "road_segment_1")
  ) %>%
  # 基于进入时的车辆数计算专属行驶时间并存储
  set_attribute(
    "travel_mins",
    function() mins_segment1(vehicles = get_attribute(.env = road_sim, "entry_vehicle_count"))
  ) %>%
  # 使用专属的行驶时间作为超时
  timeout(function() get_attribute(.env = road_sim, "travel_mins")) %>%
  release("road_segment_1")

road_sim %>%
  add_generator(
    name_prefix = "vehicle",
    trajectory = vehicle_traj,
    at(sort(rep(1:1, 100))) # 100辆车同时在时刻1到达
  ) %>%
  add_resource(name = "road_segment_1", capacity = limit_segment1) %>%
  run()

# 获取结果 ----
arrivals <- road_sim %>% get_mon_arrivals()
resources <- road_sim %>% get_mon_resources()
attributes <- road_sim %>% get_mon_attributes()

View(arrivals)
关键改动说明
  • 用set_attribute替代set_global:全局变量会被所有实体共享覆盖,而实体属性是每个车辆独有的,能保留该车辆进入路段时的车辆数。
  • timeout时调用实体自身的travel_mins属性:确保每个车辆使用的是自己进入路段时计算的行驶时间,而非当前时刻的拥堵状态。

这样修改后,前20辆车(vehicle0到vehicle19)会使用自由流速度计算的60分钟行驶时间,后续车辆则根据进入时的总车辆数计算拥堵后的行驶时间,完全符合需求。

内容的提问来源于stack exchange,提问作者jimbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 08:02:03