Question

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; 2 and 3 with edge weights corresponding to 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({})
}

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:

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. Each parent node takes the count and multiplies it with the corresponding edge (e.g. 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). Then those parents also passes this message to their parents, e.g. 3 will pass a count of 7 to node 1 and node 1 will replace his count with 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? Any help, pointers or pseudo code is appreciated.

Was it helpful?

Solution

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

OTHER TIPS

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. 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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top