Implementing a D/M/1 Queue in Ciw

Python
Discrete Event Simulation
Ciw
Queueing Network
Queueing System
Queueing Theory
Exponential Distribution
Statistics
Operations Research
Random Variables
Inter-Arrival Times
Service Times
Random Number Generation
Servers
Author

Galen Seilis

Published

December 20, 2023

Introduction

Ciw is a Python package for simulating queueing networks.

Simulation

A D/M/1 queue can be implemented and simulated using Ciw in the following way.

"""Simulate a D/M/1 queue with Ciw and collect the customer records."""

import ciw

ciw.seed(2018)

ARRIVAL_TIME = 1
SERVICE_TIME = 1 / 2
HORIZON = 365

network = ciw.create_network(
    arrival_distributions = [ciw.dists.Deterministic(ARRIVAL_TIME)],
    service_distributions = [ciw.dists.Exponential(SERVICE_TIME)],
    number_of_servers = [1]
    )

simulation = ciw.Simulation(network)
simulation.simulate_until_max_time(HORIZON)
records = simulation.get_all_records()

Results

We can tabulate the results.

"""Summarize the D/M/1 queue records with a Markdown table."""

import pandas as pd

from simulate_queue import records

records = pd.DataFrame(records)
print(
    records
    [['waiting_time', 'service_time', 'queue_size_at_arrival', 'queue_size_at_departure']]
    .describe()
    .to_markdown()
    )
|        |   waiting_time |   service_time |   queue_size_at_arrival |   queue_size_at_departure |
|:-------|---------------:|---------------:|------------------------:|--------------------------:|
| count  |            183 |            183 |                     183 |                       183 |
| mean   |        71.9111 |        1.96964 |                 36.8087 |                   73.3607 |
| std    |         51.243 |         1.8815 |                 25.7219 |                   51.6083 |
| min    |              0 |      0.0229044 |                       0 |                         0 |
| 25%    |        19.1338 |       0.676208 |                    13.5 |                        20 |
| 50%    |        75.1552 |        1.28472 |                      34 |                        76 |
| 75%    |        111.045 |        2.53828 |                      61 |                       112 |
| max    |        175.985 |        9.49261 |                      80 |                       179 |

We can plot the arrival times against the waiting times.

"""Plot the arrival times against the waiting times for the D/M/1 queue."""

import os

import matplotlib

matplotlib.use("Agg")

import pandas as pd

from simulate_queue import records

here = os.path.dirname(os.path.abspath(__file__))
figures = os.path.join(here, "..", "figures")
os.makedirs(figures, exist_ok=True)

records = pd.DataFrame(records)
ax = records.plot(x='arrival_date', y='waiting_time')
ax.figure.savefig(
    os.path.join(figures, "arrival_vs_waiting.png"),
    dpi=300,
    bbox_inches="tight",
)

Arrival times against waiting times

We can plot the service start times against the service times.

"""Plot the service start times against the service times for the D/M/1 queue."""

import os

import matplotlib

matplotlib.use("Agg")

import pandas as pd

from simulate_queue import records

here = os.path.dirname(os.path.abspath(__file__))
figures = os.path.join(here, "..", "figures")
os.makedirs(figures, exist_ok=True)

records = pd.DataFrame(records)
ax = records.plot(x='service_start_date', y='service_time')
ax.figure.savefig(
    os.path.join(figures, "service_start_vs_service.png"),
    dpi=300,
    bbox_inches="tight",
)

Service start times against service times

We can plot the arrival dates against the length of the queue when the customer arrived.

"""Plot the arrival dates against the queue length at arrival for the D/M/1 queue."""

import os

import matplotlib

matplotlib.use("Agg")

import pandas as pd

from simulate_queue import records

here = os.path.dirname(os.path.abspath(__file__))
figures = os.path.join(here, "..", "figures")
os.makedirs(figures, exist_ok=True)

records = pd.DataFrame(records)
ax = records.plot(x='arrival_date', y='queue_size_at_arrival')
ax.figure.savefig(
    os.path.join(figures, "arrival_vs_queue_size_at_arrival.png"),
    dpi=300,
    bbox_inches="tight",
)

Arrival dates against the queue length at arrival

We can plot the departure dates against the length of the queue when the customer departed.

"""Plot the departure dates against the queue length at departure for the D/M/1 queue."""

import os

import matplotlib

matplotlib.use("Agg")

import pandas as pd

from simulate_queue import records

here = os.path.dirname(os.path.abspath(__file__))
figures = os.path.join(here, "..", "figures")
os.makedirs(figures, exist_ok=True)

records = pd.DataFrame(records)
ax = records.plot(x='exit_date', y='queue_size_at_departure')
ax.figure.savefig(
    os.path.join(figures, "exit_vs_queue_size_at_departure.png"),
    dpi=300,
    bbox_inches="tight",
)

Departure dates against the queue length at departure