# Generate a list of values sampled from a Poisson distribution
from scipy.stats import poisson
import numpy as np
def gen_invoices(poisson_mu, num_vendors):
# poisson_mu is the lambda parameter of the Poisson distribution used to generate
# the number of invoices for the period
# Set poisson_mu appropriately to result in approximately the right number of invoices
# for a given time period
# num_vendors is the number of vendors Accounts Payable deals with
invoices_per_vendor = poisson.rvs(poisson_mu, size=num_vendors)
total_invoices_per_period = np.sum(invoices_per_vendor)
return total_invoices_per_period
# Generate the workload over a period of time
# It could be for any period of time -- substitute the appropriate number in period_duration
# This produces the number of invoices that were routed (both correctly or incorrectly)
# and the number of invoices that couldn't be tackled that day
from scipy.stats import norm # the Gaussian distribution
import math # for floor and ceil functions
def get_period_workload(num_invoices_input,
mean_std_dev,
period_duration,
routing_success_rate):
# num_invoices_input is the arriving number of invoices for the period
# It can be a straight number or can be a number generated by gen_invoices function above
# mean_std_dev is an array [mean, std_dev] -- the Gaussian parameters
# for how long it takes to route an invoice
mean = mean_std_dev[0]
std_dev = mean_std_dev[1]
# num_vendors is the number of vendors Accounts Payable deals with
# num_seconds_in_period is the amount of time worked in total by all of the
# Accounts Payable people who are routing invoices.
# routing_success_rate is the rate at which invoices are routed correctly
# Array of time it takes to route each invoice
time_array = norm.rvs(loc=mean, scale=std_dev, size=num_invoices_input)
print("Time to route the first few invoices...{} ... and the last few {}".\
format(time_array[0:5], time_array[-5:-1]))
# Cumulative sums of the time_array (this is not strictly the right model, but a good approx)
time_array_cu = np.cumsum(time_array)
print("Cumulative time to route the first few invoices...{} ... and the last few {}".\
format(time_array_cu[0:5], time_array_cu[-5:-1]))
# Split the time_array_cu into two parts:
# 1) The list of items where the times are less than or equal to NUM_SECS_WORKED_DAILY
# 2) The list of items where the times are greater than NUM_SECS_WORKED_DAILY
invoices_routed = [x for x in time_array_cu if x <= period_duration]
num_invoices_routed = len(invoices_routed)
print("Number of invoices routed = {}".format(num_invoices_routed))
# Of the number of the invoices_routed, the ones successfully/correctly routed
num_correctly_routed = int(math.floor(routing_success_rate * num_invoices_routed))
print("Number of invoices correctly routed = {}".format(num_correctly_routed))
# The number of invoices not correctly routed
num_not_correctly_routed = num_invoices_routed - num_correctly_routed
print("Number of invoices NOT correctly routed = {}".format(num_not_correctly_routed))
# Number of invoices not gotten to because time ran out in the period
num_invoices_not_routed = len([x for x in time_array_cu if x > period_duration])
print("Number of invoices not handled due to lack of time = {}".format(num_invoices_not_routed))
# How much extra time was left over in the period (if any)?
# If this value is negative it means it will take this much more time to
# route the invoices that were not handled due to lack of time in the period
time_left_in_period = period_duration - time_array_cu[-1]
print("Extra time left over in the period = {}".format(time_left_in_period))
return [num_invoices_input,
num_invoices_routed,
num_correctly_routed,
num_not_correctly_routed,
num_invoices_not_routed,
time_left_in_period
]
# The number of vendors who are sending invoices to Accounts Payable
NUM_VENDORS = 2500
# Poisson Rate - Rate at which a vendor generates invoices
# Choose it so invoices_per_day for the number of vendoors
# matches the real numbers seen by the organization
MU = 0.35
# Number of AP Specialists routing invoices
NUM_AP_SPECIALISTS = 4
# Number of working seconds in a day
# Number of hours worked by a single AP Specialist in a day
NUM_HOURS_WORKED_DAILY_PER_PERSON = 6.5
NUM_HOURS_WORKED_DAILY = NUM_HOURS_WORKED_DAILY_PER_PERSON * NUM_AP_SPECIALISTS
NUM_SECS_WORKED_DAILY = NUM_HOURS_WORKED_DAILY * 60 * 60
print("Number of seconds available for routing invoices per day = {}".format(NUM_SECS_WORKED_DAILY))
Number of seconds available for routing invoices per day = 93600.0
# Number of business days in a month
MONTH_DAYS = 20
NUM_SECS_WORKED_MONTHLY = NUM_SECS_WORKED_DAILY * MONTH_DAYS
print("Number of seconds available for routing invoices per month = {}".format(NUM_SECS_WORKED_MONTHLY))
Number of seconds available for routing invoices per month = 1872000.0
# Invoices for a given month
invoices = [gen_invoices(MU, NUM_VENDORS) * MONTH_DAYS for i in range(10)]
invoices
[17960, 17980, 17420, 18080, 17360, 17420, 18360, 17240, 18020, 18840]
# The time it takes to route an invoice is distributed as a Gaussian
# Mean of the Gaussian distribution for the time it takes to route an invoice
MEAN = 80
# Standard Deviation for the time it takes to route an invoice
STD_DEV = 20
# The time it takes a machine learning system route an invoice is distributed as a Gaussian
# Mean of the Gaussian distribution for the time it takes to route an invoice
MEAN_ML = 0.5
# Standard Deviation for the time it takes to route an invoice
STD_DEV_ML = .002
ROUTING_SUCCESS_RATE = 0.95
# For the incorrectly routed invoices, it take a much longer time for them to get sorted out.
# Hence, the values of the mean and standard deviation for the normal distribution
# of the times it takes to resolve this are much larger than MEAN and STD_DEV
# 3 hours = 10,800 seconds
LARGE_MEAN = 10800
# 30 minutes = 1,800 seconds
LARGE_STD_DEV = 1800
# Assume that the success rate for re-routing is 1
LARGE_ROUTING_SUCCESS_RATE = 1.0
# 1 hour = 3600 seconds
# 2 hours = 7200 seconds
# 3 hours = 10,800 seconds
# 4 hours = 14,400 seconds
TIMES_TO_FIX = [[3600, 600], [7200, 1200], [10800, 1800], [14400, 2400]]
This is the baseline against which to compare the benefits of the machine learning solution.
# First round of processing by AP Specialists
res1 = get_period_workload(gen_invoices(MU, NUM_VENDORS) * MONTH_DAYS, \
[MEAN, STD_DEV], NUM_SECS_WORKED_MONTHLY, ROUTING_SUCCESS_RATE)
num_high_touch = res1[3]
time_remaining = res1[5]
# Handling the high touch in the second round in the time remaining
res2 = [get_period_workload(num_high_touch, time_to_fix, time_remaining, \
LARGE_ROUTING_SUCCESS_RATE) for time_to_fix in TIMES_TO_FIX]
res2
Time to route the first few invoices...[ 58.85249067 56.41052914 63.34892083 110.44108854 80.88286722] ... and the last few [ 99.58078064 57.82384557 93.84999207 57.60581212] Cumulative time to route the first few invoices...[ 58.85249067 115.26301981 178.61194064 289.05302919 369.9358964 ] ... and the last few [ 1414875.5450205 1414933.36886606 1415027.21885813 1415084.82467025] Number of invoices routed = 17680 Number of invoices correctly routed = 16796 Number of invoices NOT correctly routed = 884 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 456826.5028999923 Time to route the first few invoices...[ 3906.55394924 3575.03816914 3612.53051785 4063.15202707 4741.27699229] ... and the last few [ 3146.54239694 2883.96121001 4127.06318926 3971.31428828] Cumulative time to route the first few invoices...[ 3906.55394924 7481.59211838 11094.12263624 15157.27466331 19898.55165559] ... and the last few [ 3192420.25692521 3195304.21813521 3199431.28132448 3203402.59561276] Number of invoices routed = 124 Number of invoices correctly routed = 124 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 760 Extra time left over in the period = -2750542.5920591033 Time to route the first few invoices...[ 7197.58506586 8043.37169082 8529.41114889 6748.84743956 5116.81068407] ... and the last few [ 5899.03122909 6349.88696656 5654.7628085 7981.06095795] Cumulative time to route the first few invoices...[ 7197.58506586 15240.95675668 23770.36790556 30519.21534513 35636.0260292 ] ... and the last few [ 6381265.1026818 6387614.98964836 6393269.75245686 6401250.81341481] Number of invoices routed = 63 Number of invoices correctly routed = 63 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 821 Extra time left over in the period = -5950859.420763288 Time to route the first few invoices...[ 13668.01935254 8901.40281751 6909.75236661 12268.09523274 9593.23735674] ... and the last few [ 9299.69135888 9430.50917436 12866.16061663 9967.11279318] Cumulative time to route the first few invoices...[ 13668.01935254 22569.42217005 29479.17453666 41747.26976939 51340.50712614] ... and the last few [ 9425772.51801412 9435203.02718848 9448069.18780511 9458036.3005983 ] Number of invoices routed = 43 Number of invoices correctly routed = 43 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 841 Extra time left over in the period = -9013129.626141194 Time to route the first few invoices...[ 16735.4816595 14369.14768369 14372.65639777 10595.92751701 12069.09456535] ... and the last few [ 9776.56773286 15476.53479697 18262.4154956 15209.18178954] Cumulative time to route the first few invoices...[ 16735.4816595 31104.62934318 45477.28574095 56073.21325795 68142.30782331] ... and the last few [ 12602851.37500149 12618327.90979846 12636590.32529405 12651799.50708359] Number of invoices routed = 31 Number of invoices correctly routed = 31 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 853 Extra time left over in the period = -12210160.869213931
[[884, 124, 124, 0, 760, -2750542.5920591033], [884, 63, 63, 0, 821, -5950859.4207632877], [884, 43, 43, 0, 841, -9013129.6261411943], [884, 31, 31, 0, 853, -12210160.869213931]]
ML_SYS_ACC_50 = 0.5
# First round of processing by the ML system
res1 = get_period_workload(gen_invoices(MU, NUM_VENDORS) * MONTH_DAYS, \
[MEAN_ML, STD_DEV_ML], NUM_SECS_WORKED_MONTHLY, ML_SYS_ACC_50)
num_high_touch1 = res1[3]
time_remaining1 = res1[5] # not used -- AP Specialists have the same time as before
# Second round - AP specialists deal with the num_high_touch that ML spat out
res2 = get_period_workload(num_high_touch1, [MEAN, STD_DEV], NUM_SECS_WORKED_MONTHLY, \
ROUTING_SUCCESS_RATE)
num_high_touch2 = res2[3]
time_remaining2 = res2[5]
# Handling the high touch in the next round in the time remaining
res3 = [get_period_workload(num_high_touch2, time_to_fix, time_remaining2, LARGE_ROUTING_SUCCESS_RATE) \
for time_to_fix in TIMES_TO_FIX]
res3
Time to route the first few invoices...[ 0.49974946 0.49854968 0.49602019 0.50017993 0.50084236] ... and the last few [ 0.50015236 0.50087878 0.50029739 0.50319799] Cumulative time to route the first few invoices...[ 0.49974946 0.99829913 1.49431932 1.99449924 2.49534161] ... and the last few [ 9147.83881359 9148.33969237 9148.83998976 9149.34318775] Number of invoices routed = 18300 Number of invoices correctly routed = 9150 Number of invoices NOT correctly routed = 9150 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 1862850.1553823473 Time to route the first few invoices...[ 81.58141949 93.69113805 70.02528165 62.74299764 41.75213866] ... and the last few [ 79.31266814 45.75515461 59.96069253 43.35151112] Cumulative time to route the first few invoices...[ 81.58141949 175.27255754 245.29783919 308.04083682 349.79297549] ... and the last few [ 734391.99187621 734437.74703082 734497.70772334 734541.05923446] Number of invoices routed = 9150 Number of invoices correctly routed = 8692 Number of invoices NOT correctly routed = 458 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 1137381.248003095 Time to route the first few invoices...[ 3206.10827324 4478.70687642 2324.46656522 3272.17346412 3194.99285309] ... and the last few [ 4169.29189395 3241.72594783 3555.78192581 2353.79294474] Cumulative time to route the first few invoices...[ 3206.10827324 7684.81514966 10009.28171487 13281.455179 16476.44803209] ... and the last few [ 1642825.56194266 1646067.28789049 1649623.0698163 1651976.86276105] Number of invoices routed = 314 Number of invoices correctly routed = 314 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 144 Extra time left over in the period = -518165.13989768946 Time to route the first few invoices...[ 8858.72331873 6964.40712809 6539.62984025 7178.286357 4695.49902544] ... and the last few [ 7947.25369265 8212.06906224 6327.53198447 8636.13135761] Cumulative time to route the first few invoices...[ 8858.72331873 15823.13044682 22362.76028707 29541.04664407 34236.54566952] ... and the last few [ 3242745.46161717 3250957.53067941 3257285.06266388 3265921.1940215 ] Number of invoices routed = 159 Number of invoices correctly routed = 159 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 299 Extra time left over in the period = -2136038.7127798423 Time to route the first few invoices...[ 9679.94749669 9414.92025778 13230.85711676 6940.89206822 8498.77577717] ... and the last few [ 10342.50422212 12412.29872092 12726.19501826 10947.61010053] Cumulative time to route the first few invoices...[ 9679.94749669 19094.86775446 32325.72487122 39266.61693944 47765.39271662] ... and the last few [ 4860770.46583183 4873182.76455275 4885908.95957101 4896856.56967154] Number of invoices routed = 105 Number of invoices correctly routed = 105 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 353 Extra time left over in the period = -3770409.0035145287 Time to route the first few invoices...[ 16093.40796283 18843.33323034 9722.14582995 10373.44369676 17272.63430856] ... and the last few [ 11373.27939023 18630.49995888 12452.00109398 13906.12985929] Cumulative time to route the first few invoices...[ 16093.40796283 34936.74119317 44658.88702312 55032.33071988 72304.96502844] ... and the last few [ 6530867.9087956 6549498.40875448 6561950.40984846 6575856.53970775] Number of invoices routed = 78 Number of invoices correctly routed = 78 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 380 Extra time left over in the period = -5451518.315365456
[[458, 314, 314, 0, 144, -518165.13989768946], [458, 159, 159, 0, 299, -2136038.7127798423], [458, 105, 105, 0, 353, -3770409.0035145287], [458, 78, 78, 0, 380, -5451518.315365456]]
ML_SYS_ACC_60 = 0.6
# First round of processing by the ML system
res1 = get_period_workload(gen_invoices(MU, NUM_VENDORS) * MONTH_DAYS, \
[MEAN_ML, STD_DEV_ML], NUM_SECS_WORKED_MONTHLY, ML_SYS_ACC_60)
num_high_touch1 = res1[3]
time_remaining1 = res1[5] # not used -- AP Specialists have the same time as before
# Second round - AP specialists deal with the num_high_touch that ML spat out
res2 = get_period_workload(num_high_touch1, [MEAN, STD_DEV], NUM_SECS_WORKED_MONTHLY, \
ROUTING_SUCCESS_RATE)
num_high_touch2 = res2[3]
time_remaining2 = res2[5]
# Handling the high touch in the next round in the time remaining
res3 = [get_period_workload(num_high_touch2, time_to_fix, time_remaining2, LARGE_ROUTING_SUCCESS_RATE) \
for time_to_fix in TIMES_TO_FIX]
res3
Time to route the first few invoices...[ 0.49955008 0.49871643 0.49739794 0.50115547 0.50207393] ... and the last few [ 0.50040959 0.50171421 0.50001161 0.50096635] Cumulative time to route the first few invoices...[ 0.49955008 0.99826651 1.49566445 1.99681992 2.49889386] ... and the last few [ 8668.00644136 8668.50815557 8669.00816717 8669.50913353] Number of invoices routed = 17340 Number of invoices correctly routed = 10404 Number of invoices NOT correctly routed = 6936 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 1863329.9934656532 Time to route the first few invoices...[ 69.17360973 96.24132137 109.21591763 45.60603689 61.20169756] ... and the last few [ 58.95951329 94.43401605 61.66653335 38.14121088] Cumulative time to route the first few invoices...[ 69.17360973 165.4149311 274.63084873 320.23688562 381.43858318] ... and the last few [ 550030.60479545 550125.0388115 550186.70534485 550224.84655573] Number of invoices routed = 6936 Number of invoices correctly routed = 6589 Number of invoices NOT correctly routed = 347 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 1321678.4439901258 Time to route the first few invoices...[ 3558.33618517 3919.92299843 3820.24593383 3463.27778196 3127.87039043] ... and the last few [ 3089.43486502 4174.82947864 4852.50232803 3003.3892593 ] Cumulative time to route the first few invoices...[ 3558.33618517 7478.2591836 11298.50511743 14761.78289939 17889.65328982] ... and the last few [ 1260280.19054944 1264455.02002808 1269307.52235611 1272310.91161541] Number of invoices routed = 347 Number of invoices correctly routed = 347 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 46660.831880063284 Time to route the first few invoices...[ 7486.20342071 6272.90407902 6957.1103375 5402.42353153 6891.41333189] ... and the last few [ 5745.04164689 5628.05147545 5952.70299431 5282.10146244] Cumulative time to route the first few invoices...[ 7486.20342071 13759.10749973 20716.21783724 26118.64136877 33010.05470065] ... and the last few [ 2481752.03403995 2487380.0855154 2493332.78850971 2498614.88997215] Number of invoices routed = 184 Number of invoices correctly routed = 184 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 163 Extra time left over in the period = -1182453.3980094232 Time to route the first few invoices...[ 7061.64329794 11885.50347128 13295.12645621 8337.55773409 9354.23906981] ... and the last few [ 12564.0113147 9812.48877555 10386.99508962 8773.78596677] Cumulative time to route the first few invoices...[ 7061.64329794 18947.14676922 32242.27322543 40579.83095952 49934.07002933] ... and the last few [ 3742916.74033683 3752729.22911238 3763116.224202 3771890.01016877] Number of invoices routed = 120 Number of invoices correctly routed = 120 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 227 Extra time left over in the period = -2461457.3361068508 Time to route the first few invoices...[ 19369.21089827 15030.67830324 16040.08754528 12605.22160492 16890.7772109 ] ... and the last few [ 12365.36008483 18192.37143358 12901.78813334 9298.68326834] Cumulative time to route the first few invoices...[ 19369.21089827 34399.88920151 50439.97674678 63045.1983517 79935.9755626 ] ... and the last few [ 4928425.67662776 4946618.04806133 4959519.83619468 4968818.51946302] Number of invoices routed = 91 Number of invoices correctly routed = 91 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 256 Extra time left over in the period = -3657916.945735863
[[347, 347, 347, 0, 0, 46660.831880063284], [347, 184, 184, 0, 163, -1182453.3980094232], [347, 120, 120, 0, 227, -2461457.3361068508], [347, 91, 91, 0, 256, -3657916.9457358629]]
ML_SYS_ACC_70 = 0.7
# First round of processing by the ML system
res1 = get_period_workload(gen_invoices(MU, NUM_VENDORS) * MONTH_DAYS, \
[MEAN_ML, STD_DEV_ML], NUM_SECS_WORKED_MONTHLY, ML_SYS_ACC_70)
num_high_touch1 = res1[3]
time_remaining1 = res1[5] # not used -- AP Specialists have the same time as before
# Second round - AP specialists deal with the num_high_touch that ML spat out
res2 = get_period_workload(num_high_touch1, [MEAN, STD_DEV], NUM_SECS_WORKED_MONTHLY, \
ROUTING_SUCCESS_RATE)
num_high_touch2 = res2[3]
time_remaining2 = res2[5]
# Handling the high touch in the next round in the time remaining
res3 = [get_period_workload(num_high_touch2, time_to_fix, time_remaining2, LARGE_ROUTING_SUCCESS_RATE) \
for time_to_fix in TIMES_TO_FIX]
res3
Time to route the first few invoices...[ 0.50117694 0.50215079 0.50118644 0.4959717 0.50066867] ... and the last few [ 0.4975494 0.49831851 0.50270478 0.49684775] Cumulative time to route the first few invoices...[ 0.50117694 1.00332773 1.50451417 2.00048587 2.50115454] ... and the last few [ 8938.13811598 8938.63643449 8939.13913928 8939.63598703] Number of invoices routed = 17880 Number of invoices correctly routed = 12516 Number of invoices NOT correctly routed = 5364 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 1863059.8593763227 Time to route the first few invoices...[ 109.9587264 70.08682748 83.46690847 89.01753603 78.62326722] ... and the last few [ 80.08429955 81.95180789 84.8862476 118.16875157] Cumulative time to route the first few invoices...[ 109.9587264 180.04555387 263.51246234 352.52999838 431.15326559] ... and the last few [ 430170.82820936 430252.78001725 430337.66626485 430455.83501643] Number of invoices routed = 5364 Number of invoices correctly routed = 5095 Number of invoices NOT correctly routed = 269 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 1441464.9638588212 Time to route the first few invoices...[ 4502.47493073 4272.39612439 4665.28865235 3266.83478047 2523.81322811] ... and the last few [ 3145.65178041 3884.5933454 2822.69104814 3443.28601264] Cumulative time to route the first few invoices...[ 4502.47493073 8774.87105512 13440.15970746 16706.99448793 19230.80771604] ... and the last few [ 958764.03955041 962648.63289581 965471.32394395 968914.6099566 ] Number of invoices routed = 269 Number of invoices correctly routed = 269 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 0 Extra time left over in the period = 468398.97304329684 Time to route the first few invoices...[ 8264.08205603 5824.60386643 7551.60740938 5283.46465882 8883.34543403] ... and the last few [ 9609.41348275 7042.5634666 7059.77998015 8595.16582941] Cumulative time to route the first few invoices...[ 8264.08205603 14088.68592246 21640.29333184 26923.75799065 35807.10342468] ... and the last few [ 1909882.57728908 1916925.14075567 1923984.92073582 1932580.08656523] Number of invoices routed = 199 Number of invoices correctly routed = 199 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 70 Extra time left over in the period = -497143.61828381056 Time to route the first few invoices...[ 11374.94161205 11824.39863203 9728.46782104 9481.18569458 10669.95345922] ... and the last few [ 8569.76080612 13121.08817909 11014.01193993 11740.08642544] Cumulative time to route the first few invoices...[ 11374.94161205 23199.34024409 32927.80806512 42408.9937597 53078.94721893] ... and the last few [ 2883820.35623262 2896941.44441171 2907955.45635164 2919695.54277709] Number of invoices routed = 133 Number of invoices correctly routed = 133 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 136 Extra time left over in the period = -1489843.323325834 Time to route the first few invoices...[ 16543.72861497 15987.2083055 14468.05086727 15856.89032567 12546.82115084] ... and the last few [ 13816.44066129 14876.73926822 14493.64665377 14328.80061838] Cumulative time to route the first few invoices...[ 16543.72861497 32530.93692046 46998.98778773 62855.87811341 75402.69926425] ... and the last few [ 3807162.07761481 3822038.81688303 3836532.4635368 3850861.26415517] Number of invoices routed = 102 Number of invoices correctly routed = 102 Number of invoices NOT correctly routed = 0 Number of invoices not handled due to lack of time = 167 Extra time left over in the period = -2426616.9081719443
[[269, 269, 269, 0, 0, 468398.97304329684], [269, 199, 199, 0, 70, -497143.61828381056], [269, 133, 133, 0, 136, -1489843.323325834], [269, 102, 102, 0, 167, -2426616.9081719443]]