call same function for different resources several times

50 views
Skip to first unread message

tor son

unread,
Jul 13, 2022, 9:22:51 AM7/13/22
to simmer-devel
Hi, I want to call a function for different resources (locations). I can create each time a trajectory by calling the fucntion as in the example below. is there an easier, automatic way to do it? is it possible to call the trajectory once, and fill it when activated first with "location1", the second time with "location2",... because I need this for many locations. Additionally, for each location a different duration should be provided. 

library(simmer)

start <- trajectory() %>%
  log_("start")%>%
  activate("activity1_1")

activity <- function (name, location, activate_next, duration) {
 
  name<-trajectory("name")%>%
   
    seize("resource", 1) %>%
    seize(location, 1) %>%
   
    timeout ( duration ) %>%
    log_("done") %>%
   
    release(location, 1)  %>%
    release("resource",1)   %>%  
   
    activate (activate_next)
 
}

activity2 <- function (name, location, activate_next, duration) {
 
  name<-trajectory("name")%>%
   
    seize("resource2", 1) %>%
    seize(location, 1) %>%
   
    timeout (duration) %>%
    log_("done") %>%
   
    release(location, 1)  %>%
    release("resource2",1)   %>%  
   
    activate (activate_next)
 
}

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


activity1_1 <- activity ("activity1_1", "location1", "activity2_1", 20)
activity2_1 <- activity2 ("activity2_1", "location1", "activity1_2",10)
activity1_2 <- activity ("activity1_2", "location2","activity2_2", 10)
activity2_2 <- activity2 ("activity2_2", "location2", "finish",5)

 
env <- simmer() %>%  
 
  add_generator("start", start, at (0)) %>%
  add_generator("activity1_1", activity1_1, when_activated()) %>%
  add_generator("activity2_1", activity2_1, when_activated()) %>%
  add_generator("activity1_2", activity1_2, when_activated()) %>%
  add_generator("activity2_2", activity2_2, when_activated()) %>%
  add_generator("finish", finish, when_activated()) %>%
 
  add_resource("resource", 1) %>%
  add_resource("resource2", 1) %>%
  add_resource("location1", 1) %>%
  add_resource("location2", 1)

   
   
run(env) %>%
    get_mon_arrivals()

Iñaki Ucar

unread,
Jul 13, 2022, 12:54:38 PM7/13/22
to simmer-devel
I would define a grid of cases, then loop over it. Example:

library(simmer)

start <- trajectory() %>%
  log_("start")%>%
  activate("activity1_1")

# general case, with varying resource number and location
activity <- function(name, resource, location, activate_next, duration) {
  trajectory(name) %>%
    seize(paste0("resource", resource), 1) %>%
    seize(paste0("location", location), 1) %>%
    timeout(duration) %>%

    log_("done") %>%
    release(paste0("location", location), 1) %>%
    release(paste0("resource", resource), 1) %>%
    activate(activate_next)

}

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

env <- simmer() %>%
  add_generator("start", start, at(0)) %>%

  add_generator("finish", finish, when_activated())

# define the grid of resources and locations
gr <- expand.grid(resource=1:2, location=1:2)
# add durations
gr$t <- c(20, 10, 10, 5)

# add a generator for each element in the grid
for (i in seq_len(nrow(gr))) {
  name_current <- paste0("activity", gr$resource[i], "_", gr$location[i])
  name_next <- if (i < nrow(gr))
    paste0("activity", gr$resource[i+1], "_", gr$location[i+1]) else "finish"
  
  env %>% add_generator(
    name_current,
    activity(name_current, gr$resource[i], gr$location[i], name_next, gr$t[i]),
    when_activated()
  )
}

# finally, if the resources are all equal, simply
env %>%
  add_resource(paste0("location", unique(gr$location)), 1) %>%
  add_resource(paste0("resource", unique(gr$resource)), 1)
#> simmer environment: anonymous | now: 0 | next: 0
#> { Monitor: in memory }
#> { Resource: location1 | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
#> { Resource: location2 | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
#> { Resource: resource1 | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
#> { Resource: resource2 | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
#> { Source: start | monitored: 1 | n_generated: 0 }
#> { Source: finish | monitored: 1 | n_generated: 0 }
#> { Source: activity1_1 | monitored: 1 | n_generated: 0 }
#> { Source: activity2_1 | monitored: 1 | n_generated: 0 }
#> { Source: activity1_2 | monitored: 1 | n_generated: 0 }
#> { Source: activity2_2 | monitored: 1 | n_generated: 0 }
# if they are NOT equal, you could always build a loop as before

run(env) %>%
  get_mon_arrivals()
#> 0: start0: start
#> 20: activity1_10: done
#> 30: activity2_10: done
#> 40: activity1_20: done
#> 45: activity2_20: done
#> 45: finish0: finish
#>           name start_time end_time activity_time finished replication
#> 1       start0          0        0             0     TRUE           1
#> 2 activity1_10          0       20            20     TRUE           1
#> 3 activity2_10         20       30            10     TRUE           1
#> 4 activity1_20         30       40            10     TRUE           1
#> 5 activity2_20         40       45             5     TRUE           1
#> 6      finish0         45       45             0     TRUE           1
There are more examples about the use of expand.grid and loops to create a large number of trajectories/generators/resources in this vignette: https://r-simmer.org/articles/simmer-aa-5g

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/2e02c0c7-640c-42e0-b4d9-972e802e512en%40googlegroups.com.


--
Iñaki Úcar
Reply all
Reply to author
Forward
0 new messages