在BFS / DFS中对边进行排序

时间:2018-01-25 21:55:59

标签: python sorting graph

我正在解决边缘排序的问题,其中边缘存储在元组形式(node_i, node_j)中,如下所示

>> edgeLst
>> [('123','234'),
    ('123','456'),
    ('123','789'),
    ('456','765'),
    ('456','789')
    ('234','765')]

请注意,边缘是唯一的,如果您看到('123', '234'),则不会看到('234', '123')(图表未定向)。并且图表中可能存在循环。由于图形非常大,任何人都可以向我展示使用给定的起始节点对BFS和DFS中的边进行排序的有效方法,例如'123'

演示输出:

>> edgeSorting(input_lst=edgeLst, by='BFS', start_node='123')
>> [('123','234'),
    ('123','456'),
    ('123','789'),
    ('234','765')
    ('456','765'),
    ('456','789')]

1 个答案:

答案 0 :(得分:0)

以下是如何为BFS和DFS执行此操作:

from collections import defaultdict
def sorted_edges(input_lst, by, start_node):
    # Key the edges by the vertices
    vertices = defaultdict(lambda: [])
    for u, v in input_lst:
        vertices[u].append(v)
        vertices[v].append(u)
    if by == 'DFS':
        # Sort the lists
        for lst in vertices:
            lst = sorted(lst)
        # Perform DFS
        visited = set()
        def recurse(a):
            for b in vertices[a]:
                if not (a, b) in visited:
                    yield ((a,b))
                    # Make sure this edge is not visited anymore in either direction
                    visited.add((a,b))
                    visited.add((b,a))
                    for edge in recurse(b):
                        yield edge
        for edge in recurse(start_node):
            yield edge
    else: #BFS
        # Collect the edges
        visited = set()
        queue = [start_node]
        while len(queue):
            for a in queue: # Process BFS level by order of id
                level = []
                for b in vertices[a]:
                    if not (a, b) in visited:
                        yield ((a,b))
                        # Add to next level to process
                        level.append(b)
                        # Make sure this edge is not visited anymore in either direction
                        visited.add((a,b))
                        visited.add((b,a))
            queue = sorted(level)


edgeLst = [('123','234'),
('123','456'),
('123','789'),
('456','765'),
('456','789'),
('234','765')]

print (list(sorted_edges(edgeLst, 'DFS', '123')))

在Python 3中,您可以简化:

for edge in recurse(b):
    yield edge

为:

yield from recurse(b)

...和start_node相同。