Initialization and loading of files

In [26]:
%matplotlib inline

import matplotlib.pyplot as plt
import pandas
import glob
In [27]:
files = glob.glob('wasted-capacity*.csv')
print('Loading %s'%str(files))
partial_data = [pandas.read_csv(f, index_col=None, header=0) for f in files]
data = pandas.concat(partial_data)
Loading ['wasted-capacity-offline-sessions-512-32.csv', 'wasted-capacity-offline-sessions-128-16.csv', 'wasted-capacity-offline-sessions-16-2.csv', 'wasted-capacity-offline-sessions-32-32.csv', 'wasted-capacity-offline-sessions-8-8.csv', 'wasted-capacity-offline-sessions-32-4.csv', 'wasted-capacity-offline-sessions-16-8.csv', 'wasted-capacity-offline-sessions-128-32.csv', 'wasted-capacity-offline-sessions-512-8.csv', 'wasted-capacity-offline-sessions-128-8.csv', 'wasted-capacity-offline-sessions-512-2.csv', 'wasted-capacity-offline-sessions-8-4.csv', 'wasted-capacity-offline-sessions-16-16.csv', 'wasted-capacity-offline-sessions-32-16.csv', 'wasted-capacity-offline-sessions-128-2.csv', 'wasted-capacity-offline-sessions-32-2.csv', 'wasted-capacity-offline-sessions-32-8.csv', 'wasted-capacity-offline-sessions-8-2.csv', 'wasted-capacity-offline-sessions-16-4.csv', 'wasted-capacity-offline-sessions-512-4.csv', 'wasted-capacity-offline-sessions-512-16.csv', 'wasted-capacity-offline-sessions-128-4.csv']

The design

In [28]:
yellow = '#FFC107'
green = '#AFB42B'
red = '#F44336'
blue = '#3F51B5'
purple = '#7B1FA2'
grey = '#9E9E9E'
teal = '#009688'

plt.rc('lines', linewidth=3, solid_capstyle='round', dash_capstyle='round')
plt.rc('font', size=13)
plt.rc('legend', fontsize=13)

Little bit of inserting calculated values into the original data

In [29]:
data['#relations'] = data['#reservations']/data['relation size']
data['wasted capacity percentage'] = data['wasted capacity']/ \
        (data['initial capacity']*data['remaining capacity ratio']) * 100
data['remaining session percentage'] = data['online sessions']/data['#relations']*100
data['could-be session percentage'] = data['could-be sessions']/data['#relations']*100

Proportion of the wasted capacity of the remaining

In order to show, that the system brings a benefit at all, we're showing the proportion of the remaining capacity after cutting, that is wasted.

First: an average of all scenarios

In [30]:
wc = data.groupby(['system type', '#reservations', 'remaining capacity ratio']).mean()
In [31]:
num_paths = data['#reservations'].unique()
num_paths.sort()
plt.figure(figsize=(10,7))
plt.ylabel('wasted capacity (%)')
plt.xlabel('remaining capacity ratio (%)')
plt.ylim(0,100)
plt.xlim(10, 90)
plts = []
styles=[(blue, 'o'), (yellow, '^'), (green, 's'), (purple, 'D'), (red, 'v'), teal]
for system in ['standard', 'correlated']:
    color_index = 0
    for i in num_paths:
        remaining_capacity = (wc.loc[system].loc[i]['initial capacity']*wc.loc[system].loc[i].index.values)
        plts.extend(plt.plot(wc.loc[system].loc[i].index.values*100,\
                             (wc.loc[system].loc[i]['wasted capacity']/ \
                              remaining_capacity*100).values,\
                             '-'+styles[color_index][1] if system=='standard' \
                                 else '--'+styles[color_index][1], color=styles[color_index][0]))
        color_index += 1
legend_entries = ['8 (PO)']
legend_entries.extend([int(i) for i in num_paths[1:]])
legend_entries.append('8 (CT)')
legend_entries.extend([int(i) for i in num_paths[1:]])
plt.legend(plts, legend_entries, loc='upper right', ncol=2)
plt.savefig('wasted-capacity-ratio-mean.pdf', bbox_inches='tight', format='pdf')

Unused capacity

The figure shows, that 10 paths in the initial setup behave much differently, than the rest → this is due to the fact, that we have a larger amount of unassigned capacity

In [58]:
num_paths = data['#reservations'].unique()
num_paths.sort()
plt.figure(figsize=(10,7))
plt.ylabel('capacity (%)')
plt.xlabel('remaining capacity ratio (%)')
plt.ylim(0,100)
plt.xlim(10, 90)
plts = []
style=[(blue, 'o'), (red, 'v')]
color_index = 0
system = 'standard'
for i in [8, 512]:
    remaining_capacity = (wc.loc[system].loc[i]['initial capacity']*wc.loc[system].loc[i].index.values)
    plts.extend(plt.plot(wc.loc[system].loc[i].index.values*100,\
                         ((wc.loc[system].loc[i]['wasted capacity']/ \
                          remaining_capacity)*100).values,\
                         '-'+style[color_index][1], color=style[color_index][0]))
    plts.extend(plt.plot(wc.loc[system].loc[i].index.values*100,\
                         (((remaining_capacity\
                            -wc.loc[system].loc[i]['used capacity']\
                            +wc.loc[system].loc[i]['wasted capacity'])/ \
                          remaining_capacity)*100).values,\
                         '--', color=style[color_index][0]))
    color_index += 1
legend = plt.legend(plts, ['    8', 512, '    8 (w/ unassigned capacity)',\
                           '512 (w/ unassigned capacity)'], loc='lower right', ncol=2)

plt.savefig('unused-capacity-ratio-mean.pdf',bbox_inches='tight', format='pdf')

all following analyses are done only for 512 paths to reduce visualization complexity

The results behave the same way anyway

In [33]:
filtered = data[data['#reservations']==512]

wasted capacity again (for better overview)

In [34]:
wc_single = filtered.groupby(['system type', 'remaining capacity ratio']).mean()
plt.figure(figsize=(10,7))
plt.ylabel('wasted capacity (%)')
plt.xlabel('remaining capacity ratio (%)')
plt.ylim(0,100)
plt.xlim(10, 90)
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
plts.extend(plt.plot(wc_single.loc['standard'].index.values*100,\
                    wc_single.loc['standard']['wasted capacity percentage'], '-v', color=red))
plts.extend(plt.plot(wc_single.loc['correlated'].index.values*100,\
                    wc_single.loc['correlated']['wasted capacity percentage'], '-s', color=blue))
plts.extend(plt.plot(wc_single.loc['kasymosa'].index.values*100,\
                    wc_single.loc['kasymosa']['wasted capacity percentage'], '-o', color=green))
plt.legend(plts, ['PO', 'CT', 'RA'])
plt.savefig('wasted-capacity-single.pdf',bbox_inches='tight', format='pdf')

remaining sessions

Due to the better redistribution of capacity more sessions should be online for the relation-aware case.

Note: this overview figure excludes the Exclusive relation at this performs really bad in the relation-unaware case. It is simply a use case that cannot be expressed. We'll look at it in detail later on.

In [35]:
rs2 = filtered[filtered['relation type'] != 'Exclusive'].groupby([
        'system type', 'remaining capacity ratio']).mean()

plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.ylabel('remaining sessions (%)')
plt.xlabel('remaining capacity ratio (%)')
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for system in ['standard', 'correlated', 'kasymosa']:
    plts.extend(plt.plot(
                rs2.loc[system].index.values*100,\
                rs2.loc[system]['remaining session percentage'],\
                '-'+style[system][1], color=style[system][0]))
legend = plt.legend(plts, ['PO', 'CT', 'RA'] , loc='lower right', ncol=3)
plt.savefig('remaining-sessions-complete.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')

a more detailled view

The three constituent relation types from above

In [36]:
rs2 = filtered[filtered['relation type'] != 'Exclusive'].groupby([
        'system type', 'relation type', 'remaining capacity ratio']).mean()

plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.ylabel('remaining sessions (%)')
plt.xlabel('remaining capacity ratio (%)')
plts = []
line_style = { 'AtLeastN' : '-', 'Dependent' : '--', 'Mutual' : ':' }
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for rel_type in ['AtLeastN', 'Dependent', 'Mutual']:
    for system in ['standard', 'correlated', 'kasymosa']:
        plts.extend(plt.plot(
                    rs2.loc[system].loc[rel_type].index.values*100,\
                    rs2.loc[system].loc[rel_type]['remaining session percentage'],\
                    line_style[rel_type]+style[system][1], color=style[system][0]))
legend = plt.legend(plts, [
        'AtLeastN (PO)',
        'AtLeastN (CT)',
        'AtLeastN (RA)',
        'Dependent (PO)',
        'Dependent (CT)',
        'Dependent (RA)',
        'Mutual (PO)',
        'Mutual (CT)',
        'Mutual (RA)'
    ] , loc='lower right', ncol=3, bbox_to_anchor=(0.95,-0.3))
plt.savefig('remaining-sessions-by-relation-type-detail.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')

A closer look at the Exclusive relation

The exclusive relation is not in the mean above as it is a use case that is simply not possible to express without some kind of relation information

In [37]:
rs3 = filtered[filtered['relation type'] == 'Exclusive'].groupby([
        'system type', 'relation type', 'remaining capacity ratio']).mean()

plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.ylabel('remaining sessions (%)')
plt.xlabel('remaining capacity ratio (%)')
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for system in ['standard', 'correlated', 'kasymosa']:
    for rel_type in rs3.loc[system].index.levels[0]:
        plts.extend(plt.plot(
                    rs3.loc[system].loc[rel_type].index.values*100,\
                    rs3.loc[system].loc[rel_type]['remaining session percentage'],\
                    '-'+style[system][1], color=style[system][0]))
for system in ['standard', 'correlated']:
    for rel_type in rs3.loc[system].index.levels[0]:
        plts.extend(plt.plot(
                    rs3.loc[system].loc[rel_type].index.values*100,\
                    rs3.loc[system].loc[rel_type]['could-be session percentage'],\
                    '--'+style[system][1], color=style[system][0]))
legend = plt.legend(plts, [
        'PO', 'CT', 'RA',
        'PO (usable)', 'CT (usable)'
    ] , loc='lower right', ncol=2,\
           bbox_to_anchor=(1,0.1))
plt.savefig('remaining-sessions-exclusive.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')
As a function of the relation type and complexity

Different relation types and complexities behave quite differently in terms of optimization performance.

In [38]:
wc_rel_type = filtered.groupby(['system type', 'relation type', 'remaining capacity ratio']).mean()
In [39]:
plt.figure(figsize=(10,7))
plt.xlim(10, 90)
plts = []
style = { 'AtLeastN' : (blue, 'o'), 'Dependent' : (red, 'v'), 'Mutual' : (green, 's'), 'Exclusive' : (yellow, 'D')}
linestyles = { 'standard' : '-', 'correlated' : '--'}
for rel in wc_rel_type.loc[system].index.levels[0]:
    for system in ['standard', 'correlated']:
        dataset = wc_rel_type.loc[system].loc[rel]
        plts.extend(plt.plot(dataset.index.values*100,\
                    dataset['wasted capacity percentage'],\
                    linestyles[system]+style[rel][1], color=style[rel][0]))
plt.legend(plts, [
     'AtLeastN (PO)',
     'AtLeastN (CT)',
     'Dependent (PO)',
     'Dependent (CT)',
     'Exclusive (PO)',
     'Exclusive (CT)',
     'Mutual (PO)',
     'Mutual (CT)'
    ], loc='lower left', ncol=4, bbox_to_anchor=(-0.05,-0.25))
