influence model definition
In [8]:
topology = [("sales", "value"), ("dev costs", "value"),
("feature set", "dev costs"), ("debt amount", "dev costs"),
("feature set", "sales"),
("feature set", "decision 1"),
("decision 1", "debt amount"), ("decision 2", "debt amount"), ]
draw the model graph
In [9]:
from graphviz import Digraph
dot = Digraph(comment='Influences')
dot.edges(topology)
dot
Out[9]:
create a networkx model graph to use as a primary data structure for manipulations
In [10]:
import networkx as nx
model = nx.DiGraph()
model.add_edges_from(topology)
perform topological sort to sort nodes in the order of dependencies (and reversed)
In [11]:
ordered_nodes = nx.topological_sort(model)
reverse_ordered_nodes = nx.topological_sort(model, reverse=True)
print("topologically ordered nodes", "=", ordered_nodes)
print("topologically ordered nodes in reverse", "=", reverse_ordered_nodes)
compute variants
In [13]:
for node in ordered_nodes:
print(node, "<-", model.in_edges(node))
for edge in model.in_edges_iter(node):
pass
define options for the nodes
In [69]:
import itertools
options = {
'feature set': ('f1', 'f2', 'f3'),
'decision 2': ('d2-o1', 'd2-o2')
}
id_gen = lambda node, inputs: options[node]
uncertain_gen = lambda node, inputs: '?'
def d1_gen(node, inputs):
opts = {'f1': ('d1-o1',), 'f2': ('d1-o2',), 'f3': ('d1-o2',)}
return opts[inputs[0]]
def debt_gen(node, inputs):
d2, d1 = inputs
if d1 == 'd1-o1':
return (1.2,)
elif d1 == 'd1-o2'and d2 == 'd2-o2':
return (0.9,)
else:
return (1.0,)
def dev_gen(node, inputs):
f, debt = inputs
if f == 'f1':
effort = 1200
elif f == 'f2':
effort = 1100
else:
effort = 800
effort = effort * debt
rate = 50
return (effort * rate,)
def sales_gen(node, inputs):
opts = {'f1': (100000.0,), 'f2': (80000.0,), 'f3': (50000.0,)}
return opts[inputs[0]]
def value_gen(node, inputs):
sales, costs = inputs
return (sales - costs,)
option_generators = {
'feature set': id_gen,
'decision 2': id_gen,
'decision 1': d1_gen,
'debt amount': debt_gen,
'dev costs': dev_gen,
'sales': sales_gen,
'value': value_gen,
}
for node in ordered_nodes:
print('===', node)
related_nodes = [edge[0] for edge in model.in_edges_iter(node)]
related_options = [options[n] for n in related_nodes]
related_option_combinations = list(itertools.product(*related_options))
print('related option combinations', related_option_combinations)
node_options = []
for c in related_option_combinations:
node_options.extend(option_generators[node](node, c))
options[node] = node_options
print('node options', node_options)
In [ ]: