This notebook provides documentation for the function calculate_objective_serv_time_lookup, which calculates an objective value (in terms of expected waiting time and expected spillover) based on a given schedule and pre-computed convolutions of a probability mass function (PMF).
The function uses the following inputs:
schedule: A list of integers representing the number of patients scheduled in each time slot.
d: An integer indicating the duration threshold for a time slot.
convolutions: A dictionary of precomputed convolutions of the service time PMF. The key 1 should correspond to the adjusted service time distribution (for example, one adjusted for no-shows), while keys greater than 1 are used for multiple patients in a time slot.
The function returns a tuple:
ewt: The sum of expected waiting times over the schedule.
esp: The expected spillover time (or overtime) after the final time slot.
Example Usage
A trivial example using a precomputed convolution dictionary with a degenerate PMF (i.e. always zero service time) is provided in the unit tests below.
import numpy as npfrom typing import List, Dict, Tuplefrom functions import service_time_with_no_shows, compute_convolutions, calculate_objective_serv_time_lookup# For demonstration purposes, we use a trivial convolution dictionary.original_distribution = [0.0, 0.5, 0.3, 0.2]no_show_probability =0.1adjusted_distribution = service_time_with_no_shows(original_distribution, no_show_probability)schedule_example = [2, 0, 0, 0, 0, 0, 1]N =sum(schedule_example)convolutions_example = compute_convolutions(original_distribution, N, no_show_probability)d_example =1ewt, esp = calculate_objective_serv_time_lookup(schedule_example, d_example, convolutions_example)print("Adjusted Service Time Distribution: ", adjusted_distribution)print("Expected Adjusted Service Time: ", np.dot(range(len(adjusted_distribution)), adjusted_distribution))print("Expected Waiting Time:", ewt)print("Expected Spillover:", esp)
Adjusted Service Time Distribution: [0.1, 0.45, 0.27, 0.18000000000000002]
Expected Adjusted Service Time: 1.53
Expected Waiting Time: 1.53
Expected Spillover: 0.6300000000000001
import unittestclass TestCalculateObjectiveServTimeLookup(unittest.TestCase):def setUp(self):# Create a convolution dictionaryself.convolutions = convolutions_exampleself.d = d_exampledef test_single_time_slot(self):# With one patient there will be no waiting and spillover (overtime) can be calculated by hand. schedule = [1] ewt, esp = calculate_objective_serv_time_lookup(schedule, self.d, self.convolutions)self.assertAlmostEqual(ewt, 0.0, places=5, msg="Expected waiting time should be 0")self.assertAlmostEqual(esp, 0.6300000000000001, places=5, msg="Expected spillover should be 0")def test_zero_patients(self):# If no patients are scheduled in a time slot, the process simply advances in time. schedule = [0] ewt, esp = calculate_objective_serv_time_lookup(schedule, self.d, self.convolutions)self.assertAlmostEqual(ewt, 0.0, places=5, msg="Expected waiting time should be 0 when no patients")self.assertAlmostEqual(esp, 0.0, places=5, msg="Expected spillover should be 0 when no patients")if__name__=='__main__': unittest.main(argv=[''], exit=False)
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK