simmer 4.4.0 on CRAN

The 4.4.0 release of simmer, the Discrete-Event Simulator for R, is on CRAN. This update stabilises a new pace of a couple of new releases per year, which is more appropriate given the maturity that the project has reached.

This release brings us a dozen bug fixes and improvements, including the unification of the leave/renege API, further enhancements of convenience function to set up generators, and performance improvements for the simulation environment definition thanks to the vectorisation of add_resource and add_generator. See below for a complete list of changes.

New features

  • Add out and keep_seized parameters to leave() with the same behaviour as in renege_in() and renege_if(). Code and documentation of these functions are now integrated under help(renege) (#208, #217).
  • Convenience functions fromto and from_to accept dynamic parameters for arguments start_timestop_time and every (#219).
  • Activities to interact with sources have been vectorised to modify multiple sources at once (#222).
  • Several generators or resources with the same parameters can be added with a single call to add_generator() and add_resource() respectively if a vector of names is provided (#221).

Minor changes and fixes:

  • Fix get_mon_*() dispatch for named lists (#210).
  • Get/put the RNG state when random numbers are required in the backend (#218).
  • Fix convenience functions fromto and from_to to preserve the environment of the supplied functions (as part of #219).
  • Documentation improvements (#212, #220).
  • Fix queueing in multiple resources after preemption (#224 addressing #206).

simmer 4.3.0 + JSS publication

The 4.3.0 release of simmer, the Discrete-Event Simulator for R, is on CRAN. Along with this update, we are very glad to announce that our homonymous paper finally appeared in the Journal of Statistical Software. Please, use the following reference for citations (see citation("simmer")):

  • Ucar I, Smeets B, Azcorra A (2019). “simmer: Discrete-Event Simulation for R.” Journal of Statistical Software90(2), 1-30. doi: 10.18637/jss.v090.i02 (URL: https://doi.org/10.18637/jss.v090.i02).

It took quite a lot of work and time, but we are very proud of the final result. We would like to thank the editorial team for their hard work, with special thanks to the anonymous referee for their thorough reviews and valuable comments, and Norman Matloff for his advice and support. Last but not least, we are very grateful for all the discussion and fruitful ideas that our growing community provides via the simmer-devel mailing list and GitHub.

The new release bring us the ability to keep seized resources after reneging, as well as to define a range of arrival priorities that are allowed to access a resource’s queue if there is no room in the server. We moved a lot of activity usage examples that were scattered in a far too long vignette to the appropriate help pages, and of course there is the usual share of bug fixes. See below for a complete list of changes.

Special thanks to Tom Lawton for his contributions to this release, and to Benjamin Sawicki for his generous donation.

New features

  • Add ability to keep_seized resources after reneging (#204 addressing #200).
  • Add ability to define a range of arrival priorities that are allowed to access a resource’s queue if there is no room in the server (#205 addressing #202).

Minor changes and fixes:

  • Drop R6 as a dependency (#193 addressing #190).
  • Small fix in from and from_to + documentation update (75a9569).
  • Move activity usage examples to help pages (#194).
  • Fix shortest-queue selection policies (#196).
  • Fix batch triggering (#203).
  • Update JSS paper, CITATION, references and DOI.

simmer 4.2.1

The 4.2.1 release of simmer, the Discrete-Event Simulator for R, is on CRAN with quite interesting new features and fixes. As discussed in the mailing list, there is a way to handle the specific case in which an arrival is rejected because a queue is full:

library(simmer)

reject <- trajectory() %>%
  log_("kicked off...")

patient <- trajectory() %>%
  seize("nurse", continue=FALSE, reject=reject) %>%
  log_("nurse seized") %>%
  timeout(5) %>%
  release("nurse") %>%
  log_("nurse released")

env <- simmer() %>%
  add_resource("nurse", 1, 0) %>%
  add_generator("patient", patient, at(0, 1)) %>%
  run()
## 0: patient0: nurse seized
## 1: patient1: kicked off...
## 5: patient0: nurse released

But as Tom Lawton pointed out, until now, there was no way of handling any alternative path for an arrival that was preempted and “kicked off” from a resource. This mechanism has been implemented into the new handle_unfinished() activity:

patient <- trajectory() %>%
  handle_unfinished(reject) %>%
  seize("nurse") %>%
  log_("nurse seized") %>%
  timeout(5) %>%
  release("nurse") %>%
  log_("nurse released")

env <- simmer() %>%
  add_resource("nurse", 1, 0, preemptive=TRUE, queue_size_strict=TRUE) %>%
  add_generator("LowPrio_patient", patient, at(0), priority=0) %>%
  add_generator("HighPrio_patient", patient, at(1), priority=10) %>%
  run()
## 0: LowPrio_patient0: nurse seized
## 1: HighPrio_patient0: nurse seized
## 1: LowPrio_patient0: kicked off...
## 6: HighPrio_patient0: nurse released

Note that such a mechanism is more general, because it also covers the first scenario:

env <- simmer() %>%
  add_resource("nurse", 1, 0) %>%
  add_generator("patient", patient, at(0, 1)) %>%
  run()
## 0: patient0: nurse seized
## 1: patient1: kicked off...
## 5: patient0: nurse released

Whenever rejection (or preemption) happens and it is catched by the appropriate handler, the new getter get_seized() may be useful to know which resource was abandoned.

Finally, the readership may find interesting the new section about the implementation of state-dependent service rates in the Queueing Systems vignette. See below for a complete list of changes.

New features:

  • New handle_unfinished() activity sets a drop-out trajectory for unfinished arrivals, i.e., those dropped from a resource (due to preemption, resource shrinkage or a rejected seize) or those that leave a trajectory (#178 addressing #177).
  • New release_all() and release_selected_all() activities automatically retrieve the amount of resources seized and release it (#180 addressing #25).
  • New get_seized() and get_seized_selected() getters allow an arrival to retrieve the amount of resources seized (#180 addressing #179).
  • New stop_if() activity sets a conditional breakpoint (#181 addressing #100).

Minor changes and fixes:

  • Fix performance issues in data sources (#176).
  • Update CITATION.
  • Fix monitored activity for preempted arrivals (as part of #178).
  • Fix seizes/releases with a null amount (as part of #180).
  • Rename internal status codes (as part of #181).
  • Provide more context on error or warning (as part of #181).
  • Extend the Queueing Systems vignette with a section about state-dependent service rates.
  • Fix performance issues in getters (#183).

simmer 4.1.0

The 4.1.0 release of simmer, the Discrete-Event Simulator for R, is on CRAN. As per request in the mailing list, now get_global() is able to work inside a generator function. Moreover, the new add_global() method attaches a global attribute to a simulator.

library(simmer)

env <- simmer()

hello_sayer <- trajectory() %>%
  log_("hello world!") %>%
  set_global("interarrival", 1, mod="+")

generator <- function() get_global(env, "interarrival")

env %>%
  add_global("interarrival", 1) %>%
  add_generator("dummy", hello_sayer, generator) %>%
  run(7) %>%
  get_global("interarrival")
## 1: dummy0: hello world!
## 3: dummy1: hello world!
## 6: dummy2: hello world!
## [1] 4

Compared to plain global variables, these ones are automatically managed and thus reinitialised if the environment is reset.

env %>%
  reset() %>%
  get_global("interarrival")
## [1] 1
env %>%
  run(7) %>%
  get_global("interarrival")
## 1: dummy0: hello world!
## 3: dummy1: hello world!
## 6: dummy2: hello world!
## [1] 4

There has been a small refactoring of some parts of the C++ core, which motivates the minor version bump, but this shouldn’t be noticeable to the users. Finally, several bug fixes and improvements complete this release. See below for a complete list.

New features:

  • New getter get_selected() retrieves names of selected resources via the select() activity (#172 addressing #171).
  • Source and resource getters have been vectorised to retrieve parameters from multiple entities (as part of #172).
  • Simplify C++ Simulator interface for adding processes and resources (#162). The responsibility of building the objects has been moved to the caller.
  • New add_global() method to attach global attributes to a simulation environment (#174 addressing #158).

Minor changes and fixes:

  • Remove 3.8.0 and 4.0.1 deprecations (#170 addressing #165).
  • Fix get_global() to work outside trajectories (#170 addressing #165).
  • Fix rollback() with an infinite amount (#173).
  • Fix and improve schedules and managers (as part of #174).
  • Fix reset() to avoid overwriting the simulation environment (#175).

simmer 4.0.1

The 4.0.1 release of simmer, the Discrete-Event Simulator for R, is on CRAN since a couple of weeks ago. There are few changes, notably new getters (get_sources()get_resources()get_trajectory()) for simmer environments and some improvements in resource selection policies (see details in help(select)).

A new convenience function, when_activated, makes it easier to generate arrivals on demand, triggered from trajectories. Let us consider, for instance, a simple restocking pattern:

library(simmer)

restock <- trajectory() %>%
  log_("restock")

serve <- trajectory() %>%
  log_("serve") %>%
  activate("Restock")

env <- simmer() %>%
  add_generator("Customer", serve, at(1, 2, 3)) %>%
  add_generator("Restock", restock, when_activated()) %>%
  run()
## 1: Customer0: serve
## 1: Restock0: restock
## 2: Customer1: serve
## 2: Restock1: restock
## 3: Customer2: serve
## 3: Restock2: restock

Finally, this release leverages the new fast evaluation framework offered by Rcpp (>= 0.12.18) by default, and includes some minor improvements and bug fixes.

New features:

  • New getters (#159):
    • get_sources() and get_resources() retrieve a character vector of source/resource names defined in a simulation environment.
    • get_trajectory() retrieves a trajectory to which a given source is attached.
  • New resource selection policies: shortest-queue-availableround-robin-availablerandom-available (#156). These are the same as the existing non-available ones, but they exclude unavailable resources (capacity set to zero). Thus, if all resources are unavailable, an error is raised.

Minor changes and fixes:

  • Rename -DRCPP_PROTECTED_EVAL (Rcpp >= 0.12.17.4) as -DRCPP_USE_UNWIND_PROTECT (6d27671).
  • Keep compilation quieter with -DBOOST_NO_AUTO_PTR (70328b6).
  • Improve log_ print (7c2e3b1).
  • Add when_activated() convenience function to easily generate arrivals on demand from trajectories (#161 closing #160).
  • Enhance schedule printing (9c66285).
  • Fix generator-manager name clashing (#163).
  • Deprecate set_attribute(global=TRUE)get_attribute(global=TRUE) and timeout_from_attribute(global=TRUE) (#164), the *_global versions should be used instead.