Cyclopts Results Investigation

This notebook provides a series of tools to confirm expected behavior of solutions and investigate possible errors thereof.


In [1]:
from __future__ import print_function

%matplotlib inline
%load_ext autoreload
%autoreload 2

import matplotlib.pyplot as plt
import numpy as np
import tables as t
from collections import defaultdict
import os
import uuid

from cyclopts import tools


The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload

In [4]:
prefix = '../../exec/run_results/small-long-times'
fname = 'combined.h5'
f = t.open_file(os.path.join(prefix, fname), mode='r')

props = f.root.Instances.ExchangeInstProperties
arcs = f.root.Instances.ExchangeArcs
nodes = f.root.Instances.ExchangeNodes
samplers = f.root.ReactorRequestSampler
grps = f.root.Instances.ExchangeGroups
results = f.root.Results.General
solns = f.root.Instances.ExchangeInstSolutions

inst_to_param = {}
for x in props.iterrows():
    inst_to_param[x['instid']] = x['paramid']

soln_to_inst = {}
inst_to_soln = defaultdict(list)
for x in results.iterrows():
    soln_to_inst[x['solnid']] = x['instid']
    inst_to_soln[x['instid']].append(x['solnid'])

soln_to_param = {}
for s, i in soln_to_inst.items():
    soln_to_param[s] = inst_to_param[i]

Sanity Checks on Data


In [6]:
req_grp_qtys = defaultdict(float)
total_mass_flow = defaultdict(float)
total_node_qty = {}

for x in grps.iterrows():
    if x['kind']: # true == req, false == bidtotal_flows = sum(flows)
        req_grp_qtys[x['instid']] += x['caps'][0]
    
for x in samplers.iterrows():
    total_node_qty[x['paramid']] = \
        x['assem_per_req_avg'] * x['n_request_avg'] * x['req_qty_avg']

# test modeling assumption that the group mass constraint
# is equal to the expected total request quantity
iids = req_grp_qtys.keys()
obs = [req_grp_qtys[iid] - total_node_qty[inst_to_param[iid]] for iid in iids]
exp = [0] * len(total_node_qty)
np.testing.assert_array_equal(exp, obs)
print(('Group quantity constraint equals the number of '
       'requested assemblies as expected.'))
    
for x in solns.iterrows():
    total_mass_flow[x['solnid']] += x['flow']

# test truth that total flows are at most equal
# to the group mass constraint being precisely equal
tol = 1e-8
bad = []
good_eq = []
good_lt = []
for sid, iid in soln_to_inst.items():
    diff = total_mass_flow[sid] - req_grp_qtys[iid]
    if diff > tol:
        bad.append((sid, iid, diff))
    elif diff < -tol:
        good_lt.append((sid, iid))
    else:
        good_eq.append((sid, iid))

if len(bad) > 0:
    print("{0} runs had more mass flow than total group qty.".format(len(bad)))

frac_equal = len(good_eq) / float(len(good_eq) + len(good_lt))
print(('Of flows with expected total mass behavior, '
       '{:.2%} meet total request demand.'.format(frac_equal)))


Group quantity constraint equals the number of requested assemblies as expected.
617 runs had more mass flow than total group qty.
Of flows with expected total mass behavior, 79.65% meet total request demand.

In [3]:

# # this cell is raw text and intended to be a place from which common operations can be copy/pasted # http://imgur.com/Q3ai1U7 iids = set(iid for _, iid, _ in bad) sids = set(sid for sid, _, _ in bad) pids = set(inst_to_param[x] for x in iids) print("n in list not in set:", len(bad) - len(iids), '\n') x = set(x['solver'] for x in results.iterrows() if x['solnid'] in sids) print('solvers with incorrect answers:', ' '.join(x), '\n') x = set(x['req_qty_avg'] for x in samplers.iterrows() \ if x['paramid'] in pids) print('Request quantities with incorrect answers:', x, '\n') min_iid = '86f45b85b8c04d028308cdc3cd17795c' print('testing ', min_iid, '\n') min_iid = uuid.UUID(min_iid).bytes x = [x['n_commods_avg'] for x in samplers.iterrows() \ if x['paramid'] == inst_to_param[min_iid]] print('N commods in this inst:', x[0], '\n') caps = [x['caps'][0] for x in grps.iterrows() \ if x['instid'] == min_iid and x['kind']] print('That instid has a total request quantity of', sum(caps), '\n') caps = [x['caps'][0] for x in grps.iterrows() \ if x['instid'] == min_iid and x['kind']] print('req group caps', caps, '\n') caps = [x['caps'][0] for x in grps.iterrows() \ if x['instid'] == min_iid and not x['kind']] print('sup group caps', caps, '\n') caps = [x['ucaps'][0] for x in arcs.iterrows() \ if x['instid'] == min_iid] print('node caps', caps, '\n') qtys = [x['qty'] for x in nodes.iterrows() \ if x['instid'] == min_iid and x['kind']] print('node request qtys', qtys, '\n') excls = [x['excl'] for x in nodes.iterrows() \ if x['instid'] == min_iid and x['kind']] print('node request excl', excls, '\n') efracs = [x['excl_frac'] for x in props.iterrows() \ if x['instid'] == min_iid] print('excl_fraction', efracs, '\n') nper = [x['n_u_nodes']/float(x['n_u_grps']) for x in props.iterrows() \ if x['instid'] == min_iid] print('req nodes per req', nper, '\n') nper = [x['n_v_nodes']/float(x['n_v_grps']) for x in props.iterrows() \ if x['instid'] == min_iid] print('sup nodes per sup', nper, '\n')

In [4]:
import uuid
hexid = '86f45b85b8c04d028308cdc3cd17795c'
iid = uuid.UUID(hexid)

In [4]: