繁体   English   中英

如何对图的路径进行排序

[英]How to sort a path of a graph

我一直在尝试对图表的路径进行排序。

例如,我在 python 中有以下列表。

graph = [
  [4, 6], [6, 8], [8, 3], [3, 7], [7, 5], [5, 2], [1, 0], [0, 2], [4, 1]
]

结果必须是,

graph = [
  [0, 2], [2, 5], [5, 7], [7, 3], [3, 8], [8, 6], [6, 4], [4, 1], [1, 0]
]

0 -> 2 -> 5 -> 7 -> 3 -> 8 -> 6 -> 4 -> 1 -> 0

前提是路径以初始值为零 (0) 的边开始,以最后一个元素也为零的边结束。

这是另一个例子:

graph = [
  [0, 4], [4, 6], [8, 3], [3, 7], [5, 2], [2, 1], [1, 0], [7, 6], [5, 8]
]

结果需要是:

graph = [
  [0, 1], [1, 2], [2, 5], [5, 8], [8, 3], [3, 7], [7, 6], [6, 4], [4, 0]
]

0 -> 1 -> 2 -> 5 -> 8 -> 3 -> 7 -> 6 -> 4 -> 0

方向无所谓。

我从这段代码开始。

def sort_graph(graph):
  sorted_graph = []
  for edge in graph:
    if edge[0] == 0:
      sorted_graph.append(edge)
  for edge in graph:
    if edge[0] != 0:
      sorted_graph.append(edge)
  return sorted_graph

但我不知道从这里去哪里。

对于循环中的每个节点,跟踪它的两个邻居。 然后,您可以遍历这些邻居以生成节点的排序。 一旦你到达一个节点,两个邻居都已经被访问过,你就完成了。

neighbors = {}
for fst, snd in graph:
    neighbors.setdefault(fst, []).append(snd)
    neighbors.setdefault(snd, []).append(fst)

seen_both_neighbors = False
current = 0
path = []
seen = set()
while not seen_both_neighbors:
    path.append(current)
    fst, snd = neighbors[current]

    if fst not in seen:
        seen.add(current)
        current = fst
    elif snd not in seen:
        seen.add(current)
        current = snd
    else:
        seen_both_neighbors = True
    
result = list(map(list, zip(path, path[1:] + [path[0]])))
print(result)

对于您的两个示例,这都会产生正确的排序答案。

这是一个有趣的问题要解决! 这是我对这种方法的想法:

  1. 查找所有对(向前和向后)
  2. 创建查找表以轻松导航它们
  3. 从 0 开始,遍历并移除你已经访问过的节点
from itertools import chain
import random

graph = [
  [4, 6], [6, 8], [8, 3], [3, 7], [7, 5], [5, 2], [1, 0], [0, 2], [4, 1]
]

# find all pairs independent of their direction
all_pairs = [*graph, *([t, f] for f, t in graph)]

# find all nodes
nodes = set(chain(*all_pairs))

# create a lookup dictionary for each point to show where you could go to
lookup = {node: {to_ for (from_, to_) in all_pairs if from_ == node} for node in nodes}


# simple solution - take a random path
from_ = 0
to_ = None

sorted_graph = []
while to_ != 0:
    # select a random next point
    to_ = random.choice(list(lookup[from_]))
    
    # make sure to delete it so it doesn't get used again
    lookup[from_].remove(to_)
    lookup[to_].remove(from_)
    
    # add to output
    sorted_graph.append((from_, to_))
    
    # tick one step forward
    from_ = to_

print(sorted_graph)

您还可以实现循环,如下所示:

def cycle(vec):
    result = [vec[0]]
    s = vec[1:]
    index = 0
    while s:
        if result[-1][0] == 0: 
            start = index
        for i,v in enumerate(s):
            if result[-1][1] in v:
                del s[i]
                result.append(v if v[0] == result[-1][1] else v[::-1])
                break
        index += 1
    return result[start:] + result[:start]

cycle(graph)
 [[0, 1], [1, 4], [4, 6], [6, 8], [8, 3], [3, 7], [7, 5], [5, 2], [2, 0]]
      

暂无
暂无

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

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