当容量-->0时,R simmer资源不丢弃到达

3lxsmp7m  于 2023-04-27  发布在  其他
关注(0)|答案(1)|浏览(107)

在我的模拟中,某些资源在能力计划中,该计划根据一天中的时间在0和1之间交替。如果资源在其能力变为零时无法完成其任务,则应放弃到达,等待一段短时间,然后回滚以尝试选择可用资源。如果没有可用资源,到达经过超时--〉回滚循环,直到资源变得可用。
相关代码如下:

# Use a reject trajectory used to go back and select a new resource if the
# current resource runs out of time (i.e., its shift ends)
... |> 
simmer::seize_selected(
  continue = TRUE,
  reject = simmer::trajectory('dropped') |>
    simmer::timeout(\() runif(1, min = 0.07, max = 0.1)) |>
    simmer::rollback(target = 'select_resource')
  ) |>

# Clear the queue of the selected resource when its capacity is zero
simmer::renege_if(
  signal = 'clear_queue'
  ) |>
simmer::send(
  signals =  \() {
    cap <- simmer::get_capacity_selected(env)

    res_name <- simmer::get_selected(env)
    now <- simmer::now(env)

    queue_count <- simmer::get_queue_count_selected(env)
    if (res_name == 'Operator_Bill' & now > 41 & queue_count > 0) {
      browser()
    }

    if (cap == 0) {
      'clear_queue'
      } else {
        ''
      }
    }
  ) |> ...

由于某种原因,调试条件从未被触发,但是在检查mon_resources时,它显示当capacity == 0时到达正在被服务/在队列中。处理这种情况的正确代码是什么?

w8rqjzmb

w8rqjzmb1#

下面是你的问题的一个简单例子:

library(simmer)

t <- trajectory() %>%
  seize("res") %>%
  timeout(Inf)

simmer() %>%
  add_resource("res", capacity=schedule(c(0, 5), c(1, 0))) %>%
  add_generator("dummy", t, at(0)) %>%
  run(10)
#> simmer environment: anonymous | now: 10 | next: Inf
#> { Monitor: in memory }
#> { Resource: res | monitored: TRUE | server status: 1(0) | queue status: 0(Inf) }
#> { Source: dummy | monitored: 1 | n_generated: 1 }

在上面的例子中,一个到达占用了一个资源并停留在那里。由于指定的调度,资源在t=5“关闭”。但是在t=10的模拟状态中,我们可以看到到达仍然在服务器中。这就是你想要实现的:

t <- trajectory() %>%
  handle_unfinished(trajectory() %>% log_("dropped!")) %>%
  seize("res") %>%
  timeout(Inf)

simmer() %>%
  add_resource("res", capacity=schedule(c(0, 5), c(1, 0)),
               queue_size=0, queue_size_strict=TRUE, preemptive=TRUE) %>%
  add_generator("dummy", t, at(0)) %>%
  run(10)
#> 5: dummy0: dropped!
#> simmer environment: anonymous | now: 5 | next: 
#> { Monitor: in memory }
#> { Resource: res | monitored: TRUE | server status: 0(0) | queue status: 0(0) }
#> { Source: dummy | monitored: 1 | n_generated: 1 }

现在到达下降.几件事要注意:

  • 默认情况下,资源不是抢占式的,这意味着,即使容量下降,设法抢占资源的到达者仍然会在那里,所以我们需要做的第一件事就是指定preemptive=TRUE标志。
  • 有了这个标志,到达将从服务器中删除,但它将留在队列中。因此,我们需要指定queue_size=0,但也需要指定queue_size_strict=TRUE,因为默认情况下允许抢占的到达超过队列大小。现在到达实际上从资源中删除。
  • 最后,如果你想处理丢弃的到达,seizereject参数将不起作用,因为到达没有被拒绝:它在访问资源后被丢弃。拼图的最后一块是handle_unfinished()活动,它被设计来处理这些特殊情况。

相关问题