R Simmer - 根据队列大小在容器之间重新分配资源
R Simmer - Reallocate resource between pots based on queue size
我有一个 simmer DES 的工作示例,用于简单的门诊服务。有高优先级和低优先级患者,每个患者都有专门的诊所。高优先级诊所每天有 5 个时段,低优先级诊所每天有 1 个时段。这是测试代码:
testmixcap <- simmer()
highpriority <- trajectory("high") %>%
log_("High priority arrival - add to wl") %>%
select("highpclinic") %>%
seize_selected() %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
lowpriority <- trajectory("low") %>%
log_("Low priority arrival - add to wl") %>%
select("lowpclinic") %>%
seize_selected() %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
testmixcap %>%
add_generator("high",highpriority,at(1,1,1,2,2,3,3,3,4)) %>%
add_generator("low",lowpriority,at(1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6)) %>%
add_resource("highpclinic",5) %>%
add_resource("lowpclinic",1)
testmixcap %>%
run(until = 100)
testmixcap %>%
get_mon_resources()
我的问题是,在没有对高优先级诊所时段的需求(或并非所有 5 个都需要)的日子里,有没有办法告诉 simmer 释放其余的插槽到低优先级资源? 例如高优先级诊所有 2 个病人,但它的剩余 3 个插槽被添加到低优先级诊所并通过 4 个病人?
第二天诊所需要恢复到正常容量,但我认为我可以使用时间表而不是固定优先级来做到这一点。
我认为答案在于使用信号,但我无法理解它们。我还考虑过将两个诊所合并为一个锅,并使用优先级分配给更高优先级的患者。但这意味着可能会有几天我们看到零低优先级患者,这是非常不可能的。
感谢收到任何帮助!
我设法找到了一个使用全局变量的解决方案,以及一个假到达生成器,它充当每日监视器,用于监测何时将过剩容量分配给高优先级诊所。
library(simmer)
library(dplyr)
testmixcap <- simmer()
highpriority <- trajectory("high") %>%
log_("High priority arrival - add to wl") %>%
select("highpclinic") %>%
seize_selected() %>%
set_global("highpseentoday",1,"+") %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
lowpriority <- trajectory("low") %>%
log_("Low priority arrival - add to wl") %>%
select("lowpclinic") %>%
seize_selected() %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
cap_monitor <- trajectory() %>%
set_global("highpseentoday",0) %>%
timeout(0.1) %>%
log_("Check if all today's slots used in high priority clinic") %>%
branch(
function(){
seentoday <- get_global(testmixcap,"highpseentoday")
highpcap <- get_capacity(testmixcap,"highpclinic")
if(seentoday < highpcap) {1} else {0}
}
,continue = TRUE
,trajectory() %>% set_capacity("lowpclinic",value = function(){
seentoday <- get_global(testmixcap,"highpseentoday")
highpcap <- get_capacity(testmixcap,"highpclinic")
highpcap - seentoday
},mod = "+")
) %>%
timeout(0.9) %>%
rollback(Inf)
testmixcap %>%
add_generator("high",highpriority,at(1,1,1,2,2,3,3,3,4),mon = 2) %>%
add_generator("low",lowpriority,at(1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6)) %>%
add_resource("highpclinic",5) %>%
add_resource("lowpclinic",schedule(c(1,2),c(1,1),2)) %>%
add_generator("monitor",cap_monitor,at(1))
testmixcap %>%
run(until = 100)
testmixcap %>%
get_mon_resources()
testmixcap %>%
get_mon_arrivals()
我有一个 simmer DES 的工作示例,用于简单的门诊服务。有高优先级和低优先级患者,每个患者都有专门的诊所。高优先级诊所每天有 5 个时段,低优先级诊所每天有 1 个时段。这是测试代码:
testmixcap <- simmer()
highpriority <- trajectory("high") %>%
log_("High priority arrival - add to wl") %>%
select("highpclinic") %>%
seize_selected() %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
lowpriority <- trajectory("low") %>%
log_("Low priority arrival - add to wl") %>%
select("lowpclinic") %>%
seize_selected() %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
testmixcap %>%
add_generator("high",highpriority,at(1,1,1,2,2,3,3,3,4)) %>%
add_generator("low",lowpriority,at(1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6)) %>%
add_resource("highpclinic",5) %>%
add_resource("lowpclinic",1)
testmixcap %>%
run(until = 100)
testmixcap %>%
get_mon_resources()
我的问题是,在没有对高优先级诊所时段的需求(或并非所有 5 个都需要)的日子里,有没有办法告诉 simmer 释放其余的插槽到低优先级资源? 例如高优先级诊所有 2 个病人,但它的剩余 3 个插槽被添加到低优先级诊所并通过 4 个病人?
第二天诊所需要恢复到正常容量,但我认为我可以使用时间表而不是固定优先级来做到这一点。
我认为答案在于使用信号,但我无法理解它们。我还考虑过将两个诊所合并为一个锅,并使用优先级分配给更高优先级的患者。但这意味着可能会有几天我们看到零低优先级患者,这是非常不可能的。
感谢收到任何帮助!
我设法找到了一个使用全局变量的解决方案,以及一个假到达生成器,它充当每日监视器,用于监测何时将过剩容量分配给高优先级诊所。
library(simmer)
library(dplyr)
testmixcap <- simmer()
highpriority <- trajectory("high") %>%
log_("High priority arrival - add to wl") %>%
select("highpclinic") %>%
seize_selected() %>%
set_global("highpseentoday",1,"+") %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
lowpriority <- trajectory("low") %>%
log_("Low priority arrival - add to wl") %>%
select("lowpclinic") %>%
seize_selected() %>%
log_("Attend appointment") %>%
timeout(1) %>%
release_selected() %>%
log_("Discharge")
cap_monitor <- trajectory() %>%
set_global("highpseentoday",0) %>%
timeout(0.1) %>%
log_("Check if all today's slots used in high priority clinic") %>%
branch(
function(){
seentoday <- get_global(testmixcap,"highpseentoday")
highpcap <- get_capacity(testmixcap,"highpclinic")
if(seentoday < highpcap) {1} else {0}
}
,continue = TRUE
,trajectory() %>% set_capacity("lowpclinic",value = function(){
seentoday <- get_global(testmixcap,"highpseentoday")
highpcap <- get_capacity(testmixcap,"highpclinic")
highpcap - seentoday
},mod = "+")
) %>%
timeout(0.9) %>%
rollback(Inf)
testmixcap %>%
add_generator("high",highpriority,at(1,1,1,2,2,3,3,3,4),mon = 2) %>%
add_generator("low",lowpriority,at(1,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6)) %>%
add_resource("highpclinic",5) %>%
add_resource("lowpclinic",schedule(c(1,2),c(1,1),2)) %>%
add_generator("monitor",cap_monitor,at(1))
testmixcap %>%
run(until = 100)
testmixcap %>%
get_mon_resources()
testmixcap %>%
get_mon_arrivals()