简体   繁体   English

如何在Python中累积有向图中的计数

[英]How to accumulate a count in directed graph in Python

I am keeping a directed acyclic graph structure in a dictionary where each key is a parent and each value is another dictionary, which maps the children of the parent with corresponding edge weights. 我在字典中保持有向非循环图结构,其中每个键是父键,每个值是另一个字典,它将父元素的子元素映射到相应的边缘权重。 For example, in the graph below, parent 1 has 2 children; 例如,在下图中,父1有2个孩子; 2 and 3 with edge weights corresponding to 2: 边缘权重对应于2的2和3:

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({})
}

I also have a frequency map for each node, where everyone has 0 counts (except the children nodes, where they have a count of 1), such that: 我还为每个节点都有一个频率图,每个节点都有0个计数(子节点除外,它们的计数为1),这样:

count_map = {i: 0 for i in range(7)}

I would like to increase the value of each node by the following scheme: each leaf (4, 5 and 6 in this case) sends a count of 1 to the upper nodes. 我想通过以下方案增加每个节点的值:每个叶子(在这种情况下为4,5和6)向上部节点发送计数1。 Each parent node takes the count and multiplies it with the corresponding edge (eg if 5 sends the count 1 to upper level, then its parent 2 will get a count of 1x2 and its other parent 3 will get a count of 1x7). 每个父节点获取计数并将其与相应的边相乘(例如,如果5将计数1发送到上一级,则其父2将获得1x2的计数,而其另一父3将获得1x7的计数)。 Then those parents also passes this message to their parents, eg 3 will pass a count of 7 to node 1 and node 1 will replace his count with 7x6. 然后这些父母也将此消息传递给他们的父母,例如3将7的计数传递给节点1,节点1将用7x6替换他的计数。 Each parent will pass the accumulated counts to upper levels until they reach to the root node. 每个父级都会将累计计数传递给上级,直到它们到达根节点。

Of course, if a node gets a message from multiple parents, it needs to add up the counts and pass it to its parent. 当然,如果节点从多个父节点获取消息,则需要将计数加起来并将其传递给其父节点。

How can I compute this count_map? 我该如何计算这个count_map? Any help, pointers or pseudo code is appreciated. 任何帮助,指针或伪代码表示赞赏。

Maybe something like this: 也许是这样的:

# 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

Our algorithm will compute the values for each node bottom-up and propagate values up to parents. 我们的算法将自下而上计算每个节点的值,并将值传播到父项。

First, we need to determine an order to iterate over the graph so that we never process a node before we're done processing its children. 首先,我们需要确定迭代图形的顺序,这样我们就不会在处理完子节点之前处理节点。 This problem is known as topological sorting ; 这个问题被称为拓扑排序 ; there are several standard algorithms. 有几种标准算法。 Note that the order we need to iterate in is the reverse of a standard topological sort order. 请注意,我们需要迭代的顺序与标准拓扑排序顺序相反。

Second, we'll need a reversed version of the graph, so we can easily determine the parents of a node and the weights of the edges leading to the parents. 其次,我们需要图形的反转版本,因此我们可以轻松确定节点的父节点和通向父节点的边的权重。 This is straightforward. 这很简单。

Now, we initialize the values of the leaves to 1 and all other values to 0. Then, we iterate over the nodes of the graph in the order determined in the first step. 现在,我们将叶子的值初始化为1,将所有其他值初始化为0.然后,我们按照第一步中确定的顺序迭代图形的节点。 For each parent of a node, we increase the parent's value by the product of the child's value and the weight of the edge linking the two nodes. 对于节点的每个父节点,我们将父节点的值乘以子节点的值与链接两个节点的边的权重。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM