Dynamic cloning(?) to simultaneously seize multiple resources with different timeouts

21 views
Skip to first unread message

Philemon Cyclone

unread,
May 18, 2023, 9:42:05 PM5/18/23
to simmer-devel
I have a scenario in which an arrival must seize multiple resources simultaneously, with each resource seized for a different timeout. The logical approach seems to be to use clone(); however, the problem I have here is that the number and specific names of the resources are not known a priori - they depend on certain attributes of the arrival. 

If I have these resources stored as attributes of the arrival, is there some way for each clone to get a different attribute? For example, the following code sets the attributes to identify which resources are required by the arrival:

... |> 
simmer::set_attribute(
        keys = \() {
          # Get the number of resources required
          n_res <- simmer::get_attribute(env, 'res_count') |> 
            as.integer()
          # Dynamically generate the keys
          sprintf('resource_%d', seq.int(1, n_res))
        },
        values = \() {
          # step_index identifies the state of the arrival and the appropriate resources are retrieved from a lookup table, res_df
          step_index <- simmer::get_attribute(env, keys = 'step_index')
          avail_res <- get_valid_resources(step_index)

          # Get resource code(s) from lookup table to store in the attribute
          res_codes <- res_df |>
            dplyr::filter(EquipmentNbr %in% avail_res) |>
            dplyr::pull(EquipmentInt)

          res_codes
        }
      ) |>
    simmer::clone(n = \() simmer::get_attribute('res_count'), ...) |>
    simmer::synchronize() |> ...

I'm stuck on how to dynamically define the cloned trajectories. Although one thought I just had, which I will attempt tomorrow, is to define the list of clone trajectories within one of functions used in set_attribute() and super-assign that list via <<- (perhaps with a unique name so it does not get re-used by other arrivals running in other trajectories with similar structure). Could this be feasible, or is there a more straightforward alternative?

Thank you!

Iñaki Ucar

unread,
May 19, 2023, 6:56:50 AM5/19/23
to simmer...@googlegroups.com
What about setting a different index for each clone path that you could use as an offset?

library(simmer)

parallel_trajectories <- function(n=10) {
  trajs <- list()
  for (i in 1:n) {
    t <- trajectory() |> 
      set_attribute("traj_idx", i) |> 
      log_(\() paste0(get_attribute(env, c("res_count", "traj_idx")), collapse=", "))
    trajs <- c(trajs, t)
  }
  trajs
}

t <- trajectory() |> 
  set_attribute("res_count", 5) |> 
  clone(\() get_attribute(env, "res_count"), parallel_trajectories()) |> 
  synchronize()

env <- simmer()

env |> 
  add_generator("dummy", t, at(0)) |> 
  run() |> 
  invisible()
#> 0: dummy0: 5, 1
#> 0: dummy0: 5, 2
#> 0: dummy0: 5, 3
#> 0: dummy0: 5, 4
#> 0: dummy0: 5, 5

Iñaki

--
You received this message because you are subscribed to the Google Groups "simmer-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email to simmer-devel...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/simmer-devel/ea8ccaac-7750-4177-8bec-4cf994977d3cn%40googlegroups.com.


--
Iñaki Úcar

Philemon Cyclone

unread,
May 26, 2023, 11:36:26 AM5/26/23
to simmer-devel
Brilliant - thank you!
Reply all
Reply to author
Forward
0 new messages