A new version of the Discrete-Event Simulator for R was released a few days ago on CRAN. The most interesting new feature is the implementation of the subsetting operators [
and [[
for trajectory objects. Basically, think about trajectories as lists of activities and these operators will do (almost) everything you expect.
library(simmer)
t0 <- trajectory() %>%
seize("resource", 1) %>%
timeout(function() rexp(1, 2)) %>%
release("resource", 2)
t0
## trajectory: anonymous, 3 activities
## { Activity: Seize | resource: resource | amount: 1 }
## { Activity: Timeout | delay: 0x55ffd06c5858 }
## { Activity: Release | resource: resource | amount: 2 }
t0[c(3, 1)]
## trajectory: anonymous, 2 activities
## { Activity: Release | resource: resource | amount: 2 }
## { Activity: Seize | resource: resource | amount: 1 }
After the last maintenance update (v3.5.1), which fixed several bugs and included a new interesting vignette with SimPy examples translated to ‘simmer’, this v3.6.0 comes hand in hand with the first ‘simmer’ extension released on CRAN: simmer.plot.
The primary purpose of ‘simmer.plot’ is to detach plotting capabilities from the core package, to systematise and enhance them. If you were using any of the old plot_*()
functions, you will get a deprecation warning pointing to the S3 method simmer.plot::plot.simmer
. This vignette will help you make the transition.
‘simmer.plot’ also implements a new plot
S3 method for trajectories. It produces a diagram of a given trajectory object, which is very helpful for debugging and checking that everything conforms your simulation model. Let us consider, for instance, the following pretty complex trajectory:
t0 <- trajectory() %>%
seize("res0", 1) %>%
branch(function() 1, c(TRUE, FALSE),
trajectory() %>%
clone(2,
trajectory() %>%
seize("res1", 1) %>%
timeout(1) %>%
release("res1", 1),
trajectory() %>%
trap("signal",
handler=trajectory() %>%
timeout(1)) %>%
timeout(1)),
trajectory() %>%
set_attribute("dummy", 1) %>%
seize("res2", function() 1) %>%
timeout(function() rnorm(1, 20)) %>%
release("res2", function() 1) %>%
release("res0", 1) %>%
rollback(11)) %>%
synchronize() %>%
rollback(2) %>%
release("res0", 1)
We must ensure that:
- Resources are seized and released as we expect.
- Branches end (or continue) where we expect.
- Rollbacks point back to the activity we expect.
- …
Things are indeed much easier if you can just inspect it visually:
library(simmer.plot)
plot(t0)
Note that different resources are mapped to a qualitative color scale, so that you can quickly glance whether you placed the appropriate seizes/releases for each resource.
Other interesting ‘simmer’ extensions are already on our roadmap. Particularly, Bart has been simmering a new package (still under development) called simmer.optim, which brings parameter optimisation to ‘simmer’. While ‘simmer’, as is, can help you answer a question like the following:
If we have x amount of resources of type A, what will the average waiting time in the process be?
‘simmer.optim’ is targeted to a reformulation like this:
What amount x of resources of type A minimises the waiting time, while still maintaining a utilisation level of ?
We would be very grateful if someone with experience on DES optimisation could try it out and give us some feedback. Simply install it from GitHub using ‘devtools’
devtools::install_github("r-simmer/simmer.optim")
and start from the README, which demonstrates the current functionalities.