plt.xlabel('remaining capacity ratio')
plt.ylabel('wasted capacity')
plt.savefig('wasted-capacity-by-relation-type.pdf', bbox_extra_artists=(legend,), bbox_inches='tight', format='pdf')
In [40]:
rel_type_overview = filtered.groupby(['system type', 'relation type']).mean()
fig,ax = plt.subplots(figsize=(10,7))
ticks = (1.0, 3.0, 5.0, 7.0)
plt.xlim(0,8) # add some margin left and right of the bars
plt.xticks(ticks)
ax.set_xticklabels(('AtLeastN', 'Dependent', 'Exclusive', 'Mutual'))
plt.ylabel('wasted capacity (%)')
ax.bar([tick-0.75 for tick in ticks], \
       rel_type_overview.loc['standard']['wasted capacity percentage'], 0.75, color=red, edgecolor='none')
ax.bar(ticks, \
       rel_type_overview.loc['correlated']['wasted capacity percentage'], 0.75,color=blue, edgecolor='none')
plt.legend(['PO', 'CT'], loc='upper right')
plt.savefig('wasted-capacity-by-relation-type-bar.pdf', bbox_inches='tight', format='pdf')
In [41]:
fig,ax = plt.subplots(figsize=(10,7))
ticks = (1.0, 3.0, 5.0, 7.0)
plt.xlim(0.0,8.0) # add some margin left and right of the bars
plt.xticks(ticks)
ax.set_xticklabels(('AtLeastN', 'Dependent', 'Exclusive', 'Mutual'))
plt.ylabel('remaining sessions (%)')
ax.bar([tick-0.75 for tick in ticks], \
       rel_type_overview.loc['standard']['remaining session percentage'], 0.5, color=red, edgecolor='none')
ax.bar([tick-0.25 for tick in ticks], \
       rel_type_overview.loc['correlated']['remaining session percentage'], 0.5, color=blue, edgecolor='none')
ax.bar([tick+0.25 for tick in ticks], \
       rel_type_overview.loc['kasymosa']['remaining session percentage'], 0.5, color=green, edgecolor='none')
plt.legend(['PO', 'CT', 'RA'], loc='upper right')
plt.savefig('remaining-sessions-by-relation-type-bar.pdf', bbox_inches='tight', format='pdf')
In [42]:
wc_rel_complexity_complete = filtered.\
                                groupby(['system type', 'relation size']).mean()
wc_rel_complexity_no_exclusive = filtered[filtered['relation type'] != 'Exclusive'].\
                                groupby(['system type', 'relation size']).mean()
In [43]:
plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.xlim(2,32)
plt.ylabel('wasted capacity (%)')
plt.xlabel('relation complexity (paths/relation)')
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for dataset in [(wc_rel_complexity_complete, '-'), (wc_rel_complexity_no_exclusive, '--')]:
    for system in ['standard', 'correlated']:
        plts.extend(plt.plot(
                    dataset[0].loc[system].index.values,\
                    dataset[0].loc[system]['wasted capacity percentage'],\
                    dataset[1]+style[system][1], color=style[system][0]))
legend = plt.legend(plts, [
        'PO', 'CT',
        'PO (w/o Exclusive)', 'CT (w/o Exclusive)'
    ] , loc='upper right', ncol=2)
plt.savefig('wasted-capacity-complexity.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')
In [44]:
wc_rel_complexity_by_type = filtered.\
                                groupby(['system type', 'relation type', 'relation size']).mean()
plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.xlim(2,32)
plt.ylabel('wasted capacity (%)')
plt.xlabel('relation complexity (paths/relation)')
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
lgd_entries = []
for rel_type in [('AtLeastN', '-'), ('Dependent', '--'), ('Mutual', ':'), ('Exclusive', '-.')]:
    for system in ['standard', 'correlated']:
        lgd_entries.append('%s (%s)'%(rel_type[0], 'PO' if system=='standard' else 'CT'))
        plts.extend(plt.plot(
                    wc_rel_complexity_by_type.loc[system].loc[rel_type[0]].index.values,\
                    wc_rel_complexity_by_type.loc[system].loc[rel_type[0]]['wasted capacity percentage'],\
                    rel_type[1]+style[system][1], color=style[system][0]))
