在有向树中递归添加值

时间:2018-03-16 06:45:51

标签: python algorithm recursion tree directed-graph

早上好,我的数据结构为树。除根之外的每个节点都有属性 - '相对于父节点的比例'。但只是叶子有额外的属性'价值'。我想要做的是编写一个函数来计算树中所有节点的值。
例如,在下图中,它们将按如下方式计算:

value of b= 5*0.3 + 6*0.7 = 5.7;
value of c= 7*1 = 7;
value of d = 8*0.5+9*0.4+10*0.1=8.6;
value of a = 5.7*0.3+7*0.4+8.6*0.3=7.09;

我假设从数据结构的本质 - 这个设置节点值的函数 - 应该是递归的。 如果有人在python中提供描述,伪代码或函数,将会感激不尽。

这是树的图像: data structure

现在按照Srinivas的建议,我试过了:

import networkx as nx
from networkx.algorithms.traversal.depth_first_search import dfs_tree
t=nx.DiGraph()

nds=[{"name":"a"},{"name":"b","proportion":"0.3"},{"name":"c","proportion":"0.4"},{"name":"d","proportion":"0.3"},{"name":"e","proportion":"0.3","value":"5"},{"name":"f","proportion":"0.7","value":"6"},{"name":"g","proportion":"1","value":"7"},{"name":"h","proportion":"0.5","value":"8"},{"name":"i","proportion":"0.4","value":"9"},{"name":"j","proportion":"0.1","value":"10"}]
for nd in nds:
 t.add_node(nd['name'],**nd)

eds=[('a','b'),('a','c'),('a','d'),('b','e'),('b','f'),('c','g'),('d','h'),('d','i'),('d','j')]
for ed in eds:
 t.add_edge(ed[0],ed[1])

def answer(node):
    if node not in t: # no tree
        return 0
    if len(list(t.successors(node)))==0: # leaf
        return float(t.node[node]['value'])
    value_list = []
    for child in list(t.successors(node)):
        value_list.append(float(t.node[child]['proportion']) * answer(child))
    t.node[node]['value']=sum(value_list)

answer('a')

但是它给出了一个错误:TypeError:*:'float'和'NoneType'的不支持的操作数类型。我认为由于某种原因,它可以做一个早午餐 - a-> b-> e a-> b-> f但不能进入下一个......

1 个答案:

答案 0 :(得分:0)

一些初始代码本来不错,但这是我的镜头。

这会有用吗?

 #Assuming you've defined root, leaf as special subclasses of type node. 
    #With the root having no proportion attrib set.

 def answer(node):
    if not node: # no tree
        return 0
    if node.children = []: # leaf
        return node.value
    value_list = []
    for child in node.children:
        value_list.append(child.proportion * answer(child))
    node.value = sum(value_list)

说明:考虑一个类似于您概述的结构。

使用根answer(root)调用答案功能。 这反过来在b上调用它,并在e上调用它。 e是一个返回其值的叶子。然后是f。功能回溯到现在具有值b的{​​{1}}。等等......