r-simmer / simmer

Discrete-Event Simulation for R
https://r-simmer.org
GNU General Public License v2.0
220 stars 42 forks source link

Branch is not repeated after "self join" #238

Closed DannyO-dev closed 3 years ago

DannyO-dev commented 3 years ago

Hello again, I have another question: Why is my branch in this case is not repeated?

library(simmer)
set.seed(123)

controller <- trajectory("Test Path")

elevator <- simmer()

controller <- controller %>%
  log_("Enter trajectory") %>%
  timeout(1) %>%

  branch(
    function() 1 > 0, continue = TRUE,
    trajectory() %>%
      log_("Enter branch") %>%
      join(controller),

    trajectory() %>%
      log_("DUMMY for branch")) %>%

  log_("Leave trajectory")

elevator <-
  simmer("elevator") %>%
  add_generator("Controller_", controller, at(0))

elevator %>% run(until = 10)
0: Controller_0: Enter trajectory
1: Controller_0: Enter branch
1: Controller_0: Enter trajectory

Thank you in advance and best regards.

Enchufa2 commented 3 years ago

Short answer: just don't reference trajectories recursively. Trajectories are built sequentially. If you do that, wherever you insert the join, you are referencing an object that is being built, and copying that intermediate state, so that's not a good idea.

DannyO-dev commented 3 years ago

OK all right. I am looking for a way to call up a trajectory more than once. What would be the right way to do this? I could for example do it like this:

library(simmer)
set.seed(123)

drive <- trajectory("Test Path")
controller <- trajectory("Controller")

elevator <- simmer()

drive <- drive %>%
  log_("Enter trajectory") %>%
  timeout(1) %>%

  branch(
    function() 1 > 0, continue = TRUE,
    trajectory() %>%
      log_(function() {
        paste("Enter branch")
      }),

    trajectory() %>%
      log_("DUMMY for branch")) %>%

  log_("Leave trajectory")

controller <- controller %>%
  branch(
    function() 1 > 0, continue = TRUE,
    trajectory() %>%
      log_(function() {
        paste("Restart branch")
      }) %>%
      join(drive),

    trajectory() %>%
      log_("DUMMY for branch")) %>%
  rollback(1)

elevator <-
  simmer("elevator") %>%
  add_generator("Controller", controller, at(0))

elevator %>% run(until = 10)

Than I would need the branch a second time. Thank you in advance and best regrads

Enchufa2 commented 3 years ago

If you want to repeat something, that's a loop, and there's a mechanism for that which doesn't involve recursion: rollback().