-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.json
1 lines (1 loc) · 339 KB
/
search.json
1
[{"path":"https://r-simmer.org/articles/simmer-01-introduction.html","id":"basic-usage","dir":"Articles","previous_headings":"","what":"Basic usage","title":"Introduction to simmer","text":"First, load package instantiate new simulation environment. Set-simple trajectory. Let’s say want simulate ambulatory consultation patient first seen nurse intake, next doctor consultation finally administrative staff schedule follow-appointment. case, argument timeout activity function, evaluated dynamically produce stochastic waiting time, constant . Apart , function may complex need may whatever want: interact entities simulation model, get resources’ status, make decisions according latter… trajectory known, may attach arrivals define resources needed. example , three types resources added: nurse administration resources, one capacity 1, doctor resource, capacity 2. last method adds generator arrivals (patients) following trajectory patient. time patients 10 minutes (Gaussian mean=10 sd=2). (Note: returning negative interarrival time point stop generator). simulation now ready test run; just let simmer bit. , specify want limit runtime 80 time units using argument. , verify current simulation time (now) next 3 events (peek). possible run simulation step step, method chainable . Also, possible resume automatic execution simply specifying longer runtime. , continue execution 120 time units. can also reset simulation, flush results, resources generators, restart beginning.","code":"library(simmer) set.seed(42) env <- simmer(\"SuperDuperSim\") env #> simmer environment: SuperDuperSim | now: 0 | next: #> { Monitor: in memory } patient <- trajectory(\"patients' path\") %>% ## add an intake activity seize(\"nurse\", 1) %>% timeout(function() rnorm(1, 15)) %>% release(\"nurse\", 1) %>% ## add a consultation activity seize(\"doctor\", 1) %>% timeout(function() rnorm(1, 20)) %>% release(\"doctor\", 1) %>% ## add a planning activity seize(\"administration\", 1) %>% timeout(function() rnorm(1, 5)) %>% release(\"administration\", 1) env %>% add_resource(\"nurse\", 1) %>% add_resource(\"doctor\", 2) %>% add_resource(\"administration\", 1) %>% add_generator(\"patient\", patient, function() rnorm(1, 10, 2)) #> simmer environment: SuperDuperSim | now: 0 | next: 0 #> { Monitor: in memory } #> { Resource: nurse | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Resource: doctor | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) } #> { Resource: administration | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: patient | monitored: 1 | n_generated: 0 } env %>% run(80) %>% now() #> [1] 80 env %>% peek(3) #> [1] 80.69540 81.62105 81.62105 env %>% stepn() %>% # 1 step print() %>% stepn(3) # 3 steps #> simmer environment: SuperDuperSim | now: 80.6953988949657 | next: 80.6953988949657 #> { Monitor: in memory } #> { Resource: nurse | monitored: TRUE | server status: 1(1) | queue status: 1(Inf) } #> { Resource: doctor | monitored: TRUE | server status: 1(2) | queue status: 0(Inf) } #> { Resource: administration | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: patient | monitored: 1 | n_generated: 7 } #> simmer environment: SuperDuperSim | now: 81.6210531397386 | next: 81.6210531397386 #> { Monitor: in memory } #> { Resource: nurse | monitored: TRUE | server status: 1(1) | queue status: 2(Inf) } #> { Resource: doctor | monitored: TRUE | server status: 1(2) | queue status: 0(Inf) } #> { Resource: administration | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: patient | monitored: 1 | n_generated: 7 } env %>% peek(Inf, verbose=TRUE) #> time process #> 1 81.62105 patient #> 2 86.74154 patient4 #> 3 89.36934 patient3 env %>% run(120) %>% now() #> [1] 120 env %>% reset() %>% run(80) %>% now() #> [1] 80"},{"path":"https://r-simmer.org/articles/simmer-01-introduction.html","id":"replication","dir":"Articles","previous_headings":"","what":"Replication","title":"Introduction to simmer","text":"easy replicate simulation multiple times using standard R functions. advantage latter approach , individual replicas heavy, straightforward parallelise execution (instance, next example use function mclapply parallel) package. However, external pointers C++ simmer core longer valid parallelised execution ends. Thus, necessary extract results thread end execution. can done helper function wrap follows. helper function brings simulation data back R makes accessible methods ordinarily used simmer environment. Unfortunately, C++ simulation cores destroyed, downside kind parallelization one resume execution replicas.","code":"envs <- lapply(1:100, function(i) { simmer(\"SuperDuperSim\") %>% add_resource(\"nurse\", 1) %>% add_resource(\"doctor\", 2) %>% add_resource(\"administration\", 1) %>% add_generator(\"patient\", patient, function() rnorm(1, 10, 2)) %>% run(80) }) library(parallel) envs <- mclapply(1:100, function(i) { simmer(\"SuperDuperSim\") %>% add_resource(\"nurse\", 1) %>% add_resource(\"doctor\", 2) %>% add_resource(\"administration\", 1) %>% add_generator(\"patient\", patient, function() rnorm(1, 10, 2)) %>% run(80) %>% wrap() }) envs[[1]] %>% get_n_generated(\"patient\") #> [1] 8 envs[[1]] %>% get_queue_count(\"doctor\") #> [1] 0 envs[[1]] %>% get_queue_size(\"doctor\") #> [1] Inf envs %>% get_mon_resources() %>% head() #> resource time server queue capacity queue_size system limit replication #> 1 nurse 9.584649 1 0 1 Inf 1 Inf 1 #> 2 nurse 21.456291 1 1 1 Inf 2 Inf 1 #> 3 nurse 25.608300 1 0 1 Inf 1 Inf 1 #> 4 doctor 25.608300 1 0 2 Inf 1 Inf 1 #> 5 nurse 31.368188 1 1 1 Inf 2 Inf 1 #> 6 nurse 40.273794 1 0 1 Inf 1 Inf 1 envs %>% get_mon_arrivals() %>% head() #> name start_time end_time activity_time finished replication #> 1 patient0 9.584649 48.87690 39.29225 TRUE 1 #> 2 patient1 21.456291 62.39177 36.78347 TRUE 1 #> 3 patient0 6.582937 45.98016 39.39722 TRUE 2 #> 4 patient1 18.105428 59.39427 40.01821 TRUE 2 #> 5 patient2 24.048864 75.18522 39.97037 TRUE 2 #> 6 patient0 10.242791 48.46888 38.22609 TRUE 3"},{"path":"https://r-simmer.org/articles/simmer-01-introduction.html","id":"basic-visualisation-tools","dir":"Articles","previous_headings":"","what":"Basic visualisation tools","title":"Introduction to simmer","text":"may want try simmer.plot package, plugin simmer provides basic visualisation tools help take quick glance simulation results debug trajectory object: Plotting simmer statistics Plotting simmer trajectories.","code":""},{"path":"https://r-simmer.org/articles/simmer-03-trajectories.html","id":"available-set-of-activities","dir":"Articles","previous_headings":"","what":"Available set of activities","title":"Advanced Trajectory Usage","text":"generator creates arrival, couples arrival given trajectory. trajectory defined interlinkage activities together form arrivals’ lifetime system. arrival coupled trajectory, (general) start processing activities specified order , eventually, leave system. Consider following: create trajectory patient seizes doctor 3 minutes releases . straightforward example, however, trajectory-related functions allow advanced usage. Usage examples provided help page activity. complete set activities can found navigated reference page, can list follows: Additionally, may want try simmer.bricks package, plugin simmer provides helper methods trajectories. brick wraps common activity pattern can used build trajectories conveniently (see Introduction simmer.bricks).","code":"traj <- trajectory() %>% seize(resource = \"doctor\", amount = 1) %>% timeout(task = 3) %>% release(resource = \"doctor\", amount = 1) methods(class=\"trajectory\") #> [1] [ [[ [[<- #> [4] [<- activate batch #> [7] branch clone deactivate #> [10] get_n_activities handle_unfinished join #> [13] leave length log_ #> [16] print release_all release_selected_all #> [19] release_selected release renege_abort #> [22] renege_if renege_in rep #> [25] rollback seize_selected seize #> [28] select send separate #> [31] set_attribute set_capacity_selected set_capacity #> [34] set_global set_prioritization set_queue_size_selected #> [37] set_queue_size set_source set_trajectory #> [40] stop_if synchronize timeout_from_attribute #> [43] timeout_from_global timeout trap #> [46] untrap wait #> see '?methods' for accessing help and source code"},{"path":"https://r-simmer.org/articles/simmer-03-trajectories.html","id":"dynamic-arguments","dir":"Articles","previous_headings":"","what":"Dynamic arguments","title":"Advanced Trajectory Usage","text":"Many activities accept functions arguments evaluated dynamically simulation. example, see help(timeout): task: timeout duration supplied either passing numeric callable object (function) must return numeric. aware want timeout()’s task parameter evaluated dynamically, supply callable function. example timeout(function() rexp(1, 10)), rexp(1, 10) evaluated every time timeout activity executed. However, supply form timeout(rexp(1, 10)), evaluated trajectory defined, remain static . course, task, supplied function, may complex need , instance, may check status particular resource, interact entities simulation model… applies activities accept function parameter.","code":"trajectory() %>% timeout(rexp(1, 10)) %>% # fixed timeout(function() rexp(1, 10)) # dynamic #> trajectory: anonymous, 2 activities #> { Activity: Timeout | delay: 0.237144 } #> { Activity: Timeout | delay: function() }"},{"path":"https://r-simmer.org/articles/simmer-03-trajectories.html","id":"interaction-with-the-environment","dir":"Articles","previous_headings":"","what":"Interaction with the environment","title":"Advanced Trajectory Usage","text":"Dynamic arguments may interact environment extract parameters interest current simulation time (see ?now), status resources (see ?get_capacity), status generators (see ?get_n_generated), directly gather history monitored values (see ?get_mon). requirement simulation environment must scope trajectory. Therefore, work: global env available runtime: simulation runs resulting object assigned env. env scope t simulation, enough detach run() method definition pipe: get expected output. However, general rule good practice, recommended instantiate environment always first place avoid possible mistakes, code becomes readable:","code":"traj <- trajectory() %>% log_(function() as.character(now(env))) env <- simmer() %>% add_generator(\"dummy\", traj, function() 1) %>% run(4) #> 1: dummy0: #> Error in (function () : object 'env' not found traj <- trajectory() %>% log_(function() as.character(now(env))) env <- simmer() %>% add_generator(\"dummy\", traj, function() 1) env %>% run(4) %>% invisible #> 1: dummy0: 1 #> 2: dummy1: 2 #> 3: dummy2: 3 # first, instantiate the environment env <- simmer() # here I'm using it traj <- trajectory() %>% log_(function() as.character(now(env))) # and finally, run it env %>% add_generator(\"dummy\", traj, function() 1) %>% run(4) %>% invisible #> 1: dummy0: 1 #> 2: dummy1: 2 #> 3: dummy2: 3"},{"path":"https://r-simmer.org/articles/simmer-03-trajectories.html","id":"trajectory-toolbox-joining-and-subsetting","dir":"Articles","previous_headings":"","what":"Trajectory toolbox: joining and subsetting","title":"Advanced Trajectory Usage","text":"join(...) method useful concatenate together number trajectories. may used standalone function follows: may operate inline, like another activity: can think trajectory object list activities length can subset using standard operator [. instance, can select activities want logical vector: set indices respect order given: set indices remove selection: name, note respect order given though, performs match: provide indices, whole trajectory returned: fact, cloning trajectory latter command. equivalent t0[1:length(t0)] join(t0). generics head() tail() use [ operator hood, thus can use well: [[ operator can also used extract one element: equivalent t0[2]. string provided, ensures first match returned:","code":"t1 <- trajectory() %>% seize(\"dummy\", 1) t2 <- trajectory() %>% timeout(1) t3 <- trajectory() %>% release(\"dummy\", 1) t0 <- join(t1, t2, t3) t0 #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Timeout | delay: 1 } #> { Activity: Release | resource: dummy, amount: 1 } t0 <- trajectory() %>% join(t1) %>% timeout(1) %>% join(t3) t0 #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Timeout | delay: 1 } #> { Activity: Release | resource: dummy, amount: 1 } length(t0) #> [1] 3 t0[c(TRUE, FALSE, TRUE)] #> trajectory: anonymous, 2 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Release | resource: dummy, amount: 1 } t0[c(1, 3)] #> trajectory: anonymous, 2 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Release | resource: dummy, amount: 1 } t0[c(3, 1)] #> trajectory: anonymous, 2 activities #> { Activity: Release | resource: dummy, amount: 1 } #> { Activity: Seize | resource: dummy, amount: 1 } t0[-2] #> trajectory: anonymous, 2 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Release | resource: dummy, amount: 1 } t0[c(\"seize\", \"release\")] #> trajectory: anonymous, 2 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Release | resource: dummy, amount: 1 } t0[c(\"release\", \"seize\")] #> trajectory: anonymous, 2 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Release | resource: dummy, amount: 1 } t0[] #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Timeout | delay: 1 } #> { Activity: Release | resource: dummy, amount: 1 } head(t0, 2) #> trajectory: anonymous, 2 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Timeout | delay: 1 } tail(t0, -1) #> trajectory: anonymous, 2 activities #> { Activity: Timeout | delay: 1 } #> { Activity: Release | resource: dummy, amount: 1 } t0[[2]] #> trajectory: anonymous, 1 activities #> { Activity: Timeout | delay: 1 } join(t0, t0)[\"timeout\"] #> trajectory: anonymous, 2 activities #> { Activity: Timeout | delay: 1 } #> { Activity: Timeout | delay: 1 } join(t0, t0)[[\"timeout\"]] #> trajectory: anonymous, 1 activities #> { Activity: Timeout | delay: 1 }"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"The Bank Tutorial: Part I","text":"tutorial adapted tutorial Python 2 package ‘SimPy’, . Users familiar SimPy may find tutorial helpful transitioning simmer.","code":""},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"a-single-customer","dir":"Articles","previous_headings":"","what":"A single customer","title":"The Bank Tutorial: Part I","text":"tutorial model simple bank customers arriving random. develop model step--step, starting simply, producing running program stage. simulation always developed answer specific question; models investigate changing number bank servers tellers might affect waiting time customers.","code":""},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"a-customer-arriving-at-a-fixed-time","dir":"Articles","previous_headings":"A single customer","what":"A customer arriving at a fixed time","title":"The Bank Tutorial: Part I","text":"first model single customer arrives bank visit, looks around decor time leaves. queueing. First assume arrival time time spends bank fixed. arrival time fixed 5, time spent bank fixed 10. interpret ‘5’ ‘10’ ‘5 minutes’ ‘10 minutes’. simulation runs maximum 100 minutes, customers generated complete trajectories. Note constants appear code . short trace printed get_mon_arrivals function shows result. program finishes simulation time 15 events executed. end visit, customer actions objects customers active.","code":"library(simmer) customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% timeout(10) %>% log_(\"I must leave\") bank <- simmer(\"bank\") %>% add_generator(\"Customer\", customer, at(5)) bank %>% run(until = 100) #> 5: Customer0: Here I am #> 15: Customer0: I must leave #> simmer environment: bank | now: 15 | next: #> { Monitor: in memory } #> { Source: Customer | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 Customer0 5 15 10 TRUE 1"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"a-customer-arriving-at-random","dir":"Articles","previous_headings":"A single customer","what":"A customer arriving at random","title":"The Bank Tutorial: Part I","text":"Now extend model allow customer arrive random simulated time though keep time bank 10, . change occurs arguments add_generator function. function rexp draws exponential distribution given parameter, case 1/5. See ?rexp details. also seed random number generator 10211 sequence random numbers drawn every time script run. trace shows customer now arrives time 7.839305. Changing seed value change time.","code":"library(simmer) set.seed(10212) customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% timeout(10) %>% log_(\"I must leave\") bank <- simmer(\"bank\") %>% add_generator(\"Customer\", customer, at(rexp(1, 1/5))) bank %>% run(until = 100) #> 7.8393: Customer0: Here I am #> 17.8393: Customer0: I must leave #> simmer environment: bank | now: 17.8393046225526 | next: #> { Monitor: in memory } #> { Source: Customer | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 Customer0 7.839305 17.8393 10 TRUE 1"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"more-customers","dir":"Articles","previous_headings":"A single customer","what":"More customers","title":"The Bank Tutorial: Part I","text":"simulation little far. consider simulation several customers return simple deterministic model add customers. program almost easy first example (customer arriving fixed time). main change add_generator function, generate three customers defining three start times. also increase maximum simulation time 400 run function. Observe need one definition customer trajectory, generate several customers follow trajectory. customers act quite independently model. customer also stays bank different, non-random, amount time. unusual case, requires unusual bit R code. timeout function accepts either constant waiting time, function called per customer returns single value (e.g. rexp(1, 1/10)). need create function returns different, specific, value time called. define function called loop . loop function returns another function. example, store function name x. called, function x returns one (example) 7, 10, 20, sequence, wrapping around called fourth time. technical term loop function ‘closure’. closures work beyond scope vignette; wish learn , Advanced R Hadley Wickam good explanation. use loop timeout function, don’t need assign output name; can ‘anonymous’ function. called whenever customer wait needs know long wait . three customers generated, first step timeout step, assigned 7, 10, 20 order. Note code differs SimPy order customers defined. , first customer defined one arrives 2 waits 7. arguments () must ascending order. Alternatively, can create three different customer trajectories three waiting times. best done creating initial template, modifying waiting time copy. Note order customers defined matter time, can also name customer. , simulations finish 400 specified run function.","code":"# Function to specify a series of waiting times, that loop around loop <- function(...) { time_diffs <- c(...) i <- 0 function() { if (i < length(time_diffs)) { i <<- i+1 } else { i <<- 1 } return(time_diffs[i]) } } x <- loop(10, 7, 20) x(); x(); x(); x(); x() #> [1] 10 #> [1] 7 #> [1] 20 #> [1] 10 #> [1] 7 library(simmer) # Function to specify a series of waiting times in a loop loop <- function(...) { time_diffs <- c(...) i <- 0 function() { if (i < length(time_diffs)) { i <<- i+1 } else { i <<- 1 } return(time_diffs[i]) } } customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% timeout(loop(7, 10, 20)) %>% log_(\"I must leave\") bank <- simmer(\"bank\") %>% add_generator(\"Customer\", customer, at(2, 5, 12)) bank %>% run(until = 400) #> 2: Customer0: Here I am #> 5: Customer1: Here I am #> 9: Customer0: I must leave #> 12: Customer2: Here I am #> 15: Customer1: I must leave #> 32: Customer2: I must leave #> simmer environment: bank | now: 32 | next: #> { Monitor: in memory } #> { Source: Customer | monitored: 1 | n_generated: 3 } bank %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 Customer0 2 9 7 TRUE 1 #> 2 Customer1 5 15 10 TRUE 1 #> 3 Customer2 12 32 20 TRUE 1 library(simmer) # Create a template trajectory customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% timeout(1) %>% # The timeout of 1 is a placeholder to be overwritten later log_(\"I must leave\") # Create three copies of the template Klaus <- customer Tony <- customer Evelyn <- customer # Modify the timeout of each copy Klaus[2] <- timeout(trajectory(), 10) Tony[2] <- timeout(trajectory(), 7) Evelyn[2] <- timeout(trajectory(), 20) # Check that the modifications worked Klaus #> trajectory: Customer's path, 3 activities #> { Activity: Log | message: Here I am, level: 0 } #> { Activity: Timeout | delay: 10 } #> { Activity: Log | message: I must lea..., level: 0 } Tony #> trajectory: Customer's path, 3 activities #> { Activity: Log | message: Here I am, level: 0 } #> { Activity: Timeout | delay: 7 } #> { Activity: Log | message: I must lea..., level: 0 } Evelyn #> trajectory: Customer's path, 3 activities #> { Activity: Log | message: Here I am, level: 0 } #> { Activity: Timeout | delay: 20 } #> { Activity: Log | message: I must lea..., level: 0 } bank <- simmer(\"bank\") %>% add_generator(\"Klaus\", Klaus, at(5)) %>% add_generator(\"Tony\", Tony, at(2)) %>% add_generator(\"Evelyn\", Evelyn, at(12)) bank %>% run(until = 400) #> 2: Tony0: Here I am #> 5: Klaus0: Here I am #> 9: Tony0: I must leave #> 12: Evelyn0: Here I am #> 15: Klaus0: I must leave #> 32: Evelyn0: I must leave #> simmer environment: bank | now: 32 | next: #> { Monitor: in memory } #> { Source: Klaus | monitored: 1 | n_generated: 1 } #> { Source: Tony | monitored: 1 | n_generated: 1 } #> { Source: Evelyn | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 Tony0 2 9 7 TRUE 1 #> 2 Klaus0 5 15 10 TRUE 1 #> 3 Evelyn0 12 32 20 TRUE 1"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"many-customers","dir":"Articles","previous_headings":"A single customer","what":"Many customers","title":"The Bank Tutorial: Part I","text":"Another change allow us customers. make things clearer use random numbers model. change add_generator function, use convenience function from_to create sequence start times five customers, starting time 0, interarrival time 10 customer. One idiosyncracy syntax arrival created time, give 41, one unit last arrival generated. Another interarrival time must specified function, hence define constant function function() {10}","code":"library(simmer) customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% timeout(12) %>% log_(\"I must leave\") bank <- simmer(\"bank\") %>% add_generator(\"Customer\", customer, from_to(0, 41, function() {10})) bank %>% run(until = 400) #> 0: Customer0: Here I am #> 10: Customer1: Here I am #> 12: Customer0: I must leave #> 20: Customer2: Here I am #> 22: Customer1: I must leave #> 30: Customer3: Here I am #> 32: Customer2: I must leave #> 40: Customer4: Here I am #> 42: Customer3: I must leave #> 52: Customer4: I must leave #> simmer environment: bank | now: 52 | next: #> { Monitor: in memory } #> { Source: Customer | monitored: 1 | n_generated: 5 } bank %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 Customer0 0 12 12 TRUE 1 #> 2 Customer1 10 22 12 TRUE 1 #> 3 Customer2 20 32 12 TRUE 1 #> 4 Customer3 30 42 12 TRUE 1 #> 5 Customer4 40 52 12 TRUE 1"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"many-random-customers","dir":"Articles","previous_headings":"A single customer","what":"Many random customers","title":"The Bank Tutorial: Part I","text":"now extend model allow arrivals random. simulation usually interpreted meaning times customer arrivals distributed exponential random variates. little change program. difference previous example single customer generated random time example generates several customers different random times. change occurs arguments add_generator function. function rexp draws exponential distribution given parameter, case 1/10. See ?rexp details. also seed random number generator 1289 sequence random numbers drawn every time script run. 0 time first customer, four random interarrival times drawn, final -1 stops generator. reason use from_to function want control number arrivals generated, rather end-time arrival generation.","code":"library(simmer) set.seed(1289) customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% timeout(12) %>% log_(\"I must leave\") bank <- simmer(\"bank\") %>% add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) bank %>% run(until = 400) #> 0: Customer0: Here I am #> 12: Customer0: I must leave #> 14.3114: Customer1: Here I am #> 26.3114: Customer1: I must leave #> 26.5588: Customer2: Here I am #> 35.8506: Customer3: Here I am #> 38.2706: Customer4: Here I am #> 38.5588: Customer2: I must leave #> 47.8506: Customer3: I must leave #> 50.2706: Customer4: I must leave #> simmer environment: bank | now: 50.2705868901582 | next: #> { Monitor: in memory } #> { Source: Customer | monitored: 1 | n_generated: 5 } bank %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 Customer0 0.00000 12.00000 12 TRUE 1 #> 2 Customer1 14.31136 26.31136 12 TRUE 1 #> 3 Customer2 26.55882 38.55882 12 TRUE 1 #> 4 Customer3 35.85064 47.85064 12 TRUE 1 #> 5 Customer4 38.27059 50.27059 12 TRUE 1"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"a-service-counter","dir":"Articles","previous_headings":"","what":"A Service counter","title":"The Bank Tutorial: Part I","text":"far, model like art gallery, customers entering, looking around, leaving. Now going require service bank clerk. extend model include service counter modelled ‘resource’. actions Resource simple: customer requests unit resource (clerk). one free, customer gets service (unit longer available customers). free clerk, customer joins queue (managed resource object) customer’s turn served. customer completes service releases unit, clerk can start serving next line.","code":""},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"one-service-counter","dir":"Articles","previous_headings":"A Service counter","what":"One Service counter","title":"The Bank Tutorial: Part I","text":"service counter created add_resource function. Default arguments specify can serve one customer time, infinite queueing capacity. seize function causes customer join queue counter. queue empty counter available (serving customers), customer claims counter moves onto timeout step. Otherwise customer must wait counter becomes available. Behaviour customer queue controlled arguments seize function, rather functions. timeout step complete, release function causes customer make counter available customers queue. Since activity trace produce waiting time default, calculated appended using transform function. Examining trace see first two customers get instant service others wait. still five customers, draw general conclusions.","code":"library(simmer) set.seed(1234) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% seize(\"counter\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(12) %>% release(\"counter\") %>% log_(\"Finished\") bank <- simmer(\"bank\") %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) bank %>% run(until = 400) #> 0: Customer0: Here I am #> 0: Customer0: Waited: 0 #> 12: Customer0: Finished #> 25.0176: Customer1: Here I am #> 25.0176: Customer1: Waited: 0 #> 27.4852: Customer2: Here I am #> 27.551: Customer3: Here I am #> 37.0176: Customer1: Finished #> 37.0176: Customer2: Waited: 9.53241116646677 #> 44.9785: Customer4: Here I am #> 49.0176: Customer2: Finished #> 49.0176: Customer3: Waited: 21.466591599012 #> 61.0176: Customer3: Finished #> 61.0176: Customer4: Waited: 16.0391307005949 #> 73.0176: Customer4: Finished #> simmer environment: bank | now: 73.0175860496223 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication waiting_time #> 1 Customer0 0.00000 12.00000 12 TRUE 1 0.000000 #> 2 Customer1 25.01759 37.01759 12 TRUE 1 0.000000 #> 3 Customer2 27.48517 49.01759 12 TRUE 1 9.532411 #> 4 Customer3 27.55099 61.01759 12 TRUE 1 21.466592 #> 5 Customer4 44.97846 73.01759 12 TRUE 1 16.039131"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"a-server-with-a-random-service-time","dir":"Articles","previous_headings":"A Service counter","what":"A server with a random service time","title":"The Bank Tutorial: Part I","text":"simple change model retain single service counter make customer service time random variable. traditional study simple queues first assume exponential service time. Note argument timeout must function, otherwise apply constant timeout every customer. model random arrivals exponential service times example M/M/1 queue rather easily solved analytically calculate steady-state mean waiting time operating characteristics. (easily solved transient behavior.)","code":"library(simmer) set.seed(1269) customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% seize(\"counter\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% # timeout(rexp(1, 1/12)) would generate a single random time and use it for # every arrival, whereas the following line generates a random time for each # arrival timeout(function() {rexp(1, 1/12)}) %>% release(\"counter\") %>% log_(\"Finished\") bank <- simmer(\"bank\") %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) bank %>% run(until = 400) #> 0: Customer0: Here I am #> 0: Customer0: Waited: 0 #> 3.68365: Customer1: Here I am #> 3.89529: Customer2: Here I am #> 4.91521: Customer0: Finished #> 4.91521: Customer1: Waited: 1.23156707156024 #> 10.961: Customer3: Here I am #> 12.4143: Customer4: Here I am #> 21.0552: Customer1: Finished #> 21.0552: Customer2: Waited: 17.1598927142276 #> 65.3116: Customer2: Finished #> 65.3116: Customer3: Waited: 54.3505873236467 #> 80.1134: Customer3: Finished #> 80.1134: Customer4: Waited: 67.6990166719428 #> 93.7286: Customer4: Finished #> simmer environment: bank | now: 93.7285504163997 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication #> 1 Customer0 0.000000 4.915215 4.915215 TRUE 1 #> 2 Customer1 3.683648 21.055183 16.139968 TRUE 1 #> 3 Customer2 3.895290 65.311551 44.256368 TRUE 1 #> 4 Customer3 10.960963 80.113355 14.801804 TRUE 1 #> 5 Customer4 12.414338 93.728550 13.615196 TRUE 1 #> waiting_time #> 1 0.000000 #> 2 1.231567 #> 3 17.159893 #> 4 54.350587 #> 5 67.699017"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"several-service-counters","dir":"Articles","previous_headings":"","what":"Several Service Counters","title":"The Bank Tutorial: Part I","text":"introduce several counters must decide queue discipline. customers going make one queue going form separate queues front counter? complications - allowed switch lines (jockey)? first consider single queue several counters later consider separate isolated queues. look jockeying.","code":""},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"several-counters-but-a-single-queue","dir":"Articles","previous_headings":"Several Service Counters","what":"Several Counters but a Single Queue","title":"The Bank Tutorial: Part I","text":"model bank whose customers arrive randomly served group counters, taking random time service, assume waiting customers form single first-first-queue. difference model single-server model add_resource function, increased capacity two can serve two customers . waiting times model much shorter single service counter. example, waiting time Customer3 reduced nearly 17 minutes less 9. customers processed draw general conclusions.","code":"library(simmer) set.seed(1269) customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% seize(\"counter\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(function() {rexp(1, 1/12)}) %>% release(\"counter\") %>% log_(\"Finished\") bank <- simmer(\"bank\") %>% add_resource(\"counter\", 2) %>% # Here is the change add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) bank %>% run(until = 400) #> 0: Customer0: Here I am #> 0: Customer0: Waited: 0 #> 3.68365: Customer1: Here I am #> 3.68365: Customer1: Waited: 0 #> 3.89529: Customer2: Here I am #> 4.91521: Customer0: Finished #> 4.91521: Customer2: Waited: 1.01992474790691 #> 10.961: Customer3: Here I am #> 12.4143: Customer4: Here I am #> 19.8236: Customer1: Finished #> 19.8236: Customer3: Waited: 8.86265226572255 #> 34.6254: Customer3: Finished #> 34.6254: Customer4: Waited: 22.2110816140186 #> 48.2406: Customer4: Finished #> 49.1716: Customer2: Finished #> simmer environment: bank | now: 49.1715828181142 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication #> 1 Customer0 0.000000 4.915215 4.915215 TRUE 1 #> 2 Customer1 3.683648 19.823616 16.139968 TRUE 1 #> 3 Customer3 10.960963 34.625419 14.801804 TRUE 1 #> 4 Customer4 12.414338 48.240615 13.615196 TRUE 1 #> 5 Customer2 3.895290 49.171583 44.256368 TRUE 1 #> waiting_time #> 1 0.000000 #> 2 0.000000 #> 3 8.862652 #> 4 22.211082 #> 5 1.019925"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"several-counters-with-individual-queues","dir":"Articles","previous_headings":"Several Service Counters","what":"Several Counters with individual queues","title":"The Bank Tutorial: Part I","text":"counter now assumed queue. programming complicated customer decide queue join. obvious technique make counter separate resource. practice, customer might join shortest queue. implement behaviour first selecting shortest queue, using select function. use seize_selected enter chosen queue, later release_selected. rest program . results show customers chose counter smallest number. Unlucky Customer2 joins wrong queue wait Customer0 finishes time 62.10372, last leave. , however, arrivals runs, limited five customers, draw general conclusions relative efficiencies two systems.","code":"library(simmer) set.seed(1014) customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% select(c(\"counter1\", \"counter2\"), policy = \"shortest-queue\") %>% seize_selected() %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(function() {rexp(1, 1/12)}) %>% release_selected() %>% log_(\"Finished\") bank <- simmer(\"bank\") %>% add_resource(\"counter1\", 1) %>% add_resource(\"counter2\", 1) %>% add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) bank %>% run(until = 400) #> 0: Customer0: Here I am #> 0: Customer0: Waited: 0 #> 23.7144: Customer1: Here I am #> 23.7144: Customer1: Waited: 0 #> 30.4011: Customer2: Here I am #> 32.4163: Customer3: Here I am #> 33.941: Customer1: Finished #> 33.941: Customer3: Waited: 1.52471543798104 #> 39.5302: Customer3: Finished #> 48.8559: Customer4: Here I am #> 48.8559: Customer4: Waited: 0 #> 55.3965: Customer4: Finished #> 62.1037: Customer0: Finished #> 62.1037: Customer2: Waited: 31.7026170465295 #> 62.3885: Customer2: Finished #> simmer environment: bank | now: 62.3885266177193 | next: #> { Monitor: in memory } #> { Resource: counter1 | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Resource: counter2 | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } bank %>% get_mon_arrivals() %>% transform(service_start_time = end_time - activity_time) %>% .[order(.$start_time),] #> name start_time end_time activity_time finished replication #> 4 Customer0 0.00000 62.10372 62.1037152 TRUE 1 #> 1 Customer1 23.71444 33.94103 10.2265939 TRUE 1 #> 5 Customer2 30.40110 62.38853 0.2848114 TRUE 1 #> 2 Customer3 32.41632 39.53020 5.5891677 TRUE 1 #> 3 Customer4 48.85593 55.39645 6.5405163 TRUE 1 #> service_start_time #> 4 0.00000 #> 1 23.71444 #> 5 62.10372 #> 2 33.94103 #> 3 48.85593 bank %>% get_mon_resources() %>% .[order(.$time),] #> resource time server queue capacity queue_size system limit replication #> 1 counter1 0.00000 1 0 1 Inf 1 Inf 1 #> 2 counter2 23.71444 1 0 1 Inf 1 Inf 1 #> 3 counter1 30.40110 1 1 1 Inf 2 Inf 1 #> 4 counter2 32.41632 1 1 1 Inf 2 Inf 1 #> 5 counter2 33.94103 1 0 1 Inf 1 Inf 1 #> 6 counter2 39.53020 0 0 1 Inf 0 Inf 1 #> 7 counter2 48.85593 1 0 1 Inf 1 Inf 1 #> 8 counter2 55.39645 0 0 1 Inf 0 Inf 1 #> 9 counter1 62.10372 1 0 1 Inf 1 Inf 1 #> 10 counter1 62.38853 0 0 1 Inf 0 Inf 1"},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"the-bank-with-a-monitor-aka-summary-statistics","dir":"Articles","previous_headings":"Several Service Counters","what":"The bank with a monitor (aka summary statistics)","title":"The Bank Tutorial: Part I","text":"now demonstrate calculate average waiting times customers. original SimPy version tutorial, involved using ‘Monitors’. simmer, data returned get_mon_* family functions, already demonstrated. , simply summarise data frame returned get_mon_arrivals function, using standard R functions. also increase number customers 50 (find number ‘49’ code). average waiting time 50 customers 2-counter system reliable (.e., less subject random simulation effects) times measured still sufficiently reliable real-world decisions. also replicate runs using different random number seeds. result run :","code":"library(simmer) set.seed(100005) customer <- trajectory(\"Customer's path\") %>% seize(\"counter\") %>% timeout(function() {rexp(1, 1/12)}) %>% release(\"counter\") bank <- simmer(\"bank\") %>% add_resource(\"counter\", 2) %>% add_generator(\"Customer\", customer, function() {c(0, rexp(49, 1/10), -1)}) bank %>% run(until = 1000) #> simmer environment: bank | now: 650.615510598544 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 50 } result <- bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) paste(\"Average wait for \", sum(result$finished), \" completions was \", mean(result$waiting_time), \"minutes.\") #> [1] \"Average wait for 50 completions was 3.05085138406832 minutes.\""},{"path":"https://r-simmer.org/articles/simmer-04-bank-1.html","id":"multiple-runs","dir":"Articles","previous_headings":"Several Service Counters","what":"Multiple runs","title":"The Bank Tutorial: Part I","text":"get number independent measurements must replicate runs using different random number seeds. replication must independent previous ones, environment (bank) must redefined run, random interarrival times add_generator function generated scratch. take chunks code build environment (bank) run simulation, wrap mclapply function ‘parallel’ package. function runs simulation parallel, using available cores computer’s processor. use seeds reproducability, pass function runs simulation (function(the_seed)). results show variation. Remember, though, system still operating 50 customers, system may steady-state.","code":"library(simmer) library(parallel) customer <- trajectory(\"Customer's path\") %>% seize(\"counter\") %>% timeout(function() {rexp(1, 1/12)}) %>% release(\"counter\") mclapply(c(393943, 100005, 777999555, 319999772), function(the_seed) { set.seed(the_seed) bank <- simmer(\"bank\") %>% add_resource(\"counter\", 2) %>% add_generator(\"Customer\", customer, function() {c(0, rexp(49, 1/10), -1)}) bank %>% run(until = 400) result <- bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) paste(\"Average wait for \", sum(result$finished), \" completions was \", mean(result$waiting_time), \"minutes.\") }) %>% unlist() #> [1] \"Average wait for 49 completions was 3.4958501806687 minutes.\" #> [2] \"Average wait for 29 completions was 0.584941574937737 minutes.\" #> [3] \"Average wait for 32 completions was 1.00343842138177 minutes.\" #> [4] \"Average wait for 42 completions was 7.41231393636088 minutes.\""},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"The Bank Tutorial: Part II","text":"tutorial adapted tutorial Python 2 package ‘SimPy’, . Users familiar SimPy may find tutorial helpful transitioning simmer. basic material covered. Beginners first read Bank Tutorial: Part .","code":""},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"priority-customers","dir":"Articles","previous_headings":"","what":"Priority customers","title":"The Bank Tutorial: Part II","text":"many situations system priority service. customers high priority served first, low priority must wait. cases, preemptive priority even allow high-priority customer interrupt service one lower priority. Simmer implements priority requests extra integer priority argument add_generator(). default, priority zero; higher integers higher priority. operate, resource must created preemptive = TRUE.","code":""},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"priority-customers-without-preemption","dir":"Articles","previous_headings":"Priority customers","what":"Priority customers without preemption","title":"The Bank Tutorial: Part II","text":"first example, modify program random arrivals, one counter, fixed service time (like One Service counter Bank Tutorial: Part ) process high priority customer. , give customer priority. Since default priority = 0 easy . observe priority action, customers default priority 0, create activate one special customer, Guido, priority 1 arrives time 23. ensure arrives Customer2. Since activity trace produce waiting time default, calculated appended using transform function. output displays number customers queue just one arrives. count include customer service. Reading carefully one can see Guido arrives Customer0 served left 12, Customer1 service two (customers 2 3) queueing. Guido priority waiting served 24. Guido leaves 36, Customer2 starts service.","code":"library(simmer) set.seed(1933) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% log_(function() { paste(\"Queue is\", get_queue_count(bank, \"counter\"), \"on arrival\") }) %>% seize(\"counter\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(12) %>% release(\"counter\") %>% log_(\"Completed\") bank <- simmer(\"bank\") %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) %>% add_generator(\"Guido\", customer, at(23), priority = 1) bank %>% run(until = 400) #> 0: Customer0: Queue is 0 on arrival #> 0: Customer0: Waited: 0 #> 0.177365: Customer1: Queue is 0 on arrival #> 8.64106: Customer2: Queue is 1 on arrival #> 12: Customer0: Completed #> 12: Customer1: Waited: 11.8226352687925 #> 21.1346: Customer3: Queue is 1 on arrival #> 23: Guido0: Queue is 2 on arrival #> 24: Customer1: Completed #> 24: Guido0: Waited: 1 #> 28.0923: Customer4: Queue is 2 on arrival #> 36: Guido0: Completed #> 36: Customer2: Waited: 27.3589401547341 #> 48: Customer2: Completed #> 48: Customer3: Waited: 26.8654149797765 #> 60: Customer3: Completed #> 60: Customer4: Waited: 31.9076510670601 #> 72: Customer4: Completed #> simmer environment: bank | now: 72 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } #> { Source: Guido | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication waiting_time #> 1 Customer0 0.0000000 12 12 TRUE 1 0.00000 #> 2 Customer1 0.1773647 24 12 TRUE 1 11.82264 #> 3 Guido0 23.0000000 36 12 TRUE 1 1.00000 #> 4 Customer2 8.6410598 48 12 TRUE 1 27.35894 #> 5 Customer3 21.1345850 60 12 TRUE 1 26.86541 #> 6 Customer4 28.0923489 72 12 TRUE 1 31.90765"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"priority-customers-with-preemption","dir":"Articles","previous_headings":"Priority customers","what":"Priority customers with preemption","title":"The Bank Tutorial: Part II","text":"Now allow Guido preemptive priority. displace customer service arrives. customer resume Guido finishes (unless higher priority customers intervene). requires change one line program, adding argument, preemptive = TRUE add_resource function call. Though Guido arrives time, 23, longer wait immediately goes service, displacing incumbent, Customer1. customer already completed 23 - 12 = 11 minutes service. Guido finishes 35, Customer1 resumes service takes 36 - 35 = 1 minutes finish. total service time (12 minutes).","code":"library(simmer) set.seed(1933) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% log_(function() { paste(\"Queue is\", get_queue_count(bank, \"counter\"), \"on arrival\") }) %>% seize(\"counter\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(12) %>% release(\"counter\") %>% log_(\"Completed\") bank <- simmer(\"bank\") %>% add_resource(\"counter\", preemptive = TRUE) %>% add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) %>% add_generator(\"Guido\", customer, at(23), priority = 1) bank %>% run(until = 400) #> 0: Customer0: Queue is 0 on arrival #> 0: Customer0: Waited: 0 #> 0.177365: Customer1: Queue is 0 on arrival #> 8.64106: Customer2: Queue is 1 on arrival #> 12: Customer0: Completed #> 12: Customer1: Waited: 11.8226352687925 #> 21.1346: Customer3: Queue is 1 on arrival #> 23: Guido0: Queue is 2 on arrival #> 23: Guido0: Waited: 0 #> 28.0923: Customer4: Queue is 3 on arrival #> 35: Guido0: Completed #> 36: Customer1: Completed #> 36: Customer2: Waited: 27.3589401547341 #> 48: Customer2: Completed #> 48: Customer3: Waited: 26.8654149797765 #> 60: Customer3: Completed #> 60: Customer4: Waited: 31.9076510670601 #> 72: Customer4: Completed #> simmer environment: bank | now: 72 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } #> { Source: Guido | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication waiting_time #> 1 Customer0 0.0000000 12 12 TRUE 1 0.00000 #> 2 Guido0 23.0000000 35 12 TRUE 1 0.00000 #> 3 Customer1 0.1773647 36 12 TRUE 1 23.82264 #> 4 Customer2 8.6410598 48 12 TRUE 1 27.35894 #> 5 Customer3 21.1345850 60 12 TRUE 1 26.86541 #> 6 Customer4 28.0923489 72 12 TRUE 1 31.90765"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"balking-and-reneging-customers","dir":"Articles","previous_headings":"","what":"Balking and reneging customers","title":"The Bank Tutorial: Part II","text":"Balking occurs customer refuses join queue long. Reneging (, better, abandonment) occurs impatient customer gives still waiting served.","code":""},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"balking-customers","dir":"Articles","previous_headings":"Balking and reneging customers","what":"Balking customers","title":"The Bank Tutorial: Part II","text":"Another term system balking customers one “blocked customers” “cleared”, termed engineers BCC system. convenient analytically queueing theory formulae developed using assumption used extensively planning communication systems. easiest case queueing allowed. example let us investigate BCC system single server waiting space limited. estimate rate balking maximum number queue set 1. arrival system customer must first check see room. enough room, customer balks. get balking rate, first count number arrivals didn’t finish, using data given get_mon_arrivals(). divide current model time now(bank). Customer2 arrives, Customer0 already service Customer1 waiting. room, Customer2 balks. vagaries exponential random numbers, Customer0 takes long time serve (22.7358 minutes) first one find room number Customer6 25.5339.","code":"library(simmer) timeInBank <- 12 # mean, minutes ARRint <- 10 # mean, minutes numServers <- 1 # servers maxInSystem <- 2 # customers maxInQueue <- maxInSystem - numServers maxNumber <- 8 maxTime <- 400 # minutes set.seed(59098) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% seize(\"counter\", continue = FALSE, reject = trajectory(\"Balked customer\") %>% log_(\"BALKING\") %>% leave(1)) %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(function() {rexp(1, 1/timeInBank)}) %>% release(\"counter\") %>% log_(\"Finished\") bank <- simmer(\"bank\") %>% add_resource(\"counter\", capacity = numServers, queue_size = maxInQueue) %>% add_generator(\"Customer\", customer, at(c(0, cumsum(rexp(maxNumber - 1, 1 / ARRint))))) bank %>% run(until = maxTime) #> 0: Customer0: Here I am #> 0: Customer0: Waited: 0 #> 0.822239: Customer1: Here I am #> 1.01227: Customer2: Here I am #> 1.01227: Customer2: BALKING #> 4.7448: Customer3: Here I am #> 4.7448: Customer3: BALKING #> 20.5472: Customer4: Here I am #> 20.5472: Customer4: BALKING #> 21.6132: Customer5: Here I am #> 21.6132: Customer5: BALKING #> 22.7358: Customer0: Finished #> 22.7358: Customer1: Waited: 21.9136007670654 #> 23.5339: Customer6: Here I am #> 32.1107: Customer7: Here I am #> 32.1107: Customer7: BALKING #> 33.4243: Customer1: Finished #> 33.4243: Customer6: Waited: 9.89045904344415 #> 34.0249: Customer6: Finished #> simmer environment: bank | now: 34.0249444457964 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(1) } #> { Source: Customer | monitored: 1 | n_generated: 8 } number_balked <- sum(!get_mon_arrivals(bank)$finished) paste(\"Balking rate is\", number_balked / now(bank), \"customers per minute.\") #> [1] \"Balking rate is 0.146951011425317 customers per minute.\""},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"reneging-or-abandoning-customers","dir":"Articles","previous_headings":"Balking and reneging customers","what":"Reneging (or abandoning) customers","title":"The Bank Tutorial: Part II","text":"Often practice impatient customer leave queue served. Simmer can model reneging behaviour using renege_in() function trajectory. defines maximum time customer wait reneging, well ‘’ trajectory follow renege. customer reaches server reneging, impatience must cancelled renege_abort() function. Customer1 arrives Customer0 12 minutes patience. time queue (time 28.5058) abandons queue leave Customer2 take place. Customer2 Customer3 also renege. Customer4 served within 12 minutes.","code":"library(simmer) timeInBank <- 15 # mean, minutes ARRint <- 10 # mean, minutes numServers <- 1 # servers maxNumber <- 5 maxTime <- 400 # minutes maxWaitTime <- 12 # minutes, maximum time to wait before reneging set.seed(59030) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am\") %>% renege_in(maxWaitTime, out = trajectory(\"Reneging customer\") %>% log_(function() { paste(\"Waited\", now(bank) - get_start_time(bank), \"I am off\") })) %>% seize(\"counter\") %>% renege_abort() %>% # Stay if I'm being attended within maxWaitTime log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(function() {rexp(1, 1/timeInBank)}) %>% release(\"counter\") %>% log_(\"Completed\") bank <- simmer(\"bank\") %>% add_resource(\"counter\", capacity = numServers) %>% add_generator(\"Customer\", customer, at(c(0, cumsum(rexp(maxNumber - 1, 1 / ARRint))))) bank %>% run(until = maxTime) #> 0: Customer0: Here I am #> 0: Customer0: Waited: 0 #> 16.5058: Customer1: Here I am #> 28.5058: Customer1: Waited 12 I am off #> 34.339: Customer2: Here I am #> 41.8687: Customer3: Here I am #> 46.339: Customer2: Waited 12 I am off #> 49.3671: Customer4: Here I am #> 53.8687: Customer3: Waited 12 I am off #> 54.7374: Customer0: Completed #> 54.7374: Customer4: Waited: 5.37030150208617 #> 64.6857: Customer4: Completed #> simmer environment: bank | now: 64.6856688172597 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 }"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"interrupting-a-process","dir":"Articles","previous_headings":"","what":"Interrupting a process","title":"The Bank Tutorial: Part II","text":"Klaus goes bank talk manager. clarity ignore counters customers. conversation cellphone rings. finishes call continues conversation. example, call another trajectory, whose activities send signal (ringing phone), write event log. Klaus’ trajectory, trap activity causes listen phone ring. Supposing phone doesn’t ring, trajectory continue timeout activity, banking business 20 minutes, finish. Supposing phone ring, Klaus enter sub-trajectory defined within trap function ‘handler’. trajectory, makes excuses, answers phone, returns business. end trajectory, continues original trajectory next step following original timeout, without spending rest 20 minutes banking. make Klaus spend full 20 minutes banking, add timeout activity end ‘handler’, first calculate much time remains interruption. done storing ‘start’ time attribute, calculating much time left phone rings. default, interruptions can interrupted, illustrated example phone ringing twice. avoided setting interruptible = FALSE trap activity. random numbers results reasonably clear: first interrupting call occurs 9. takes Klaus 3 minutes listen message resumes conversation bank manager 12. phone rings 16, listens three minutes, resumes conversation 19, finally finishing 26. total time conversation 9 + 4 + 7 = 20 minutes, interrupt occurred.","code":"library(simmer) timeInBank <- 20 timeOfCall <- 9 onphone <- 3 maxTime <- 100 bank <- simmer() customer <- trajectory(\"Customer's path\") %>% trap(\"phonecall\", handler = trajectory() %>% log_(\"Excuse me\") %>% set_attribute( \"timeleft\", function() { sum(get_attribute(bank, c(\"timeleft\", \"start\"))) - now(bank) }) %>% log_(\"Hello! I'll call back\") %>% timeout(onphone) %>% log_(\"Sorry, where were we?\") %>% set_attribute(\"start\", function() {now(bank)}) %>% log_(function() {paste(\"Time left:\", get_attribute(bank, \"timeleft\"))}) %>% timeout_from_attribute(\"timeleft\") ) %>% log_(\"Here I am\") %>% set_attribute(\"timeleft\", timeInBank) %>% set_attribute(\"start\", function() {now(bank)}) %>% timeout(timeInBank) %>% log_(\"Completed\") phone <- trajectory(\"Phone\") %>% log_(\"Ringgg!\") %>% send(\"phonecall\") bank <- simmer(\"bank\") %>% add_generator(\"Klaus\", customer, at(0)) %>% add_generator(\"Phone\", phone, at(timeOfCall, timeOfCall + 7)) bank %>% run(until = maxTime) #> 0: Klaus0: Here I am #> 9: Phone0: Ringgg! #> 9: Klaus0: Excuse me #> 9: Klaus0: Hello! I'll call back #> 12: Klaus0: Sorry, where were we? #> 12: Klaus0: Time left: 11 #> 16: Phone1: Ringgg! #> 16: Klaus0: Excuse me #> 16: Klaus0: Hello! I'll call back #> 19: Klaus0: Sorry, where were we? #> 19: Klaus0: Time left: 7 #> 26: Klaus0: Completed #> simmer environment: bank | now: 26 | next: #> { Monitor: in memory } #> { Source: Klaus | monitored: 1 | n_generated: 1 } #> { Source: Phone | monitored: 1 | n_generated: 2 }"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"wait-until-the-bank-door-opens","dir":"Articles","previous_headings":"","what":"Wait until the bank door opens","title":"The Bank Tutorial: Part II","text":"Customers arrive random, getting bank door opened doorman. wait door opened rush queue served. model defines door resource, just like counter. capacity door defined according schedule function, zero capacity shut, infinite capacity open. Customers ‘seize’ door must wait capacity ‘serve’ . available, waiting customers ‘served’ immediately (.e. pass door). timeout ‘seizing’ ‘releasing’ door. sake announcing log door opened, doorman trajectory defined. output programs shows first two customers wait door opened.","code":"library(simmer) maxTime = 400 set.seed(393937) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% log_(function() if (get_capacity(bank, \"door\") == 0) \"Here I am but the door is shut.\" else \"Here I am and the door is open.\" ) %>% seize(\"door\") %>% log_(\"I can go in!\") %>% release(\"door\") %>% seize(\"counter\") %>% timeout(function() {rexp(1, 1/10)}) %>% release(\"counter\") openTime <- rexp(1, 1/10) door_schedule <- schedule(c(0, openTime), c(0, Inf)) doorman <- trajectory() %>% timeout(openTime) %>% log_(\"Ladies and Gentlemen! You may all enter.\") bank <- simmer(\"bank\") %>% add_resource(\"door\", capacity = door_schedule) %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, at(c(0, cumsum(rexp(5 - 1, 0.1))))) %>% add_generator(\"Doorman\", doorman, at(0)) bank %>% run(until = maxTime) #> 0: Customer0: Here I am but the door is shut. #> 6.44076: Customer1: Here I am but the door is shut. #> 8.77564: Customer2: Here I am but the door is shut. #> 19.7241: Doorman0: Ladies and Gentlemen! You may all enter. #> 19.7241: Customer0: I can go in! #> 19.7241: Customer1: I can go in! #> 19.7241: Customer2: I can go in! #> 24.2037: Customer3: Here I am and the door is open. #> 24.2037: Customer3: I can go in! #> 33.3576: Customer4: Here I am and the door is open. #> 33.3576: Customer4: I can go in! #> simmer environment: bank | now: 79.2542060826083 | next: #> { Monitor: in memory } #> { Resource: door | monitored: TRUE | server status: 0(Inf) | queue status: 0(Inf) } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } #> { Source: Doorman | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication waiting_time #> 1 Doorman0 0.000000 19.72408 19.724085 TRUE 1 0.00000 #> 2 Customer0 0.000000 46.61084 26.886751 TRUE 1 19.72408 #> 3 Customer1 6.440758 64.20811 17.597279 TRUE 1 40.17008 #> 4 Customer2 8.775635 71.50006 7.291950 TRUE 1 55.43248 #> 5 Customer3 24.203687 73.96270 2.462632 TRUE 1 47.29638 #> 6 Customer4 33.357600 79.25421 5.291510 TRUE 1 40.60510"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"wait-for-the-doorman-to-give-a-signal","dir":"Articles","previous_headings":"","what":"Wait for the doorman to give a signal","title":"The Bank Tutorial: Part II","text":"Customers arrive random, getting bank door open. controlled automatic machine called doorman opens door intervals 30 minutes (secure bank). customers wait door opened waiting enter proceed counter. door closed behind . least two ways implement model. first example uses schedule, second uses batching. principle behind schedule door modelled server zero capacity 30 minutes, infinite capacity zero minutes, repeat 30-minute cycle. moment infinite capacity, customers pass door (.e. ‘served’). sake announcing log door opened, doorman trajectory defined. doorman rollback step keeps opening shutting door every 30 minutes ever. output run program shows first two customers wait door opened, next three wait. second method batching. Customers can collected batches given size, given time, whichever occurs first. , collected periods 30, number customers batch unrestricted. batch created batch, usually customers processed together server, separating separate. example, need server – door modelled batch – customers separated immediately batch. second method gives output first.","code":"library(simmer) maxTime = 150 customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am, but the door is shut.\") %>% seize(\"door\") %>% log_(\"The door is open!\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% release(\"door\") %>% seize(\"counter\") %>% timeout(function() {rexp(1, 1/10)}) %>% release(\"counter\") %>% log_(\"Finished.\") door_schedule <- schedule(c(30, 30), c(Inf, 0), period = 30) doorman <- trajectory(\"Doorman\") %>% timeout(30) %>% log_(\"You may enter.\") %>% rollback(2, times = Inf) set.seed(393939) bank <- simmer(\"bank\") bank %>% add_resource(\"door\", capacity = door_schedule) %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, at(c(0, cumsum(rexp(5 - 1, 0.1))))) %>% add_generator(\"Doorman\", doorman, at(0)) #> simmer environment: bank | now: 0 | next: 0 #> { Monitor: in memory } #> { Resource: door | monitored: TRUE | server status: 0(0) | queue status: 0(Inf) } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 0 } #> { Source: Doorman | monitored: 1 | n_generated: 0 } bank %>% run(until = maxTime) #> 0: Customer0: Here I am, but the door is shut. #> 25.4605: Customer1: Here I am, but the door is shut. #> 30: Doorman0: You may enter. #> 30: Customer0: The door is open! #> 30: Customer0: Waited: 30 #> 30: Customer1: The door is open! #> 30: Customer1: Waited: 4.53951782839885 #> 35.4334: Customer2: Here I am, but the door is shut. #> 36.0565: Customer0: Finished. #> 40.6413: Customer3: Here I am, but the door is shut. #> 48.7442: Customer1: Finished. #> 49.063: Customer4: Here I am, but the door is shut. #> 60: Doorman0: You may enter. #> 60: Customer2: The door is open! #> 60: Customer2: Waited: 24.566617201638 #> 60: Customer3: The door is open! #> 60: Customer3: Waited: 19.3586741095377 #> 60: Customer4: The door is open! #> 60: Customer4: Waited: 10.9369934153668 #> 66.7763: Customer2: Finished. #> 71.3982: Customer3: Finished. #> 79.5795: Customer4: Finished. #> 90: Doorman0: You may enter. #> 120: Doorman0: You may enter. #> simmer environment: bank | now: 150 | next: 150 #> { Monitor: in memory } #> { Resource: door | monitored: TRUE | server status: 0(0) | queue status: 0(Inf) } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } #> { Source: Doorman | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication waiting_time #> 1 Customer0 0.00000 36.05646 6.056458 TRUE 1 30.00000 #> 2 Customer1 25.46048 48.74417 12.687713 TRUE 1 10.59598 #> 3 Customer2 35.43338 66.77625 6.776253 TRUE 1 24.56662 #> 4 Customer3 40.64133 71.39816 4.621910 TRUE 1 26.13493 #> 5 Customer4 49.06301 79.57954 8.181380 TRUE 1 22.33516 library(simmer) maxTime = 150 customer <- trajectory(\"Customer's path\") %>% log_(\"Here I am, but the door is shut.\") %>% batch(n = Inf, timeout = 30) %>% separate() %>% log_(\"The door is open!\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% seize(\"counter\") %>% timeout(function() {rexp(1, 1/10)}) %>% release(\"counter\") %>% log_(\"Finished.\") doorman <- trajectory(\"Doorman\") %>% timeout(30) %>% log_(\"You may enter.\") %>% rollback(2, times = Inf) set.seed(393939) bank <- simmer(\"bank\") bank %>% add_resource(\"door\") %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, at(c(0, cumsum(rexp(5 - 1, 0.1))))) %>% add_generator(\"Doorman\", doorman, at(0)) #> simmer environment: bank | now: 0 | next: 0 #> { Monitor: in memory } #> { Resource: door | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 0 } #> { Source: Doorman | monitored: 1 | n_generated: 0 } bank %>% run(until = maxTime) #> 0: Customer0: Here I am, but the door is shut. #> 25.4605: Customer1: Here I am, but the door is shut. #> 30: Doorman0: You may enter. #> 30: Customer0: The door is open! #> 30: Customer0: Waited: 30 #> 30: Customer1: The door is open! #> 30: Customer1: Waited: 4.53951782839885 #> 35.4334: Customer2: Here I am, but the door is shut. #> 36.0565: Customer0: Finished. #> 40.6413: Customer3: Here I am, but the door is shut. #> 48.7442: Customer1: Finished. #> 49.063: Customer4: Here I am, but the door is shut. #> 60: Doorman0: You may enter. #> 65.4334: Customer2: The door is open! #> 65.4334: Customer2: Waited: 30 #> 65.4334: Customer3: The door is open! #> 65.4334: Customer3: Waited: 24.7920569078997 #> 65.4334: Customer4: The door is open! #> 65.4334: Customer4: Waited: 16.3703762137288 #> 72.2096: Customer2: Finished. #> 76.8315: Customer3: Finished. #> 85.0129: Customer4: Finished. #> 90: Doorman0: You may enter. #> 120: Doorman0: You may enter. #> simmer environment: bank | now: 150 | next: 150 #> { Monitor: in memory } #> { Resource: door | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } #> { Source: Doorman | monitored: 1 | n_generated: 1 } bank %>% get_mon_arrivals() %>% transform(waiting_time = end_time - start_time - activity_time) #> name start_time end_time activity_time finished replication waiting_time #> 1 Customer0 0.00000 36.05646 6.056458 TRUE 1 30.00000 #> 2 Customer1 25.46048 48.74417 12.687713 TRUE 1 10.59598 #> 3 Customer2 35.43338 72.20964 6.776253 TRUE 1 30.00000 #> 4 Customer3 40.64133 76.83155 4.621910 TRUE 1 31.56831 #> 5 Customer4 49.06301 85.01293 8.181380 TRUE 1 27.76854"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"monitors","dir":"Articles","previous_headings":"Wait for the doorman to give a signal","what":"Monitors","title":"The Bank Tutorial: Part II","text":"Monitors record events simulation. Unlike SimPy, Simmer default, records available – fact, even – simulation. Data collected monitors available following functions: get_mon_*() functions return data frame (growing simulation, , although possible, computationally expensive call inside trajectory). others return numeric value.","code":"get_capacity get_mon_arrivals get_mon_attributes get_mon_resources get_n_activities get_n_generated get_queue_count get_queue_size get_server_count"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"plotting-a-histogram-of-monitor-results","dir":"Articles","previous_headings":"Wait for the doorman to give a signal > Monitors","what":"Plotting a histogram of monitor results","title":"The Bank Tutorial: Part II","text":"histogram amount time customers spend bank can plotted taking basic information – start end time customer – get_mon_arrivals() function, calculating elapsed time. example draws plot ggplot2 package, plotting packages, base R graphics, something similar.","code":"library(simmer) library(simmer.plot) #> Loading required package: ggplot2 #> #> Attaching package: 'simmer.plot' #> The following objects are masked from 'package:simmer': #> #> get_mon_arrivals, get_mon_attributes, get_mon_resources # library(ggplot2) # (automatically loaded with simmer.plot) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% seize(\"counter\") %>% timeout(12) %>% release(\"counter\") set.seed(393939) bank <- simmer(\"bank\") %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, at(c(0, cumsum(rexp(20 - 1, 0.1))))) bank %>% run(400) #> simmer environment: bank | now: 253.460482171601 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 20 } bank %>% get_mon_arrivals %>% ggplot(aes(end_time - start_time)) + geom_histogram() + xlab(\"Time spent in the system\") + ylab(\"Number of customers\") #> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`."},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"monitoring-a-resource","dir":"Articles","previous_headings":"Wait for the doorman to give a signal > Monitors","what":"Monitoring a resource","title":"The Bank Tutorial: Part II","text":"Now consider observing number customers waiting active Resource. get_mon_resources() returns table states times counter. Whenever customer enters/leaves queue/counter, new row created recording number customers queue, counter system whole. call ‘state’. amount time state lasts difference time one state next, calculate diff() function. Finally, multiply number customers state duration state, divide duration simulation (time end) get average.","code":"library(simmer) set.seed(1234) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% log_(\"Arrived\") %>% seize(\"counter\") %>% log_(\"Got counter\") %>% log_(function() {paste(\"Waited: \", now(bank) - get_start_time(bank))}) %>% timeout(12) %>% release(\"counter\") %>% log_(\"Finished\") bank <- simmer(\"bank\") %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, function() {c(0, rexp(4, 1/10), -1)}) bank %>% run(until = 400) #> 0: Customer0: Arrived #> 0: Customer0: Got counter #> 0: Customer0: Waited: 0 #> 12: Customer0: Finished #> 25.0176: Customer1: Arrived #> 25.0176: Customer1: Got counter #> 25.0176: Customer1: Waited: 0 #> 27.4852: Customer2: Arrived #> 27.551: Customer3: Arrived #> 37.0176: Customer1: Finished #> 37.0176: Customer2: Got counter #> 37.0176: Customer2: Waited: 9.53241116646677 #> 44.9785: Customer4: Arrived #> 49.0176: Customer2: Finished #> 49.0176: Customer3: Got counter #> 49.0176: Customer3: Waited: 21.466591599012 #> 61.0176: Customer3: Finished #> 61.0176: Customer4: Got counter #> 61.0176: Customer4: Waited: 16.0391307005949 #> 73.0176: Customer4: Finished #> simmer environment: bank | now: 73.0175860496223 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 5 } customer_monitor <- get_mon_arrivals(bank) %>% transform(wait = end_time - start_time - activity_time) mean_waiting_time <- mean(customer_monitor$wait) resource_monitor <- get_mon_resources(bank) queue_state <- head(resource_monitor$queue, -1) server_state <- head(resource_monitor$server, -1) time_state_lasted <- diff(resource_monitor$time) time_at_end <- max(resource_monitor$time) mean_active_customers <- sum(server_state * time_state_lasted) / time_at_end mean_waiting_customers <- sum(queue_state * time_state_lasted) / time_at_end cat(\" Average waiting = \", mean_waiting_customers, \"\\n\", \"Average active = \", mean_active_customers, \"\\n\") #> Average waiting = 0.6442028 #> Average active = 0.8217199"},{"path":"https://r-simmer.org/articles/simmer-04-bank-2.html","id":"plotting-from-resource-monitors","dir":"Articles","previous_headings":"Wait for the doorman to give a signal > Monitors","what":"Plotting from resource monitors","title":"The Bank Tutorial: Part II","text":"get_mon_*() return information enables us graph output. Alternative plotting packages can used; use simmer.plot package just graph number customers waiting counter. simmer.plot package imported line 2. function get_mon_resources() called function plot() calles get_mon_resources() . plot() function arguments specifiy plot.","code":"library(simmer) library(simmer.plot) timeInBank <- 12 # mean, minutes set.seed(1234) bank <- simmer() customer <- trajectory(\"Customer's path\") %>% seize(\"counter\") %>% timeout(function() {rexp(1, 1/timeInBank)}) %>% release(\"counter\") bank <- simmer(\"bank\") %>% add_resource(\"counter\") %>% add_generator(\"Customer\", customer, function() {c(0, rexp(19, 1/10), -1)}) bank %>% run(until = 400) #> simmer environment: bank | now: 248.706140163915 | next: #> { Monitor: in memory } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: Customer | monitored: 1 | n_generated: 20 } plot(get_mon_resources(bank), metric = \"usage\", names = \"counter\", items = \"system\", steps = TRUE)"},{"path":"https://r-simmer.org/articles/simmer-05-simpy.html","id":"introduction","dir":"Articles","previous_headings":"","what":"Introduction","title":"Other SimPy Examples","text":"examples adapted Python package ‘SimPy’, . Users familiar SimPy may find examples helpful transitioning simmer. basic material covered. Beginners first read Bank Tutorial: Part & Part II.","code":""},{"path":"https://r-simmer.org/articles/simmer-05-simpy.html","id":"carwash","dir":"Articles","previous_headings":"","what":"Carwash","title":"Other SimPy Examples","text":"Covers: Standard resources. Waiting processes. Logging messages console. : carwash limited number washing machines defines washing process takes time. Cars arrive carwash random time. one washing machine available, start washing process wait finish. , wait use one. Parameters setup: implementation simmer simple defining trajectory arriving car share follow. trajectory comprises seizing wash machine, spending time releasing . process takes WASHTIME removes random percentage dirt 50 90%. log_() messages merely illustrative. Finally, setup resources feed trajectory couple generators. result shown :","code":"library(simmer) NUM_MACHINES <- 2 # Number of machines in the carwash WASHTIME <- 5 # Minutes it takes to clean a car T_INTER <- 7 # Create a car every ~7 minutes SIM_TIME <- 20 # Simulation time in minutes # setup set.seed(42) env <- simmer() car <- trajectory() %>% log_(\"arrives at the carwash\") %>% seize(\"wash\", 1) %>% log_(\"enters the carwash\") %>% timeout(WASHTIME) %>% set_attribute(\"dirt_removed\", function() sample(50:99, 1)) %>% log_(function() paste0(get_attribute(env, \"dirt_removed\"), \"% of dirt was removed\")) %>% release(\"wash\", 1) %>% log_(\"leaves the carwash\") env %>% add_resource(\"wash\", NUM_MACHINES) %>% # feed the trajectory with 4 initial cars add_generator(\"car_initial\", car, at(rep(0, 4))) %>% # new cars approx. every T_INTER minutes add_generator(\"car\", car, function() sample((T_INTER-2):(T_INTER+2), 1)) %>% # start the simulation run(SIM_TIME) #> 0: car_initial0: arrives at the carwash #> 0: car_initial0: enters the carwash #> 0: car_initial1: arrives at the carwash #> 0: car_initial1: enters the carwash #> 0: car_initial2: arrives at the carwash #> 0: car_initial3: arrives at the carwash #> 5: car_initial0: 86% of dirt was removed #> 5: car_initial1: 50% of dirt was removed #> 5: car_initial0: leaves the carwash #> 5: car_initial1: leaves the carwash #> 5: car0: arrives at the carwash #> 5: car_initial2: enters the carwash #> 5: car_initial3: enters the carwash #> 10: car_initial2: 59% of dirt was removed #> 10: car_initial3: 85% of dirt was removed #> 10: car_initial2: leaves the carwash #> 10: car_initial3: leaves the carwash #> 10: car0: enters the carwash #> 10: car1: arrives at the carwash #> 10: car1: enters the carwash #> 15: car0: 98% of dirt was removed #> 15: car1: 96% of dirt was removed #> 15: car0: leaves the carwash #> 15: car1: leaves the carwash #> 16: car2: arrives at the carwash #> 16: car2: enters the carwash #> simmer environment: anonymous | now: 20 | next: 21 #> { Monitor: in memory } #> { Resource: wash | monitored: TRUE | server status: 1(2) | queue status: 0(Inf) } #> { Source: car_initial | monitored: 1 | n_generated: 4 } #> { Source: car | monitored: 1 | n_generated: 4 }"},{"path":"https://r-simmer.org/articles/simmer-05-simpy.html","id":"machine-shop","dir":"Articles","previous_headings":"","what":"Machine Shop","title":"Other SimPy Examples","text":"Covers: Preemptive resources. Interruptions. Loops. Attributes. : example comprises workshop n identical machines. stream jobs (enough keep machines busy) arrives. machine breaks periodically. Repairs carried one repairman. repairman , less important tasks perform, . Broken machines preempt theses tasks. repairman continues done machine repair. workshop works continuously. First , load libraries prepare environment. make_parts trajectory defines machine’s operating loop. worker seizes machine starts manufacturing counting parts infinite loop. Provided want one machine, parametrise trajectory function machine: Repairman’s unimportant jobs may modelled way (without accounting part): Failures high-priority arrivals, machines repairman. random generated failure randomly select seize (break) machine, seize (call) repairman. machine repaired, resources released corresponding workers begin left. machines workers appended simulation environment. Note machine, defined preemptive, space one worker (failure) space queue. repairman, time queue infinite, since number machines time waiting repairments. Finally, failure generator defined priority=1 (default: 0), simulation begins: last value per worker attributes table reports number parts made:","code":"library(simmer) PT_MEAN <- 10.0 # Avg. processing time in minutes PT_SIGMA <- 2.0 # Sigma of processing time MTTF <- 300.0 # Mean time to failure in minutes BREAK_MEAN <- 1 / MTTF # Param. for exponential distribution REPAIR_TIME <- 30.0 # Time it takes to repair a machine in minutes JOB_DURATION <- 30.0 # Duration of other jobs in minutes NUM_MACHINES <- 10 # Number of machines in the machine shop WEEKS <- 4 # Simulation time in weeks SIM_TIME <- WEEKS * 7 * 24 * 60 # Simulation time in minutes # setup set.seed(42) env <- simmer() make_parts <- function(machine) trajectory() %>% seize(machine, 1) %>% timeout(function() rnorm(1, PT_MEAN, PT_SIGMA)) %>% set_attribute(\"parts\", 1, mod=\"+\") %>% rollback(2, Inf) # go to 'timeout' over and over other_jobs <- trajectory() %>% seize(\"repairman\", 1) %>% timeout(JOB_DURATION) %>% rollback(1, Inf) machines <- paste0(\"machine\", 1:NUM_MACHINES-1) failure <- trajectory() %>% select(machines, policy = \"random\") %>% seize_selected(1) %>% seize(\"repairman\", 1) %>% timeout(REPAIR_TIME) %>% release(\"repairman\", 1) %>% release_selected(1) for (i in machines) env %>% add_resource(i, 1, 0, preemptive = TRUE) %>% add_generator(paste0(i, \"_worker\"), make_parts(i), at(0), mon = 2) env %>% add_resource(\"repairman\", 1, Inf, preemptive = TRUE) %>% add_generator(\"repairman_worker\", other_jobs, at(0)) %>% invisible env %>% add_generator(\"failure\", failure, function() rexp(1, BREAK_MEAN * NUM_MACHINES), priority = 1) %>% run(SIM_TIME) %>% invisible aggregate(value ~ name, get_mon_attributes(env), max) #> name value #> 1 machine0_worker0 3250 #> 2 machine1_worker0 3303 #> 3 machine2_worker0 3241 #> 4 machine3_worker0 3336 #> 5 machine4_worker0 3399 #> 6 machine5_worker0 3423 #> 7 machine6_worker0 3304 #> 8 machine7_worker0 3181 #> 9 machine8_worker0 3253 #> 10 machine9_worker0 3169"},{"path":"https://r-simmer.org/articles/simmer-05-simpy.html","id":"movie-renege","dir":"Articles","previous_headings":"","what":"Movie Renege","title":"Other SimPy Examples","text":"Covers: Standard resources. Condition events. Shared events. Attributes. : example models movie theater one ticket counter selling tickets three movies (next show ). People arrive random times try buy random number (1-6) tickets random movie. movie sold , people waiting buy ticket movie renege (leave queue). First , load libraries prepare environment. main actor simulation moviegoer, process try buy number tickets certain movie. logic follows: Select movie go theater. moment, moviegoer reneges movie becomes sold (“sold ” event received). particular, leave immediately movie already became sold . enough tickets, moviegoer rejected discussion. Provided moviegoer tickets, reneging condition aborted. Set instant rejection future customers (point 3.). Send “sold ” event (subscribed point 2.) current customers (waiting point 4.). Release ticket counter duration purchase. Enjoy movie! recipe directly translated simmer trajectory follows: actually constitutes quite interesting subset simmer’s capabilities. next step add required resources environment env: three movies ticket counter. finally, attach exponential moviegoer generator moviegoer trajectory simulation starts: analysis performed standard R tools:","code":"library(simmer) TICKETS <- 50 # Number of tickets per movie SIM_TIME <- 120 # Simulate until movies <- c(\"R Unchained\", \"Kill Process\", \"Pulp Implementation\") # setup set.seed(42) env <- simmer() get_movie <- function() movies[get_attribute(env, \"movie\")] soldout_signal <- function() paste0(get_movie(), \" sold out\") check_soldout <- function() get_capacity(env, get_movie()) == 0 check_tickets_available <- function() get_server_count(env, get_movie()) > (TICKETS - 2) moviegoer <- trajectory() %>% # select a movie set_attribute(\"movie\", function() sample(3, 1)) %>% select(get_movie) %>% # set reneging condition renege_if(soldout_signal) %>% # leave immediately if the movie was already sold out leave(check_soldout) %>% # wait for my turn seize(\"counter\", 1) %>% # buy tickets seize_selected( function() sample(6, 1), continue = FALSE, reject = trajectory() %>% timeout(0.5) %>% release(\"counter\", 1) ) %>% # abort reneging condition renege_abort() %>% # check the tickets available branch( check_tickets_available, continue = TRUE, trajectory() %>% set_capacity_selected(0) %>% send(soldout_signal) ) %>% timeout(1) %>% release(\"counter\", 1) %>% # watch the movie wait() # add movies as resources with capacity TICKETS and no queue for (i in movies) env %>% add_resource(i, TICKETS, 0) # add ticket counter with capacity 1 and infinite queue env %>% add_resource(\"counter\", 1, Inf) #> simmer environment: anonymous | now: 0 | next: #> { Monitor: in memory } #> { Resource: R Unchained | monitored: TRUE | server status: 0(50) | queue status: 0(0) } #> { Resource: Kill Process | monitored: TRUE | server status: 0(50) | queue status: 0(0) } #> { Resource: Pulp Implementation | monitored: TRUE | server status: 0(50) | queue status: 0(0) } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } # add a moviegoer generator and start simulation env %>% add_generator(\"moviegoer\", moviegoer, function() rexp(1, 1 / 0.5), mon=2) %>% run(SIM_TIME) #> simmer environment: anonymous | now: 120 | next: 120.027892152333 #> { Monitor: in memory } #> { Resource: R Unchained | monitored: TRUE | server status: 50(0) | queue status: 0(0) } #> { Resource: Kill Process | monitored: TRUE | server status: 50(0) | queue status: 0(0) } #> { Resource: Pulp Implementation | monitored: TRUE | server status: 49(0) | queue status: 0(0) } #> { Resource: counter | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: moviegoer | monitored: 2 | n_generated: 223 } # get the three rows with the sold out instants sold_time <- get_mon_resources(env) %>% subset(resource != \"counter\" & capacity == 0) # get the arrivals that left at the sold out instants # count the number of arrivals per movie n_reneges <- get_mon_arrivals(env) %>% subset(finished == FALSE & end_time %in% sold_time$time) %>% merge(get_mon_attributes(env)) %>% transform(resource = movies[value]) %>% aggregate(value ~ resource, data=., length) # merge the info and print invisible(apply(merge(sold_time, n_reneges), 1, function(i) { cat(\"Movie '\", i[\"resource\"], \"' was sold out in \", i[\"time\"], \" minutes.\\n\", \" Number of people that left the queue: \", i[\"value\"], \"\\n\", sep=\"\") })) #> Movie 'Kill Process' was sold out in 53.09917 minutes. #> Number of people that left the queue: 9 #> Movie 'Pulp Implementation' was sold out in 51.59917 minutes. #> Number of people that left the queue: 9 #> Movie 'R Unchained' was sold out in 33.09917 minutes. #> Number of people that left the queue: 8"},{"path":"https://r-simmer.org/articles/simmer-05-simpy.html","id":"gas-station-refuelling","dir":"Articles","previous_headings":"","what":"Gas Station Refuelling","title":"Other SimPy Examples","text":"Covers: Standard resources. Waiting processes. Condition events. Shared events. Concatenating trajectories. Loops. Logging messages console. : example models gas station cars arrive refuelling. gas station limited number fuel pumps fuel tank shared fuel pumps. Vehicles arriving gas station first request fuel pump station. acquire one, try take desired amount fuel fuel pump. leave done. fuel level reqularly monitored controller. level drops certain threshold, tank truck called refilling tank. Parameters setup: SimPy solves problem using special kind resource called container, present simmer far. However, container nothing embellished counter. Therefore, can implement simmer global counter (GAS_STATION_LEVEL ), signaling care checking counter bounds. Let us consider just refuelling process first place. car needs check whether enough fuel available fill tank. , needs block gas station refilled. Now car’s trajectory straightforward. First, starting time saved well tank level. , car seizes pump, refuels leaves. tank truck takes time arrive. , gas station completely refilled signal “gas station refilled” sent blocked cars. controller periodically checks GAS_STATION_LEVEL calls tank truck needed. Finally, need add couple pumps, controller worker car generator. Note though model important flaw, original adaptation, discussed #239: two cars require fuel available, level still threshold, cars completely block queue, refilling truck never called. solved detecting situation controller.","code":"library(simmer) GAS_STATION_SIZE <- 200 # liters THRESHOLD <- 10 # Threshold for calling the tank truck (in %) FUEL_TANK_SIZE <- 50 # liters FUEL_TANK_LEVEL <- c(5, 25) # Min/max levels of fuel tanks (in liters) REFUELING_SPEED <- 2 # liters / second TANK_TRUCK_TIME <- 300 # Seconds it takes the tank truck to arrive T_INTER <- c(30, 100) # Create a car every [min, max] seconds SIM_TIME <- 1000 # Simulation time in seconds # setup set.seed(42) env <- simmer() GAS_STATION_LEVEL <- GAS_STATION_SIZE signal <- \"gas station refilled\" refuelling <- trajectory() %>% # check if there is enough fuel available branch(function() FUEL_TANK_SIZE - get_attribute(env, \"level\") > GAS_STATION_LEVEL, continue = TRUE, # if not, block until the signal \"gas station refilled\" is received trajectory() %>% trap(signal) %>% wait() %>% untrap(signal) ) %>% # refuel timeout(function() { liters_required <- FUEL_TANK_SIZE - get_attribute(env, \"level\") GAS_STATION_LEVEL <<- GAS_STATION_LEVEL - liters_required return(liters_required / REFUELING_SPEED) }) car <- trajectory() %>% set_attribute(c(\"start\", \"level\"), function() c(now(env), sample(FUEL_TANK_LEVEL[1]:FUEL_TANK_LEVEL[2], 1))) %>% log_(\"arriving at gas station\") %>% seize(\"pump\", 1) %>% # 'join()' concatenates the refuelling trajectory here join(refuelling) %>% release(\"pump\", 1) %>% log_(function() paste0(\"finished refuelling in \", now(env) - get_attribute(env, \"start\"), \" seconds\")) tank_truck <- trajectory() %>% timeout(TANK_TRUCK_TIME) %>% log_(\"tank truck arriving at gas station\") %>% log_(function() { refill <- GAS_STATION_SIZE - GAS_STATION_LEVEL GAS_STATION_LEVEL <<- GAS_STATION_SIZE paste0(\"tank truck refilling \", refill, \" liters\") }) %>% send(signal) controller <- trajectory() %>% branch(function() GAS_STATION_LEVEL / GAS_STATION_SIZE * 100 < THRESHOLD, continue = TRUE, trajectory() %>% log_(\"calling the tank truck\") %>% join(tank_truck) ) %>% timeout(10) %>% rollback(2, Inf) env %>% add_resource(\"pump\", 2) %>% add_generator(\"controller\", controller, at(0)) %>% add_generator(\"car\", car, function() sample(T_INTER[1]:T_INTER[2], 1)) %>% run(SIM_TIME) #> 78: car0: arriving at gas station #> 98.5: car0: finished refuelling in 20.5 seconds #> 172: car1: arriving at gas station #> 190: car1: finished refuelling in 18 seconds #> 219: car2: arriving at gas station #> 233.5: car2: finished refuelling in 14.5 seconds #> 295: car3: arriving at gas station #> 314.5: car3: finished refuelling in 19.5 seconds #> 361: car4: arriving at gas station #> 377: car4: finished refuelling in 16 seconds #> 410: car5: arriving at gas station #> 442: car6: arriving at gas station #> 498: car7: arriving at gas station #> 532: car8: arriving at gas station #> 595: car9: arriving at gas station #> 627: car10: arriving at gas station #> 698: car11: arriving at gas station #> 742: car12: arriving at gas station #> 807: car13: arriving at gas station #> 854: car14: arriving at gas station #> 952: car15: arriving at gas station #> simmer environment: anonymous | now: 1000 | next: 1000 #> { Monitor: in memory } #> { Resource: pump | monitored: TRUE | server status: 2(2) | queue status: 9(Inf) } #> { Source: controller | monitored: 1 | n_generated: 1 } #> { Source: car | monitored: 1 | n_generated: 17 }"},{"path":"https://r-simmer.org/articles/simmer-06-queueing.html","id":"mmck-systems","dir":"Articles","previous_headings":"","what":"M/M/c/k systems","title":"Queueing Systems","text":"Kendall’s notation, M/M/c/k system exponential arrivals (M/M/c/k), cc servers (M/M/c/k) exponential service time (M/M/c/k) k−ck-c positions queue (M/M/c/k). instance, router may several processors handle packets, /queues necessarily finite. simulation M/M/2/3 system (2 server, 1 position queue). Note trajectory identical M/M/1 system (one server, infinite queue). rejections queue full. solving balance equations system, obtain following: p0=[∑n=0c−1rnn!+∑n=ckrnc!cn−c]−1N=∑n=0∞nPn=p0(∑n=0c−nnrnn!+∑n=cknrnc!cn−c) \\begin{aligned} p_0 &= \\left[ \\sum_{n=0}^{c-1}\\frac{r^n}{n!} + \\sum_{n=c}^{k}\\frac{r^n}{c!c^{n-c}} \\right]^{-1}\\\\ N &= \\sum_{n=0}^{\\infty}nP_n = p_0\\left(\\sum_{n=0}^{c-n}\\frac{nr^n}{n!} + \\sum_{n=c}^{k}\\frac{nr^n}{c!c^{n-c}}\\right) \\end{aligned} r=λ/μr=\\lambda/\\mu. Finally, can see simulation quickly converges theoretical average number customers system NN:","code":"lambda <- 3 mu <- 4 m.queue <- trajectory() %>% seize(\"server\", amount=1) %>% timeout(function() rexp(1, mu)) %>% release(\"server\", amount=1) mm23.env <- simmer() %>% add_resource(\"server\", capacity=2, queue_size=1) %>% add_generator(\"arrival\", m.queue, function() rexp(1, lambda)) %>% run(until=2000) get_mon_arrivals(mm23.env) %>% with(sum(!finished) / length(finished)) #> [1] 0.04253894 # Theoretical value rho <- lambda/mu div <- 1 / c(1, 1, factorial(2) * 2^(2:3-2)) mm23.N <- sum(0:3 * rho^(0:3) * div) / sum(rho^(0:3) * div) # Evolution of the average number of customers in the system plot(get_mon_resources(mm23.env), \"usage\", \"server\", items=\"system\") + geom_hline(yintercept=mm23.N)"},{"path":"https://r-simmer.org/articles/simmer-06-queueing.html","id":"custom-service-policies","dir":"Articles","previous_headings":"","what":"Custom service policies","title":"Queueing Systems","text":"Resources implement FIFO (FCFS) priority queue, means arrivals higher priority processed first, among priority, first--first-policy applies. priorities can statically assigned arrivals coming particular source (using priority argument add_generator() dedicated column data frame passed add_dataframe()). However, useful activity change priorities dynamically (well two prioritization values, preemtible restart), set_prioritization(). activity allows us, example, implement LIFO queue just assigning increasing priority incoming arrivals: mechanism, together signaling, serves basis implement custom servicing policy. main idea signal whenever arrival going release resource arrivals queue can leave queue momentarily recompute priorities: Note null timeout added resource released last place. way, arrivals recompute priorities enter queue resource released.","code":"env <- simmer() lifo <- trajectory() %>% set_global(\"resource prio\", 1, mod=\"+\") %>% set_prioritization(function() c(get_global(env, \"resource prio\"), NA, NA)) %>% seize(\"resource\") %>% log_(\"processing\") %>% timeout(5) %>% release(\"resource\") env %>% add_resource(\"resource\") %>% add_generator(\"dummy\", lifo, at(0:4)) %>% run() %>% invisible() #> 0: dummy0: processing #> 5: dummy4: processing #> 10: dummy3: processing #> 15: dummy2: processing #> 20: dummy1: processing env <- simmer() custom <- trajectory() %>% renege_if( \"recompute priority\", out = trajectory() %>% # e.g., increase priority if wait_time < 3 set_prioritization(function() { if (now(env) - get_start_time(env) < 3) c(1, NA, NA) # only change the priority else c(NA, NA, NA) # don't change anything }, mod=\"+\") %>% # go 2 steps back to renege_if rollback(2)) %>% seize(\"resource\") %>% renege_abort() %>% log_(\"processing\") %>% timeout(5) %>% # trigger this before releasing the resource send(\"recompute priority\") %>% timeout(0) %>% release(\"resource\") env %>% add_resource(\"resource\") %>% add_generator(\"dummy\", custom, at(0:4)) %>% run() %>% invisible() #> 0: dummy0: processing #> 5: dummy3: processing #> 10: dummy4: processing #> 15: dummy1: processing #> 20: dummy2: processing"},{"path":"https://r-simmer.org/articles/simmer-06-queueing.html","id":"state-dependent-service-rates","dir":"Articles","previous_headings":"","what":"State-dependent service rates","title":"Queueing Systems","text":"many practical queueing scenarios, speed server depends state system. consider multi-server resource able distribute processing capacity evenly among arrivals. means , example, capacity=2 single arrival server, served twice fast. terms simulation model, state-dependent service rate implies time spent server must asynchronously updated time arrival seizes releases resource. consequence, first need define trajectory updates running service delay restarts new time left release resource. following trajectory assumes three attributes available: start: simulation time arrival started last timeout activity. multiplier: distribution processing capacity. delay: service delay applied last timeout activity. new delay time left scaled last new multipliers. main trajectory first seizes server initialises three attributes. , arrivals need follow update.delay trajectory must interrupted given time re-run , thus re-computing service time left. simmer, can done signaling (see help(trap)): signal subscribed update.delay registered handler. first send signals arriving entity, causing arrivals execute handler. Eventually, handler finishes execution path returns unregister handler, release server signal departing entity. following, compare M/M/2 state-dependent system. systems fed interarrival times , expected, average resource usage significantly reduced.","code":"update.delay <- trajectory() %>% set_attribute(c(\"start\", \"multiplier\", \"delay\"), function() { # previous multiplier, service time left multiplier <- get_attribute(env, \"multiplier\") left <- sum(get_attribute(env, c(\"start\", \"delay\"))) - now(env) # distribute processing capacity new_multiplier <- capacity / get_server_count(env, \"sd.server\") # return new values c(now(env), new_multiplier, left * multiplier / new_multiplier) }) %>% timeout_from_attribute(\"delay\") sd.queue <- trajectory() %>% seize(\"sd.server\") %>% # initialisation set_attribute(c(\"start\", \"multiplier\", \"delay\"), function() c(now(env), 1, rexp(1, mu))) %>% # set the handler trap(\"update delay\", handler=update.delay) %>% # the following null timeout is required to act as a priority \"fence\" # and get a properly ordered set of simultaneous events # (see https://groups.google.com/g/simmer-devel/c/SkOcpu12sT8/m/xG8p5nmTAAAJ) timeout(0) %>% # trigger the handler send(\"update delay\") %>% # returning point untrap(\"update delay\") %>% release(\"sd.server\") %>% send(\"update delay\") lambda <- mu <- 4 capacity <- 2 arrivals <- data.frame(time=rexp(2000*lambda, lambda)) env <- simmer() %>% # M/M/2 add_resource(\"server\", capacity) %>% add_dataframe(\"arrival\", m.queue, arrivals) %>% # state-dependent service rate add_resource(\"sd.server\", capacity) %>% add_dataframe(\"sd.arrival\", sd.queue, arrivals) env %>% run() %>% get_mon_resources() %>% plot(metric=\"usage\", c(\"server\", \"sd.server\"))"},{"path":"https://r-simmer.org/articles/simmer-06-queueing.html","id":"queueing-networks","dir":"Articles","previous_headings":"","what":"Queueing Networks","title":"Queueing Systems","text":"Let us consider following network queues (example taken Grotto Networking): three exponential generators (λ1\\lambda_1, λ2\\lambda_2, λ4\\lambda_4) inject messages exponential size mean 100 bytes. four M/D/1 queues deterministic rate equal 220 bytes/s. 25% probability messages λ1\\lambda_1 dropped second queue, fork 35/65% output second queue reach queues 3 4. interested, instance, accumulated waiting time messages entering queue 1 exiting queue 3 4. ’ll start setting main constants couple functions set message size seize M/D/1 queue: next step set three points attachment generators: Finally, prepare run simulation environment resources generators required: analysis, filter arrivals generator 1 reach queues 3 4, examine average waiting time total number messages:","code":"mean_pkt_size <- 100 # bytes lambda1 <- 2 # pkts/s lambda3 <- 0.5 # pkts/s lambda4 <- 0.6 # pkts/s rate <- 2.2 * mean_pkt_size # bytes/s # set an exponential message size of mean mean_pkt_size set_msg_size <- function(.) set_attribute(., \"size\", function() rexp(1, 1/mean_pkt_size)) # seize an M/D/1 queue by id; the timeout is function of the message size md1 <- function(., id) seize(., paste0(\"md1_\", id), 1) %>% timeout(function() get_attribute(env, \"size\") / rate) %>% release(paste0(\"md1_\", id), 1) to_queue_1 <- trajectory() %>% set_msg_size() %>% md1(1) %>% leave(0.25) %>% md1(2) %>% branch( function() (runif(1) > 0.65) + 1, continue=c(F, F), trajectory() %>% md1(3), trajectory() %>% md1(4) ) to_queue_3 <- trajectory() %>% set_msg_size() %>% md1(3) to_queue_4 <- trajectory() %>% set_msg_size() %>% md1(4) env <- simmer() for (i in 1:4) env %>% add_resource(paste0(\"md1_\", i)) env %>% add_generator(\"arrival1_\", to_queue_1, function() rexp(1, lambda1), mon=2) %>% add_generator(\"arrival3_\", to_queue_3, function() rexp(1, lambda3), mon=2) %>% add_generator(\"arrival4_\", to_queue_4, function() rexp(1, lambda4), mon=2) %>% run(4000) #> simmer environment: anonymous | now: 4000 | next: 4000.0322040152 #> { Monitor: in memory } #> { Resource: md1_1 | monitored: TRUE | server status: 1(1) | queue status: 0(Inf) } #> { Resource: md1_2 | monitored: TRUE | server status: 1(1) | queue status: 3(Inf) } #> { Resource: md1_3 | monitored: TRUE | server status: 1(1) | queue status: 0(Inf) } #> { Resource: md1_4 | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) } #> { Source: arrival1_ | monitored: 2 | n_generated: 8079 } #> { Source: arrival3_ | monitored: 2 | n_generated: 2044 } #> { Source: arrival4_ | monitored: 2 | n_generated: 2402 } res <- get_mon_arrivals(env, per_resource = TRUE) %>% subset(resource %in% c(\"md1_3\", \"md1_4\"), select=c(\"name\", \"resource\")) arr <- get_mon_arrivals(env) %>% transform(waiting_time = end_time - (start_time + activity_time)) %>% transform(generator = regmatches(name, regexpr(\"arrival[[:digit:]]\", name))) %>% merge(res) aggregate(waiting_time ~ generator + resource, arr, function(x) sum(x)/length(x)) #> generator resource waiting_time #> 1 arrival1 md1_3 5.1816915 #> 2 arrival3 md1_3 0.6969347 #> 3 arrival1 md1_4 4.9417576 #> 4 arrival4 md1_4 0.4751263 get_n_generated(env, \"arrival1_\") + get_n_generated(env, \"arrival4_\") #> [1] 10481 aggregate(waiting_time ~ generator + resource, arr, length) #> generator resource waiting_time #> 1 arrival1 md1_3 3867 #> 2 arrival3 md1_3 2042 #> 3 arrival1 md1_4 2166 #> 4 arrival4 md1_4 2401"},{"path":"https://r-simmer.org/articles/simmer-07-ctmc.html","id":"example-1","dir":"Articles","previous_headings":"","what":"Example 1","title":"Continuous-Time Markov Chains","text":"gas station single pump space vehicles wait (vehicle arrives pump available, leaves). Vehicles arrive gas station following Poisson process rate λ=3/20\\lambda=3/20 vehicles per minute, 75% cars 25% motorcycles. refuelling time can modelled exponential random variable mean 8 minutes cars 3 minutes motorcycles, , services rates μc=1/8\\mu_\\mathrm{c}=1/8 cars μm=1/3\\mu_\\mathrm{m}=1/3 motorcycles per minute respectively. problem described following continuous-time Markov chain: $$\\xymatrix{ *=<15mm,8mm>[o][F]{car} \\ar@/^/[r]^{\\mu_\\mathrm{c}} & *=<15mm,8mm>[o][F]{empty} \\ar@/^/[l]^{p\\lambda} \\ar@/^/[r]^{(1-p)\\lambda} & *=<15mm,8mm>[o][F]{m/cycle} \\ar@/^/[l]^{\\mu_\\mathrm{m}} }\\qquad\\qquad Q = \\begin{pmatrix} -\\mu_\\mathrm{c} & \\mu_\\mathrm{c} & 0 \\\\ p\\lambda & -\\lambda & (1-p) \\lambda \\\\ 0 & \\mu_\\mathrm{m} & -\\mu_\\mathrm{m} \\end{pmatrix}$$ p=0.75p=0.75. chain irreducible recurrent. theoretically find steady state distribution, solve balance equations pQ=0pQ = 0 constraint ∑ipi=1\\sum_i p_i = 1 dim(Q)−1\\operatorname{dim}(Q)-1 independent columns, latter constraint equivalent substitute column ones match one side equation, : p⋅(11/801−3/200.25⋅3/2011/3−1/3)=(1,0,0)p\\cdot\\begin{pmatrix} 1 & 1/8 & 0 \\\\ 1 & -3/20 & 0.25\\cdot 3/20 \\\\ 1 & 1/3 & -1/3 \\end{pmatrix} = (1, 0, 0) solution pp represents probability state long-term. Therefore, can calculate average number vehicles system summing probabilities multiplied number vehicles state. case, N=1⋅p1+0⋅p2+1⋅p3N = 1\\cdot p_1 + 0\\cdot p_2 + 1\\cdot p_3 Now, going simulate system simmer verify converges theoretical solution. various options selecting model. first approach, due properties Poisson processes, can break problem two trajectories (one type vehicle), differ service time , therefore two generators rates λc=pλ\\lambda_\\mathrm{c} = p\\lambda λm=(1−p)λ\\lambda_\\mathrm{m} = (1-p)\\lambda. arrival processes may property, define single generator kind vehicles single trajectory follows. order distinguish cars motorcycles, define branch seizing resource select proper service time. option adds unnecessary overhead since additional call R function select branch, therefore performance decreases. much better option select service time directly inside timeout function. option.3 equivalent option.1 terms performance. , course, three lead us result. instance, performance results:","code":"# Arrival rate lambda <- 3/20 # Service rate (cars, motorcycles) mu <- c(1/8, 1/3) # Probability of car p <- 0.75 # Theoretical resolution A <- matrix(c(1, mu[1], 0, 1, -lambda, (1-p)*lambda, 1, mu[2], -mu[2]), byrow=T, ncol=3) B <- c(1, 0, 0) P <- solve(t(A), B) N_average_theor <- sum(P * c(1, 0, 1)) ; N_average_theor #> [1] 0.5031056 option.1 <- function(t) { car <- trajectory() %>% seize(\"pump\", amount=1) %>% timeout(function() rexp(1, mu[1])) %>% release(\"pump\", amount=1) mcycle <- trajectory() %>% seize(\"pump\", amount=1) %>% timeout(function() rexp(1, mu[2])) %>% release(\"pump\", amount=1) simmer() %>% add_resource(\"pump\", capacity=1, queue_size=0) %>% add_generator(\"car\", car, function() rexp(1, p*lambda)) %>% add_generator(\"mcycle\", mcycle, function() rexp(1, (1-p)*lambda)) %>% run(until=t) } option.2 <- function(t) { vehicle <- trajectory() %>% seize(\"pump\", amount=1) %>% branch(function() sample(c(1, 2), 1, prob=c(p, 1-p)), c(T, T), trajectory(\"car\") %>% timeout(function() rexp(1, mu[1])), trajectory(\"mcycle\") %>% timeout(function() rexp(1, mu[2]))) %>% release(\"pump\", amount=1) simmer() %>% add_resource(\"pump\", capacity=1, queue_size=0) %>% add_generator(\"vehicle\", vehicle, function() rexp(1, lambda)) %>% run(until=t) } option.3 <- function(t) { vehicle <- trajectory() %>% seize(\"pump\", amount=1) %>% timeout(function() { if (runif(1) < p) rexp(1, mu[1]) # car else rexp(1, mu[2]) # mcycle }) %>% release(\"pump\", amount=1) simmer() %>% add_resource(\"pump\", capacity=1, queue_size=0) %>% add_generator(\"vehicle\", vehicle, function() rexp(1, lambda)) %>% run(until=t) } gas.station <- option.3(5000) # Evolution + theoretical value plot(get_mon_resources(gas.station), \"usage\", \"pump\", items=\"system\") + geom_hline(yintercept=N_average_theor) library(microbenchmark) t <- 1000/lambda tm <- microbenchmark(option.1(t), option.2(t), option.3(t)) autoplot(tm) + scale_y_log10(breaks=function(limits) pretty(limits, 5)) + ylab(\"Time [milliseconds]\")"},{"path":"https://r-simmer.org/articles/simmer-07-ctmc.html","id":"example-2","dir":"Articles","previous_headings":"","what":"Example 2","title":"Continuous-Time Markov Chains","text":"Let us complicate things bit. Consider previous example, , time, space one motorcycle wait pump used another vehicle. words, cars see queue size 0 motorcycles see queue size 1. new Markov chain following: $$\\vcenter{\\xymatrix{ *=<15mm,8mm>[o][F]{car+} \\ar@(r,u)[drr]^{\\mu_\\mathrm{c}} \\\\ *=<15mm,8mm>[o][F]{car} \\ar@/_/[r]_{\\mu_\\mathrm{c}} \\ar@/^/[u]^{(1-p)\\lambda} & *=<15mm,8mm>[o][F]{empty} \\ar@/_/[l]_{p\\lambda} \\ar@/^/[r]^{(1-p)\\lambda} & *=<15mm,8mm>[o][F]{m/cycle} \\ar@/^/[l]^{\\mu_\\mathrm{m}} \\ar@/_/[d]_{(1-p)\\lambda} \\\\ & & *=<15mm,8mm>[o][F]{m/c+} \\ar@/_/[u]_{\\mu_\\mathrm{m}} }}$$ Q=(−μc00μc0(1−p)λ−(1−p)λ−μcμc000pλ−λ(1−p)λ000μm−(1−p)λ−μm(1−p)λ000μm−μm)Q = \\begin{pmatrix} -\\mu_\\mathrm{c} & 0 & 0 & \\mu_\\mathrm{c} & 0 \\\\ (1-p)\\lambda & -(1-p)\\lambda-\\mu_\\mathrm{c} & \\mu_\\mathrm{c} & 0 & 0 \\\\ 0 & p\\lambda & -\\lambda & (1-p)\\lambda & 0 \\\\ 0 & 0 & \\mu_\\mathrm{m} & -(1-p)\\lambda-\\mu_\\mathrm{m} & (1-p)\\lambda \\\\ 0 & 0 & 0 & \\mu_\\mathrm{m} & -\\mu_\\mathrm{m} \\\\ \\end{pmatrix} states car+ m/c+ represent car + waiting motorcycle motorcycle + waiting motorcycle respectively. pp steady state distribution, average number vehicles system given N=2(p1+p5)+p2+p4N = 2(p_1 + p_5) + p_2 + p_4 first example, can simulate chain breaking problem two trajectories (one type vehicle service rate) two generators. order disallow cars stay pump’s queue, need introduce little trick cars’ seize: argument amount function returns 1 pump vacant 2 otherwise. implies car gets rejected, one position queue seize requesting two positions. Note also environment env must defined running, needed inside trajectory. idea using branch, single generator single trajectory. may also avoid messing things branches subtrajectories. can decide type vehicle set attribute arrival set_attribute(). , attributes can retrieved using get_attribute(). Although branch option little bit faster, one nicer, subtrajectories involved. performance requirement, can play cleverly resource capacity queue size, amounts requested seize, order model problem without checking status resource. Think : resource capacity=3 queue_size=2. car always tries seize amount=3. motorcycle always tries seize amount=2. conditions, following possibilities: Pump empty. One car (3 units) server [optionally one motorcycle (2 units) queue]. One motorcycle (2 units) server [optionally one motorcycle (2 units) queue]. Just expected! , let’s try: still wasting time branch decision. can mix solution option.1 gain extra performance: Options 1, 2 3 slower, give us correct numbers, parameters (capacity, queue size, amounts) model remain unchanged compared problem. instance, However, case options 4 5. parameters models adulterated fit performance purposes. Therefore, need extract RAW data, rescale numbers plot . , course, get figure: Finally, performance results:","code":"# Theoretical resolution A <- matrix(c(1, 0, 0, mu[1], 0, 1, -(1-p)*lambda-mu[1], mu[1], 0, 0, 1, p*lambda, -lambda, (1-p)*lambda, 0, 1, 0, mu[2], -(1-p)*lambda-mu[2], (1-p)*lambda, 1, 0, 0, mu[2], -mu[2]), byrow=T, ncol=5) B <- c(1, 0, 0, 0, 0) P <- solve(t(A), B) N_average_theor <- sum(P * c(2, 1, 0, 1, 2)) ; N_average_theor #> [1] 0.6349615 option.1 <- function(t) { car <- trajectory() %>% seize(\"pump\", amount=function() { if (env %>% get_server_count(\"pump\")) 2 # rejection else 1 # serve }) %>% timeout(function() rexp(1, mu[1])) %>% release(\"pump\", amount=1) mcycle <- trajectory() %>% seize(\"pump\", amount=1) %>% timeout(function() rexp(1, mu[2])) %>% release(\"pump\", amount=1) env <- simmer() %>% add_resource(\"pump\", capacity=1, queue_size=1) %>% add_generator(\"car\", car, function() rexp(1, p*lambda)) %>% add_generator(\"mcycle\", mcycle, function() rexp(1, (1-p)*lambda)) env %>% run(until=t) } option.2 <- function(t) { vehicle <- trajectory() %>% branch(function() sample(c(1, 2), 1, prob=c(p, 1-p)), c(F, F), trajectory(\"car\") %>% seize(\"pump\", amount=function() { if (env %>% get_server_count(\"pump\")) 2 # rejection else 1 # serve }) %>% timeout(function() rexp(1, mu[1])) %>% release(\"pump\", amount=1), # always 1 trajectory(\"mcycle\") %>% seize(\"pump\", amount=1) %>% timeout(function() rexp(1, mu[2])) %>% release(\"pump\", amount=1)) env <- simmer() %>% add_resource(\"pump\", capacity=1, queue_size=1) %>% add_generator(\"vehicle\", vehicle, function() rexp(1, lambda)) env %>% run(until=t) } option.3 <- function(t) { vehicle <- trajectory(\"car\") %>% set_attribute(\"vehicle\", function() sample(c(1, 2), 1, prob=c(p, 1-p))) %>% seize(\"pump\", amount=function() { if (get_attribute(env, \"vehicle\") == 1 && env %>% get_server_count(\"pump\")) 2 # car rejection else 1 # serve }) %>% timeout(function() rexp(1, mu[get_attribute(env, \"vehicle\")])) %>% release(\"pump\", amount=1) # always 1 env <- simmer() %>% add_resource(\"pump\", capacity=1, queue_size=1) %>% add_generator(\"vehicle\", vehicle, function() rexp(1, lambda)) env %>% run(until=t) } option.4 <- function(t) { vehicle <- trajectory() %>% branch(function() sample(c(1, 2), 1, prob=c(p, 1-p)), c(F, F), trajectory(\"car\") %>% seize(\"pump\", amount=3) %>% timeout(function() rexp(1, mu[1])) %>% release(\"pump\", amount=3), trajectory(\"mcycle\") %>% seize(\"pump\", amount=2) %>% timeout(function() rexp(1, mu[2])) %>% release(\"pump\", amount=2)) simmer() %>% add_resource(\"pump\", capacity=3, queue_size=2) %>% add_generator(\"vehicle\", vehicle, function() rexp(1, lambda)) %>% run(until=t) } option.5 <- function(t) { car <- trajectory() %>% seize(\"pump\", amount=3) %>% timeout(function() rexp(1, mu[1])) %>% release(\"pump\", amount=3) mcycle <- trajectory() %>% seize(\"pump\", amount=2) %>% timeout(function() rexp(1, mu[2])) %>% release(\"pump\", amount=2) simmer() %>% add_resource(\"pump\", capacity=3, queue_size=2) %>% add_generator(\"car\", car, function() rexp(1, p*lambda)) %>% add_generator(\"mcycle\", mcycle, function() rexp(1, (1-p)*lambda)) %>% run(until=t) } gas.station <- option.1(5000) # Evolution + theoretical value plot(get_mon_resources(gas.station), \"usage\", \"pump\", items=\"system\") + geom_hline(yintercept=N_average_theor) gas.station <- option.5(5000) get_mon_resources(gas.station) %>% transform(system = round(system * 2/5)) %>% # rescaling transform(avg = c(0, cumsum(head(system, -1) * diff(time))) / time) %>% ggplot(aes(time, avg)) + geom_line(color=\"red\") + expand_limits(y=0) + labs(title=\"Resource usage: pump\", x=\"time\", y=\"in use\") + geom_hline(yintercept=2, lty=2, color=\"red\") + geom_hline(yintercept=N_average_theor) library(microbenchmark) t <- 1000/lambda tm <- microbenchmark(option.1(t), option.2(t), option.3(t), option.4(t), option.5(t)) autoplot(tm) + scale_y_log10(breaks=function(limits) pretty(limits, 5)) + ylab(\"Time [milliseconds]\")"},{"path":"https://r-simmer.org/articles/simmer-08-philosophers.html","id":"problem-description","dir":"Articles","previous_headings":"","what":"Problem description","title":"Dining Philosophers Problem","text":"Dining Philosophers problem classical example computer science illustrate synchronisation issues concurrent processes. originally formulated 1965 E. W. Dijkstra student exam exercise, later reworked current form Tony Hoare: NN silent philosophers sit round table bowls spaghetti. Forks placed pair adjacent philosophers. philosopher must alternately think eat. However, philosopher can eat spaghetti left right forks. fork can held one philosopher philosopher can use fork used another philosopher. individual philosopher finishes eating, need put forks forks become available others. philosopher can take fork right one left become available, start eating getting forks. problem design discipline behavior (concurrent algorithm) philosopher starve; .e., can forever continue alternate eating thinking, assuming philosopher can know others may want eat think.","code":""},{"path":"https://r-simmer.org/articles/simmer-08-philosophers.html","id":"simulation","dir":"Articles","previous_headings":"","what":"Simulation","title":"Dining Philosophers Problem","text":"Let us define philosopher process executing thinking + eating loop, acting concurrently shared resources (forks). process follow similar trajectory Spend random time thinking become hungry. Take one fork, available, following given policy. lag, take fork, available. Spend random time eating. Put forks go back 1. following function sets simulation NN dining philosophers established : fork_seq argument consists named list fork sequences. instance, given numbering conventions image , decide philosopher 1, Socrates, must take fork 1 first fork 2, fork sequence Socrates = c(1, 2). function also expects simulation time, arguments play , thinking eating random processes, lag forks, seed. following function allow us plot kind Gantt chart simulation: simplest algorithm, philosopher take, example, right fork first left one. easy see policy may result starvation: can see, simulation stopped soon point every philosopher holds one fork waits available. solution originally proposed Dijkstra establishes convention resources must requested order. means , simulation, Aristotle pick fork 1 first instead: multiple solutions starvation problem, probably straightforward way break circularity initial algorithm making one philosopher pick left fork first.","code":"library(simmer) library(simmer.plot) simulate <- function(fork_seq, time, thinking=function() rexp(1, 1), eating=function() rexp(1, 1), lag=0.1, seed=333) { set.seed(seed) env <- simmer(\"Dining philosophers\") for (i in seq_along(fork_seq)) { philosopher <- names(fork_seq)[[i]] forks <- paste0(\"fork_\", fork_seq[[i]]) dining <- trajectory() %>% timeout(thinking, tag=\"think\") %>% seize(forks[[1]]) %>% timeout(lag) %>% seize(forks[[2]]) %>% timeout(eating) %>% release(forks[[1]]) %>% release(forks[[2]]) %>% rollback(\"think\") # back to think env %>% add_resource(paste0(\"fork_\", i)) %>% add_generator(paste0(philosopher, \"_\"), dining, at(0)) } run(env, time) } states <- c(\"hungry\", \"eating\") philosophers_gantt <- function(env, size=15) env %>% get_mon_arrivals(per_resource=TRUE) %>% transform(philosopher = sub(\"_[0-9]*\", \"\", name), state = factor(states, states)) %>% ggplot(aes(y=philosopher, yend=philosopher)) + xlab(\"time\") + geom_segment(aes(x=start_time, xend=end_time, color=state), size=size) fork_seq <- list( Socrates = c(1, 2), Pythagoras = c(2, 3), Plato = c(3, 4), Aristotle = c(4, 1) ) simulate(fork_seq, time=50) %>% print() %>% philosophers_gantt() + theme_bw() #> simmer environment: Dining philosophers | now: 3.89681179066325 | next: #> { Monitor: in memory } #> { Resource: fork_1 | monitored: TRUE | server status: 1(1) | queue status: 1(Inf) } #> { Resource: fork_2 | monitored: TRUE | server status: 1(1) | queue status: 1(Inf) } #> { Resource: fork_3 | monitored: TRUE | server status: 1(1) | queue status: 1(Inf) } #> { Resource: fork_4 | monitored: TRUE | server status: 1(1) | queue status: 1(Inf) } #> { Source: Socrates_ | monitored: 1 | n_generated: 1 } #> { Source: Pythagoras_ | monitored: 1 | n_generated: 1 } #> { Source: Plato_ | monitored: 1 | n_generated: 1 } #> { Source: Aristotle_ | monitored: 1 | n_generated: 1 } #> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0. #> ℹ Please use `linewidth` instead. #> This warning is displayed once every 8 hours. #> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was #> generated. fork_seq$Aristotle <- rev(fork_seq$Aristotle) simulate(fork_seq, time=50) %>% print() %>% philosophers_gantt() + theme_bw() #> simmer environment: Dining philosophers | now: 50 | next: 50.8360142024587 #> { Monitor: in memory } #> { Resource: fork_1 | monitored: TRUE | server status: 1(1) | queue status: 0(Inf) } #> { Resource: fork_2 | monitored: TRUE | server status: 1(1) | queue status: 1(Inf) } #> { Resource: fork_3 | monitored: TRUE | server status: 1(1) | queue status: 0(Inf) } #> { Resource: fork_4 | monitored: TRUE | server status: 1(1) | queue status: 0(Inf) } #> { Source: Socrates_ | monitored: 1 | n_generated: 1 } #> { Source: Pythagoras_ | monitored: 1 | n_generated: 1 } #> { Source: Plato_ | monitored: 1 | n_generated: 1 } #> { Source: Aristotle_ | monitored: 1 | n_generated: 1 }"},{"path":"https://r-simmer.org/articles/simmer-aa-5G.html","id":"abstract","dir":"Articles","previous_headings":"","what":"Abstract","title":"Design and Analysis of 5G Scenarios","text":"Simulation frameworks important tools analysis design communication networks protocols, can result extremely costly /complex (case specialized tools), naive lacking proper features support (case ad-hoc tools). paper, present analysis three 5G scenarios using simmer, recent R package discrete-event simulation sits two paradigms. results show, provides simple yet powerful syntax, supporting efficient simulation relatively complex scenarios low implementation cost. vignette contains code associated article Design Analysis 5G Scenarios simmer: R Package Fast DES Prototyping (see draft version arXiv), published IEEE Communications Magazine (see citation(\"simmer\")). Refer article full description analysis scenario.","code":""},{"path":"https://r-simmer.org/articles/simmer-aa-5G.html","id":"crosshauling-of-fh-and-bh-traffic","dir":"Articles","previous_headings":"","what":"Crosshauling of FH and BH traffic","title":"Design and Analysis of 5G Scenarios","text":"scenario motivated Cloud Radio Access Network (C-RAN) paradigm, mobile base station functionality split simple Remote Radio Heads (RRH), spread across deployment connected fiber centralized (possibly virtualized) Base-Band Units (BBU), operators’ premises. C-RAN paradigm, fronthaul (FH) traffic RRH stringent delay requirements, backhaul (BH) traffic BBU mild delay requirements. general topology, one illustrated figure, packet switches forward types traffic. use simmer simulate scenario decide whether introducing service differentiation might improve ability fulfil delivery guarantees FH traffic. configuration parameters considered: model defined encapsulated simulate function. , several scenarios different parameters defined cases, can run parallel: Finally, information extracted, summarised represented lines code:","code":"C <- 40e9 # link capacity [bps] rho <- 0.75 # utilization FH_EX <- (80 + 46) * 8 / C # avg. FH interarrival time [s] BH_bytes <- c(40, 576, 1500) # BH traffic distribution Weights <- c(7, 4, 1) / 12 # BH_EX <- sum(Weights * (8 * BH_bytes / C)) # avg. BH interarrival time [s] FH_w <- 0.5 # FH traffic ratio BH_w <- 1 - FH_w # BH traffic ratio FH_lambda <- FH_w * rho / FH_EX # FH avg. rate [pkts/s] BH_lambda <- BH_w * rho / BH_EX # BH avg. rate [pkts/s] Tsim <- 1e5 / (FH_lambda + BH_lambda) # simulation time library(simmer) set.seed(1234) # parametrized simulation function # - param[[\"n_switch\"]] is the number of switches # - param[[\"fh_prio\"]] is the priority level for FH traffic # - param[[\"preemptive\"]] is the preemptiveness flag for switches simulate <- function(param) { # single FH traffic trajectory traversing n_switch elements sequentially fh_traffic <- lapply(1:param[[\"n_switch\"]], function(i) { trajectory() %>% seize(paste0(\"switch\", i)) %>% timeout(FH_EX) %>% release(paste0(\"switch\", i)) }) %>% join() # list of n_switch trajectories, one per element, modeling the interfering BH traffic bh_traffic <- lapply(1:param[[\"n_switch\"]], function(i) { trajectory() %>% seize(paste0(\"switch\", i)) %>% timeout(function() sample(BH_bytes*8/C, size=1, prob=Weights)) %>% release(paste0(\"switch\", i)) }) # simulation environment env <- simmer() %>% # generator of FH traffic add_generator(\"FH_0_\", fh_traffic, function() rexp(100, FH_lambda), priority=param[[\"fh_prio\"]]) for (i in 1:param[[\"n_switch\"]]) env %>% # n_switch resources, one per switch add_resource(paste0(\"switch\", i), 1, Inf, mon=FALSE, preemptive=param[[\"preemptive\"]]) %>% # n_switch generators of BH traffic add_generator(paste0(\"BH_\", i, \"_\"), bh_traffic[[i]], function() rexp(100, BH_lambda)) env %>% run(until=Tsim) %>% wrap() } # grid of scenarios cases <- expand.grid(n_switch = c(1, 2, 5), fh_prio = c(0, 1), preemptive = c(TRUE, FALSE)) # parallel simulation system.time({ envs <- parallel::mclapply(split(cases, 1:nrow(cases)), simulate, mc.cores=nrow(cases), mc.set.seed=FALSE) }) library(tidyverse) bp.vals <- function(x, probs=c(0.05, 0.25, 0.5, 0.75, 0.95)) { r <- quantile(x, probs=probs, na.rm=TRUE) names(r) <- c(\"ymin\", \"lower\", \"middle\", \"upper\", \"ymax\") r } arrivals <- envs %>% get_mon_arrivals() %>% left_join(rowid_to_column(cases, \"replication\")) %>% filter(!(fh_prio==0 & preemptive==TRUE)) %>% separate(name, c(\"Flow\", \"index\", \"n\")) %>% mutate(total_time = end_time - start_time, waiting_time = total_time - activity_time, Queue = forcats::fct_recode(interaction(fh_prio, preemptive), \"without SP\" = \"0.FALSE\", \"with SP\" = \"1.FALSE\", \"with SP & preemption\" = \"1.TRUE\")) arrivals %>% filter(n_switch == 1) %>% # plot ggplot(aes(Queue, waiting_time*1e9, color=Flow)) + theme_bw() + stat_summary(fun.data=bp.vals, geom=\"boxplot\", position=\"dodge\") + theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) + labs(y = \"Queueing Delay [ns]\", x = element_blank()) arrivals %>% filter(Flow == \"FH\") %>% # plot ggplot(aes(factor(n_switch), waiting_time*1e9, color=Queue)) + theme_bw() + stat_summary(fun.data=bp.vals, geom=\"boxplot\", position=\"dodge\") + theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) + labs(y = \"Queueing Delay [ns]\", x = \"No. of switches\")"},{"path":"https://r-simmer.org/articles/simmer-aa-5G.html","id":"mobile-traffic-backhauling-with-fttx","dir":"Articles","previous_headings":"","what":"Mobile traffic backhauling with FTTx","title":"Design and Analysis of 5G Scenarios","text":"next consider case residencial area Fiber---Premises (FTTx) infrastructure, , Optical Distribution Network (ODN), composed Optical Line Terminal (OLT), splitters, Optical Network Unit (ONU) users’ premises. figure illustrates, assume operator planning deploy antenna, carrying mobile traffic ODN, considering two implementation options: Deployment Small Cell, reducing amount requirements generated traffic. Deployment RRH, following C-RAN paradigm discussed , therefore generate time-sensitive FH traffic. cases, analyze upstream channel Time-Division Multiplexed Passive Optical Network (TDM-PON) providing broadband access residential users mobile users. configuration parameters considered: model defined encapsulated simulate function. , several scenarios different parameters defined cases, can run parallel: Finally, information extracted, summarised represented lines code:","code":"C <- 1.25e9 # link capacity [bps] Tg <- 1e-6 # guard time [s] bytes <- c(40, 576, 1500) # traffic distribution Weights <- c(7, 4, 1) / 12 # EX <- sum(Weights * (8 * bytes / C)) # avg. interarrival time [s] burst <- 20 # burst length [pkts] ONU_lambda <- 20e6 / C / EX # avg. rate per ONU [pkts/s] SC_lambda <- 150e6 / C / EX # avg. rate for the SC [pkts/s] RRH_on <- 8 * 6000 / C # RRH on period [s] RRH_period <- RRH_on * C / 720e6 # RRH total period [s] RRH_off <- RRH_period - RRH_on # RRH off period [s] # helper function: round-robin-based selection of ONUs cyclic_counter <- function(n) { n <- as.numeric(n) i <- 1 function(op) { if (!missing(op)) { i <<- i + op if (i > n) i <<- 1 else if (i < 1) i <<- n } i } } # helper function: generator of packet sizes of n packets gen_pkts <- function(n) sample(bytes*8/C, size=n, prob=Weights, replace=TRUE) # helper function: double-exponential generator of interarrival times gen_exp <- function(lambda, burst) function() unlist(lapply(rexp(100/burst, lambda/burst), function(i) c(i, rep(0, rpois(1, burst))))) library(simmer) set.seed(1234) # parametrized simulation function # - param[[\"scenario\"]] is the scenario identifier (A=small cell, B=RRH) # - param[[\"ONU_n\"]] is the number of ONUs # - param[[\"limit\"]] is the max. transmission window simulate <- function(param) { # global variables lambda <- rep(ONU_lambda, param[[\"ONU_n\"]]) limit <- rep(param[[\"limit\"]], param[[\"ONU_n\"]]) * 8 / C if (param[[\"scenario\"]] == \"A\") { param[[\"ONU_n\"]] <- param[[\"ONU_n\"]] + 1 lambda <- c(lambda, SC_lambda) limit <- c(limit, Inf) tx_t <- RRH_on + Tg + Tg * 0:param[[\"ONU_n\"]] } else { Tg_n <- RRH_off %/% Tg - 1 Tg_i <- rep(1:Tg_n, length.out=param[[\"ONU_n\"]]+1) period_i <- rep(0:param[[\"ONU_n\"]], each=Tg_n, length.out=param[[\"ONU_n\"]]+1) tx_t <- RRH_on + RRH_period * period_i + Tg * Tg_i } eq_pkts <- rep(list(NULL), param[[\"ONU_n\"]]) tx_pkts <- rep(list(NULL), param[[\"ONU_n\"]]) t_head <- tail(tx_t, 1) onu_i <- cyclic_counter(param[[\"ONU_n\"]]) remaining <- Inf # DBA logic set_next_window <- function() { # time until the next RRH_on if (param[[\"scenario\"]] == \"B\") remaining <- (t_head %/% RRH_period + 1) * RRH_period - t_head # generate new pkt lengths pkts <- get_queue_count(env, paste0(\"ONU\", onu_i())) eq_pkts[[onu_i()]] <<- c(eq_pkts[[onu_i()]], gen_pkts(pkts - length(eq_pkts[[onu_i()]]))) # reserve the next transmission window eq_cumsum <- cumsum(eq_pkts[[onu_i()]]) n <- sum(eq_cumsum <= min(limit[[onu_i()]], remaining - Tg)) if ((pkts && !n) || (remaining <= Tg)) { # go past the next RRH_on t_head <<- t_head + remaining + RRH_on + Tg n <- sum(eq_cumsum <= min(limit[[onu_i()]], RRH_off - 2*Tg)) } tx_pkts[[onu_i()]] <<- head(eq_pkts[[onu_i()]], n) eq_pkts[[onu_i()]] <<- tail(eq_pkts[[onu_i()]], -n) tx_t[[onu_i()]] <<- t_head t_head <<- t_head + sum(tx_pkts[[onu_i()]]) + Tg index <<- 0 tx_t[[onu_i(1)]] - now(env) } # list of ONU_n trajectories, one per ONU ONUs <- lapply(1:param[[\"ONU_n\"]], function(i) { trajectory() %>% seize(paste0(\"ONU\", i)) %>% set_capacity(paste0(\"ONU\", i), 0) %>% seize(\"link\") %>% timeout(function() { index <<- index + 1 tx_pkts[[i]][index] }) %>% release(\"link\") %>% release(paste0(\"ONU\", i)) }) # OLT logic OLT <- trajectory() %>% simmer::select(function() paste0(\"ONU\", onu_i())) %>% set_attribute(\"ONU\", function() onu_i()) %>% set_capacity_selected(function() length(tx_pkts[[onu_i()]])) %>% timeout(function() sum(tx_pkts[[onu_i()]])) %>% timeout(set_next_window) %>% rollback(amount=6, times=Inf) # RRH logic RRH <- trajectory() %>% seize(\"link\") %>% timeout(RRH_on) %>% release(\"link\") %>% timeout(RRH_off) %>% rollback(amount=4, times=Inf) # simulation environment env <- simmer() %>% # the fiber link as a resource add_resource(\"link\", 1, Inf) if (param[[\"scenario\"]] == \"B\") # RRH worker env %>% add_generator(\"RRH_\", RRH, at(0)) for (i in 1:param[[\"ONU_n\"]]) env %>% # ONU_n resources, one per ONU add_resource(paste0(\"ONU\", i), 0, Inf) %>% # ONU_n traffic generators, one per ONU add_generator(paste0(\"ONU_\", i, \"_\"), ONUs[[i]], gen_exp(lambda[i], burst)) env %>% # OLT worker add_generator(\"token_\", OLT, at(RRH_on + Tg), mon=2) %>% run(until=1e5/sum(lambda)) %>% wrap() } # grid of scenarios cases <- data.frame(scenario = c(rep(\"A\", 4), rep(\"B\", 1)), ONU_n = c(rep(31, 4), rep(7, 1)), limit = c(Inf, 1500, 3000, 6000, Inf)) # parallel simulation system.time({ envs <- parallel::mclapply(split(cases, 1:nrow(cases)), simulate, mc.cores=nrow(cases), mc.set.seed=FALSE) }) library(tidyverse) bp.vals <- function(x, probs=c(0.05, 0.25, 0.5, 0.75, 0.95)) { r <- quantile(x, probs=probs, na.rm=TRUE) names(r) <- c(\"ymin\", \"lower\", \"middle\", \"upper\", \"ymax\") r } envs %>% get_mon_arrivals() %>% left_join(rowid_to_column(cases, \"replication\")) %>% mutate(scenario = forcats::fct_recode( scenario, `SmallCell + 31 ONUs`=\"A\", `RRH + 7 ONUs`=\"B\")) %>% separate(name, c(\"flow\", \"index\", \"n\")) %>% mutate(flow = if_else(index == ONU_n+1, \"SmallCell\", flow)) %>% mutate(total_time = end_time - start_time, waiting_time = total_time - activity_time) %>% # plot ggplot(aes(forcats::fct_rev(flow), waiting_time*1e6, color=factor(limit))) + theme_bw() + facet_grid(~scenario, scales=\"free\", space=\"free\") + stat_summary(fun.data=bp.vals, geom=\"boxplot\", position=\"dodge\") + theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) + labs(y=expression(paste(\"Queueing Delay [\", mu, \"s]\")), x=element_blank(), color=\"Limit [bytes]\")"},{"path":"https://r-simmer.org/articles/simmer-aa-5G.html","id":"energy-efficiency-for-massive-iot","dir":"Articles","previous_headings":"","what":"Energy efficiency for massive IoT","title":"Design and Analysis of 5G Scenarios","text":"Finally, consider case massive Internet--Things (mIoT) scenario, use case Long Term Evolution (LTE) next-generation 5G networks, defined Third Generation Partnership Project (3GPP). figure (left) illustrates, consider single LTE macrocell dense urban area. buildings cell area populated NN smart meters (electricity, gas water), meter operates independently Narrowband IoT (NB-IoT) device. devices’ behaviour modeled following diagram depicted figure (right). configuration parameters considered: model defined encapsulated simulate function. , several scenarios different parameters defined cases, can run parallel: Finally, information extracted, summarised represented lines code:","code":"m <- 9 # number of RA retries Ps <- 0.03 # sleep power consumption [mW] Pi <- 10 # idle power consumption [mW] Prx <- 100 # rx power consumption [mW] Prbp <- 32.18 # tx power consumption per RB pair [mW] Ppre <- 32.18 # preamble tx power consumption [mW] Tbpre <- 0.0025 # time before preamble transmission [s] Tpre <- 0.0014 # time for preamble transmission [s] Trarx <- 0.01 # rx time to perform RA [s] Tcrcp <- 0.016 # sum of processing delays to establish a connection [s] Twait <- 0.054 # S1 processing and transfer delay [s] Brbp <- 36 # bytes per RB pair (QPSK modulation) Breq <- 7 # RRC request message size (bytes) Bcompcp <- 129 # RRC setup complete + NAS control plane SR + data for CP (bytes) Tra <- Tbpre + Trarx + Tpre Pra <- (Tbpre*Pi + Trarx*Prx + Tpre*Ppre) / Tra rbs <- (ceiling(Breq/Brbp) + ceiling(Bcompcp/Brbp)) * 1e-3 Ttx <- Tcrcp + rbs + Twait Ptx <- (Tcrcp*Prx + rbs*Prbp + Twait*Prx) / Ttx tx_period <- 3600 # time between transmissions (seconds) Tsim <- 24*3600 # simulation time (seconds) library(simmer) set.seed(1234) # parametrized simulation function # - param[[\"meter_n\"]] is the number of IoT devices in the cell # - param[[\"backoff\"]] is the backoff time simulate <- function(param) { # identifiers for RA preambles preambles <- paste0(\"preamble_\", 1:54) # IoT device logic meter <- trajectory() %>% trap(\"reading\") %>% # sleep set_attribute(\"P\", 0) %>% wait() %>% timeout(function() round(runif(1, 0, param[[\"backoff\"]]), 3)) %>% # ra start simmer::select(preambles, policy=\"random\") %>% seize_selected( continue=c(TRUE, TRUE), # ra & tx post.seize=trajectory() %>% set_attribute(\"P\", Pra) %>% timeout(Tra) %>% release_selected() %>% set_attribute(\"P\", Ptx) %>% timeout(Ttx), # ra & backoff & retry reject=trajectory() %>% set_attribute(\"P\", Pra) %>% timeout(Tra) %>% set_attribute(\"P\", Pi) %>% timeout(function() sample(1:20, 1) * 1e-3) %>% rollback(6, times=m) ) %>% rollback(5, times=Inf) # trigger a reading for all the meters every tx_period trigger <- trajectory() %>% timeout(tx_period) %>% send(\"reading\") %>% rollback(2, times=Inf) # simulation environment env <- simmer() %>% # IoT device workers add_generator(\"meter_\", meter, at(rep(0, param[[\"meter_n\"]])), mon=2) %>% # trigger worker add_generator(\"trigger_\", trigger, at(0), mon=0) for (i in preambles) # one resource per preamble env %>% add_resource(i, 1, 0, mon=FALSE) env %>% run(until=Tsim) %>% wrap() } # grid of scenarios cases <- expand.grid(meter_n = c(5e3, 1e4, 3e4), backoff = c(5, 10, 30, 60)) # parallel simulation system.time({ envs <- parallel::mclapply(split(cases, 1:nrow(cases)), simulate, mc.cores=nrow(cases), mc.set.seed=FALSE) }) library(tidyverse) bp.vals <- function(x, probs=c(0.05, 0.25, 0.5, 0.75, 0.95)) { r <- quantile(x, probs=probs, na.rm=TRUE) names(r) <- c(\"ymin\", \"lower\", \"middle\", \"upper\", \"ymax\") r } envs %>% get_mon_attributes() %>% group_by(replication, name) %>% summarise(dE = sum(c(0, head(value, -1) * diff(time)))) %>% left_join(rowid_to_column(cases, \"replication\")) %>% # plot ggplot(aes(factor(meter_n), dE*tx_period/Tsim, color=factor(backoff))) + stat_summary(fun.data=bp.vals, geom=\"boxplot\", position=\"dodge\") + theme_bw() + theme(legend.justification=c(0, 1), legend.position=c(.02, .98)) + labs(y=\"Energy per Tx [mJ]\", x=\"No. of devices\", color=\"Backoff window [s]\")"},{"path":"https://r-simmer.org/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Iñaki Ucar. Author, copyright holder, maintainer. Bart Smeets. Author, copyright holder.","code":""},{"path":"https://r-simmer.org/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Ucar , Smeets B, Azcorra (2019). “simmer: Discrete-Event Simulation R.” Journal Statistical Software, 90(2), 1–30. doi:10.18637/jss.v090.i02. Ucar , Hernández J, Serrano P, Azcorra (2018). “Design Analysis 5G Scenarios simmer: R Package Fast DES Prototyping.” IEEE Communications Magazine, 56(11), 145–151. doi:10.1109/MCOM.2018.1700960.","code":"@Article{, title = {{simmer}: Discrete-Event Simulation for {R}}, author = {I{\\~n}aki Ucar and Bart Smeets and Arturo Azcorra}, journal = {Journal of Statistical Software}, year = {2019}, volume = {90}, number = {2}, pages = {1--30}, doi = {10.18637/jss.v090.i02}, } @Article{, title = {Design and Analysis of 5G Scenarios with {simmer}: An {R} Package for Fast DES Prototyping}, author = {I{\\~n}aki Ucar and José Alberto Hernández and Pablo Serrano and Arturo Azcorra}, journal = {IEEE Communications Magazine}, year = {2018}, month = {November}, volume = {56}, number = {11}, pages = {145--151}, doi = {10.1109/MCOM.2018.1700960}, }"},{"path":"https://r-simmer.org/extensions/bricks/articles/index.html","id":null,"dir":"Extensions > Bricks > Articles","previous_headings":"","what":"All vignettes","title":"Articles","text":"Introduction `simmer.bricks`","code":""},{"path":"https://r-simmer.org/extensions/bricks/articles/introduction.html","id":"a-motivating-example","dir":"Extensions > Bricks > Articles","previous_headings":"","what":"A motivating example","title":"Introduction to `simmer.bricks`","text":"simmer package provides rich flexible API build discrete-event simulations. However, certain recurring patterns typed . common example probably spend time holding resource. Let us consider basic example Introduction simmer: seize > timeout > release blocks can substituted visit verb, included simmer.bricks: Internally, simmer.bricks just uses simmer verbs, trajectories equivalent: means must mind want use rollback() loop part trajectory. summary, simmer.bricks package repository simmer activity patterns like one. See help(package=\"simmer.bricks\") comprehensive list.","code":"library(simmer) patient.1 <- trajectory(\"patients' path\") %>% ## add an intake activity seize(\"nurse\", 1) %>% timeout(function() rnorm(1, 15)) %>% release(\"nurse\", 1) %>% ## add a consultation activity seize(\"doctor\", 1) %>% timeout(function() rnorm(1, 20)) %>% release(\"doctor\", 1) %>% ## add a planning activity seize(\"administration\", 1) %>% timeout(function() rnorm(1, 5)) %>% release(\"administration\", 1) library(simmer.bricks) patient.2 <- trajectory(\"patients' path\") %>% ## add an intake activity visit(\"nurse\", function() rnorm(1, 15)) %>% ## add a consultation activity visit(\"doctor\", function() rnorm(1, 20)) %>% ## add a planning activity visit(\"administration\", function() rnorm(1, 5)) patient.1 #> trajectory: patients' path, 9 activities #> { Activity: Seize | resource: nurse, amount: 1 } #> { Activity: Timeout | delay: function() } #> { Activity: Release | resource: nurse, amount: 1 } #> { Activity: Seize | resource: doctor, amount: 1 } #> { Activity: Timeout | delay: function() } #> { Activity: Release | resource: doctor, amount: 1 } #> { Activity: Seize | resource: administration, amount: 1 } #> { Activity: Timeout | delay: function() } #> { Activity: Release | resource: administration, amount: 1 } patient.2 #> trajectory: patients' path, 9 activities #> { Activity: Seize | resource: nurse, amount: 1 } #> { Activity: Timeout | delay: function() } #> { Activity: Release | resource: nurse, amount: 1 } #> { Activity: Seize | resource: doctor, amount: 1 } #> { Activity: Timeout | delay: function() } #> { Activity: Release | resource: doctor, amount: 1 } #> { Activity: Seize | resource: administration, amount: 1 } #> { Activity: Timeout | delay: function() } #> { Activity: Release | resource: administration, amount: 1 }"},{"path":[]},{"path":"https://r-simmer.org/extensions/bricks/articles/introduction.html","id":"delayed-release","dir":"Extensions > Bricks > Articles","previous_headings":"More compelling examples","what":"Delayed release","title":"Introduction to `simmer.bricks`","text":"simulations require resource become inoperative time release. possible simulate simmer using technique call delayed release. Basically, arrival releases resource continues trajectory, clone latter keeps resource busy time required; finally, clone removed. main problem keeping resource busy must implemented different ways depending resource type, .e., whether preemptive . package encapsulates logic easy--use brick called delayed_release(): curious, can print trajectory see happens behind scenes.","code":"env <- simmer() %>% add_resource(\"res1\") %>% add_resource(\"res2\", preemptive=TRUE) t <- trajectory() %>% seize(\"res1\") %>% log_(\"res1 seized\") %>% seize(\"res2\") %>% log_(\"res2 seized\") %>% # inoperative for 2 units of time delayed_release(\"res1\", 2) %>% log_(\"res1 released\") %>% # inoperative for 5 units of time delayed_release(\"res2\", 5, preemptive=TRUE) %>% log_(\"res2 released\") env %>% add_generator(\"dummy\", t, at(0, 1)) %>% run() %>% invisible #> 0: dummy0: res1 seized #> 0: dummy0: res2 seized #> 0: dummy0: res1 released #> 0: dummy0: res2 released #> 2: dummy1: res1 seized #> 5: dummy1: res2 seized #> 5: dummy1: res1 released #> 5: dummy1: res2 released"},{"path":"https://r-simmer.org/extensions/bricks/articles/introduction.html","id":"parallel-tasks","dir":"Extensions > Bricks > Articles","previous_headings":"More compelling examples","what":"Parallel tasks","title":"Introduction to `simmer.bricks`","text":"Another common pattern set number parallel tasks clone(). challenging original arrival resources seized. Let us consider following case, doctor nurse visiting patients hospital room: simulation fails. original arrival, seized room follows first path (doctor), finishes duty first place. Given wait = TRUE synchronize() activity, means last clone arrive (nurse case) continues, others removed. Solving requires ensuring original arrival reaches synchronize() activity last place (first place wait = FALSE), can tricky, asynchronous programming must used. However, simmer.bricks provides do_parallel() brick: everything just works.","code":"t <- trajectory() %>% seize(\"room\") %>% clone( n = 2, trajectory(\"doctor\") %>% timeout(1), trajectory(\"nurse\") %>% timeout(2)) %>% synchronize(wait = TRUE) %>% timeout(0.5) %>% release(\"room\",1) simmer() %>% add_resource(\"room\") %>% add_generator(\"visit\", t, at(0)) %>% run() #> Error: 'visit0' at 2.50 in [Timeout]->Release->[]: #> 'room' not previously seized env <- simmer() t <- trajectory() %>% seize(\"room\") %>% log_(\"room seized\") %>% do_parallel( trajectory(\"doctor\") %>% timeout(1) %>% log_(\"doctor path done\"), trajectory(\"nurse\") %>% timeout(2) %>% log_(\"nurse path done\"), .env = env ) %>% timeout(0.5) %>% release(\"room\",1) %>% log_(\"room released\") env %>% add_resource(\"room\") %>% add_generator(\"visit\", t, at(0)) %>% run() %>% invisible #> 0: visit0: room seized #> 1: visit0: doctor path done #> 2: visit0: nurse path done #> 2.5: visit0: room released"},{"path":"https://r-simmer.org/extensions/bricks/articles/introduction.html","id":"interleaved-resources","dir":"Extensions > Bricks > Articles","previous_headings":"More compelling examples","what":"Interleaved resources","title":"Introduction to `simmer.bricks`","text":"Assembly lines chains limited resources current resource released next one available. class problems can solved pattern called interleaved resources. pattern uses auxiliary resources guard access second subsequent resources chain, serving token guarded resource. consequence, resource blocked reason, tokens exhaust eventually, thus blockage propagate backwards. Let us consider chain two machines, B, whose service times 1 2 respectively. , chain resources can set follows: can seen, interleave brick uses auxiliary resource called \"B_token\" must defined . machine B capacity=1 queue_size=1, \"B_token\" must capacity=2 (B’s capacity + queue size) queue_size=Inf, avoid dropping arrivals. simuation , three arrivals processed machine 1 unit time. first two successfully seize token B, last arrival wait one leave B releasing .","code":"t <- trajectory() %>% interleave(c(\"A\", \"B\"), c(1, 2)) t #> trajectory: anonymous, 8 activities #> { Activity: Seize | resource: A, amount: 1 } #> { Activity: Timeout | delay: 1 } #> { Activity: Seize | resource: B_token, amount: 1 } #> { Activity: Release | resource: A, amount: 1 } #> { Activity: Seize | resource: B, amount: 1 } #> { Activity: Timeout | delay: 2 } #> { Activity: Release | resource: B, amount: 1 } #> { Activity: Release | resource: B_token, amount: 1 } simmer() %>% add_resource(\"A\", 3, 1) %>% add_resource(\"B_token\", 2, Inf) %>% add_resource(\"B\", 1, 1) %>% add_generator(\"dummy\", t, at(rep(0, 3))) %>% run(4) %>% get_mon_arrivals(per_resource = TRUE) #> name start_time end_time activity_time resource replication #> 1 dummy0 0 1 1 A 1 #> 2 dummy1 0 1 1 A 1 #> 3 dummy0 1 3 2 B 1 #> 4 dummy0 1 3 2 B_token 1 #> 5 dummy2 0 3 1 A 1"},{"path":"https://r-simmer.org/extensions/bricks/articles/introduction.html","id":"contributing","dir":"Extensions > Bricks > Articles","previous_headings":"","what":"Contributing","title":"Introduction to `simmer.bricks`","text":"know patterns like see included simmer.bricks, please, open issue pull request GitHub.","code":""},{"path":"https://r-simmer.org/extensions/bricks/authors.html","id":null,"dir":"Extensions > Bricks","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Iñaki Ucar. Author, copyright holder, maintainer.","code":""},{"path":"https://r-simmer.org/extensions/bricks/authors.html","id":"citation","dir":"Extensions > Bricks","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Ucar (2023). simmer.bricks: Helper Methods 'simmer' Trajectories. https://r-simmer.org, https://github.com/r-simmer/simmer.bricks.","code":"@Manual{, title = {simmer.bricks: Helper Methods for 'simmer' Trajectories}, author = {Iñaki Ucar}, year = {2023}, note = {https://r-simmer.org, https://github.com/r-simmer/simmer.bricks}, }"},{"path":"https://r-simmer.org/extensions/bricks/index.html","id":"bricks","dir":"Extensions > Bricks","previous_headings":"","what":"Helper Methods for simmer Trajectories","title":"Helper Methods for simmer Trajectories","text":"simmer.bricks provides helper methods simmer, Discrete-Event Simulation (DES) package R. simmer brick wraps common activity pattern can used build trajectories conveniently.","code":""},{"path":"https://r-simmer.org/extensions/bricks/index.html","id":"documentation","dir":"Extensions > Bricks","previous_headings":"","what":"Documentation","title":"Helper Methods for simmer Trajectories","text":"Documentation available r-simmer.org/extensions/bricks/reference. get started, please explore vignettes online, R:","code":"vignette(package = \"simmer.bricks\")"},{"path":"https://r-simmer.org/extensions/bricks/index.html","id":"installation","dir":"Extensions > Bricks","previous_headings":"","what":"Installation","title":"Helper Methods for simmer Trajectories","text":"Install release version CRAN: installation GitHub requires remotes package.","code":"install.packages(\"simmer.bricks\") # install.packages(\"remotes\") remotes::install_github(\"r-simmer/simmer.bricks\")"},{"path":"https://r-simmer.org/extensions/bricks/news/index.html","id":"simmerbricks-022","dir":"Extensions > Bricks > News","previous_headings":"","what":"simmer.bricks 0.2.2","title":"Changelog","text":"Fix amount argument delayed_release() support functions (#16).","code":""},{"path":"https://r-simmer.org/extensions/bricks/news/index.html","id":"simmerbricks-021","dir":"Extensions > Bricks > News","previous_headings":"","what":"simmer.bricks 0.2.1","title":"Changelog","text":"CRAN release: 2019-01-09 Fix tests simmer 4.2.0.","code":""},{"path":"https://r-simmer.org/extensions/bricks/news/index.html","id":"simmerbricks-020","dir":"Extensions > Bricks > News","previous_headings":"","what":"simmer.bricks 0.2.0","title":"Changelog","text":"CRAN release: 2018-08-05","code":""},{"path":"https://r-simmer.org/extensions/bricks/news/index.html","id":"new-features-0-2-0","dir":"Extensions > Bricks > News","previous_headings":"simmer.bricks 0.2.0","what":"New features","title":"Changelog","text":"Implement delayed_release_selected() (#9 addressing #4). New interleave() brick set interleaved resources (#11 addressing #7).","code":""},{"path":"https://r-simmer.org/extensions/bricks/news/index.html","id":"minor-changes-and-fixes-0-2-0","dir":"Extensions > Bricks > News","previous_headings":"simmer.bricks 0.2.0","what":"Minor changes and fixes","title":"Changelog","text":"Fix do_parallel() also accept lists trajectories input (#6). Simplify delayed_release() interface (part #9). Change do_parallel() interface: move environment dots force user name (#10).","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/delayed_release.html","id":null,"dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Delayed Release of a Resource — delayed_release","title":"Delayed Release of a Resource — delayed_release","text":"brick encapsulates delayed release: arrival releases resource continues way immediately, resource busy additional period time.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/delayed_release.html","id":"ref-usage","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Usage","title":"Delayed Release of a Resource — delayed_release","text":"","code":"delayed_release( .trj, resource, task, amount = 1, preemptive = FALSE, mon_all = FALSE ) delayed_release_selected( .trj, task, amount = 1, preemptive = FALSE, mon_all = FALSE )"},{"path":"https://r-simmer.org/extensions/bricks/reference/delayed_release.html","id":"arguments","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Arguments","title":"Delayed Release of a Resource — delayed_release","text":".trj trajectory object. resource name resource. task timeout duration supplied either passing numeric callable object (function) must return numeric (negative values automatically coerced positive). amount amount seize/release, accepts either numeric callable object (function) must return numeric. preemptive whether arrivals server can preempted based seize priorities. mon_all TRUE, get_mon_arrivals show one line per clone.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/delayed_release.html","id":"value","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Value","title":"Delayed Release of a Resource — delayed_release","text":"Returns following chain activities: clone > synchronize (see examples ).","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/delayed_release.html","id":"ref-examples","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Examples","title":"Delayed Release of a Resource — delayed_release","text":"","code":"## These are equivalent for a non-preemptive resource: trajectory() %>% delayed_release(\"res1\", 5, 1) #> trajectory: anonymous, 6 activities #> { Activity: Clone | n: 2 } #> Fork 1, continue, trajectory: anonymous, 2 activities #> { Activity: SetCapacity | resource: res1, value: -1, mod: + } #> { Activity: Release | resource: res1, amount: 1 } #> Fork 2, continue, trajectory: anonymous, 2 activities #> { Activity: Timeout | delay: 5 } #> { Activity: SetCapacity | resource: res1, value: 1, mod: + } #> { Activity: Synchronize | wait: 0 } trajectory() %>% clone( 2, trajectory() %>% set_capacity(\"res1\", -1, mod=\"+\") %>% release(\"res1\", 1), trajectory() %>% timeout(5) %>% set_capacity(\"res1\", 1, mod=\"+\") ) %>% synchronize(wait=FALSE) #> trajectory: anonymous, 6 activities #> { Activity: Clone | n: 2 } #> Fork 1, continue, trajectory: anonymous, 2 activities #> { Activity: SetCapacity | resource: res1, value: -1, mod: + } #> { Activity: Release | resource: res1, amount: 1 } #> Fork 2, continue, trajectory: anonymous, 2 activities #> { Activity: Timeout | delay: 5 } #> { Activity: SetCapacity | resource: res1, value: 1, mod: + } #> { Activity: Synchronize | wait: 0 } ## These are equivalent for a preemptive resource: trajectory() %>% delayed_release(\"res2\", 5, 1, preemptive=TRUE) #> trajectory: anonymous, 7 activities #> { Activity: Clone | n: 2 } #> Fork 1, continue, trajectory: anonymous, 1 activities #> { Activity: Release | resource: res2, amount: 1 } #> Fork 2, continue, trajectory: anonymous, 4 activities #> { Activity: SetPrior | values: [2147483647, 2147483647, 0], mod: N } #> { Activity: Seize | resource: res2, amount: 1 } #> { Activity: Timeout | delay: 5 } #> { Activity: Release | resource: res2, amount: 1 } #> { Activity: Synchronize | wait: 0 } trajectory() %>% clone( 2, trajectory() %>% release(\"res2\", 1), trajectory() %>% set_prioritization(c(rep(.Machine$integer.max, 2), 0)) %>% seize(\"res2\", 1) %>% timeout(5) %>% release(\"res2\", 1) ) %>% synchronize(wait=FALSE) #> trajectory: anonymous, 7 activities #> { Activity: Clone | n: 2 } #> Fork 1, continue, trajectory: anonymous, 1 activities #> { Activity: Release | resource: res2, amount: 1 } #> Fork 2, continue, trajectory: anonymous, 4 activities #> { Activity: SetPrior | values: [2147483647, 2147483647, 0], mod: N } #> { Activity: Seize | resource: res2, amount: 1 } #> { Activity: Timeout | delay: 5 } #> { Activity: Release | resource: res2, amount: 1 } #> { Activity: Synchronize | wait: 0 }"},{"path":"https://r-simmer.org/extensions/bricks/reference/do_parallel.html","id":null,"dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Perform Parallel Tasks — do_parallel","title":"Perform Parallel Tasks — do_parallel","text":"brick encapsulates activity n workers running parallel sub-trajectories.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/do_parallel.html","id":"ref-usage","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Usage","title":"Perform Parallel Tasks — do_parallel","text":"","code":"do_parallel(.trj, ..., .env, wait = TRUE, mon_all = FALSE)"},{"path":"https://r-simmer.org/extensions/bricks/reference/do_parallel.html","id":"arguments","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Arguments","title":"Perform Parallel Tasks — do_parallel","text":".trj trajectory object. ... sub-trajectories list sub-trajectories parallelise. .env simulation environment. wait TRUE, arrival waits parallel sub-trajectories finished; FALSE, arrival continues soon first parallel task ends. mon_all TRUE, get_mon_arrivals show one line per clone.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/do_parallel.html","id":"value","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Value","title":"Perform Parallel Tasks — do_parallel","text":"Returns following chain activities: clone > synchronize (> wait > untrap wait=FALSE) (see examples ).","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/do_parallel.html","id":"ref-examples","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Examples","title":"Perform Parallel Tasks — do_parallel","text":"","code":"env <- simmer() signal <- function() get_name(env) task.1 <- trajectory(\"task 1\") %>% timeout(function() rexp(1)) task.2 <- trajectory(\"task 2\") %>% timeout(function() rexp(1)) ## These are equivalent: trajectory() %>% do_parallel( task.1, task.2, .env = env, wait = TRUE ) #> trajectory: anonymous, 10 activities #> { Activity: Clone | n: 3 } #> Fork 1, continue, trajectory: original, 4 activities #> { Activity: Trap | signals: function() } #> { Activity: Wait | } #> { Activity: Wait | } #> { Activity: UnTrap | signals: function() } #> Fork 2, continue, trajectory: task 1, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> Fork 3, continue, trajectory: task 2, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> { Activity: Synchronize | wait: 1 } trajectory() %>% clone( n = 3, trajectory(\"original\") %>% trap(signal) %>% wait() %>% wait() %>% untrap(signal), task.1[] %>% send(signal), task.2[] %>% send(signal)) %>% synchronize(wait = TRUE) #> trajectory: anonymous, 10 activities #> { Activity: Clone | n: 3 } #> Fork 1, continue, trajectory: original, 4 activities #> { Activity: Trap | signals: function() } #> { Activity: Wait | } #> { Activity: Wait | } #> { Activity: UnTrap | signals: function() } #> Fork 2, continue, trajectory: task 1, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> Fork 3, continue, trajectory: task 2, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> { Activity: Synchronize | wait: 1 } ## These are equivalent: trajectory() %>% do_parallel( task.1, task.2, .env = env, wait = FALSE ) #> trajectory: anonymous, 9 activities #> { Activity: Clone | n: 3 } #> Fork 1, continue, trajectory: original, 1 activities #> { Activity: Trap | signals: function() } #> Fork 2, continue, trajectory: task 1, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> Fork 3, continue, trajectory: task 2, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> { Activity: Synchronize | wait: 0 } #> { Activity: Wait | } #> { Activity: UnTrap | signals: function() } trajectory() %>% clone( n = 3, trajectory(\"original\") %>% trap(signal), task.1[] %>% send(signal), task.2[] %>% send(signal)) %>% synchronize(wait = FALSE) %>% wait() %>% untrap(signal) #> trajectory: anonymous, 9 activities #> { Activity: Clone | n: 3 } #> Fork 1, continue, trajectory: original, 1 activities #> { Activity: Trap | signals: function() } #> Fork 2, continue, trajectory: task 1, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> Fork 3, continue, trajectory: task 2, 2 activities #> { Activity: Timeout | delay: function() } #> { Activity: Send | signals: function(), delay: 0 } #> { Activity: Synchronize | wait: 0 } #> { Activity: Wait | } #> { Activity: UnTrap | signals: function() }"},{"path":"https://r-simmer.org/extensions/bricks/reference/index.html","id":"simmer-bricks","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"simmer bricks","title":"Function reference","text":"Helper methods ‘simmer’ trajectories","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/index.html","id":null,"dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Function reference","title":"Function reference","text":"delayed_release() delayed_release_selected() Delayed Release Resource do_parallel() Perform Parallel Tasks interleave() Interleaved Resources visit() visit_selected() Visit Resource wait_n() wait_until() Wait Number Signals","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/interleave.html","id":null,"dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Interleaved Resources — interleave","title":"Interleaved Resources — interleave","text":"brick encapsulates chain interleaved resources, .e., current resource released next one chain available. interesting property pattern , one resource blocked reason, whole chain stops.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/interleave.html","id":"ref-usage","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Usage","title":"Interleaved Resources — interleave","text":"","code":"interleave(.trj, resources, task, amount = 1)"},{"path":"https://r-simmer.org/extensions/bricks/reference/interleave.html","id":"arguments","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Arguments","title":"Interleaved Resources — interleave","text":".trj trajectory object. resources character vector resource names. task timeout duration supplied either passing numeric callable object (function) must return numeric (negative values automatically coerced positive). amount amount seize/release, accepts either numeric callable object (function) must return numeric.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/interleave.html","id":"value","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Value","title":"Interleaved Resources — interleave","text":"Returns following chain activities: seize (1) > timeout > [seize (token 2) > release (1) > seize (2) > timeout > release (2) > release (token 2) > ... (repeat) ] (see examples ). Thus, total number activities appended length(resources) * 3 + (length(resources)-1) * 2.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/interleave.html","id":"details","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Details","title":"Interleaved Resources — interleave","text":"task amount accept list values/functions, instead single one, length resources, value/function applied resource index. transition second subsequent resources guarded token, auxiliary resource whose capacity must equal capacity + queue size guarded resource, queue size must infinite. example, two resources provided, c(\"\", \"B\"), auxiliary resource named \"B_token\". capacity=2 queue_size=1 B, capacity=3 queue_size=Inf must values B_token. note user responsible adding auxiliary resource simulation environment appropriate parameters.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/interleave.html","id":"ref-examples","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Examples","title":"Interleaved Resources — interleave","text":"","code":"## These are equivalent: trajectory() %>% interleave(c(\"A\", \"B\"), c(2, 10), 1) #> trajectory: anonymous, 8 activities #> { Activity: Seize | resource: A, amount: 1 } #> { Activity: Timeout | delay: 2 } #> { Activity: Seize | resource: B_token, amount: 1 } #> { Activity: Release | resource: A, amount: 1 } #> { Activity: Seize | resource: B, amount: 1 } #> { Activity: Timeout | delay: 10 } #> { Activity: Release | resource: B, amount: 1 } #> { Activity: Release | resource: B_token, amount: 1 } trajectory() %>% seize(\"A\", 1) %>% timeout(2) %>% seize(\"B_token\", 1) %>% release(\"A\", 1) %>% seize(\"B\", 1) %>% timeout(10) %>% release(\"B\", 1) %>% release(\"B_token\", 1) #> trajectory: anonymous, 8 activities #> { Activity: Seize | resource: A, amount: 1 } #> { Activity: Timeout | delay: 2 } #> { Activity: Seize | resource: B_token, amount: 1 } #> { Activity: Release | resource: A, amount: 1 } #> { Activity: Seize | resource: B, amount: 1 } #> { Activity: Timeout | delay: 10 } #> { Activity: Release | resource: B, amount: 1 } #> { Activity: Release | resource: B_token, amount: 1 }"},{"path":"https://r-simmer.org/extensions/bricks/reference/simmer.bricks-package.html","id":null,"dir":"Extensions > Bricks > Reference","previous_headings":"","what":"simmer.bricks: Helper Methods for simmer Trajectories — simmer.bricks-package","title":"simmer.bricks: Helper Methods for simmer Trajectories — simmer.bricks-package","text":"Provides wrappers common activity patterns simmer trajectories.","code":""},{"path":[]},{"path":"https://r-simmer.org/extensions/bricks/reference/simmer.bricks-package.html","id":"author","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Author","title":"simmer.bricks: Helper Methods for simmer Trajectories — simmer.bricks-package","text":"Iñaki Ucar","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/visit.html","id":null,"dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Visit a Resource — visit","title":"Visit a Resource — visit","text":"bricks encapsulate resource visit: seize, spend time release.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/visit.html","id":"ref-usage","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Usage","title":"Visit a Resource — visit","text":"","code":"visit(.trj, resource, task, amount = 1) visit_selected(.trj, task, amount = 1, id = 0)"},{"path":"https://r-simmer.org/extensions/bricks/reference/visit.html","id":"arguments","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Arguments","title":"Visit a Resource — visit","text":".trj trajectory object. resource name resource. task timeout duration supplied either passing numeric callable object (function) must return numeric (negative values automatically coerced positive). amount amount seize/release, accepts either numeric callable object (function) must return numeric. id selection identifier nested usage.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/visit.html","id":"value","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Value","title":"Visit a Resource — visit","text":"Returns following chain activities: seize > timeout > release (see examples ).","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/visit.html","id":"ref-examples","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Examples","title":"Visit a Resource — visit","text":"","code":"## These are equivalent: trajectory() %>% visit(\"res\", 5, 1) #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: res, amount: 1 } #> { Activity: Timeout | delay: 5 } #> { Activity: Release | resource: res, amount: 1 } trajectory() %>% seize(\"res\", 1) %>% timeout(5) %>% release(\"res\", 1) #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: res, amount: 1 } #> { Activity: Timeout | delay: 5 } #> { Activity: Release | resource: res, amount: 1 } ## These are equivalent: trajectory() %>% visit_selected(5, 1) #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: [0], amount: 1 } #> { Activity: Timeout | delay: 5 } #> { Activity: Release | resource: [0], amount: 1 } trajectory() %>% seize_selected(1) %>% timeout(5) %>% release_selected(1) #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: [0], amount: 1 } #> { Activity: Timeout | delay: 5 } #> { Activity: Release | resource: [0], amount: 1 }"},{"path":"https://r-simmer.org/extensions/bricks/reference/wait_n.html","id":null,"dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Wait a Number of Signals — wait_n","title":"Wait a Number of Signals — wait_n","text":"bricks encapsulate n stops: wait sequence n signals. wait_until also traps untraps required signals.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/wait_n.html","id":"ref-usage","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Usage","title":"Wait a Number of Signals — wait_n","text":"","code":"wait_n(.trj, n = 1) wait_until(.trj, signals, n = 1)"},{"path":"https://r-simmer.org/extensions/bricks/reference/wait_n.html","id":"arguments","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Arguments","title":"Wait a Number of Signals — wait_n","text":".trj trajectory object. n number wait activities chain. signals signal list signals, accepts either string, list strings callable object (function) must return string list strings.","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/wait_n.html","id":"value","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Value","title":"Wait a Number of Signals — wait_n","text":"wait_n returns n times wait. wait_until also adds trap untrap beginning end, respectively, chain waits (see examples ).","code":""},{"path":"https://r-simmer.org/extensions/bricks/reference/wait_n.html","id":"ref-examples","dir":"Extensions > Bricks > Reference","previous_headings":"","what":"Examples","title":"Wait a Number of Signals — wait_n","text":"","code":"## These are equivalent: trajectory() %>% wait_n(3) #> trajectory: anonymous, 3 activities #> { Activity: Wait | } #> { Activity: Wait | } #> { Activity: Wait | } trajectory() %>% wait() %>% wait() %>% wait() #> trajectory: anonymous, 3 activities #> { Activity: Wait | } #> { Activity: Wait | } #> { Activity: Wait | } ## These are equivalent: trajectory() %>% wait_until(\"green\") #> trajectory: anonymous, 3 activities #> { Activity: Trap | signals: [green] } #> { Activity: Wait | } #> { Activity: UnTrap | signals: [green] } trajectory() %>% trap(\"green\") %>% wait() %>% untrap(\"green\") #> trajectory: anonymous, 3 activities #> { Activity: Trap | signals: [green] } #> { Activity: Wait | } #> { Activity: UnTrap | signals: [green] } ## These are equivalent: trajectory() %>% wait_until(c(\"one\", \"another\"), 2) #> trajectory: anonymous, 4 activities #> { Activity: Trap | signals: [one, another] } #> { Activity: Wait | } #> { Activity: Wait | } #> { Activity: UnTrap | signals: [one, another] } trajectory() %>% trap(c(\"one\", \"another\")) %>% wait() %>% wait() %>% untrap(c(\"one\", \"another\")) #> trajectory: anonymous, 4 activities #> { Activity: Trap | signals: [one, another] } #> { Activity: Wait | } #> { Activity: Wait | } #> { Activity: UnTrap | signals: [one, another] }"},{"path":"https://r-simmer.org/extensions/plot/articles/index.html","id":null,"dir":"Extensions > Plot > Articles","previous_headings":"","what":"All vignettes","title":"Articles","text":"Plotting simmer statistics Plotting simmer trajectories","code":""},{"path":"https://r-simmer.org/extensions/plot/articles/plot.simmer.html","id":"simulation-example","dir":"Extensions > Plot > Articles","previous_headings":"","what":"Simulation example","title":"Plotting simmer statistics","text":"basic example Introduction simmer. Please, refer vignette detail.","code":"library(simmer) library(parallel) patient <- trajectory(\"patients' path\") %>% ## add an intake activity seize(\"nurse\", 1) %>% timeout(function() rnorm(1, 15)) %>% release(\"nurse\", 1) %>% ## add a consultation activity seize(\"doctor\", 1) %>% timeout(function() rnorm(1, 20)) %>% release(\"doctor\", 1) %>% ## add a planning activity seize(\"administration\", 1) %>% timeout(function() rnorm(1, 5)) %>% release(\"administration\", 1) envs <- mclapply(1:100, function(i) { simmer(\"SuperDuperSim\") %>% add_resource(\"nurse\", 1) %>% add_resource(\"doctor\", 2) %>% add_resource(\"administration\", 1) %>% add_generator(\"patient\", patient, function() rnorm(1, 10, 2)) %>% run(80) %>% wrap() })"},{"path":"https://r-simmer.org/extensions/plot/articles/plot.simmer.html","id":"basic-visualisation-tools","dir":"Extensions > Plot > Articles","previous_headings":"","what":"Basic visualisation tools","title":"Plotting simmer statistics","text":"package provides basic visualisation tools help take glance simulations quickly, course probably may want develop data analysis. three types plot implemented different metrics available: usage resource simulation time frame. utilization specified resources simulation. activity time. waiting time. flow time. Plot attributes. plots metrics accessible S3 methods plot generic provided package (see ?plot.mon details), uses ggplot2 package backend. instance, ’ve left simmering bit (pun intended), can look overall resource utilization. top bottom error bars show respectively 25th 75th percentile utilization across replications. top bar shows median utilization. also possible look resources’ activity simulation. graph, individual lines separate replications. smoothing performed cumulative average. Let’s take look now instantaneous behaviour specific replication resource. example , 6th replication shown. Next can look evolution arrivals’ flow time simulation. plot , individual line represents replication. smooth line drawn . arrivals didn’t finish entire trajectory excluded plot. Similarly one can look evolution activity times metric = \"activity_time\" waiting times metric = \"waiting_time\".","code":"library(simmer.plot) resources <- get_mon_resources(envs) plot(resources, metric = \"utilization\") plot(resources, metric = \"usage\", c(\"nurse\", \"doctor\"), items = \"server\") plot(get_mon_resources(envs[[6]]), metric = \"usage\", \"doctor\", items = \"server\", steps = TRUE) arrivals <- get_mon_arrivals(envs) plot(arrivals, metric = \"flow_time\")"},{"path":"https://r-simmer.org/extensions/plot/authors.html","id":null,"dir":"Extensions > Plot","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Iñaki Ucar. Author, copyright holder, maintainer. Bart Smeets. Author, copyright holder.","code":""},{"path":"https://r-simmer.org/extensions/plot/authors.html","id":"citation","dir":"Extensions > Plot","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Ucar , Smeets B (2023). simmer.plot: Plotting Methods 'simmer'. https://r-simmer.org, https://github.com/r-simmer/simmer.plot.","code":"@Manual{, title = {simmer.plot: Plotting Methods for 'simmer'}, author = {Iñaki Ucar and Bart Smeets}, year = {2023}, note = {https://r-simmer.org, https://github.com/r-simmer/simmer.plot}, }"},{"path":"https://r-simmer.org/extensions/plot/index.html","id":"plot","dir":"Extensions > Plot","previous_headings":"","what":"Plotting Methods for simmer","title":"Plotting Methods for simmer","text":"simmer.plot provides plotting methods simmer, Discrete-Event Simulation (DES) package R.","code":""},{"path":"https://r-simmer.org/extensions/plot/index.html","id":"documentation","dir":"Extensions > Plot","previous_headings":"","what":"Documentation","title":"Plotting Methods for simmer","text":"Documentation available r-simmer.org/extensions/plot/reference. get started, please explore vignettes online, R:","code":"vignette(package = \"simmer.plot\")"},{"path":"https://r-simmer.org/extensions/plot/index.html","id":"installation","dir":"Extensions > Plot","previous_headings":"","what":"Installation","title":"Plotting Methods for simmer","text":"Install release version CRAN: installation GitHub requires remotes package.","code":"install.packages(\"simmer.plot\") # install.packages(\"remotes\") remotes::install_github(\"r-simmer/simmer.plot\")"},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0118","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.18","title":"Changelog","text":"Fix rollback parsing simmer > 4.4.5. Fix test warnings due deprecated features. Remove deprecated methods plot.simmer plot.wrap. Fix clone postprocessing n specified function (#27). Add support activity tags named rollbacks (#26).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0117","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.17","title":"Changelog","text":"CRAN release: 2022-02-07 Fix calculation resource utilization zero capacity values present (#22 addressing #21; #24). Expose limits plot.resources(metric=\"usage\"), improve documentation method-specific options (#25).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0116","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.16","title":"Changelog","text":"CRAN release: 2020-04-25 Fix rollback pointer infinite amount (#18). Workaround bug DiagrammeR (#19). Workaround bug ggplot2 (#20).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0115","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.15","title":"Changelog","text":"CRAN release: 2019-03-10 Fix test simmer v4.2.2.","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0114","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.14","title":"Changelog","text":"CRAN release: 2018-08-04 Arrange factors (names items plot.resources) order provided (#15). Improve documentation (#16).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0113","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.13","title":"Changelog","text":"CRAN release: 2018-03-02 Update DiagrammeR 1.0.0 (7c2b9c7).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0112","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.12","title":"Changelog","text":"CRAN release: 2017-12-21 New S3 methods plotting monitoring statistics, enable us call plot() output get_mon_arrivals(), get_mon_attributes() get_mon_resources() (see ?plot.mon). Calling plot() simmer environment continue work, deprecated (#11). Better defaults resources attributes: names/keys plotted nothing specified (#13).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0111","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.11","title":"Changelog","text":"CRAN release: 2017-10-24 Fix trajectory parsing variable-length pointers (#9). Update tidyr 0.7.x (da58045). Update DiagrammeR 0.9.1 (247aa4f).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-0110","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.10","title":"Changelog","text":"CRAN release: 2017-07-22 Fix resource utilization plot varying resource capacity (#8). Fix trajectory parsing yet another NULL pointer format: (nil) (#4). Update dplyr 0.7.x (537cdea).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-019","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.9","title":"Changelog","text":"CRAN release: 2017-03-15 Workaround Solaris SPARC (#2). Remove ignored edges clone() (#6). Add optional verbose info plot.trajectory() labels (#5).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-018","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.8","title":"Changelog","text":"CRAN release: 2017-02-10 Fix forks single path (5fa5937). Re-arrange dataframes tests (6cc4f0a). Fix trajectory parsing another NULL pointer format: 0x0 (#4).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-017","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.7","title":"Changelog","text":"CRAN release: 2017-02-08 Fix trajectory parsing (8295c52). Parsing DOT definitely unreliable. Rely entirely DiagrammeR.","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-016","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.6","title":"Changelog","text":"CRAN release: 2017-02-07 robust testing (d4879ee, trying address #2). Visual improvements plot.trajectory() (9b49f83, d84a469). Assign dashed-gray edge style subtrajectories consistent way (addressing #3). Fix defaults (8a7fb7d). plot cumulative average steps time resources usage (89040bd). Change alpha number replications (60beae2).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-015","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.5","title":"Changelog","text":"CRAN release: 2017-01-04 Fix plot trajectories without forks rollbacks (332ec61). Fix plot trajectories single node (f787c95). Fail gracefully empty trajectories (2d42d7f). Fail gracefully simmer doesn’t return pointers (3be41cf, a60a641). happen, though. Improve tests (a9e7fa0). Update DiagrammeR 0.9.0 (dbc01b8).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-014","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.4","title":"Changelog","text":"CRAN release: 2016-12-30 Fix trajectory parsing (da45863). Different compilers represent NULL pointers different ways: 0, (nil)…","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-013","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.3","title":"Changelog","text":"CRAN release: 2016-12-29 Reduce footprint caused “Plotting simmer trajectories” vignette, thus solving also WARN Solaris builds (9cb833a). Assign reproducible identifiers nodes instead using external pointers plot.trajectory(). DOT output can verified regardless ordering (3c3bc9b).","code":""},{"path":"https://r-simmer.org/extensions/plot/news/index.html","id":"simmerplot-011","dir":"Extensions > Plot > News","previous_headings":"","what":"simmer.plot 0.1.1","title":"Changelog","text":"CRAN release: 2016-12-28 package detaches plotting functionalities simmer package (present versions 3.5.x ). old plot_resource_usage(), plot_resource_utilization(), plot_evolution_arrival_times() plot_attributes() implemented S3 method plot() generic (see ?plot.simmer). S3 method plotting diagrams trajectories also provided (see ?plot.trajectory).","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/get_mon.html","id":null,"dir":"Extensions > Plot > Reference","previous_headings":"","what":"Monitoring Statistics — get_mon","title":"Monitoring Statistics — get_mon","text":"Replacements get_mon_arrivals, get_mon_attributes get_mon_resources. versions just add new class (arrivals, attributes resources respectively) resulting data frame.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/get_mon.html","id":"ref-usage","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Usage","title":"Monitoring Statistics — get_mon","text":"","code":"get_mon_arrivals(...) get_mon_attributes(...) get_mon_resources(...)"},{"path":"https://r-simmer.org/extensions/plot/reference/get_mon.html","id":"arguments","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Arguments","title":"Monitoring Statistics — get_mon","text":"... see get_mon.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/get_mon.html","id":"value","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Value","title":"Monitoring Statistics — get_mon","text":"Returns data frame class arrivals, attributes resources.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/index.html","id":"plot-simmer-objects","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Plot simmer objects","title":"Function reference","text":"S3 methods simmer classes","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/index.html","id":null,"dir":"Extensions > Plot > Reference","previous_headings":"","what":"Function reference","title":"Function reference","text":"plot(<trajectory>) Plot Method trajectory Objects plot(<arrivals>) plot(<attributes>) plot(<resources>) Plot Methods simmer Monitoring Statistics","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/index.html","id":"monitoring","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Monitoring","title":"Function reference","text":"Methods getting monitoring statistics","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/index.html","id":null,"dir":"Extensions > Plot > Reference","previous_headings":"","what":"Function reference","title":"Function reference","text":"get_mon_arrivals() get_mon_attributes() get_mon_resources() Monitoring Statistics","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.mon.html","id":null,"dir":"Extensions > Plot > Reference","previous_headings":"","what":"Plot Methods for simmer Monitoring Statistics — plot.mon","title":"Plot Methods for simmer Monitoring Statistics — plot.mon","text":"Methods plot generic. See details metric available.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.mon.html","id":"ref-usage","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Usage","title":"Plot Methods for simmer Monitoring Statistics — plot.mon","text":"","code":"# S3 method for arrivals plot(x, metric = c(\"activity_time\", \"waiting_time\", \"flow_time\"), ...) # S3 method for attributes plot(x, metric = NULL, keys, ...) # S3 method for resources plot(x, metric = c(\"usage\", \"utilization\"), names, items = c(\"queue\", \"server\", \"system\"), steps = FALSE, limits = TRUE, ...)"},{"path":"https://r-simmer.org/extensions/plot/reference/plot.mon.html","id":"arguments","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Arguments","title":"Plot Methods for simmer Monitoring Statistics — plot.mon","text":"x data frame class arrivals/attributes/resources (see get_mon). metric specific metric compute. ... unused. keys attributes plot (left empty, attributes shown). names resources plot (left empty, resources shown). items (metric=\"usage\") resource items include chart. steps (metric=\"usage\") whether show instantaneous usage rather cumulative average. limits (metric=\"usage\") whether show limits.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.mon.html","id":"value","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Value","title":"Plot Methods for simmer Monitoring Statistics — plot.mon","text":"Returns ggplot2 object.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.mon.html","id":"details","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Details","title":"Plot Methods for simmer Monitoring Statistics — plot.mon","text":"S3 method 'arrivals' provides three metrics: \"activity_time\", \"waiting_time\", \"flow_time\". \"activity_time\" amount time spent active state (.e., timeout activities), already provided output get_mon_arrivals. \"flow_time\" amount time spent system, computed follows: flow = end_time - start_time. Finally, \"waiting_time\" amount time spent waiting (e.g., resources' queues, due wait activity...), computed follows: waiting_time = flow_time - activity_time. method apply summary, just shows line plot values throughout simulation. S3 method 'attributes' support metric. simply shows stairstep graph values throughout simulation keys provided (collected attributes key provided). S3 method 'resources' provides two metrics: \"usage\" \"utilization\". \"usage\" metric shows line graph cumulative average resource usage throughout simulation, resource, replication item (default, queue, server system, sum queue server). steps=TRUE, stairstep graph instantaneous values provided instead. \"utilization\" metric shows bar plot average resource utilization (total time use divided total simulation time). multiple replications, bar represents median, error bars represent quartiles. Thus, single replication provided, bar error bar coincide.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.mon.html","id":"ref-examples","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Examples","title":"Plot Methods for simmer Monitoring Statistics — plot.mon","text":"","code":"t0 <- trajectory(\"my trajectory\") %>% ## add an intake activity seize(\"nurse\", 1) %>% timeout(function() rnorm(1, 15)) %>% release(\"nurse\", 1) %>% ## add a consultation activity seize(\"doctor\", 1) %>% timeout(function() rnorm(1, 20)) %>% release(\"doctor\", 1) %>% ## add a planning activity seize(\"administration\", 1) %>% timeout(function() rnorm(1, 5)) %>% release(\"administration\", 1) env <- simmer(\"SuperDuperSim\") %>% add_resource(\"nurse\", 1) %>% add_resource(\"doctor\", 2) %>% add_resource(\"administration\", 1) %>% add_generator(\"patient\", t0, function() rnorm(1, 10, 2)) %>% run(until=80) resources <- get_mon_resources(env) arrivals <- get_mon_arrivals(env) plot(resources, metric=\"usage\", \"doctor\", items = \"server\", steps = TRUE) plot(resources, metric=\"utilization\", c(\"nurse\", \"doctor\", \"administration\")) plot(arrivals, metric=\"waiting_time\") #> `geom_smooth()` using method = 'loess' and formula = 'y ~ x' #> Warning: span too small. fewer data values than degrees of freedom. #> Warning: pseudoinverse used at 48.513 #> Warning: neighborhood radius 16.168 #> Warning: reciprocal condition number 0 #> Warning: There are other near singularities as well. 197.98 #> Warning: span too small. fewer data values than degrees of freedom. #> Warning: pseudoinverse used at 48.513 #> Warning: neighborhood radius 16.168 #> Warning: reciprocal condition number 0 #> Warning: There are other near singularities as well. 197.98 #> Warning: no non-missing arguments to max; returning -Inf"},{"path":"https://r-simmer.org/extensions/plot/reference/plot.simmer.html","id":null,"dir":"Extensions > Plot > Reference","previous_headings":"","what":"Plot Method for simmer Objects — plot.simmer","title":"Plot Method for simmer Objects — plot.simmer","text":"Deprecated. See plot.mon instead.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.simmer.html","id":"ref-usage","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Usage","title":"Plot Method for simmer Objects — plot.simmer","text":"","code":"# S3 method for simmer plot(x, what = c(\"resources\", \"arrivals\", \"attributes\"), metric = NULL, ...)"},{"path":"https://r-simmer.org/extensions/plot/reference/plot.simmer.html","id":"arguments","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Arguments","title":"Plot Method for simmer Objects — plot.simmer","text":"x single simmer environment list environments representing several replications. type plot, one c(\"resources\", \"arrivals\", \"attributes\"). metric specific metric type plot. = \"resources\" one c(\"usage\", \"utilization\"). = \"arrivals\" one c(\"activity_time\", \"waiting_time\", \"flow_time\"). = \"attributes\" metrics moment. ... arguments kind plot. = \"resources\" metrics names name resource(s) (single string character vector) show. metric = \"usage\" items components resource plotted, one c(\"system\", \"queue\", \"server\"). steps TRUE, shows instantaneous usage instead cumulative average. = \"attributes\" keys keys attributes want plot (left empty, attributes shown).","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.simmer.html","id":"value","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Value","title":"Plot Method for simmer Objects — plot.simmer","text":"Returns ggplot2 object.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.trajectory.html","id":null,"dir":"Extensions > Plot > Reference","previous_headings":"","what":"Plot Method for trajectory Objects — plot.trajectory","title":"Plot Method for trajectory Objects — plot.trajectory","text":"method plot generic plots diagram given trajectory.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.trajectory.html","id":"ref-usage","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Usage","title":"Plot Method for trajectory Objects — plot.trajectory","text":"","code":"# S3 method for trajectory plot(x, engine = \"dot\", fill = scales::brewer_pal(\"qual\"), verbose = FALSE, ...)"},{"path":"https://r-simmer.org/extensions/plot/reference/plot.trajectory.html","id":"arguments","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Arguments","title":"Plot Method for trajectory Objects — plot.trajectory","text":"x simmer trajectory. engine string specifying layout engine (see grViz). fill discrete color palette resource identification. verbose show additional info directly labels. ... additional parameters render_graph.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.trajectory.html","id":"value","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Value","title":"Plot Method for trajectory Objects — plot.trajectory","text":"Returns htmlwidget.","code":""},{"path":"https://r-simmer.org/extensions/plot/reference/plot.trajectory.html","id":"ref-examples","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Examples","title":"Plot Method for trajectory Objects — plot.trajectory","text":"","code":"x <- trajectory() %>% seize(\"res\", 1) %>% timeout(1) %>% release(\"res\", 1) %>% rollback(3) plot(x) {\"x\":{\"diagram\":\"digraph {\\n\\ngraph [layout = \\\"dot\\\",\\n outputorder = \\\"edgesfirst\\\",\\n bgcolor = \\\"white\\\"]\\n\\nnode [fontname = \\\"sans-serif\\\",\\n fontsize = \\\"10\\\",\\n shape = \\\"circle\\\",\\n fixedsize = \\\"true\\\",\\n width = \\\"1.5\\\",\\n style = \\\"filled\\\",\\n fillcolor = \\\"aliceblue\\\",\\n color = \\\"gray70\\\",\\n fontcolor = \\\"gray50\\\"]\\n\\nedge [fontname = \\\"Helvetica\\\",\\n fontsize = \\\"8\\\",\\n len = \\\"1.5\\\",\\n color = \\\"gray80\\\",\\n arrowsize = \\\"0.5\\\"]\\n\\n \\\"1\\\" [label = \\\"Seize\\\", shape = \\\"box\\\", style = \\\"filled\\\", color = \\\"#7FC97F\\\", tooltip = \\\"resource: res, amount: 1\\\", fontcolor = \\\"black\\\", fillcolor = \\\"#7FC97F\\\"] \\n \\\"2\\\" [label = \\\"Timeout\\\", shape = \\\"box\\\", style = \\\"solid\\\", color = \\\"black\\\", tooltip = \\\"delay: 1\\\", fontcolor = \\\"black\\\", fillcolor = \\\"#000000\\\"] \\n \\\"3\\\" [label = \\\"Release\\\", shape = \\\"box\\\", style = \\\"filled\\\", color = \\\"#7FC97F\\\", tooltip = \\\"resource: res, amount: 1\\\", fontcolor = \\\"black\\\", fillcolor = \\\"#7FC97F\\\"] \\n \\\"4\\\" [label = \\\"Rollback\\\", shape = \\\"diamond\\\", style = \\\"filled\\\", color = \\\"lightgrey\\\", tooltip = \\\"times: -1\\\", fontcolor = \\\"black\\\", fillcolor = \\\"#D3D3D3\\\"] \\n\\\"1\\\"->\\\"2\\\" [color = \\\"black\\\", style = \\\"solid\\\"] \\n\\\"2\\\"->\\\"3\\\" [color = \\\"black\\\", style = \\\"solid\\\"] \\n\\\"3\\\"->\\\"4\\\" [color = \\\"black\\\", style = \\\"solid\\\"] \\n\\\"4\\\"->\\\"1\\\" [color = \\\"grey\\\", style = \\\"dashed\\\"] \\n}\",\"config\":{\"engine\":\"dot\",\"options\":null}},\"evals\":[],\"jsHooks\":[]}"},{"path":"https://r-simmer.org/extensions/plot/reference/simmer.plot-package.html","id":null,"dir":"Extensions > Plot > Reference","previous_headings":"","what":"simmer.plot: Plotting Methods for simmer — simmer.plot-package","title":"simmer.plot: Plotting Methods for simmer — simmer.plot-package","text":"set plotting methods simmer trajectories simulations.","code":""},{"path":[]},{"path":"https://r-simmer.org/extensions/plot/reference/simmer.plot-package.html","id":"author","dir":"Extensions > Plot > Reference","previous_headings":"","what":"Author","title":"simmer.plot: Plotting Methods for simmer — simmer.plot-package","text":"Iñaki Ucar, Bart Smeets","code":""},{"path":"https://r-simmer.org/index.html","id":"section","dir":"","previous_headings":"","what":"Discrete-Event Simulation for R","title":"Discrete-Event Simulation for R","text":"simmer process-oriented trajectory-based Discrete-Event Simulation (DES) package R. Designed generic framework like SimPy SimJulia, leverages power Rcpp boost performance turning DES R feasible. noteworthy characteristic, simmer exploits concept trajectory: common path simulation model entities type. pretty flexible simple use, leverages chaining/piping workflow introduced magrittr package.","code":""},{"path":[]},{"path":"https://r-simmer.org/index.html","id":"help","dir":"","previous_headings":"","what":"Help","title":"Discrete-Event Simulation for R","text":"bugs /issues, create new issue GitHub. questions comments, please use Discussions forum GitHub.","code":""},{"path":"https://r-simmer.org/index.html","id":"documentation","dir":"","previous_headings":"","what":"Documentation","title":"Discrete-Event Simulation for R","text":"Documentation available r-simmer.org/reference. get started, please explore vignettes online, R:","code":"vignette(package = \"simmer\")"},{"path":"https://r-simmer.org/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Discrete-Event Simulation for R","text":"Install release version CRAN: installation GitHub requires remotes package. Please note package contains C++ code thus need development environment build package (e.g., Rtools Windows).","code":"install.packages(\"simmer\") remotes::install_github(\"r-simmer/simmer\")"},{"path":"https://r-simmer.org/index.html","id":"hexagon-stickers","dir":"","previous_headings":"","what":"Hexagon stickers!","title":"Discrete-Event Simulation for R","text":"can purchase simmer hex stickers Redbubble (sticker 1, sticker 2). Browse stuff T-shirts mugs!","code":""},{"path":"https://r-simmer.org/reference/Extract.trajectory.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract or Replace Parts of a Trajectory — Extract.trajectory","title":"Extract or Replace Parts of a Trajectory — Extract.trajectory","text":"Operators acting trajectories extract replace parts.","code":""},{"path":"https://r-simmer.org/reference/Extract.trajectory.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract or Replace Parts of a Trajectory — Extract.trajectory","text":"","code":"# S3 method for class 'trajectory' x[i] # S3 method for class 'trajectory' x[[i]] # S3 method for class 'trajectory' x[i] <- value # S3 method for class 'trajectory' x[[i]] <- value"},{"path":"https://r-simmer.org/reference/Extract.trajectory.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract or Replace Parts of a Trajectory — Extract.trajectory","text":"x trajectory object. indices specifying elements extract. Indices numeric character logical vectors empty (missing) NULL. Numeric values coerced integer .integer (hence truncated towards zero). Negative integers indicate elements/slices leave selection. Character vectors matched names tags activities trajectory %%. Logical vectors indicate elements/slices select. vectors recycled necessary match corresponding extent. empty index return whole trajectory. index value NULL treated integer(0). value another trajectory object.","code":""},{"path":"https://r-simmer.org/reference/Extract.trajectory.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract or Replace Parts of a Trajectory — Extract.trajectory","text":"Returns new trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/Extract.trajectory.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract or Replace Parts of a Trajectory — Extract.trajectory","text":"","code":"x <- join(lapply(1:12, function(i) trajectory() %>% timeout(i) )) x #> trajectory: anonymous, 12 activities #> { Activity: Timeout | delay: 1 } #> { Activity: Timeout | delay: 2 } #> { Activity: Timeout | delay: 3 } #> { Activity: Timeout | delay: 4 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 6 } #> { Activity: Timeout | delay: 7 } #> { Activity: Timeout | delay: 8 } #> { Activity: Timeout | delay: 9 } #> { Activity: Timeout | delay: 10 } #> { Activity: Timeout | delay: 11 } #> { Activity: Timeout | delay: 12 } x[10] # the tenth element of x #> trajectory: anonymous, 1 activities #> { Activity: Timeout | delay: 10 } x[-1] # delete the 1st element of x #> trajectory: anonymous, 11 activities #> { Activity: Timeout | delay: 2 } #> { Activity: Timeout | delay: 3 } #> { Activity: Timeout | delay: 4 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 6 } #> { Activity: Timeout | delay: 7 } #> { Activity: Timeout | delay: 8 } #> { Activity: Timeout | delay: 9 } #> { Activity: Timeout | delay: 10 } #> { Activity: Timeout | delay: 11 } #> { Activity: Timeout | delay: 12 } x[c(TRUE, FALSE)] # logical indexing #> trajectory: anonymous, 6 activities #> { Activity: Timeout | delay: 1 } #> { Activity: Timeout | delay: 3 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 7 } #> { Activity: Timeout | delay: 9 } #> { Activity: Timeout | delay: 11 } x[c(1, 5, 2, 12, 4)] # numeric indexing #> trajectory: anonymous, 5 activities #> { Activity: Timeout | delay: 1 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 2 } #> { Activity: Timeout | delay: 12 } #> { Activity: Timeout | delay: 4 } x[c(FALSE, TRUE)] <- x[c(TRUE, FALSE)] # replacing x #> trajectory: anonymous, 12 activities #> { Activity: Timeout | delay: 1 } #> { Activity: Timeout | delay: 1 } #> { Activity: Timeout | delay: 3 } #> { Activity: Timeout | delay: 3 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 7 } #> { Activity: Timeout | delay: 7 } #> { Activity: Timeout | delay: 9 } #> { Activity: Timeout | delay: 9 } #> { Activity: Timeout | delay: 11 } #> { Activity: Timeout | delay: 11 }"},{"path":"https://r-simmer.org/reference/activate.html","id":null,"dir":"Reference","previous_headings":"","what":"Activate/Deactivate Sources — activate","title":"Activate/Deactivate Sources — activate","text":"Activities activating deactivating generation arrivals name. Sources must defined simulation environment (see add_generator, add_dataframe).","code":""},{"path":"https://r-simmer.org/reference/activate.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Activate/Deactivate Sources — activate","text":"","code":"activate(.trj, sources, ..., tag) deactivate(.trj, sources, ..., tag)"},{"path":"https://r-simmer.org/reference/activate.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Activate/Deactivate Sources — activate","text":".trj trajectory object. sources name(s) source(s) function returning name(s). ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/activate.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Activate/Deactivate Sources — activate","text":"Returns trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/activate.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Activate/Deactivate Sources — activate","text":"","code":"traj <- trajectory() %>% deactivate(\"dummy\") %>% timeout(1) %>% activate(\"dummy\") simmer() %>% add_generator(\"dummy\", traj, function() 1) %>% run(10) %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 dummy0 1 2 1 TRUE 1 #> 2 dummy1 3 4 1 TRUE 1 #> 3 dummy2 5 6 1 TRUE 1 #> 4 dummy3 7 8 1 TRUE 1"},{"path":"https://r-simmer.org/reference/add_dataframe.html","id":null,"dir":"Reference","previous_headings":"","what":"Add a Data Frame — add_dataframe","title":"Add a Data Frame — add_dataframe","text":"Attach new source arrivals trajectory data frame.","code":""},{"path":"https://r-simmer.org/reference/add_dataframe.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add a Data Frame — add_dataframe","text":"","code":"add_dataframe(.env, name_prefix, trajectory, data, mon = 1, batch = 50, col_time = \"time\", time = c(\"interarrival\", \"absolute\"), col_attributes = NULL, col_priority = \"priority\", col_preemptible = col_priority, col_restart = \"restart\")"},{"path":"https://r-simmer.org/reference/add_dataframe.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add a Data Frame — add_dataframe","text":".env simulation environment. name_prefix name prefix generated arrivals. trajectory trajectory generated arrivals follow (see trajectory). data data frame , least, column (inter)arrival times (see details). mon whether simulator must monitor generated arrivals (0 = monitoring, 1 = simple arrival monitoring, 2 = level 1 + arrival attribute monitoring) batch number arrivals generated time. Arrivals read data frame attached trajectory batches depending value. general, changed. col_time name time column data frame. time type time column: interarrival, time column contains interarrival times, absolute, time column contains absolute arrival times. col_attributes vector names attributes columns (see details). col_priority name priority column. col_preemptible name preemptible column. col_restart name restart column.","code":""},{"path":"https://r-simmer.org/reference/add_dataframe.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add a Data Frame — add_dataframe","text":"Returns simulation environment.","code":""},{"path":"https://r-simmer.org/reference/add_dataframe.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Add a Data Frame — add_dataframe","text":"data frame provided must , least, column (inter)arrival times. method look name \"time\" default, although can changed col_time parameter. column named col_priority=\"priority\", col_preemptible=priority col_restart=\"restart\", used set prioritization values arrival (see add_generator). additional columns (col_attributes=NULL, default), assigned arrival attributes named column name. columns must numeric (logical). Otherwise, vector column names specified, assigned attributes rest columns ignored. value batch=Inf means whole data frame attached beginning simulation. desirable general, performance event queue degraded populated many events. hand, low value results increased overhead due many function calls. default value tested provide good trade-.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/add_generator.html","id":null,"dir":"Reference","previous_headings":"","what":"Add a Generator — add_generator","title":"Add a Generator — add_generator","text":"Attach new source arrivals trajectory generator function.","code":""},{"path":"https://r-simmer.org/reference/add_generator.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add a Generator — add_generator","text":"","code":"add_generator(.env, name_prefix, trajectory, distribution, mon = 1, priority = 0, preemptible = priority, restart = FALSE)"},{"path":"https://r-simmer.org/reference/add_generator.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add a Generator — add_generator","text":".env simulation environment. name_prefix name prefix generated arrivals. several names provided, several generators defined parameters. trajectory trajectory generated arrivals follow (see trajectory). distribution function modelling interarrival times (returning negative value missing value stops generator). mon whether simulator must monitor generated arrivals (0 = monitoring, 1 = simple arrival monitoring, 2 = level 1 + arrival attribute monitoring) priority priority arrival (higher integer equals higher priority; defaults minimum priority, 0). preemptible seize occurs preemptive resource, parameter establishes minimum incoming priority can preempt arrivals (arrival priority greater preemptible gains resource). case, preemptible must equal greater priority, thus higher priority arrivals can trigger preemption. restart whether activity must restarted preempted.","code":""},{"path":"https://r-simmer.org/reference/add_generator.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add a Generator — add_generator","text":"Returns simulation environment.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/add_global.html","id":null,"dir":"Reference","previous_headings":"","what":"Add a Global Attribute — add_global","title":"Add a Global Attribute — add_global","text":"Attach global variable simulation.","code":""},{"path":"https://r-simmer.org/reference/add_global.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add a Global Attribute — add_global","text":"","code":"add_global(.env, key, value)"},{"path":"https://r-simmer.org/reference/add_global.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add a Global Attribute — add_global","text":".env simulation environment. key attribute name. value value set, either numeric schedule, global may change simulation.","code":""},{"path":"https://r-simmer.org/reference/add_global.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add a Global Attribute — add_global","text":"Returns simulation environment.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/add_resource.html","id":null,"dir":"Reference","previous_headings":"","what":"Add a Resource — add_resource","title":"Add a Resource — add_resource","text":"Define new resource simulation environment. Resources conceived queuing systems mind, therefore comprise two internal self-managed parts: server, active part, specified capacity can seized released (see seize); priority queue certain size, arrivals may wait server available.","code":""},{"path":"https://r-simmer.org/reference/add_resource.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add a Resource — add_resource","text":"","code":"add_resource(.env, name, capacity = 1, queue_size = Inf, mon = TRUE, preemptive = FALSE, preempt_order = c(\"fifo\", \"lifo\"), queue_size_strict = FALSE, queue_priority = c(0, Inf))"},{"path":"https://r-simmer.org/reference/add_resource.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add a Resource — add_resource","text":".env simulation environment. name name resource. several names provided, several resources defined parameters. capacity capacity server, either integer schedule, value may change simulation. queue_size size queue, either integer schedule, value may change simulation. mon whether simulator must monitor resource . preemptive whether arrivals server can preempted based seize priorities. preempt_order preemptive=TRUE several arrivals preempted, parameter defines arrival preempted first. Either fifo (First First : older preemptible tasks preempted first) lifo (Last First : newer preemptible tasks preempted first). queue_size_strict whether queue_size hard limit (see details). queue_priority priority range required able access queue room server (single value provided, treated minimum priority). default, arrivals can enqueued.","code":""},{"path":"https://r-simmer.org/reference/add_resource.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add a Resource — add_resource","text":"Returns simulation environment.","code":""},{"path":"https://r-simmer.org/reference/add_resource.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Add a Resource — add_resource","text":"entity trying seize resource (see seize) may 1) access server straightaway enough capacity, 2) wait queue room server room queue, 3) rejected room queue either. two special situations regarding queue management: 1) queue_size shrinked actual number items waiting, 2) preemption occurs, item previously server goes queue. default cases, excess items queue allowed. However, queue_size_strict=TRUE, maximum queue_size guaranteed, thus entities rejected (dropped) resource. Whenever arrival rejected (due server drop queue drop), set finished flag FALSE output get_mon_arrivals. Unfinished arrivals can handled drop-trajectory can set using handle_unfinished activity.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/batch.html","id":null,"dir":"Reference","previous_headings":"","what":"Batch/Separate Arrivals — batch","title":"Batch/Separate Arrivals — batch","text":"Activities collecting number arrivals can continue processing splitting previously established batch.","code":""},{"path":"https://r-simmer.org/reference/batch.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Batch/Separate Arrivals — batch","text":"","code":"batch(.trj, n, timeout = 0, permanent = FALSE, name = \"\", rule = NULL, ..., tag) separate(.trj, ..., tag)"},{"path":"https://r-simmer.org/reference/batch.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Batch/Separate Arrivals — batch","text":".trj trajectory object. n batch size, accepts numeric callable object (function) must return numeric. timeout set optional timer triggers batches every timeout time units even batch size fulfilled, accepts numeric callable object (function) must return numeric (0 = disabled). permanent TRUE, batches split. name optional string. Unnamed batches different batch activities independent. However, want feed arrivals different trajectories batch, need specify common name across batch activities. rule optional callable object (function) applied every arrival determine whether included batch, thus must return boolean. ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/batch.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Batch/Separate Arrivals — batch","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/batch.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Batch/Separate Arrivals — batch","text":"","code":"## unnamed batch with a timeout traj <- trajectory() %>% log_(\"arrived\") %>% batch(2, timeout=5) %>% log_(\"in a batch\") %>% timeout(5) %>% separate() %>% log_(\"leaving\") simmer() %>% add_generator(\"dummy\", traj, at(0:2)) %>% run() %>% invisible #> 0: dummy0: arrived #> 1: dummy1: arrived #> 1: batch0: in a batch #> 2: dummy2: arrived #> 6: dummy0: leaving #> 6: dummy1: leaving #> 7: batch1: in a batch #> 12: dummy2: leaving ## batching based on some dynamic rule traj <- trajectory() %>% log_(\"arrived\") %>% # always FALSE -> no batches batch(2, rule=function() FALSE) %>% log_(\"not in a batch\") %>% timeout(5) %>% separate() %>% log_(\"leaving\") simmer() %>% add_generator(\"dummy\", traj, at(0:2)) %>% run() %>% invisible #> 0: dummy0: arrived #> 0: dummy0: not in a batch #> 1: dummy1: arrived #> 1: dummy1: not in a batch #> 2: dummy2: arrived #> 2: dummy2: not in a batch #> 5: dummy0: leaving #> 6: dummy1: leaving #> 7: dummy2: leaving ## named batch, shared across trajectories traj0 <- trajectory() %>% log_(\"arrived traj0\") %>% batch(2, name = \"mybatch\") traj1 <- trajectory() %>% log_(\"arrived traj1\") %>% timeout(1) %>% batch(2, name = \"mybatch\") %>% log_(\"in a batch\") %>% timeout(2) %>% separate() %>% log_(\"leaving traj1\") simmer() %>% add_generator(\"dummy0\", traj0, at(0)) %>% add_generator(\"dummy1\", traj1, at(0)) %>% run() %>% invisible #> 0: dummy00: arrived traj0 #> 0: dummy10: arrived traj1 #> 1: batch_mybatch: in a batch #> 3: dummy00: leaving traj1 #> 3: dummy10: leaving traj1"},{"path":"https://r-simmer.org/reference/branch.html","id":null,"dir":"Reference","previous_headings":"","what":"Fork the Trajectory Path — branch","title":"Fork the Trajectory Path — branch","text":"Activity defining fork N alternative sub-trajectories.","code":""},{"path":"https://r-simmer.org/reference/branch.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Fork the Trajectory Path — branch","text":"","code":"branch(.trj, option, continue, ..., tag)"},{"path":"https://r-simmer.org/reference/branch.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Fork the Trajectory Path — branch","text":".trj trajectory object. option callable object (function) must return integer 0 N. return value equal 0 skips branch continues next activity. returning value 1 N makes arrival follow corresponding sub-trajectory. continue vector N booleans indicate whether arrival must continue main trajectory sub-trajectory (one value provided, recycled match number sub-trajectories). ... N trajectory objects (list N trajectory objects) describing sub-trajectory. tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/branch.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Fork the Trajectory Path — branch","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/branch.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Fork the Trajectory Path — branch","text":"","code":"env <- simmer() traj <- trajectory() %>% set_global(\"path\", 1, mod=\"+\", init=-1) %>% log_(function() paste(\"Path\", get_global(env, \"path\"), \"selected\")) %>% branch( function() get_global(env, \"path\"), continue=c(TRUE, FALSE), trajectory() %>% log_(\"following path 1\"), trajectory() %>% log_(\"following path 2\")) %>% log_(\"continuing after the branch (path 0)\") env %>% add_generator(\"dummy\", traj, at(0:2)) %>% run() %>% invisible #> 0: dummy0: Path 0 selected #> 0: dummy0: continuing after the branch (path 0) #> 1: dummy1: Path 1 selected #> 1: dummy1: following path 1 #> 1: dummy1: continuing after the branch (path 0) #> 2: dummy2: Path 2 selected #> 2: dummy2: following path 2"},{"path":"https://r-simmer.org/reference/clone.html","id":null,"dir":"Reference","previous_headings":"","what":"Clone/Synchronize Arrivals — clone","title":"Clone/Synchronize Arrivals — clone","text":"Activities defining parallel fork removing copies. clone replicates arrival n times (original one + n-1 copies). synchronize removes one clone set clones.","code":""},{"path":"https://r-simmer.org/reference/clone.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Clone/Synchronize Arrivals — clone","text":"","code":"clone(.trj, n, ..., tag) synchronize(.trj, wait = TRUE, mon_all = FALSE, ..., tag)"},{"path":"https://r-simmer.org/reference/clone.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Clone/Synchronize Arrivals — clone","text":".trj trajectory object. n number clones, accepts either numeric callable object (function) must return numeric. ... number optional parallel sub-trajectories (list sub-trajectories). clone follow different sub-trajectory available. tag activity tag name perform named rollbacks (see rollback) just better identify activities. wait FALSE, clones first arrive removed. TRUE (default), clones last arrive removed. mon_all TRUE, get_mon_arrivals show one line per clone.","code":""},{"path":"https://r-simmer.org/reference/clone.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Clone/Synchronize Arrivals — clone","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/clone.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Clone/Synchronize Arrivals — clone","text":"","code":"## clone and wait for the others traj <- trajectory() %>% clone( n = 3, trajectory() %>% log_(\"clone 0 (original)\") %>% timeout(1), trajectory() %>% log_(\"clone 1\") %>% timeout(2), trajectory() %>% log_(\"clone 2\") %>% timeout(3)) %>% log_(\"sync reached\") %>% synchronize(wait = TRUE) %>% log_(\"leaving\") simmer() %>% add_generator(\"arrival\", traj, at(0)) %>% run() %>% invisible #> 0: arrival0: clone 0 (original) #> 0: arrival0: clone 1 #> 0: arrival0: clone 2 #> 1: arrival0: sync reached #> 2: arrival0: sync reached #> 3: arrival0: sync reached #> 3: arrival0: leaving ## more clones that trajectories available traj <- trajectory() %>% clone( n = 5, trajectory() %>% log_(\"clone 0 (original)\") %>% timeout(1)) %>% log_(\"sync reached\") %>% synchronize(wait = TRUE) %>% log_(\"leaving\") simmer() %>% add_generator(\"arrival\", traj, at(0)) %>% run() %>% invisible #> 0: arrival0: clone 0 (original) #> 0: arrival0: sync reached #> 0: arrival0: sync reached #> 0: arrival0: sync reached #> 0: arrival0: sync reached #> 1: arrival0: sync reached #> 1: arrival0: leaving ## clone and continue without waiting traj <- trajectory() %>% clone( n = 3, trajectory() %>% log_(\"clone 0 (original)\") %>% timeout(1), trajectory() %>% log_(\"clone 1\") %>% timeout(2), trajectory() %>% log_(\"clone 2\") %>% timeout(3)) %>% log_(\"sync reached\") %>% synchronize(wait = FALSE) %>% log_(\"leaving\") simmer() %>% add_generator(\"arrival\", traj, at(0)) %>% run() %>% invisible #> 0: arrival0: clone 0 (original) #> 0: arrival0: clone 1 #> 0: arrival0: clone 2 #> 1: arrival0: sync reached #> 1: arrival0: leaving #> 2: arrival0: sync reached #> 3: arrival0: sync reached"},{"path":"https://r-simmer.org/reference/generators.html","id":null,"dir":"Reference","previous_headings":"","what":"Convenience Functions for Generators — generators","title":"Convenience Functions for Generators — generators","text":"convenience functions facilitate definition generators arrivals common cases.","code":""},{"path":"https://r-simmer.org/reference/generators.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convenience Functions for Generators — generators","text":"","code":"at(...) from(start_time, dist, arrive = TRUE) to(stop_time, dist) from_to(start_time, stop_time, dist, arrive = TRUE, every = NULL) when_activated(n = 1)"},{"path":"https://r-simmer.org/reference/generators.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convenience Functions for Generators — generators","text":"... vector multiple parameters times initiate arrival. start_time time launch initial arrival (numeric function). dist function modelling interarrival times. supposed infinite source values >= 0 (e.g., rexp like). function provided returns negative value, behaviour undefined. arrive set TRUE (default) first arrival generated start_time follow dist . set FALSE, initiate dist start_time (first arrival likely start time later start_time). stop_time time stop generator (numeric function). every repeat time cycle (numeric function). n integer callable object (function) must return number arrivals generate activated.","code":""},{"path":"https://r-simmer.org/reference/generators.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convenience Functions for Generators — generators","text":"Returns generator function (closure).","code":""},{"path":"https://r-simmer.org/reference/generators.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Convenience Functions for Generators — generators","text":"generates arrivals specific absolute times. generates inter-arrivals following given distribution specified start time. union last two. generates inter-arrivals following given distribution specified stop time. from_to union . when_activated sets initially inactive generator generates n arrivals time activated trajectory using activity activate.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/generators.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Convenience Functions for Generators — generators","text":"","code":"## common to all examples below # some trajectory t0 <- trajectory() %>% timeout(0) # some distribution distr <- function() runif(1, 1, 2) # arrivals at 0, 1, 10, 30, 40 and 43 simmer() %>% add_generator(\"dummy\", t0, at(0, c(1,10,30), 40, 43)) %>% run(100) %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 dummy0 0 0 0 TRUE 1 #> 2 dummy1 1 1 0 TRUE 1 #> 3 dummy2 10 10 0 TRUE 1 #> 4 dummy3 30 30 0 TRUE 1 #> 5 dummy4 40 40 0 TRUE 1 #> 6 dummy5 43 43 0 TRUE 1 # apply distribution starting at 5 (and no end) simmer() %>% add_generator(\"dummy\", t0, from(5, distr)) %>% run(10) %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 dummy0 5.000000 5.000000 0 TRUE 1 #> 2 dummy1 6.080750 6.080750 0 TRUE 1 #> 3 dummy2 7.915083 7.915083 0 TRUE 1 #> 4 dummy3 9.515844 9.515844 0 TRUE 1 # apply distribution until 5 (starting at 0) simmer() %>% add_generator(\"dummy\", t0, to(5, distr)) %>% run(10) %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 dummy0 1.007399 1.007399 0 TRUE 1 #> 2 dummy1 2.473793 2.473793 0 TRUE 1 #> 3 dummy2 3.971570 3.971570 0 TRUE 1 # apply distribution from 8 to 16 h every 24 h: simmer() %>% add_generator(\"dummy\", t0, from_to(8, 16, distr, every=24)) %>% run(48) %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 dummy0 8.000000 8.000000 0 TRUE 1 #> 2 dummy1 9.732882 9.732882 0 TRUE 1 #> 3 dummy2 11.505403 11.505403 0 TRUE 1 #> 4 dummy3 13.380004 13.380004 0 TRUE 1 #> 5 dummy4 14.554945 14.554945 0 TRUE 1 #> 6 dummy5 15.589186 15.589186 0 TRUE 1 #> 7 dummy6 32.000000 32.000000 0 TRUE 1 #> 8 dummy7 33.402328 33.402328 0 TRUE 1 #> 9 dummy8 34.597998 34.597998 0 TRUE 1 #> 10 dummy9 36.001536 36.001536 0 TRUE 1 #> 11 dummy10 37.065198 37.065198 0 TRUE 1 #> 12 dummy11 38.453899 38.453899 0 TRUE 1 # triggering arrivals on demand from a trajectory t1 <- trajectory() %>% activate(\"dummy\") simmer() %>% add_generator(\"dummy\", t0, when_activated()) %>% add_generator(\"trigger\", t1, at(2)) %>% run() %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 trigger0 2 2 0 TRUE 1 #> 2 dummy0 2 2 0 TRUE 1"},{"path":"https://r-simmer.org/reference/get_capacity.html","id":null,"dir":"Reference","previous_headings":"","what":"Get Resource Parameters — get_capacity","title":"Get Resource Parameters — get_capacity","text":"Getters resources: server capacity/count queue size/count, seized amount, activity time, selected resources.","code":""},{"path":"https://r-simmer.org/reference/get_capacity.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get Resource Parameters — get_capacity","text":"","code":"get_capacity(.env, resources) get_capacity_selected(.env, id = 0) get_queue_size(.env, resources) get_queue_size_selected(.env, id = 0) get_server_count(.env, resources) get_server_count_selected(.env, id = 0) get_queue_count(.env, resources) get_queue_count_selected(.env, id = 0) get_seized(.env, resources) get_seized_selected(.env, id = 0) get_activity_time(.env, resources) get_activity_time_selected(.env, id = 0) get_selected(.env, id = 0)"},{"path":"https://r-simmer.org/reference/get_capacity.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get Resource Parameters — get_capacity","text":".env simulation environment. resources one resource names. id selection identifier nested usage.","code":""},{"path":"https://r-simmer.org/reference/get_capacity.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get Resource Parameters — get_capacity","text":"Return vector (character get_selected, numeric rest ).","code":""},{"path":"https://r-simmer.org/reference/get_capacity.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Get Resource Parameters — get_capacity","text":"resources provided get_activity_time, overall activity time reported.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/get_mon.html","id":null,"dir":"Reference","previous_headings":"","what":"Monitoring Statistics — get_mon","title":"Monitoring Statistics — get_mon","text":"Getters obtaining monitored data () arrivals, attributes resources.","code":""},{"path":"https://r-simmer.org/reference/get_mon.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Monitoring Statistics — get_mon","text":"","code":"get_mon_arrivals(.envs, per_resource = FALSE, ongoing = FALSE) get_mon_attributes(.envs) get_mon_resources(.envs)"},{"path":"https://r-simmer.org/reference/get_mon.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Monitoring Statistics — get_mon","text":".envs simulation environment (list environments). per_resource TRUE, statistics reported per-resource basis. ongoing TRUE, ongoing arrivals reported. columns end_time finished arrivals reported NAs.","code":""},{"path":"https://r-simmer.org/reference/get_mon.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Monitoring Statistics — get_mon","text":"Returns data frame.","code":""},{"path":"https://r-simmer.org/reference/get_n_generated.html","id":null,"dir":"Reference","previous_headings":"","what":"Get Process Parameters — get_n_generated","title":"Get Process Parameters — get_n_generated","text":"Getters processes (sources arrivals) number arrivals generated source, name active arrival, attribute active arrival global one, prioritization values, number arrivals active batch.","code":""},{"path":"https://r-simmer.org/reference/get_n_generated.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get Process Parameters — get_n_generated","text":"","code":"get_n_generated(.env, sources) get_trajectory(.env, sources) get_name(.env) get_start_time(.env) get_attribute(.env, keys) get_global(.env, keys) get_prioritization(.env) get_batch_size(.env)"},{"path":"https://r-simmer.org/reference/get_n_generated.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get Process Parameters — get_n_generated","text":".env simulation environment. sources one resource names. keys attribute name(s).","code":""},{"path":"https://r-simmer.org/reference/get_n_generated.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Get Process Parameters — get_n_generated","text":"get_n_generated returns number arrivals generated given sources. get_trajectory returns trajectory attached (list). get_name returns number running arrival. get_start_time returns start time running arrival. get_attribute returns running arrival's attributes. provided key previously set, returns missing value. get_global returns global attribute. get_prioritization returns running arrival's prioritization values. get_name, get_start_time, get_attribute get_prioritization meant used inside trajectory; otherwise, arrival running functions throw error.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/get_sources.html","id":null,"dir":"Reference","previous_headings":"","what":"Get Sources and Resources Defined — get_sources","title":"Get Sources and Resources Defined — get_sources","text":"Get list names sources resources defined simulation environment.","code":""},{"path":"https://r-simmer.org/reference/get_sources.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Get Sources and Resources Defined — get_sources","text":"","code":"get_sources(.env) get_resources(.env)"},{"path":"https://r-simmer.org/reference/get_sources.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Get Sources and Resources Defined — get_sources","text":".env simulation environment.","code":""},{"path":"https://r-simmer.org/reference/get_sources.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Get Sources and Resources Defined — get_sources","text":"character vector.","code":""},{"path":"https://r-simmer.org/reference/handle_unfinished.html","id":null,"dir":"Reference","previous_headings":"","what":"Handle Unfinished Arrivals — handle_unfinished","title":"Handle Unfinished Arrivals — handle_unfinished","text":"Activity setting drop-trajectory unfinished arrivals, .e., dropped resource (due preemption, resource shrinkage rejected seize) leave trajectory.","code":""},{"path":"https://r-simmer.org/reference/handle_unfinished.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Handle Unfinished Arrivals — handle_unfinished","text":"","code":"handle_unfinished(.trj, handler, ..., tag)"},{"path":"https://r-simmer.org/reference/handle_unfinished.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Handle Unfinished Arrivals — handle_unfinished","text":".trj trajectory object. handler trajectory object handle unfinished arrivals. NULL value unset drop-trajectory. ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/handle_unfinished.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Handle Unfinished Arrivals — handle_unfinished","text":"Returns trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/handle_unfinished.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Handle Unfinished Arrivals — handle_unfinished","text":"","code":"traj <- trajectory() %>% log_(\"arrived\") %>% handle_unfinished( trajectory() %>% log_(\"preempted!\")) %>% seize(\"res\") %>% log_(\"resource seized\") %>% timeout(10) %>% release(\"res\") %>% log_(\"leaving\") simmer() %>% add_resource(\"res\", 1, 0, preemptive=TRUE, queue_size_strict=TRUE) %>% add_generator(\"dummy\", traj, at(0)) %>% add_generator(\"priority_dummy\", traj, at(5), priority=1) %>% run() %>% invisible #> 0: dummy0: arrived #> 0: dummy0: resource seized #> 5: priority_dummy0: arrived #> 5: priority_dummy0: resource seized #> 5: dummy0: preempted! #> 15: priority_dummy0: leaving"},{"path":"https://r-simmer.org/reference/join.html","id":null,"dir":"Reference","previous_headings":"","what":"Join Trajectories — join","title":"Join Trajectories — join","text":"Concatenate number trajectories specified order.","code":""},{"path":"https://r-simmer.org/reference/join.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Join Trajectories — join","text":"","code":"join(...)"},{"path":"https://r-simmer.org/reference/join.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Join Trajectories — join","text":"... trajectory objects.","code":""},{"path":"https://r-simmer.org/reference/join.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Join Trajectories — join","text":"Returns new trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/join.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Join Trajectories — join","text":"","code":"t1 <- trajectory() %>% seize(\"dummy\", 1) t2 <- trajectory() %>% timeout(1) t3 <- trajectory() %>% release(\"dummy\", 1) ## join can be used alone join(t1, t2, t3) #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Timeout | delay: 1 } #> { Activity: Release | resource: dummy, amount: 1 } ## or can be chained in a trajectory definition trajectory() %>% join(t1) %>% timeout(1) %>% join(t3) #> trajectory: anonymous, 3 activities #> { Activity: Seize | resource: dummy, amount: 1 } #> { Activity: Timeout | delay: 1 } #> { Activity: Release | resource: dummy, amount: 1 }"},{"path":"https://r-simmer.org/reference/length.trajectory.html","id":null,"dir":"Reference","previous_headings":"","what":"Number of Activities in a Trajectory — length.trajectory","title":"Number of Activities in a Trajectory — length.trajectory","text":"Get number activities trajectory. length returns number first-level activities (sub-trajectories included). get_n_activities returns total number activities (sub-trajectories included).","code":""},{"path":"https://r-simmer.org/reference/length.trajectory.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Number of Activities in a Trajectory — length.trajectory","text":"","code":"# S3 method for class 'trajectory' length(x) get_n_activities(x)"},{"path":"https://r-simmer.org/reference/length.trajectory.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Number of Activities in a Trajectory — length.trajectory","text":"x trajectory object.","code":""},{"path":"https://r-simmer.org/reference/length.trajectory.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Number of Activities in a Trajectory — length.trajectory","text":"Returns non-negative integer length 1.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/length.trajectory.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Number of Activities in a Trajectory — length.trajectory","text":"","code":"x <- trajectory() %>% timeout(1) x <- x %>% clone(2, x, x) x #> trajectory: anonymous, 4 activities #> { Activity: Timeout | delay: 1 } #> { Activity: Clone | n: 2 } #> Fork 1, continue, trajectory: anonymous, 1 activities #> { Activity: Timeout | delay: 1 } #> Fork 2, continue, trajectory: anonymous, 1 activities #> { Activity: Timeout | delay: 1 } ## length does not account for subtrajectories length(x) #> [1] 2 get_n_activities(x) #> [1] 4"},{"path":"https://r-simmer.org/reference/log_.html","id":null,"dir":"Reference","previous_headings":"","what":"Debugging — log_","title":"Debugging — log_","text":"Activities displaying messages preceded simulation time name arrival, setting conditional breakpoints.","code":""},{"path":"https://r-simmer.org/reference/log_.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Debugging — log_","text":"","code":"log_(.trj, message, level = 0, ..., tag) stop_if(.trj, condition, ..., tag)"},{"path":"https://r-simmer.org/reference/log_.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Debugging — log_","text":".trj trajectory object. message message display, accepts either string callable object (function) must return string. level debugging level. message printed , , level provided less equal log_level defined simulation environment (see simmer). ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities. condition boolean function returning boolean.","code":""},{"path":"https://r-simmer.org/reference/log_.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Debugging — log_","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/log_.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Debugging — log_","text":"","code":"## log levels traj <- trajectory() %>% log_(\"this is always printed\") %>% # level = 0 by default log_(\"this is printed if `log_level>=1`\", level = 1) %>% log_(\"this is printed if `log_level>=2`\", level = 2) simmer() %>% add_generator(\"dummy\", traj, at(0)) %>% run() %>% invisible #> 0: dummy0: this is always printed simmer(log_level = 1) %>% add_generator(\"dummy\", traj, at(0)) %>% run() %>% invisible #> 0: dummy0: this is always printed #> 0: dummy0: this is printed if `log_level>=1` simmer(log_level = Inf) %>% add_generator(\"dummy\", traj, at(0)) %>% run() %>% invisible #> 0: dummy0: this is always printed #> 0: dummy0: this is printed if `log_level>=1` #> 0: dummy0: this is printed if `log_level>=2`"},{"path":"https://r-simmer.org/reference/monitor.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a Monitor — monitor","title":"Create a Monitor — monitor","text":"Methods creating monitor objects simulation environments.","code":""},{"path":"https://r-simmer.org/reference/monitor.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a Monitor — monitor","text":"","code":"monitor(name, xptr, get_arrivals, get_attributes, get_resources, handlers = NULL, finalizer = NULL) monitor_mem() monitor_delim(path = tempdir(), keep = FALSE, sep = \" \", ext = \".txt\", reader = read.delim, args = list(stringsAsFactors = FALSE)) monitor_csv(path = tempdir(), keep = FALSE, reader = read.csv, args = list(stringsAsFactors = FALSE))"},{"path":"https://r-simmer.org/reference/monitor.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a Monitor — monitor","text":"name identifier show printed. xptr external pointer pointing C++ object derived abstract class simmer::Monitor. See C++ API details , particular, simmer/monitor.h header. get_arrivals function retrieve arrivals tables. must accept xptr first argument, even needed, boolean per_resource second argument (see get_mon_arrivals). get_attributes function retrieve attributes table. must accept xptr first argument, even needed. get_resources function retrieve resources table. must accept xptr first argument, even needed. handlers optional list handlers stored slot name. example, monitor_mem use slot, monitor_delim monitor_csv store path created files. finalizer optional one-argument function called object destroyed. example, monitor_mem require finalizer, monitor_delim monitor_csv use remove created files monitor destroyed. path directory files created (must exist). keep whether keep files exit. default, files removed. sep separator character. ext file extension use. reader function used read files. args list arguments reader.","code":""},{"path":"https://r-simmer.org/reference/monitor.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a Monitor — monitor","text":"monitor object.","code":""},{"path":"https://r-simmer.org/reference/monitor.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Create a Monitor — monitor","text":"monitor method generic function instantiate monitor object. used general unless want extend simmer custom monitor. -memory monitor enabled default (memory_mem), fastest. large simulations, RAM footprint issue, may consider monitoring disk. end, monitor_delim stores values flat delimited files. usual get_mon_* methods retrieve data frames files using reader provided. default, read.delim used, may consider using faster alternatives packages. also possible keep files custom directory read post-process separate workflow. monitor_csv special case monitor_delim sep=\",\" ext=\".csv\".","code":""},{"path":"https://r-simmer.org/reference/monitor.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a Monitor — monitor","text":"","code":"mon <- monitor_csv() mon #> simmer monitor: to disk (delimited files) #> { arrivals: /tmp/RtmpLoWAIb/file2557a3a5f926c_arrivals.csv } #> { releases: /tmp/RtmpLoWAIb/file2557a3a5f926c_releases.csv } #> { attributes: /tmp/RtmpLoWAIb/file2557a3a5f926c_attributes.csv } #> { resources: /tmp/RtmpLoWAIb/file2557a3a5f926c_resources.csv } env <- simmer(mon=mon) %>% add_generator(\"dummy\", trajectory() %>% timeout(1), function() 1) %>% run(10) env #> simmer environment: anonymous | now: 10 | next: 10 #> { Monitor: to disk (delimited files) } #> { arrivals: /tmp/RtmpLoWAIb/file2557a3a5f926c_arrivals.csv } #> { releases: /tmp/RtmpLoWAIb/file2557a3a5f926c_releases.csv } #> { attributes: /tmp/RtmpLoWAIb/file2557a3a5f926c_attributes.csv } #> { resources: /tmp/RtmpLoWAIb/file2557a3a5f926c_resources.csv } #> { Source: dummy | monitored: 1 | n_generated: 10 } read.csv(mon$handlers$arrivals) # direct access #> name start_time end_time activity_time finished #> 1 dummy0 1 2 1 1 #> 2 dummy1 2 3 1 1 #> 3 dummy2 3 4 1 1 #> 4 dummy3 4 5 1 1 #> 5 dummy4 5 6 1 1 #> 6 dummy5 6 7 1 1 #> 7 dummy6 7 8 1 1 #> 8 dummy7 8 9 1 1 get_mon_arrivals(env) # adds the \"replication\" column #> name start_time end_time activity_time finished replication #> 1 dummy0 1 2 1 1 1 #> 2 dummy1 2 3 1 1 1 #> 3 dummy2 3 4 1 1 1 #> 4 dummy3 4 5 1 1 1 #> 5 dummy4 5 6 1 1 1 #> 6 dummy5 6 7 1 1 1 #> 7 dummy6 7 8 1 1 1 #> 8 dummy7 8 9 1 1 1"},{"path":"https://r-simmer.org/reference/now.html","id":null,"dir":"Reference","previous_headings":"","what":"Simulation Time — now","title":"Simulation Time — now","text":"Get current simulation time.","code":""},{"path":"https://r-simmer.org/reference/now.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Simulation Time — now","text":"","code":"now(.env)"},{"path":"https://r-simmer.org/reference/now.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Simulation Time — now","text":".env simulation environment.","code":""},{"path":"https://r-simmer.org/reference/now.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Simulation Time — now","text":"Returns numeric value.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/peek.html","id":null,"dir":"Reference","previous_headings":"","what":"Peek Next Events — peek","title":"Peek Next Events — peek","text":"Look future events event queue (optionally) obtain info .","code":""},{"path":"https://r-simmer.org/reference/peek.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Peek Next Events — peek","text":"","code":"peek(.env, steps = 1, verbose = FALSE)"},{"path":"https://r-simmer.org/reference/peek.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Peek Next Events — peek","text":".env simulation environment. steps number steps peek. verbose show additional information (.e., name process) future events.","code":""},{"path":"https://r-simmer.org/reference/peek.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Peek Next Events — peek","text":"Returns numeric values verbose=F data frame otherwise.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/reexports.html","id":null,"dir":"Reference","previous_headings":"","what":"Objects exported from other packages — reexports","title":"Objects exported from other packages — reexports","text":"objects imported packages. Follow links see documentation. magrittr %>%","code":""},{"path":"https://r-simmer.org/reference/renege.html","id":null,"dir":"Reference","previous_headings":"","what":"Renege on some Condition — renege","title":"Renege on some Condition — renege","text":"Activities leaving probability, setting unsetting timer signal arrival abandon.","code":""},{"path":"https://r-simmer.org/reference/renege.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Renege on some Condition — renege","text":"","code":"leave(.trj, prob, out = NULL, keep_seized = TRUE, ..., tag) renege_in(.trj, t, out = NULL, keep_seized = FALSE, ..., tag) renege_if(.trj, signal, out = NULL, keep_seized = FALSE, ..., tag) renege_abort(.trj, ..., tag)"},{"path":"https://r-simmer.org/reference/renege.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Renege on some Condition — renege","text":".trj trajectory object. prob probability function returning probability. optional sub-trajectory case reneging. keep_seized whether keep already seized resources. default, resources released. ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities. t timeout trigger reneging, accepts either numeric callable object (function) must return numeric. signal signal trigger reneging, accepts either string callable object (function) must return string.","code":""},{"path":"https://r-simmer.org/reference/renege.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Renege on some Condition — renege","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/renege.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Renege on some Condition — renege","text":"Arrivals leave trajectory set finished flag FALSE output get_mon_arrivals. Unfinished arrivals can handled drop-trajectory can set using optional argument handle_unfinished activity. Note , historical reasons, leave keep_seized=TRUE default, renege_* . Note renege_if works similarly trap, contrast , reneging triggered even arrival waiting queue part non-permanent batch.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/renege.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Renege on some Condition — renege","text":"","code":"## leave with some probability set.seed(1234) traj <- trajectory() %>% log_(\"leave with some probability\") %>% leave(function() runif(1) < 0.5) %>% log_(\"didn't leave\") simmer() %>% add_generator(\"dummy\", traj, at(0, 1)) %>% run() %>% invisible #> 0: dummy0: leave with some probability #> 1: dummy1: leave with some probability #> 1: dummy1: didn't leave ## reneging after some time bank <- trajectory() %>% log_(\"here I am\") %>% # renege in 5 minutes renege_in( 5, out = trajectory() %>% log_(\"lost my patience. Reneging...\")) %>% seize(\"clerk\") %>% # stay if I'm being attended within 5 minutes renege_abort() %>% log_(\"I'm being attended\") %>% timeout(10) %>% release(\"clerk\") %>% log_(\"finished\") simmer() %>% add_resource(\"clerk\", 1) %>% add_generator(\"customer\", bank, at(0, 1)) %>% run() %>% invisible #> 0: customer0: here I am #> 0: customer0: I'm being attended #> 1: customer1: here I am #> 6: customer1: lost my patience. Reneging... #> 10: customer0: finished"},{"path":"https://r-simmer.org/reference/reset.html","id":null,"dir":"Reference","previous_headings":"","what":"Reset a Simulator — reset","title":"Reset a Simulator — reset","text":"Reset following components simulation environment: time, event queue, resources, sources statistics.","code":""},{"path":"https://r-simmer.org/reference/reset.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Reset a Simulator — reset","text":"","code":"reset(.env)"},{"path":"https://r-simmer.org/reference/reset.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Reset a Simulator — reset","text":".env simulation environment.","code":""},{"path":"https://r-simmer.org/reference/reset.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Reset a Simulator — reset","text":"Returns simulation environment.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/rollback.html","id":null,"dir":"Reference","previous_headings":"","what":"Rollback to a Previous Activity — rollback","title":"Rollback to a Previous Activity — rollback","text":"Activity going backwards previous point trajectory. Useful implement loops.","code":""},{"path":"https://r-simmer.org/reference/rollback.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Rollback to a Previous Activity — rollback","text":"","code":"rollback(.trj, target, times = Inf, check = NULL, ..., tag)"},{"path":"https://r-simmer.org/reference/rollback.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Rollback to a Previous Activity — rollback","text":".trj trajectory object. target tag name (previously set tag argument activity) amount activities (parent trajectories) roll back (see examples). times number repetitions arrival may continue. check callable object (function) must return boolean. present, times parameter ignored, activity uses function check whether rollback must done . ... unused tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/rollback.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Rollback to a Previous Activity — rollback","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/rollback.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Rollback to a Previous Activity — rollback","text":"","code":"## rollback a specific number of times traj <- trajectory() %>% log_(\"hello!\") %>% timeout(1) %>% rollback(2, 3) simmer() %>% add_generator(\"hello_sayer\", traj, at(0)) %>% run() %>% invisible #> 0: hello_sayer0: hello! #> 1: hello_sayer0: hello! #> 2: hello_sayer0: hello! #> 3: hello_sayer0: hello! ## same but with a tag as target traj <- trajectory() %>% log_(\"hello!\", tag=\"msg\") %>% timeout(1) %>% rollback(\"msg\", 3) simmer() %>% add_generator(\"hello_sayer\", traj, at(0)) %>% run() %>% invisible #> 0: hello_sayer0: hello! #> 1: hello_sayer0: hello! #> 2: hello_sayer0: hello! #> 3: hello_sayer0: hello! ## custom check env <- simmer() traj <- trajectory() %>% set_attribute(\"var\", 0) %>% log_(tag=\"msg\", function() paste(\"attribute level is at:\", get_attribute(env, \"var\"))) %>% set_attribute(\"var\", 25, mod=\"+\") %>% rollback(\"msg\", check=function() get_attribute(env, \"var\") < 100) %>% log_(\"done\") env %>% add_generator(\"dummy\", traj, at(0)) %>% run() %>% invisible #> 0: dummy0: attribute level is at: 0 #> 0: dummy0: attribute level is at: 25 #> 0: dummy0: attribute level is at: 50 #> 0: dummy0: attribute level is at: 75 #> 0: dummy0: done"},{"path":"https://r-simmer.org/reference/run.html","id":null,"dir":"Reference","previous_headings":"","what":"Run a Simulation — run","title":"Run a Simulation — run","text":"Execute steps given criterion.","code":""},{"path":"https://r-simmer.org/reference/run.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Run a Simulation — run","text":"","code":"run(.env, until = Inf, progress = NULL, steps = 10) stepn(.env, n = 1)"},{"path":"https://r-simmer.org/reference/run.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Run a Simulation — run","text":".env simulation environment. stop time. progress optional callback show progress simulation. completed ratio periodically passed argument callback. steps number steps show progress (takes effect progress provided). n number events simulate.","code":""},{"path":"https://r-simmer.org/reference/run.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Run a Simulation — run","text":"Returns simulation environment.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/run.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Run a Simulation — run","text":"","code":"## show the progress just printing the steps simmer() %>% run(progress=message, steps=5) #> 0 #> 0.2 #> 0.4 #> 0.6 #> 0.8 #> 1 #> simmer environment: anonymous | now: 0 | next: #> { Monitor: in memory } ## using the 'progress' package if (FALSE) { # \\dontrun{ mm1 <- trajectory() %>% seize(\"server\", 1) %>% timeout(function() rexp(1, 66)) %>% release(\"server\", 1) simmer() %>% add_resource(\"server\", 1) %>% add_generator(\"customer\", mm1, function() rexp(100, 60)) %>% run(3000, progress=progress::progress_bar$new()$update) } # }"},{"path":"https://r-simmer.org/reference/schedule.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate a Scheduling Object — schedule","title":"Generate a Scheduling Object — schedule","text":"Resource convenience function generate scheduling object timetable specification.","code":""},{"path":"https://r-simmer.org/reference/schedule.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate a Scheduling Object — schedule","text":"","code":"schedule(timetable, values, period = Inf)"},{"path":"https://r-simmer.org/reference/schedule.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate a Scheduling Object — schedule","text":"timetable absolute points time desired value changes. values one value point time. period period repetition.","code":""},{"path":"https://r-simmer.org/reference/schedule.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generate a Scheduling Object — schedule","text":"Returns schedule object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/schedule.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Generate a Scheduling Object — schedule","text":"","code":"# Schedule 3 units from 8 to 16 h # 2 units from 16 to 24 h # 1 units from 24 to 8 h capacity_schedule <- schedule(c(8, 16, 24), c(3, 2, 1), period=24) env <- simmer() %>% add_resource(\"dummy\", capacity_schedule) # Composition of schedules sch1 <- schedule(c(8, 16), c(3, 0), period=24) sch2 <- schedule(c(16, 24), c(2, 1), period=24) all.equal(sch1 + sch2, capacity_schedule) #> [1] TRUE"},{"path":"https://r-simmer.org/reference/seize.html","id":null,"dir":"Reference","previous_headings":"","what":"Seize/Release Resources — seize","title":"Seize/Release Resources — seize","text":"Activities seizing/releasing resource, name previously selected one. Resources must defined simulation environment (see add_resource).","code":""},{"path":"https://r-simmer.org/reference/seize.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Seize/Release Resources — seize","text":"","code":"seize(.trj, resource, amount = 1, continue = NULL, post.seize = NULL, reject = NULL, ..., tag) seize_selected(.trj, amount = 1, id = 0, continue = NULL, post.seize = NULL, reject = NULL, ..., tag) release(.trj, resource, amount = 1, ..., tag) release_selected(.trj, amount = 1, id = 0, ..., tag) release_all(.trj, resource, ..., tag) release_selected_all(.trj, id = 0, ..., tag)"},{"path":"https://r-simmer.org/reference/seize.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Seize/Release Resources — seize","text":".trj trajectory object. resource name resource. amount amount seize/release, accepts either numeric callable object (function) must return numeric. continue boolean (post.seize reject defined) pair booleans (post.seize reject defined; one value provided, recycled) indicate whether subtrajectories continue next activity main trajectory. post.seize optional trajectory object followed successful seize. reject optional trajectory object followed arrival rejected (dropped). ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities. id selection identifier nested usage.","code":""},{"path":"https://r-simmer.org/reference/seize.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Seize/Release Resources — seize","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/seize.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Seize/Release Resources — seize","text":"Rejection happens resource full capacity room queue (either finite queue_size full, queue_size=0 thus disabled). cases, reject parameter defines fallback trajectory. Note, however, , arrival accepted (either queue server) dropped afterwards due preemption resource shrinkage, trajectory executed. Instead, see handle_unfinished another, general, method handling kinds unfinished arrivals.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/seize.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Seize/Release Resources — seize","text":"","code":"## simple seize, delay, then release traj <- trajectory() %>% seize(\"doctor\", 1) %>% timeout(3) %>% release(\"doctor\", 1) simmer() %>% add_resource(\"doctor\", capacity=1) %>% add_generator(\"patient\", traj, at(0, 1)) %>% run() %>% get_mon_resources() #> resource time server queue capacity queue_size system limit replication #> 1 doctor 0 1 0 1 Inf 1 Inf 1 #> 2 doctor 1 1 1 1 Inf 2 Inf 1 #> 3 doctor 3 1 0 1 Inf 1 Inf 1 #> 4 doctor 6 0 0 1 Inf 0 Inf 1 ## arrival rejection (no space left in the queue) traj <- trajectory() %>% log_(\"arriving...\") %>% seize(\"doctor\", 1) %>% # the second patient won't reach this point log_(\"doctor seized\") %>% timeout(5) %>% release(\"doctor\", 1) simmer() %>% add_resource(\"doctor\", capacity=1, queue_size=0) %>% add_generator(\"patient\", traj, at(0, 1)) %>% run() %>% invisible #> 0: patient0: arriving... #> 0: patient0: doctor seized #> 1: patient1: arriving... ## capturing rejection to retry traj <- trajectory() %>% log_(\"arriving...\") %>% seize( \"doctor\", 1, continue = FALSE, reject = trajectory() %>% log_(\"rejected!\") %>% # go for a walk and try again timeout(2) %>% log_(\"retrying...\") %>% rollback(amount = 4, times = Inf)) %>% # the second patient will reach this point after a couple of walks log_(\"doctor seized\") %>% timeout(5) %>% release(\"doctor\", 1) %>% log_(\"leaving\") #> Warning: argument 'amount' is deprecated, use 'target' instead simmer() %>% add_resource(\"doctor\", capacity=1, queue_size=0) %>% add_generator(\"patient\", traj, at(0, 1)) %>% run() %>% invisible #> 0: patient0: arriving... #> 0: patient0: doctor seized #> 1: patient1: arriving... #> 1: patient1: rejected! #> 3: patient1: retrying... #> 3: patient1: rejected! #> 5: patient1: retrying... #> 5: patient0: leaving #> 5: patient1: doctor seized #> 10: patient1: leaving ## combining post.seize and reject traj <- trajectory() %>% log_(\"arriving...\") %>% seize( \"doctor\", 1, continue = c(TRUE, TRUE), post.seize = trajectory(\"admitted patient\") %>% log_(\"admitted\") %>% timeout(5) %>% release(\"doctor\", 1), reject = trajectory(\"rejected patient\") %>% log_(\"rejected!\") %>% seize(\"nurse\", 1) %>% timeout(2) %>% release(\"nurse\", 1)) %>% # both patients will reach this point, as continue = c(TRUE, TRUE) timeout(10) %>% log_(\"leaving...\") simmer() %>% add_resource(\"doctor\", capacity=1, queue_size=0) %>% add_resource(\"nurse\", capacity=10, queue_size=0) %>% add_generator(\"patient\", traj, at(0, 1)) %>% run() %>% invisible #> 0: patient0: arriving... #> 0: patient0: admitted #> 1: patient1: arriving... #> 1: patient1: rejected! #> 13: patient1: leaving... #> 15: patient0: leaving..."},{"path":"https://r-simmer.org/reference/select.html","id":null,"dir":"Reference","previous_headings":"","what":"Select Resources — select","title":"Select Resources — select","text":"Activity selecting resource subsequent seize/release setting parameters (capacity queue size). Resources must defined simulation environment (see add_resource).","code":""},{"path":"https://r-simmer.org/reference/select.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Select Resources — select","text":"","code":"select(.trj, resources, policy = c(\"shortest-queue\", \"shortest-queue-available\", \"round-robin\", \"round-robin-available\", \"first-available\", \"random\", \"random-available\"), id = 0, ..., tag)"},{"path":"https://r-simmer.org/reference/select.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Select Resources — select","text":".trj trajectory object. resources one resource names, callable object (function) must return one resource names. policy resources character vector, parameter determines criteria selecting resource among set policies available (see details). id selection identifier nested usage. ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/select.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Select Resources — select","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/select.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Select Resources — select","text":"'shortest-queue' policy selects least busy resource; 'round-robin' selects resources cyclical order; 'first-available' selects first resource available, 'random' selects resource randomly. 'available'-ending policies ('first-available', also 'shortest-queue-available', 'round-robin-available' 'random-available') check resource availability (.e., whether capacity non-zero), exclude selection procedure resources capacity set zero. means , policies, error raised resources unavailable.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/select.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Select Resources — select","text":"","code":"## predefined policy traj <- trajectory() %>% select(paste0(\"doctor\", 1:3), \"round-robin\") %>% seize_selected(1) %>% timeout(5) %>% release_selected(1) simmer() %>% add_resource(\"doctor1\") %>% add_resource(\"doctor2\") %>% add_resource(\"doctor3\") %>% add_generator(\"patient\", traj, at(0, 1, 2)) %>% run() %>% get_mon_resources() #> resource time server queue capacity queue_size system limit replication #> 1 doctor1 0 1 0 1 Inf 1 Inf 1 #> 2 doctor2 1 1 0 1 Inf 1 Inf 1 #> 3 doctor3 2 1 0 1 Inf 1 Inf 1 #> 4 doctor1 5 0 0 1 Inf 0 Inf 1 #> 5 doctor2 6 0 0 1 Inf 0 Inf 1 #> 6 doctor3 7 0 0 1 Inf 0 Inf 1 ## custom policy env <- simmer() res <- paste0(\"doctor\", 1:3) traj <- trajectory() %>% select(function() { occ <- get_server_count(env, res) + get_queue_count(env, res) res[which.min(occ)[1]] }) %>% seize_selected(1) %>% timeout(5) %>% release_selected(1) for (i in res) env %>% add_resource(i) env %>% add_generator(\"patient\", traj, at(0, 1, 2)) %>% run() %>% get_mon_resources() #> resource time server queue capacity queue_size system limit replication #> 1 doctor1 0 1 0 1 Inf 1 Inf 1 #> 2 doctor2 1 1 0 1 Inf 1 Inf 1 #> 3 doctor3 2 1 0 1 Inf 1 Inf 1 #> 4 doctor1 5 0 0 1 Inf 0 Inf 1 #> 5 doctor2 6 0 0 1 Inf 0 Inf 1 #> 6 doctor3 7 0 0 1 Inf 0 Inf 1"},{"path":"https://r-simmer.org/reference/send.html","id":null,"dir":"Reference","previous_headings":"","what":"Inter-arrival Communication — send","title":"Inter-arrival Communication — send","text":"activities enable asynchronous programming. send() broadcasts signal list signals. Arrivals can subscribe signals (optionally) assign handler trap(). Note , inside batch, signals subscribed entering batch ignored. Upon signal reception, arrival stops current activity executes handler (provided). , execution returns activity following point interruption. untrap() can used unsubscribe signals. wait() blocks signal received.","code":""},{"path":"https://r-simmer.org/reference/send.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Inter-arrival Communication — send","text":"","code":"send(.trj, signals, delay = 0, ..., tag) trap(.trj, signals, handler = NULL, interruptible = TRUE, ..., tag) untrap(.trj, signals, ..., tag) wait(.trj, ..., tag)"},{"path":"https://r-simmer.org/reference/send.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Inter-arrival Communication — send","text":".trj trajectory object. signals signal list signals, accepts either string, list strings callable object (function) must return string list strings. delay optional timeout trigger signals, accepts either numeric callable object (function) must return numeric. ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities. handler optional trajectory object handle signal received. interruptible whether handler can interrupted signals.","code":""},{"path":"https://r-simmer.org/reference/send.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Inter-arrival Communication — send","text":"Returns trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/send.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Inter-arrival Communication — send","text":"","code":"## block, signal and continue with a handler signal <- \"you shall pass\" t_blocked <- trajectory() %>% trap( signal, trajectory() %>% log_(\"executing the handler\")) %>% log_(\"waiting...\") %>% wait() %>% log_(\"continuing!\") t_signaler <- trajectory() %>% log_(signal) %>% send(signal) simmer() %>% add_generator(\"blocked\", t_blocked, at(0)) %>% add_generator(\"signaler\", t_signaler, at(5)) %>% run() %>% invisible #> 0: blocked0: waiting... #> 5: signaler0: you shall pass #> 5: blocked0: executing the handler #> 5: blocked0: continuing! ## handlers can be interrupted, unless interruptible=FALSE t_worker <- trajectory() %>% trap( signal, handler = trajectory() %>% log_(\"ok, I'm packing...\") %>% timeout(1)) %>% log_(\"performing a looong task...\") %>% timeout(100) %>% log_(\"and I'm leaving!\") simmer() %>% add_generator(\"worker\", t_worker, at(0)) %>% add_generator(\"signaler\", t_signaler, at(5, 5.5)) %>% run() %>% invisible #> 0: worker0: performing a looong task... #> 5: signaler0: you shall pass #> 5: worker0: ok, I'm packing... #> 5.5: signaler1: you shall pass #> 5.5: worker0: ok, I'm packing... #> 6.5: worker0: and I'm leaving!"},{"path":"https://r-simmer.org/reference/set_attribute.html","id":null,"dir":"Reference","previous_headings":"","what":"Set Attributes — set_attribute","title":"Set Attributes — set_attribute","text":"Activity modifying attributes. Attributes defined set_attribute per arrival, meaning arrival set attributes, visible one. hand, attributes defined set_global shared arrivals simulation.","code":""},{"path":"https://r-simmer.org/reference/set_attribute.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Set Attributes — set_attribute","text":"","code":"set_attribute(.trj, keys, values, mod = c(NA, \"+\", \"*\"), init = 0, ..., tag) set_global(.trj, keys, values, mod = c(NA, \"+\", \"*\"), init = 0, ..., tag)"},{"path":"https://r-simmer.org/reference/set_attribute.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Set Attributes — set_attribute","text":".trj trajectory object. keys attribute name(s), callable object (function) must return attribute name(s). values numeric value(s) set, callable object (function) must return numeric value(s). mod set, values modify attributes rather substituting . init initial value, applied mod set attribute previously initialised. Useful counters indexes. ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/set_attribute.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Set Attributes — set_attribute","text":"Returns trajectory object.","code":""},{"path":"https://r-simmer.org/reference/set_attribute.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Set Attributes — set_attribute","text":"Attribute monitoring disabled default. enable , set mon=2 corresponding source (see, e.g., add_generator). , evolution attributes simulation can retrieved get_mon_attributes. Global attributes reported unnamed key/value pairs.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/set_attribute.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Set Attributes — set_attribute","text":"","code":"env <- simmer() traj <- trajectory() %>% # simple assignment set_attribute(\"my_key\", 123) %>% set_global(\"global_key\", 321) %>% # more than one assignment at once set_attribute(c(\"my_key\", \"other_key\"), c(5, 64)) %>% # increment set_attribute(\"my_key\", 1, mod=\"+\") %>% # assignment using a function set_attribute(\"independent_key\", function() runif(1)) %>% # assignment dependent on another attribute set_attribute(\"dependent_key\", function() ifelse(get_attribute(env, \"my_key\") <= 0.5, 1, 0)) env %>% add_generator(\"dummy\", traj, at(3), mon=2) %>% run() %>% get_mon_attributes() #> time name key value replication #> 1 3 dummy0 my_key 123.0000000 1 #> 2 3 global_key 321.0000000 1 #> 3 3 dummy0 my_key 5.0000000 1 #> 4 3 dummy0 other_key 64.0000000 1 #> 5 3 dummy0 my_key 6.0000000 1 #> 6 3 dummy0 independent_key 0.8609154 1 #> 7 3 dummy0 dependent_key 0.0000000 1"},{"path":"https://r-simmer.org/reference/set_capacity.html","id":null,"dir":"Reference","previous_headings":"","what":"Set Resource Parameters — set_capacity","title":"Set Resource Parameters — set_capacity","text":"Activities dynamically modifying resource's server capacity queue size, name previously selected one. Resources must defined simulation environment (see add_resource).","code":""},{"path":"https://r-simmer.org/reference/set_capacity.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Set Resource Parameters — set_capacity","text":"","code":"set_capacity(.trj, resource, value, mod = c(NA, \"+\", \"*\"), ..., tag) set_capacity_selected(.trj, value, id = 0, mod = c(NA, \"+\", \"*\"), ..., tag) set_queue_size(.trj, resource, value, mod = c(NA, \"+\", \"*\"), ..., tag) set_queue_size_selected(.trj, value, id = 0, mod = c(NA, \"+\", \"*\"), ..., tag)"},{"path":"https://r-simmer.org/reference/set_capacity.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Set Resource Parameters — set_capacity","text":".trj trajectory object. resource name resource. value numeric value set, callable object (function) must return numeric value. mod set, values modify attributes rather substituting . ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities. id selection identifier nested usage.","code":""},{"path":"https://r-simmer.org/reference/set_capacity.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Set Resource Parameters — set_capacity","text":"Returns trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/set_capacity.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Set Resource Parameters — set_capacity","text":"","code":"## a resource with a queue size equal to the number of arrivals waiting traj <- trajectory() %>% set_queue_size(\"res\", 1, mod=\"+\") %>% seize(\"res\") %>% set_queue_size(\"res\", -1, mod=\"+\") %>% timeout(10) %>% release(\"res\") simmer() %>% add_resource(\"res\", 1, 0) %>% add_generator(\"dummy\", traj, at(0:2)) %>% run() %>% get_mon_resources() #> resource time server queue capacity queue_size system limit replication #> 1 res 0 0 0 1 1 0 2 1 #> 2 res 0 1 0 1 1 1 2 1 #> 3 res 0 1 0 1 0 1 1 1 #> 4 res 1 1 0 1 1 1 2 1 #> 5 res 1 1 1 1 1 2 2 1 #> 6 res 2 1 1 1 2 2 3 1 #> 7 res 2 1 2 1 2 3 3 1 #> 8 res 10 1 1 1 2 2 3 1 #> 9 res 10 1 1 1 1 2 2 1 #> 10 res 20 1 0 1 1 1 2 1 #> 11 res 20 1 0 1 0 1 1 1 #> 12 res 30 0 0 1 0 0 1 1"},{"path":"https://r-simmer.org/reference/set_prioritization.html","id":null,"dir":"Reference","previous_headings":"","what":"Set Prioritization Values — set_prioritization","title":"Set Prioritization Values — set_prioritization","text":"Activity dynamically modifying arrival's prioritization values. Default prioritization values defined source (see add_generator, add_dataframe).","code":""},{"path":"https://r-simmer.org/reference/set_prioritization.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Set Prioritization Values — set_prioritization","text":"","code":"set_prioritization(.trj, values, mod = c(NA, \"+\", \"*\"), ..., tag)"},{"path":"https://r-simmer.org/reference/set_prioritization.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Set Prioritization Values — set_prioritization","text":".trj trajectory object. values expects either vector/list callable object (function) returning vector/list three values c(priority, preemptible, restart). negative value leaves corresponding parameter unchanged. See add_generator information parameters. mod set, values modify attributes rather substituting . ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities.","code":""},{"path":"https://r-simmer.org/reference/set_prioritization.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Set Prioritization Values — set_prioritization","text":"Returns trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/set_prioritization.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Set Prioritization Values — set_prioritization","text":"","code":"traj <- trajectory() %>% # static values set_prioritization(c(3, 7, TRUE)) %>% # increment set_prioritization(c(2, 1, 0), mod=\"+\") %>% # dynamic, custom set_attribute(\"priority\", 3) %>% set_prioritization(function() { prio <- get_prioritization(env) attr <- get_attribute(env, \"priority\") c(attr, prio[[2]]+1, FALSE) })"},{"path":"https://r-simmer.org/reference/set_trajectory.html","id":null,"dir":"Reference","previous_headings":"","what":"Set Source Parameters — set_trajectory","title":"Set Source Parameters — set_trajectory","text":"Activities modifying source's trajectory source object name. Sources must defined simulation environment (see add_generator, add_dataframe).","code":""},{"path":"https://r-simmer.org/reference/set_trajectory.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Set Source Parameters — set_trajectory","text":"","code":"set_trajectory(.trj, sources, trajectory, ..., tag) set_source(.trj, sources, object, ..., tag)"},{"path":"https://r-simmer.org/reference/set_trajectory.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Set Source Parameters — set_trajectory","text":".trj trajectory object. sources name(s) source(s) function returning name(s). trajectory trajectory generated arrivals follow. ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities. object function modelling interarrival times (source type generator; returning negative value missing value stops generator) data frame (source type data source).","code":""},{"path":"https://r-simmer.org/reference/set_trajectory.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Set Source Parameters — set_trajectory","text":"Returns trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/set_trajectory.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Set Source Parameters — set_trajectory","text":"","code":"traj1 <- trajectory() %>% timeout(1) traj2 <- trajectory() %>% set_source(\"dummy\", function() 1) %>% set_trajectory(\"dummy\", traj1) %>% timeout(2) simmer() %>% add_generator(\"dummy\", traj2, function() 2) %>% run(6) %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 dummy0 2 4 2 TRUE 1 #> 2 dummy1 3 4 1 TRUE 1 #> 3 dummy2 4 5 1 TRUE 1"},{"path":"https://r-simmer.org/reference/simmer-package.html","id":null,"dir":"Reference","previous_headings":"","what":"simmer: Discrete-Event Simulation for R — simmer-package","title":"simmer: Discrete-Event Simulation for R — simmer-package","text":"process-oriented trajectory-based Discrete-Event Simulation (DES) package R. Designed generic framework like SimPy SimJulia, leverages power Rcpp boost performance turning DES R feasible. noteworthy characteristic, simmer exploits concept trajectory: common path simulation model entities type. pretty flexible simple use, leverages chaining/piping workflow introduced magrittr package.","code":""},{"path":"https://r-simmer.org/reference/simmer-package.html","id":"references","dir":"Reference","previous_headings":"","what":"References","title":"simmer: Discrete-Event Simulation for R — simmer-package","text":"Ucar ., Smeets B., Azcorra . (2019). \"simmer: Discrete-Event Simulation R.\" Journal Statistical Software, 90(2), 1-30. doi:10.18637/jss.v090.i02 . Ucar ., Hernández J.., Serrano P., Azcorra . (2018). \"Design Analysis 5G Scenarios simmer: R Package Fast DES Prototyping.\" IEEE Communications Magazine, 56(11), 145-151. doi:10.1109/MCOM.2018.1700960 .","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/simmer-package.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"simmer: Discrete-Event Simulation for R — simmer-package","text":"Iñaki Ucar Bart Smeets","code":""},{"path":"https://r-simmer.org/reference/simmer-package.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"simmer: Discrete-Event Simulation for R — simmer-package","text":"","code":"if (FALSE) { # \\dontrun{ # introduction to simmer vignette(\"simmer-01-introduction\") # JSS paper available as vignette vignette(\"simmer-02-jss\") # more vignettes vignette(package = \"simmer\") } # }"},{"path":"https://r-simmer.org/reference/simmer.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a Simulator — simmer","title":"Create a Simulator — simmer","text":"method initialises simulation environment.","code":""},{"path":"https://r-simmer.org/reference/simmer.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a Simulator — simmer","text":"","code":"simmer(name = \"anonymous\", verbose = FALSE, mon = monitor_mem(), log_level = 0)"},{"path":"https://r-simmer.org/reference/simmer.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a Simulator — simmer","text":"name name simulator. verbose enable showing activity information. mon monitor (memory default); see monitor options. log_level debugging level (see log_).","code":""},{"path":"https://r-simmer.org/reference/simmer.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a Simulator — simmer","text":"Returns simulation environment.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/simmer.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a Simulator — simmer","text":"","code":"## a simple trajectory that prints a message t0 <- trajectory(\"my trajectory\") %>% log_(\"arrival generated\") ## create an empty simulation environment env <- simmer(\"SuperDuperSim\") env #> simmer environment: SuperDuperSim | now: 0 | next: #> { Monitor: in memory } ## add a generator and attach it to the trajectory above env %>% add_generator(\"dummy\", t0, function() 1) #> simmer environment: SuperDuperSim | now: 0 | next: 0 #> { Monitor: in memory } #> { Source: dummy | monitored: 1 | n_generated: 0 } ## run for some time env %>% run(until=4.5) #> 1: dummy0: arrival generated #> 2: dummy1: arrival generated #> 3: dummy2: arrival generated #> 4: dummy3: arrival generated #> simmer environment: SuperDuperSim | now: 4.5 | next: 5 #> { Monitor: in memory } #> { Source: dummy | monitored: 1 | n_generated: 5 } env %>% now() # current simulation time #> [1] 4.5 env %>% peek() # time for the next event #> [1] 5 env %>% stepn() # execute next event #> 5: dummy4: arrival generated #> simmer environment: SuperDuperSim | now: 5 | next: 5 #> { Monitor: in memory } #> { Source: dummy | monitored: 1 | n_generated: 5 }"},{"path":"https://r-simmer.org/reference/timeout.html","id":null,"dir":"Reference","previous_headings":"","what":"Delay — timeout","title":"Delay — timeout","text":"Activity inserting delays execute user-defined tasks.","code":""},{"path":"https://r-simmer.org/reference/timeout.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Delay — timeout","text":"","code":"timeout(.trj, task, ..., tag) timeout_from_attribute(.trj, key, ..., tag) timeout_from_global(.trj, key, ..., tag)"},{"path":"https://r-simmer.org/reference/timeout.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Delay — timeout","text":".trj trajectory object. task timeout duration supplied either passing numeric callable object (function) must return numeric (negative values automatically coerced positive). ... unused. tag activity tag name perform named rollbacks (see rollback) just better identify activities. key attribute name, callable object (function) must return attribute name.","code":""},{"path":"https://r-simmer.org/reference/timeout.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Delay — timeout","text":"Returns trajectory object.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/timeout.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Delay — timeout","text":"","code":"env <- simmer() traj <- trajectory() %>% # static delay timeout(3) %>% # dynamic, exponential delay timeout(function() rexp(1, 10)) %>% # dependent on an attribute set_attribute(\"delay\", 2) %>% set_global(\"other\", function() rexp(1, 2)) %>% timeout_from_attribute(\"delay\") %>% timeout_from_global(\"other\") env %>% add_generator(\"dummy\", traj, at(0)) %>% run() %>% get_mon_arrivals() #> name start_time end_time activity_time finished replication #> 1 dummy0 0 7.215232 7.215232 TRUE 1"},{"path":"https://r-simmer.org/reference/trajectory.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a Trajectory — trajectory","title":"Create a Trajectory — trajectory","text":"method initialises trajectory object, comprises chain activities can attached generator. See complete list available activities category.","code":""},{"path":"https://r-simmer.org/reference/trajectory.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a Trajectory — trajectory","text":"","code":"trajectory(name = \"anonymous\", verbose = FALSE)"},{"path":"https://r-simmer.org/reference/trajectory.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a Trajectory — trajectory","text":"name name trajectory. verbose enable showing additional information.","code":""},{"path":"https://r-simmer.org/reference/trajectory.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a Trajectory — trajectory","text":"Returns environment represents trajectory.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/trajectory.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a Trajectory — trajectory","text":"","code":"## create an empty trajectory x <- trajectory(\"my trajectory\") x #> trajectory: my trajectory, 0 activities ## add some activities by chaining them x <- x %>% log_(\"here I am!\") %>% timeout(5) %>% log_(\"leaving!\") x #> trajectory: my trajectory, 3 activities #> { Activity: Log | message: here I am!, level: 0 } #> { Activity: Timeout | delay: 5 } #> { Activity: Log | message: leaving!, level: 0 } ## join trajectories x <- join(x, x) ## extract and replace x[c(3, 4)] <- x[2] x #> trajectory: my trajectory, 6 activities #> { Activity: Log | message: here I am!, level: 0 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 5 } #> { Activity: Timeout | delay: 5 } #> { Activity: Log | message: leaving!, level: 0 }"},{"path":"https://r-simmer.org/reference/wrap.html","id":null,"dir":"Reference","previous_headings":"","what":"Wrap a Simulation Environment — wrap","title":"Wrap a Simulation Environment — wrap","text":"function extracts monitored data simulation environment making accessible methods. useful want parallelize heavy replicas (see example ), C++ simulation backend destroyed threads exit.","code":""},{"path":"https://r-simmer.org/reference/wrap.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Wrap a Simulation Environment — wrap","text":"","code":"wrap(.env)"},{"path":"https://r-simmer.org/reference/wrap.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Wrap a Simulation Environment — wrap","text":".env simulation environment.","code":""},{"path":"https://r-simmer.org/reference/wrap.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Wrap a Simulation Environment — wrap","text":"Returns simulation wrapper.","code":""},{"path":[]},{"path":"https://r-simmer.org/reference/wrap.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Wrap a Simulation Environment — wrap","text":"","code":"if (FALSE) { # \\dontrun{ library(parallel) mm1 <- trajectory() %>% seize(\"server\", 1) %>% timeout(function() rexp(1, 2)) %>% release(\"server\", 1) envs <- mclapply(1:4, function(i) { simmer(\"M/M/1 example\") %>% add_resource(\"server\", 1) %>% add_generator(\"customer\", mm1, function() rexp(1, 1)) %>% run(100) %>% wrap() }) } # }"},{"path":"https://r-simmer.org/news/index.html","id":"simmer-447","dir":"Changelog","previous_headings":"","what":"simmer 4.4.7","title":"simmer 4.4.7","text":"CRAN release: 2024-09-27","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-4-7","dir":"Changelog","previous_headings":"","what":"New features","title":"simmer 4.4.7","text":"Add support subsetting activity tag (#305). New getter get_start_time() returns running arrival’s start time (#304).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-7","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes","title":"simmer 4.4.7","text":"Fix set_source() avoid leaking arrivals old source (#322). Fix sources properly reset distributions trajectories (#324). Fix resources properly reset initial parameters (#325). Fix start time arrivals cloned batches (#285).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-4464","dir":"Changelog","previous_headings":"","what":"simmer 4.4.6.4","title":"simmer 4.4.6.4","text":"CRAN release: 2024-07-05","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-4-6-4","dir":"Changelog","previous_headings":"","what":"New features","title":"simmer 4.4.6.4","text":"Add support activity tags via tag argument (part #287). Add support named rollbacks via tags. amount argument deprecated favor generic name target. former still work, raises warning (#287 addressing #197). Switch C++17, drop Boost usage (#297).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-6-4","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes","title":"simmer 4.4.6.4","text":"Fix call identification error (#286). Make tests less verbose default. Fix deprecated functionality vignette. Fix vignette feed character input numeric_version. Fixes Apple Clang 10. Fix format-security warning. Fix pandoc error JSS vignette.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-445","dir":"Changelog","previous_headings":"","what":"simmer 4.4.5","title":"simmer 4.4.5","text":"CRAN release: 2022-06-25","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-4-5","dir":"Changelog","previous_headings":"","what":"New features","title":"simmer 4.4.5","text":"Add arithmetic support schedule objects (#272). New get_batch_size() getter allows batch retrieve size (#263). New get_activity_time() get_activity_time_selected() getters allow arrival retrieve amount activity time spent resources (#186).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-5","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes","title":"simmer 4.4.5","text":"Apply magrittr workaround avoid copying simmer monitor objects function environments generators (#279). Fix file removal object destruction file-backed monitors (#277). Remove cap number nested branches trajectory printing (#262). Fix duplicate time-based batch trigger (part #263). Fix typo trajectory bank vignettes (#283). Fix clone synchronization wait=FALSE, .e., arrivals don’t need trigger synchronize() activity sync (#275).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-444","dir":"Changelog","previous_headings":"","what":"simmer 4.4.4","title":"simmer 4.4.4","text":"CRAN release: 2022-02-07","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-4","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes","title":"simmer 4.4.4","text":"Fix memory issues (“previously seized” error) reneging multiple resources (#268). Use ‘given’ instead ‘middle’ CITATION (#273).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-443","dir":"Changelog","previous_headings":"","what":"simmer 4.4.3","title":"simmer 4.4.3","text":"CRAN release: 2021-08-11","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-4-3","dir":"Changelog","previous_headings":"","what":"New features","title":"simmer 4.4.3","text":"Add support functions when_activated() (#250). Add support dynamic batch sizes (#258 addressing #245).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-3","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes","title":"simmer 4.4.3","text":"Fix multiple reporting ongoing arrivals (#240). Set package namespace parent simmer wrap environments (#241). Fix arrival restart queue drops (#257). Fix segfault printing activities empty vectors (#253). Fix source behaviour missing values, now stop arrival generation way negative values (#256). Fix deactivate(), now unschedules future arrivals (#249).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-442","dir":"Changelog","previous_headings":"","what":"simmer 4.4.2","title":"simmer 4.4.2","text":"CRAN release: 2020-06-06","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-2","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes","title":"simmer 4.4.2","text":"Fix memory issues trap(), synchronize() rollback(). stateful activities require storing information passing arrivals manage clones redirections. activities properly cleaning storage arrivals rejected point trajectory. result, certain simulations activities involved may show random improper behaviour depending memory reuse happens. patch unifies storage management stateful activities, adds new interface register activities another interface arrivals notify termination, stored information properly cleaned (#231). Fix state sharing round-robin policy operation select() (#233).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-441","dir":"Changelog","previous_headings":"","what":"simmer 4.4.1","title":"simmer 4.4.1","text":"CRAN release: 2020-04-11","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes","title":"simmer 4.4.1","text":"Fix pause status reneging arrivals kicked resource queue (#228 addressing #227). Set minimum execution priority timeout() activity. makes possible set null timeout next event processed last place several events happen time (#229). Extend Queueing Systems vignette section custom service policies (part #229).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-440","dir":"Changelog","previous_headings":"","what":"simmer 4.4.0","title":"simmer 4.4.0","text":"CRAN release: 2019-12-09","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-4-0","dir":"Changelog","previous_headings":"","what":"New features","title":"simmer 4.4.0","text":"Add keep_seized parameters leave() behaviour renege_in() renege_if(). Code documentation functions now integrated help(renege) (#208, #217). Convenience functions , from_to accept dynamic parameters arguments start_time, stop_time every (#219). Activities interact sources vectorised modify multiple sources (#222). Several generators resources parameters can added single call add_generator() add_resource() respectively vector names provided (#221).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-4-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.4.0","text":"Fix get_mon_*() dispatch named lists (#210). Get/put RNG state random numbers required backend (#218). Fix convenience functions , from_to preserve environment supplied functions (part #219). Documentation improvements (#212, #220). Fix queueing multiple resources preemption (#224 addressing #206).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-430","dir":"Changelog","previous_headings":"","what":"simmer 4.3.0","title":"simmer 4.3.0","text":"CRAN release: 2019-07-30","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-3-0","dir":"Changelog","previous_headings":"","what":"New features","title":"simmer 4.3.0","text":"Add ability keep_seized resources reneging (#204 addressing #200). Add ability define range arrival priorities allowed access resource’s queue room server (#205 addressing #202).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-3-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.3.0","text":"Drop R6 dependency (#193 addressing #190). Small fix from_to + documentation update (75a9569). Move activity usage examples help pages (#194). Fix shortest-queue selection policies (#196). Fix batch triggering (#203). Update JSS paper, CITATION, references DOI.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-422","dir":"Changelog","previous_headings":"","what":"simmer 4.2.2","title":"simmer 4.2.2","text":"CRAN release: 2019-03-14","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-2-2","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.2.2","text":"Fix batches infinite timeout (#184). Fix preemption arrivals previously stopped signal (#187). Fix handler loop two consecutive signals (#188). Fix incorrect handler linking (#189).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-421","dir":"Changelog","previous_headings":"","what":"simmer 4.2.1","title":"simmer 4.2.1","text":"CRAN release: 2019-01-09","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-2-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.2.1","text":"Fix memtest notes CRAN (e741686).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-420","dir":"Changelog","previous_headings":"","what":"simmer 4.2.0","title":"simmer 4.2.0","text":"CRAN release: 2019-01-09","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-2-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 4.2.0","text":"New handle_unfinished() activity sets drop-trajectory unfinished arrivals, .e., dropped resource (due preemption, resource shrinkage rejected seize) leave trajectory (#178 addressing #177). New release_all() release_selected_all() activities automatically retrieve amount resources seized release (#180 addressing #25). New get_seized() get_seized_selected() getters allow arrival retrieve amount resources seized (#180 addressing #179). New stop_if() activity sets conditional breakpoint (#181 addressing #100).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-2-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.2.0","text":"Fix performance issues data sources (#176). Update CITATION. Fix monitored activity preempted arrivals (part #178). Fix seizes/releases null amount (part #180). Rename internal status codes (part #181). Provide context error warning (part #181). Extend Queueing Systems vignette section state-dependent service rates. Fix performance issues getters (#183).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-410","dir":"Changelog","previous_headings":"","what":"simmer 4.1.0","title":"simmer 4.1.0","text":"CRAN release: 2018-11-09","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-1-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 4.1.0","text":"New getter get_selected() retrieves names selected resources via select() activity (#172 addressing #171). Source resource getters vectorised retrieve parameters multiple entities (part #172). Simplify C++ Simulator interface adding processes resources (#162). responsibility building objects moved caller. New add_global() method attach global attributes simulation environment (#174 addressing #158).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-1-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.1.0","text":"Remove 3.8.0 4.0.1 deprecations (#170 addressing #165). Fix get_global() work outside trajectories (#170 addressing #165). Fix rollback() infinite amount (#173). Fix improve schedules managers (part #174). Fix reset() avoid overwriting simulation environment (#175).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-401","dir":"Changelog","previous_headings":"","what":"simmer 4.0.1","title":"simmer 4.0.1","text":"CRAN release: 2018-09-10","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-0-1","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 4.0.1","text":"get_sources() get_resources() retrieve character vector source/resource names defined simulation environment. get_trajectory() retrieves trajectory given source attached. New resource selection policies: shortest-queue-available, round-robin-available, random-available (#156). existing non-available ones, exclude unavailable resources (capacity set zero). Thus, resources unavailable, error raised.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-0-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.0.1","text":"Rename -DRCPP_PROTECTED_EVAL (Rcpp >= 0.12.17.4) -DRCPP_USE_UNWIND_PROTECT (6d27671). Keep compilation quieter -DBOOST_NO_AUTO_PTR (70328b6). Improve log_ print (7c2e3b1). Add when_activated() convenience function easily generate arrivals demand trajectories (#161 closing #160). Enhance schedule printing (9c66285). Fix generator-manager name clashing (#163). Deprecate set_attribute(global=TRUE), get_attribute(global=TRUE) timeout_from_attribute(global=TRUE) (#164), *_global versions used instead.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-400","dir":"Changelog","previous_headings":"","what":"simmer 4.0.0","title":"simmer 4.0.0","text":"CRAN release: 2018-07-20 simmer license changed GPL >= 2.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-4-0-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 4.0.0","text":"C++ core refactorised header-library inst/include (#147 closing #145). Therefore, now possible extend C++ API another package listing simmer LinkingTo field DESCRIPTION file. New generic monitor constructor enables development new monitoring backends packages (179f656, part #147). New simulation-scoped logging levels. log_ activity new argument level determines whether message printed depending global log_level defined simmer constructor (#152). set_attribute set_global gain new argument automatically initialise new attributes (#157). Useful update counters indexes single line, without initialisation boilerplate.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-4-0-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 4.0.0","text":"Enhanced exception handling, informative error messages (#148). Refactorisation printing methods associated code (#149). Allow empty trajectories sources activities sub-trajectories (#151 closing #150). Enable -DRCPP_PROTECTED_EVAL (Rcpp >= 0.12.17.3), provides fast evaluation R expressions leveraging new stack unwinding protection API (R >= 3.5.0). Replace backspace usage vector’s ostream method (2b2f43e). Fix namespace clashes rlang purrr (#154).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-380","dir":"Changelog","previous_headings":"","what":"simmer 3.8.0","title":"simmer 3.8.0","text":"CRAN release: 2018-05-01","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-8-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.8.0","text":"New data source add_dataframe enables attachment precomputed data, form data frame, trajectory. can used instead (along ) add_generator. notable advantage latter add_dataframe able automatically set attributes prioritisation values per arrival based columns provided data frame (#140 closing #123). New set_source activity deprecates set_distribution(). works generators data sources (275a09c, part #140). New monitoring interface allows disk offloading. simmer() constructor gains new argument mon provide different types monitors. default, monitoring performed -memory, usual. Additionally, monitoring can offloaded disk monitor_delim monitor_csv, produce flat delimited files. importantly, C++ interface refactorised enable development new monitoring backends (#146 closing #119).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-8-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.8.0","text":"documentation improvements (1e14ed7, 194ed05). New default =Inf run method (3e6aae9, part #140). branch clone now accept lists trajectories, way join, need use .call (#142). argument continue (present seize branch) recycled one value provided several sub-trajectories defined (#143). Fix process reset: sources reset strict order creation (e7d909b). Fix infinite timeouts (#144).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-370","dir":"Changelog","previous_headings":"","what":"simmer 3.7.0","title":"simmer 3.7.0","text":"CRAN release: 2018-03-03","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-7-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.7.0","text":"New timeout_from_attribute() activity makes easier set timeout based attribute (#129). activities set_attribute(), set_prioritization(), set_capacity() set_queue_size() get new argument mod , set \"+\" \"*\", modifies corresponding value instead substituting . makes easier increment, decrement scale one values (#130). New *_selected() versions already available resource getters: get_capacity(), get_queue seize(), get_server_count() get_queue_count() (#134).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-7-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.7.0","text":"Broadcast signals higher priority prevent arrival catch signal trap() send() (#135). Generate new arrivals minimum priority avoid wrong interactions simultaneous activities (#136). Remove v3.6.x deprecations: old attribute retrieval system (see notes v3.6.3), well methods create_trajectory() onestep() (#117). Remove get_mon_resources()’s data argument. historical reasons probably nobody using (851d34b). New vignette, “simmer: Discrete-Event Simuation R”, paper accepted publication Journal Statistical Software. Remove “Terminology” vignette (#127). New vignette, “Design Analysis 5G Scenarios”, supplementary materials paper accepted publication IEEE Communications Magazine (#137).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-365","dir":"Changelog","previous_headings":"","what":"simmer 3.6.5","title":"simmer 3.6.5","text":"CRAN release: 2018-01-04","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-6-5","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.6.5","text":"set_attribute() (set_global() extension) can set multiple attributes providing vectors keys values (functions returning keys /values). get_attribute() (get_global() extension) can retrieve multiple keys (#122). New stepn() method deprecates onestep() (e452975).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-6-5","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.6.5","text":"Restore ostream formatting (9ff11f8). Fix arrival cloning copy attributes clone (#118). Fix self-induced preemption set_capacity() (#125). Update “Queueing Systems” vignette (a0409a0, 8f03f4f). Update “Advanced Trajectory Usage” vignette (4501927). Fix print methods return object invisibly (#128). New “Dining Philosophers Problem” vignette (ff6137e).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-364","dir":"Changelog","previous_headings":"","what":"simmer 3.6.4","title":"simmer 3.6.4","text":"CRAN release: 2017-11-04","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-6-4","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.6.4","text":"Fix preemption non-saturated multi-server resources seizing amounts > 1 (#114). Fix queue priority non-saturated finite-queue resources seizing amounts > 1 (#115). Fix resource seizing: avoid jumping queue room server arrivals waiting (#116).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-363","dir":"Changelog","previous_headings":"","what":"simmer 3.6.3","title":"simmer 3.6.3","text":"CRAN release: 2017-07-28","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-6-3","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.6.3","text":"Show simulation progress via optional progress callback run() (#103). New “Bank Tutorial: Part II” vignette, Duncan Garmonsway @nacnudus (#106). get_name() retrieves arrival name. get_attribute() retrieves attribute name. old method retrieving providing function one argument deprecated favour get_attribute(), removed version 3.7.x. get_prioritization() retrieves three prioritization values (priority, preemptible, restart) active arrival. New shortcuts global attributes (#110): set_global() get_global(), equivalent set_attribute(global=TRUE) get_attribute(global=TRUE) respectively.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-6-3","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.6.3","text":"code refactoring performance improvements (2f4b484, ffafe1e, f16912a, fb7941b, 2783cd8). Use Rcpp::DataFrame instead Rcpp::List (#104). Improve argument parsing error messages (#107). Improve internal function make_resetable() (c596f73).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-362","dir":"Changelog","previous_headings":"","what":"simmer 3.6.2","title":"simmer 3.6.2","text":"CRAN release: 2017-05-30","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-6-2","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.6.2","text":"Update “Bank Tutorial: Part ” vignette (@nacnudus #90). Fix trap()’s handler cloning associated test (#91). Apply select()’s policy also resources function (#92). Accept dynamic timeouts batches (#93). Change rollback()’s default behaviour times=Inf, .e., infinite loop (#95). Stop throw error timeout() returns missing value (#96 #97). Fix memory management: resetting environment clearing deallocating memory (#98, fixed #99). Fix object destruction: workaround tidyverse/magrittr#146 (#98, fixed effcb6b).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-361","dir":"Changelog","previous_headings":"","what":"simmer 3.6.1","title":"simmer 3.6.1","text":"CRAN release: 2017-03-30","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-6-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.6.1","text":"Recycle logical indexes subsetting (2526e75). Implement replacement operators, [<- [[<- (#88). Provide rep() S3 method trajectories (7fa515e). Remove plotting functions (bb9656b), deprecated since v3.6.0. new simmer.plot package (CRAN) already covers features among others. Don’t evaluate vignette chunks Suggests installed (e40e5b6). Rewrite DESCRIPTION (3f26516). Add every parameter from_to() convenience function (9d68887).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-360","dir":"Changelog","previous_headings":"","what":"simmer 3.6.0","title":"simmer 3.6.0","text":"CRAN release: 2016-12-28","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-6-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.6.0","text":"New subsetting operators, [ [[, trajectories (1847898). Think trajectories lists activities operators (almost) everything expect. side effect, generics head() tail() automatically work trajectories also expected. New length() method obtain number first-level activities trajectory (f86375a). Useful combination subsetting operators.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-6-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.6.0","text":"create_trajectory() deprecated favor trajectory() (76c1317). plot_resource_usage(), plot_resource_utilization(), plot_evolution_arrival_times() plot_attributes() deprecated removed next release order minimise dependencies (5b43f2b). plan release new package CRAN covering features new ones. methods now S3 methods, nice intelligible error displayed apply method wrong object (e891045). activity management -related stuff removed, .e, get_head(), get_tail(), print_activity(), get_next_activity(), get_prev_activity() (f86375a). methods useful development purposes nobody using . never good idea directly expose external pointers. Clone trajectories passing C++ core (f655cae). Update “Advanced Trajectory Usage” vignette. Update “Queueing Systems” vignette.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-351","dir":"Changelog","previous_headings":"","what":"simmer 3.5.1","title":"simmer 3.5.1","text":"CRAN release: 2016-11-26","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-5-1","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.5.1","text":"New renege_if() activity triggers reneging upon reception signal broadcasted send() (#84). Add support uninterruptible handlers trap() (bb2aa46). Add support global attributes set_attribute() (#82).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-5-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.5.1","text":"Fix bug set_queue_size() queue_size_strict=TRUE: arrivals dropped (#83). Fix bug set_capacity() preemptive resource old value Inf: arrivals preempted (63beb2c). Fix bug per-resource activity monitoring: activity reset (55097c9). Fix trap() printed information. Update “Advanced Trajectory Usage” vignette. New “SimPy Examples” vignette.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-350","dir":"Changelog","previous_headings":"","what":"simmer 3.5.0","title":"simmer 3.5.0","text":"CRAN release: 2016-10-27","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-5-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.5.0","text":"set_capacity() set_queue_size() become activities (#77). Just like seize() release(), associated set_capacity_selected() set_queue_size_selected() joint use together select(). New activate() deactivate() activities allow arrival start stop generator, respectively, inside trajectory (#80). New set_trajectory() set_distribution() activities allow arrival install new trajectory distribution, respectively, generator inside trajectory (#80). Refactorised improved arrival monitoring. New interarrival communication activities allowing asynchronous programming: send(), trap(), untrap() wait() can used send signals, wait signals, trap launch asynchronous handlers. New log_() activity simply prints messages debugging purposes (eaa4554).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-5-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.5.0","text":"Store inline trajectory objects inside simulation environment prevent garbage-collected. Update “Advanced Trajectory Usage” vignette.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-344","dir":"Changelog","previous_headings":"","what":"simmer 3.4.4","title":"simmer 3.4.4","text":"CRAN release: 2016-10-06","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-4-4","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.4.4","text":"Fix non-defined behaviour caused race condition object destruction platforms.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-343","dir":"Changelog","previous_headings":"","what":"simmer 3.4.3","title":"simmer 3.4.3","text":"CRAN release: 2016-10-02","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-4-3","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.4.3","text":"Remove warnings unused arguments seize() seize_selected() (1c8c3bb). Fix crash arrival reneging non-triggered batches (8713d95). Fix crash batches triggered timer expires (8713d95). Fix crash non-released preemptive resources capacity decreases (#75). Leaving without releasing resource throws warning (#76).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-342","dir":"Changelog","previous_headings":"","what":"simmer 3.4.2","title":"simmer 3.4.2","text":"CRAN release: 2016-09-03","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-4-2","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.4.2","text":"Ongoing (unfinished) arrivals reported get_mon_arrivals(ongoing = TRUE) (#73).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-4-2","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.4.2","text":"Simplify Rcpp glue: remove unnecessary <>() calls (ec4e51a). Simplify trajectory’s head/tail management (06432a8). Now, run() runs simulation exactly , instead first event scheduled time >= (e7264f6). Fix batch cloning (c20bc1d). Coverage improved.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-341","dir":"Changelog","previous_headings":"","what":"simmer 3.4.1","title":"simmer 3.4.1","text":"CRAN release: 2016-08-11","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-4-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.4.1","text":"Fix memtest notes CRAN (heap-use--free). Fix memory leaks.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-340","dir":"Changelog","previous_headings":"","what":"simmer 3.4.0","title":"simmer 3.4.0","text":"CRAN release: 2016-08-09","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-4-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.4.0","text":"Prioritization (priority, preemptible, restart) moved seize() add_generator() (#69). leads natural interpretation prioritization values attributes arrivals generator, rather attributes seize(). Still, prioritization values can redefined dynamically inside trajectory new activity set_prioritization(). New optional post.seize reject sub-trajectories seize() seize_selected() (#49). feature allows us fine-tune happens arrival seize resource: instead getting dropped, may execute given sub-trajectory. New clone() synchronize() activities (#71). clone() implements workflow pattern entity processed multiple parallel threads. user can define different sub-trajectory clone. synchronize(), multiple parallel clones converge synchronized: one continues (first last arrive), others removed. New batch() separate() activities (#45). can used implement rollercoaster process: batch() collects number arrivals can continue processing block, separate() splits previousl established batch. New renege_in() renege_abort() activities (#58). can used set unset timer arrival abandon.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-4-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.4.0","text":"branch()’s option returns 0, arrival skips branch() continues next activity instead throwing index range error (#70). Throw errors incorrect releases (#72). Remove deprecated convenience function every() (#65) branch()’s deprecated argument merge (#57). New “Bank Tutorial: Part ” vignette, Duncan Garmonsway @nacnudus (#68). Update “Advanced Trajectory Usage” vignette.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-330","dir":"Changelog","previous_headings":"","what":"simmer 3.3.0","title":"simmer 3.3.0","text":"CRAN release: 2016-06-28","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-3-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.3.0","text":"New join() activity concatenate trajectories (#50). Batched generation: generation function can return one interarrival value time (#65). Add option queue_size_strict add_resource() guarantee queue size limit preemption (#59). New select(), seize_selected() release_selected() activities (#52). Modify resources (capacity, queue size) inside trajectory (#66). New leave() activity (#63).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"major-fixes-3-3-0","dir":"Changelog","previous_headings":"","what":"Major fixes:","title":"simmer 3.3.0","text":"Fix per-resource activity time monitoring (#67). problem emerged arrival revisited resource enqueued. uninitialised variable lead activity time greater end_time - start_time. versions 3.2.x affected bug.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-3-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.3.0","text":"Fix description preemptible documentation seize() force preemptible equal greater priority (#53). Reset finite generators (#51). Fix handling capacity change new value infinite (#60). Various doc fixes (#61). Change branch()’s merge parameter name continue. old name deprecated (#57). Use match.arg() multiple-choice arguments (#55). Fix branch() backwards linking count (#56). Split release() two steps deal properly capacity changes point time (#64). convenience function every() deprecated due #65. Update extend previous vignettes.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-321","dir":"Changelog","previous_headings":"","what":"simmer 3.2.1","title":"simmer 3.2.1","text":"CRAN release: 2016-04-29","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-2-1","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.2.1","text":"Add time-specific resource availability support (#21). resources’ capacity queue_size can change time following user-defined scheduling, can generated new function schedule(). Advanced peek: inspect number future events event queue (8147820). details, see ?peek.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-2-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.2.1","text":"Fix steps grouping plot_resource_usage() (8da9b97). Fix incorrect trajectory behaviour rejection occurs inside branch merge=TRUE (#46). Fix couple segmentation faults preemptive resources (f64f6b2). Improve verbose output (9013db0). New multiset-based event queue unscheduling capabilities (a615fea d6a9d67). simulation may run forever (user interrupts ), , =Inf allowed now (f47baa9). New vignette queueing systems. New vignette Continuous-Time Markov Chains. Update extend previous vignettes.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-320","dir":"Changelog","previous_headings":"","what":"simmer 3.2.0","title":"simmer 3.2.0","text":"CRAN release: 2016-04-04","code":""},{"path":"https://r-simmer.org/news/index.html","id":"major-fix-3-2-0","dir":"Changelog","previous_headings":"","what":"Major fix:","title":"simmer 3.2.0","text":"previous versions, resources monitored performing corresponding seize/release activity, changing status system. Thus, t=3, queue=2 meant , t=3, queue 2 customers, t=3 system changed (new arrival new departure). idea keep values time vectors aligned (see #28). moment , resources monitored changing status system. consistent user expect, consistent behaviour related R functions (e.g., see stepfun(), stats package). Wrapping now , t=3, queue=2 means event happened t=3 whose immediate subsequent result queue 2 customers.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-2-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.2.0","text":"priority: already present previous versions. preemptible: another seize() priority value greater may preempt present seize(). restart: whether current task (timeout() activity, instance) restarted arrival preempted.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-2-0","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.2.0","text":"Remove deprecated functions show_activity() show_trajectory(). Add every(), () from_to() convenience functions (8e524cd). Fix colour scale plot_resource_usage() (6b034a7). Fix compatibility upcoming version testthat (#41). branch() activity now provides attributes option function, activities (#42). Implement error handling plot_*() functions (#44).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-312","dir":"Changelog","previous_headings":"","what":"simmer 3.1.2","title":"simmer 3.1.2","text":"CRAN release: 2016-01-04","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-1-2","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.1.2","text":"Monitor arrivals’ start/activity/end times per-resource basis (#38). far, function get_mon_arrivals() returned start/activity/end times per arrival whole trajectory. behaviour remains, additionally, get_mon_arrivals(per_resource = TRUE) returns times per resource, possible retrieve queueing/system times per resource.","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-1-2","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.1.2","text":"Fix testing ERRORs reported platforms using clang Sparc Solaris. get_mon_*() functions accept single simulation environment well list environments representing several replications (5ee2725). new column (replication) resulting data frame indicates corresponding replication number. Monitoring subsystem refactored (consequence #38).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-311","dir":"Changelog","previous_headings":"","what":"simmer 3.1.1","title":"simmer 3.1.1","text":"CRAN release: 2015-12-16","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-1-1","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.1.1","text":"Add attributes arrivals new set_attribute() activity (#16). New rollback() activity (#17 #22). Add priorities resources’ queue (#20).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-1-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.1.1","text":"Performance improvements Boost (1b654fd). Fix arrivals’ timing issues (#24). Nicer object printing (#26). Return self visibly, instead invisibly (#35). Add () () convenience functions (29cccd2 7cfdd90). work vignettes (#29). Fix ggplot2 2.0.0 compatibility issues (#37).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-301","dir":"Changelog","previous_headings":"","what":"simmer 3.0.1","title":"simmer 3.0.1","text":"CRAN release: 2015-11-17","code":""},{"path":"https://r-simmer.org/news/index.html","id":"minor-changes-and-fixes-3-0-1","dir":"Changelog","previous_headings":"","what":"Minor changes and fixes:","title":"simmer 3.0.1","text":"Complete test coverage (#12). Minor fix documentation (42363d2). Set finalizer simulator object (#14). Fix test errors Windows r-oldrelease (#15).","code":""},{"path":"https://r-simmer.org/news/index.html","id":"simmer-300","dir":"Changelog","previous_headings":"","what":"simmer 3.0.0","title":"simmer 3.0.0","text":"CRAN release: 2015-11-15","code":""},{"path":"https://r-simmer.org/news/index.html","id":"new-features-3-0-0","dir":"Changelog","previous_headings":"","what":"New features:","title":"simmer 3.0.0","text":"First major release submitted CRAN. philosophy workflow pre-release remain robust event-based C++ backend flexible frontend. Enhanced programmability. timeout activity just delay. admits user-defined function, can complex needed order interact simulation model. old v2.0 queueing network simulator. feature makes simmer flexible generic DES framework. Moreover, finally got rid infamous add_skip_event() function implement flexible user-friendly branching method. Robustness. event-based core design rigorous simple, makes simmer faster less error-prone, level state---art DES frameworks. Much better performance. Instead creating n arrivals beforehand, release leverages concept generator arrivals, faster flexible. time, concept trajectory chain activities implemented entirely C++ internally. tests show simmer even faster SimPy comes simulate queueing networks. Replication. pre-release, replication implemented inside simmer. longer makes sense since, current design, straightforward replicate even parallelize execution replicas using standard R tools.","code":""}]