我在字典中保留有向非循环图结构,其中每个键都是父键,每个值都是另一个字典,它将父元素的子元素映射到相应的边缘权重。例如,在下图中,父1有2个孩子; 2和3的边缘权重对应于2:
g = {
0: Counter({1: 1}),
1: Counter({2: 2, 3: 6}),
2: Counter({4: 3, 5: 2, 6: 1}),
3: Counter({6: 2, 5: 7}),
4: Counter({}),
5: Counter({}),
6: Counter({})
}
我还有每个节点的频率图,每个节点都有0个计数(子节点除外,它们的计数为1),这样:
count_map = {i: 0 for i in range(7)}
我想通过以下方案增加每个节点的值:每个叶子(在这种情况下为4,5和6)向上部节点发送1的计数。每个父节点获取计数并将其与相应的边相乘(例如,如果5将计数1发送到上一级,则其父2将获得1x2的计数,而其另一父3将获得1x7的计数)。那些父母也将这个信息传递给他们的父母,例如3将计数7传递给节点1,节点1将用7x6替换计数。每个父级都会将累积的计数传递给上级,直到它们到达根节点。
当然,如果节点从多个父节点获取消息,则需要将计数加起来并将其传递给其父节点。
如何计算此count_map?任何帮助,指针或伪代码表示赞赏。
答案 0 :(得分:2)
也许是这样的:
# x = root node
def acyc(graph,x=0):
node = graph[x]
if len(node) == 0:
return {x:1}
# call self on children
count_map = {}
for i in node:
count_map.update(acyc(graph,i))
count_map[x] = sum([node[i]*count_map[i] for i in node])
return count_map
答案 1 :(得分:1)
我们的算法将自下而上计算每个节点的值,并将值传播到父级。
首先,我们需要确定一个迭代图形的顺序,这样我们就不会在处理完子节点之前处理它。这个问题被称为topological sorting;有几种标准算法。请注意,我们需要迭代的顺序与标准拓扑排序顺序相反。
其次,我们需要图形的反转版本,因此我们可以轻松确定节点的父节点和通向父节点的边的权重。这很简单。
现在,我们将叶子的值初始化为1,将所有其他值初始化为0.然后,我们按照第一步中确定的顺序迭代图形的节点。对于节点的每个父节点,我们将父节点的值乘以子节点的值与链接两个节点的边的权重。