Hi Iñaki,
I am trying to simulate patient arrivals to the Emergency Department. Each patient will go through several steps, and at the end, the patient will wait for discharge, which is handled by a consultant.
The hospital has a rule that the length of stay (from arrival to discharge) should be less than N minutes. If the length of stay from arrival to the time the patient is waiting for discharge is approaching N, a coordinator will alert the consultant to prioritize the patient so they can be discharged before N minutes.
To simulate the coordinator, I created a parallel trajectory that acts as a coordinator. This trajectory loops to check the length of stay for each patient waiting to be discharged. When the time is approaching N, the patient's priority is upgraded so they can preempt the consultants.
Below is the code. However, it is not possible to change the patient's priority in the parallel trajectory. Additionally, in the parallel trajectory, it is not possible to send a signal to stop the coordinator from watching. Would you please shed some light on what's wrong?
From the the example below, patient 2 should be discharged before patient 1: The set_prioritization is excuted but it did not work.
<pre><code>
library(simmer)
library(simmer.bricks)
library(simmer.plot)
env<-simmer()
coordinator_watch<- trajectory() %>%
renege_if(function() paste0("STOP",get_attribute(env,"UID")),out=trajectory()%>%log_("stop watch"))%>%
branch(option= function() ifelse( now(env) - get_attribute(env,"arrival_time") > 10 ,1,0),continue = FALSE,
trajectory()%>%
log_("try to increase priority and stop the coordinator watch but it does not work")%>%
set_prioritization(c(1,NA,F))%>%
send(function() paste0("STOP",get_attribute(env,"UID")))
,tag="one"
)%>%
timeout(1)%>% rollback("one")
plot(coordinator_watch)
patient_path <-trajectory() %>%
seize('consultant',1) %>%
renege_abort()%>%
timeout(10) %>%
release('consultant',1) %>%
send(function() paste0("STOP",get_attribute(env,"UID")))
ed_path<-trajectory() %>%
set_attribute("arrival_time", function() now(env)) %>%
#log_(function() paste0("arrival:",get_attribute(env,"arrival_time")))%>%
set_attribute("UID",function() rnorm(1,0,1))%>%
simmer::clone(n=2,
coordinator_watch,
patient_path
) %>%
synchronize(wait=FALSE) %>%log_("discharged")
plot(ed_path)
test<-env%>%
add_resource("consultant", 1,preemptive = TRUE) %>%
add_generator("patient", ed_path, at(c(1,10,15))) %>%
run(until=80)
test %>% get_mon_arrivals(per_resource=TRUE)
</code></pre>
The code below is adapted from your example. I changed the prioritization for the arrival at time 16, so it should preempt the previous one. However, the end_time doesn't seem to be correct. Could you help me understand why this is happening?
Hi Iñaki,I just found your article here Queueing Systems • simmer | DES for R (r-simmer.org) and it aligns closely with what I'm trying to achieve. However, I want to modify the model so that when a patient's priority is changed, they can preempt other patients who have already seized the resource. I thought I could accomplish this by setting preemptive=TRUE for the resource. While it technically works, the monitored data doesn't seem to be accurate.
The code below is adapted from your example. I changed the prioritization for the arrival at time 16, so it should preempt the previous one. However, the end_time doesn't seem to be correct. Could you help me understand why this is happening?
--
You received this message because you are subscribed to the Google Groups "simmer-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email to simmer-devel...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/simmer-devel/48a44bac-afbf-4741-88c0-d2c8853c51d5n%40googlegroups.com.
Hi Iñaki,
Thank you so much for your help. I now understand that the signal is sent only from a dummy when the dummy is about to release the resource. In our case, dummy2 meets a condition to have its priority upgraded, but since dummy1 is still holding the resource, the signal isn't sent, preventing dummy2 from preempting dummy1.
What I need is for any dummy to have its priority upgraded at any point in time if it meets certain conditions. It's similar to a real-world scenario where a monitor continuously checks the queue to see if any dummy satisfies the conditions.
I've modified your code by adding a "monitor" trajectory. The monitor's only function is to continuously send out a signal. It seems to solve my problem, but the issue is that I had to use a timeout to repeatedly send the signal from the monitor. Is there a way to do this without relying on the timeout in the loop? thanks alot.
library(simmer)
env <- simmer()
monitor <- trajectory() %>%
send("recompute priority",tag="send_signal")%>%
timeout(0.001)%>% ### THE SMALLER THE TIMEOUT THE MORE ACCURATE BUT SLOW, HOW CAN WE FIX THIS?
rollback("send_signal",check=function() ifelse(now(env)<100,TRUE,FALSE))
custom <- trajectory() %>%
set_attribute("arrival time", function() now(env)) %>%
renege_if(
"recompute priority",
out = trajectory() %>%
# e.g., increase priority if wait_time < 3
set_prioritization(function() {
if ( get_attribute(env,"arrival time") ==16)
c(1, NA, F) # only change the priority
else c(NA, NA, NA) # don't change anything
}, mod="+") %>%
# go 2 steps back to renege_if
rollback("renege"),tag="renege") %>%
seize("resource") %>%
renege_abort() %>%
log_("processing") %>%
timeout(10) %>%
# trigger this before releasing the resource
#send("recompute priority") %>%
#timeout(0) %>%
release("resource")
test<-env %>%
add_resource("resource",preemptive = TRUE) %>%
add_generator("dummy", custom, at(0,8,16)) %>%
add_generator("monitor", monitor, at(0)) %>%
run()
test %>% get_mon_arrivals()
Hi Iñaki,
Thank you so much for your help. I now understand that the signal is sent only from a dummy when the dummy is about to release the resource. In our case, dummy2 meets a condition to have its priority upgraded, but since dummy1 is still holding the resource, the signal isn't sent, preventing dummy2 from preempting dummy1.
What I need is for any dummy to have its priority upgraded at any point in time if it meets certain conditions. It's similar to a real-world scenario where a monitor continuously checks the queue to see if any dummy satisfies the conditions.
I've modified your code by adding a "monitor" trajectory. The monitor's only function is to continuously send out a signal. It seems to solve my problem,
but the issue is that I had to use a timeout to repeatedly send the signal from the monitor. Is there a way to do this without relying on the timeout in the loop? thanks alot.
To view this discussion on the web visit https://groups.google.com/d/msgid/simmer-devel/c92107fe-8257-47cf-aa3e-392f74444f9bn%40googlegroups.com.