Invoice-Routing-Functions

In [1]:
# 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
In [2]:
# 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
           ]

Assumptions/Constants

In [3]:
# The number of vendors who are sending invoices to Accounts Payable
NUM_VENDORS = 2500
In [4]:
# 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
In [5]:
# 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
In [6]:
# Number of business days in a month
MONTH_DAYS = 20
In [7]:
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
In [8]:
# Invoices for a given month
invoices = [gen_invoices(MU, NUM_VENDORS) * MONTH_DAYS for i in range(10)]
invoices
Out[8]:
[17960, 17980, 17420, 18080, 17360, 17420, 18360, 17240, 18020, 18840]
In [9]:
# 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
In [10]:
# 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
In [11]:
ROUTING_SUCCESS_RATE = 0.95
In [12]:
# 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
In [13]:
# 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]]

Results

CASE 1: No Machine Learning

This is the baseline against which to compare the benefits of the machine learning solution.

In [14]:
# 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
Out[14]:
[[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]]

CASE 2: With Machine Learning Up Front

2.1 ML System Accuracy = 0.5 = 50%

In [15]:
ML_SYS_ACC_50 = 0.5
In [16]:
# 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
Out[16]:
[[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]]

2.2 ML System Accuracy = 0.6 = 60%

In [17]:
ML_SYS_ACC_60 = 0.6
In [18]:
# 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
Out[18]:
[[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 System Accuracy = 0.7 = 70%

In [19]:
ML_SYS_ACC_70 = 0.7
In [20]:
# 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
Out[20]:
[[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]]