Skip to content

Deterministic arrival and service queue not producing expected number of events #260

@matthew-machado

Description

@matthew-machado

Hello there 👋

I'm trying to understand how ciw handles deterministic arrivals and services in a simple queue simulation. Specifically, I'm seeing fewer arrivals than expected, and I'd appreciate some guidance on whether this is a bug or expected behavior. I am working on simulating a very simple queue where:

  • Arrivals occur exactly once per hour
  • Each arrival is serviced in exactly one hour
  • The simulation runs for a total of 24 hours

Since arrivals are deterministic, I would like to see the theoretical number of arrivals match what ciw returns after the simulation, and there appears to be a discrepancy (which may totally be user error on my side 😅 ). Curious if anyone can help out and opine on some of the issues I'm having.

In this dummy experiment, I would expect 24 arrivals in the system. However, I'm producing 22 arrivals in this simulation:

N = ciw.create_network(
    arrival_distributions=[ciw.dists.Deterministic(value=1)], 
    service_distributions=[ciw.dists.Deterministic(value=1)],
    number_of_servers=[1]
)

ciw.seed(1)
Q = ciw.Simulation(N)

sim_time = 24
Q.simulate_until_max_time(sim_time)
recs = pd.DataFrame(Q.get_all_records())

# there is a gap here.. I think some of this might be clipping at the upper limit (but not sure why there aren't 23 tickets then..)
print('Theoretical Arrivals: ', sim_time)
print('Actual Arrivals: ', recs.shape[0])

Interestingly, there also appears to be some influence of the number of servers. Suppose I have a the following shift schedule, which maps to EST business hours in UTC times. I intend any arrivals outside of business hours to join the waiting queue and then be serviceable in business hours. This produces 20 arrivals and similarly I would expect 24 arrivals (1 per hour for 24 hours).

# create network
N = ciw.create_network(
    arrival_distributions=[ciw.dists.Deterministic(value=1)],
    service_distributions=[ciw.dists.Deterministic(value=1)],
    number_of_servers=[
        ciw.Schedule(
            numbers_of_servers=[0, 5, 0],
            shift_end_dates=[13, 20, 24]
        )],
)

# calculate metrics
ciw.seed(2)
Q = ciw.Simulation(N)

sim_time = 24
Q.simulate_until_max_time(sim_time)
recs = pd.DataFrame(Q.get_all_records())

# there is more of a gap here, not sure why servers would impact the arrivals process (it shouldn't)
print('Theoretical Arrivals: ', sim_time)
print('Actual Arrivals: ', recs.shape[0])

Finally, if I introduce customer classes, this effect is compounded even further. Suppose I have an experiment where:

  • We have num_customer customer classes, which each arrive at the same deterministic rate. (NB I intentionally do not want to thin these by multiplying by the proportion of the customer as documented, happy to go into more detail if needed)
  • We service each class at the same deterministic rate

For this simulation, I would expect num_customer * 24 arrivals (240 in this case), but am seeing 22 arrivals.

num_customers = 10
arrivals_distributions = {f'customer_{i}': [ciw.dists.Deterministic(value=1)] for i in range(0, num_customers)}
services_distributions = {f'customer_{i}': [ciw.dists.Deterministic(value=1)] for i in range(0, num_customers)}

# create network
N = ciw.create_network(
    arrival_distributions=arrivals_distributions,
    service_distributions=services_distributions,
    number_of_servers=[1]
)

# calculate metrics
ciw.seed(2)
Q = ciw.Simulation(N)

sim_time = 24
Q.simulate_until_max_time(sim_time)
recs = pd.DataFrame(Q.get_all_records())
print('Theoretical Arrivals: ', num_customers * sim_time)
print('Actual arrivals: ', recs.shape[0])

# tickets per customer
recs.groupby('customer_class').agg(num_tickets=('id_number', 'count'))

Any advice would be really appreciated! Thanks all

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions