I am simulating a store's parking lot. Spaces are resources, cars are on a trajectory. For simplicity purposes, all parking spaces are in a single file, numbered by their proximity to the store's front door (space1 is closest, space2 is next closest, etc.)
Cars arrive and seize one open space, but there is a preference function - cars generally want to seize the closest open space to the door, but not always. There is a timeout, then the car releases their space and exit the system.
My code below works fine when I have the timeout set low enough that there is always an available space. When I raise the timeout (say, to a mean of 120), the lot fills up and I get the error:
Error in
sample.int(x, size, replace, prob) : incorrect number of probabilities
This arises because there isn't any available spaces. Is there a simple way to avoid this issue? Perhaps by making cars wait until a spot opens, then seize it?
Thanks
Ralph
-----
#Discrete Event Simulation Example: parking lot
library(tidyverse)
library(magrittr)
library(simmer)
library(simmer.plot)
#clear workspace and run Garbage Collector
rm(list=ls())
gc(T,T,T)
#no scientific notation
options(scipen=999)
parkingspot_count <- 25
car_trajectory <- trajectory("car_in_parkinglot") %>%
set_attribute(c("selected_spot"), function() {
server_count <- get_server_count(parkinglot_env, paste0("space", 1:parkingspot_count))
#find indices of available spaces
open_spaces <- sort(which(server_count ==0))
df <- cbind.data.frame(open_spaces) %>%
dplyr::mutate(prob= 0.5^dplyr::row_number()) %>%
#normalize
dplyr::mutate(prob = prob/sum(prob))
#select a space
space_index <- sample(x=df$open_spaces,size=1,replace=FALSE,prob=df$prob)
#return space_index, that's the space to occupy
return(space_index) } ) %>%
simmer::select(function() paste0("space", get_attribute(parkinglot_env, "selected_spot"))) %>%
seize_selected() %>%
timeout(function() {max(rnorm(n=1,mean=20,sd=5), 1)}) %>% #normally distributed time, min 1 minute
release_selected() %>%
log_("Left Parking Lot")
parkinglot_env <- simmer() %>%
add_resource(name= paste0("space",1:parkingspot_count), capacity=1) %>%
add_resource(name = "common_queue", capacity= parkingspot_count, queue_size=Inf)%>%
add_generator(name_prefix = "Car", trajectory= car_trajectory, function() {rexp(n=1,rate=(20/60))}) #rate is arrivals per unit of time.
#timeout is in minutes, so arrivals must be in minutes. want 30 arrivals per hour --> (30/60) arrivals per minute
sim_out <- parkinglot_env %>% run(until = (60*24))