简体   繁体   中英

Traversing relative nodes of graph in Python

Thanks in advance. I have a graph built by T-SQL and in the format of JSON. like the bellow:

  • "NodeId" is the Id of node
  • "N" is a related node (id)

How can I traverse all relative (at any level) to the requested nodes of the graph in Python?

[{"NodeId":"1","N":"2"},
{"NodeId":"1","N":"3"},
{"NodeId":"3","N":"5"},
{"NodeId":"5","N":"6"},
{"NodeId":"2","N":"4"},
{"NodeId":"9","N":"7"}]

The expected result should list of all relative nodes of the requested node in order of level (in any format). One output list like:

Input (node id) << "1":

Output >> ["2", "3", "5", "4", "6"]

You can use a "Depth First Search" or "Breadth First Search".

If you want "Level Order" then set the second parameter depth=False .

from collections import deque

def get_nodes(nodes, start_node, depth=True):
    graph = {}

    for node in nodes:
        graph.setdefault(node['NodeId'], []).append(node['N'])

    seen = set()
    d = deque()

    d.extend(graph[start_node])

    while d:
        cur_node = d.pop() if depth else d.popleft()

        if cur_node in seen:
            continue

        seen.add(cur_node)
        yield cur_node
        d.extend(graph.get(cur_node, []))

nodes = [{"NodeId":"1","N":"2"}, {"NodeId":"1","N":"3"}, {"NodeId":"3","N":"5"}, {"NodeId":"5","N":"6"}, {"NodeId":"2","N":"4"}, {"NodeId":"9","N":"7"}]

Output (directed)

print(list(get_nodes(nodes, '1', True)))
['3', '5', '6', '2', '4']
print(list(get_nodes(nodes, '1', False)))
['2', '3', '4', '5', '6']

If the graph is undirected then add

graph.setdefault(node['N'], []).append(node['NodeId']) to the for loop.

Like so

for node in nodes:
    graph.setdefault(node['NodeId'], []).append(node['N'])
    graph.setdefault(node['N'], []).append(node['NodeId'])

Now the output will look like (undirected)

print(list(get_nodes(nodes, '1', True)))
['3', '5', '6', '1', '2', '4']
print(list(get_nodes(nodes, '1', False)))
['2', '3', '1', '4', '5', '6']

You can use a recursive generator function:

d = [{'NodeId': '1', 'N': '2'}, {'NodeId': '1', 'N': '3'}, {'NodeId': '3', 'N': '5'}, {'NodeId': '5', 'N': '6'}, {'NodeId': '2', 'N': '4'}, {'NodeId': '9', 'N': '7'}]
def get_nodes(n, s = []):
  yield n
  for i in d:
     if i['NodeId'] == n and i['N'] not in s:
        yield from get_nodes(i['N'], s+[n])

_, *result = get_nodes('1')

Output:

['2', '4', '3', '5', '6']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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