我正在尝试如下建模系统:
到达根据预定义的时间表生成,并且具有由数据帧提供的已知处理时间。在模拟开始时有一个容量等于 min_daemons 的服务器。到目前为止很简单,但 nxt 部分变得棘手:根据以下算法,此容量可以在整个模拟过程中的间隔 [min_daemons , max_daemons] 上变化:
如果在模拟过程中的任何时候,队列长度达到或超过 incr_count 的值,并且在 incr_delay 中保持在此水平或以上,则向主服务器添加一个额外的容量单位。这可能随时发生,只要容量不超过 max_daemons。
反之亦然。如果在任何时候,队列长度小于 decr_count,并且在 decr_delay 中保持在此级别或以下,则删除一个容量单位,可能会降至 min_daemons 级别。
当满足上述更改服务器容量的条件时,我为所有到达分支创建了一个轨迹。这样做的问题是容量的变化总是与到达事件相关联。我真正想要的是一个独立于到达轨迹的过程,它始终监控队列长度并进行适当的容量更改。
我考虑过使用某种虚拟到达过程来完成此操作,例如在模拟的每一秒,但我不确定是否可以防止虚拟到达与真实到达竞争服务器容量。
#instantiate simulation environment
env <- simmer("queues") %>% add_resource("daemon",1) %>% add_global("incr_start",99999) %>% add_global("decr_start",99999)
run <- trajectory() %>%
branch(option = function() if (get_queue_count(env,"daemon") >= incr_count) {1}
else if (get_queue_count(env,"daemon") <= decr_count) {2}
else {3}
,
continue = c(T, T, T)
,
trajectory("increment?")
%>% branch(option = function() if (now(env) - get_global(env,"incr_start") >= incr_delay
& get_capacity(env,"daemon") < max_daemons) {1}
else if (get_global(env,"incr_start")==99999) {2}
else {3}
,
continue = c(T, T, T)
,
trajectory("increment")
%>% log_(function () {paste("Queue size is: ",get_queue_count(env,"daemon"))})
%>% log_(function ()
{paste("Queue has exceeded count for ",now(env)-get_global(env,"incr_start")," seconds.")})
%>% set_capacity(resource = "daemon", value = 1, mod="+")
,
trajectory("update incr start")
%>% set_global("incr_start",now(env))
%>% log_("Queue count is now above increment count. Starting increment timer.")
,
trajectory("do nothing")
%>% log_("Did not meet increment criteria. Doing nothing.")
)
,
trajectory("decrement?")
%>% branch(option = function() if (now(env) - get_global(env,"decr_start") >= decr_delay
& get_capacity(env,"daemon") > min_daemons) {1}
else if (get_global(env,"decr_start")==99999) {2}
else {3}
,
continue = c(T, T, T)
,
trajectory("decrement")
%>% log_(function () {paste("Queue size is: ",get_queue_count(env,"daemon"))})
%>% log_(function ()
{paste("Queue has been less than count for ",now(env)-get_global(env,"incr_start")," seconds.")})
%>% set_capacity(resource = "daemon", value = -1, mod="+")
,
trajectory("update decr start")
%>% set_global("decr_start",now(env))
%>% log_("Queue count is now below decrement count. Starting decrement timer.")
,
trajectory("do nothing")
%>% log_("Did not meet decrement criteria. Doing nothing.")
)
,
trajectory("reset_timer")
%>% log_("Did not meet criteria to increment or decrement. Resetting timers.")
%>% set_global("decr_start", values = 99999)
%>% set_global("decr_start", values = 99999)
) %>%
seize("daemon") %>%
log_("Now running") %>%
log_(function () {paste(get_queue_count(env,"daemon")," runs in the queue.")}) %>%
timeout_from_attribute("service") %>%
release("daemon") %>%
log_("Run complete")
env %>%
add_dataframe("run", run, arr,time="absolute") %>%
run(200)
我需要做更多的调试来验证模拟是否按我的预期工作,但我完全理解这个模型是错误的。我希望该设计不会过多地损害其有效性,但我也希望获得有关如何设计更符合现实生活的东西的反馈。