legend = plt.legend(plts, lgd_entries, loc='upper right', ncol=4, bbox_to_anchor=(1.05,-0.1))
plt.savefig('wasted-capacity-complexity-detail.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')
In [45]:
plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.xlim(2, 32)
plt.ylabel('remaining sessions (%)')
plt.xlabel('relation complexity (paths/relation)')
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for dataset in [(wc_rel_complexity_complete, '-'), (wc_rel_complexity_no_exclusive, '--')]:
    for system in ['standard', 'correlated', 'kasymosa']:
        plts.extend(plt.plot(
                    dataset[0].loc[system].index.values,\
                    dataset[0].loc[system]['remaining session percentage'],\
                    dataset[1]+style[system][1], color=style[system][0]))
legend = plt.legend(plts, [
        'PO', 'CT', 'RA',
        'PO (w/o Exclusive)', 'CT (w/o Exclusive)', 'RA (w/o Exclusive)'
    ], loc='lower right', ncol=2)
plt.savefig('remaining-sessions-complexity.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')
In [46]:
wc_variability = filtered.groupby(['system type', 'value variance']).mean()
wc_variability_detail = filtered.groupby(['system type', 'relation type', 'value variance']).mean()
In [47]:
plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.xlim(1, 255)
plt.ylabel('wasted capacity (%)')
plt.xlabel('path value variance')
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for system in ['standard', 'correlated']:
    plts.extend(plt.plot(
                wc_variability.loc[system].index.values,\
                wc_variability.loc[system]['wasted capacity percentage'],\
                '-'+style[system][1], color=style[system][0]))
legend = plt.legend(plts, [
        'PO', 'CT'], loc='lower right', ncol=2)
plt.savefig('wasted-capacity-variance.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')
In [48]:
plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.xlim(1, 255)
plt.ylabel('wasted capacity (%)')
plt.xlabel('path value variance')
plts = []
lgd = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for rel_type in [('AtLeastN', '-'), ('Dependent', '--'), ('Mutual', ':'), ('Exclusive', '-.')]:
    for system in ['standard', 'correlated']:
        plts.extend(plt.plot(
                    wc_variability_detail.loc[system].loc[rel_type[0]].index.values,\
                    wc_variability_detail.loc[system].loc[rel_type[0]]['wasted capacity percentage'],\
                    rel_type[1]+style[system][1], color=style[system][0]))
        lgd.append(rel_type[0]+' '+system)
legend = plt.legend(plts, lgd, loc='lower right', ncol=2)
plt.savefig('wasted-capacity-variance_detail.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')
In [49]:
plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.xlim(1, 20)
plt.ylabel('remaining (%)')
plt.xlabel('path value variance')
plts = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for system in ['standard', 'correlated', 'kasymosa']:
    plts.extend(plt.plot(
                wc_variability.loc[system].index.values,\
                wc_variability.loc[system]['remaining session percentage'],\
                '-'+style[system][1], color=style[system][0]))
legend = plt.legend(plts, [
        'PO', 'CT', 'RA'], loc='lower right', ncol=2)
plt.savefig('remaining-sessions-variance.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')
In [50]:
plt.figure(figsize=(10,7))
plt.ylim(0,100)
plt.xlim(1, 20)
plt.ylabel('wasted capacity (%)')
plt.xlabel('path value variance')
plts = []
lgd = []
style = { 'standard' : (red, 'v'), 'kasymosa' : (green, 'o'), 'correlated' : (blue, 's')}
for rel_type in [('AtLeastN', '-'), ('Dependent', '--'), ('Mutual', ':'), ('Exclusive', '-.')]:
    for system in ['standard', 'correlated', 'kasymosa']:
        plts.extend(plt.plot(
                    wc_variability_detail.loc[system].loc[rel_type[0]].index.values,\
                    wc_variability_detail.loc[system].loc[rel_type[0]]['remaining session percentage'],\
                    rel_type[1]+style[system][1], color=style[system][0]))
        lgd.append(rel_type[0]+' '+system)
legend = plt.legend(plts, lgd, loc='lower right', ncol=2)
plt.savefig('remaining-sessions-variance_detail.pdf', bbox_extra_artists=(legend,),\
            bbox_inches='tight',format='pdf')