python - 如何从图形数据中标记作为循环中初始顶点的节点
问题描述
我需要实现一种算法,以便在一组唯一且有序的图边中,我可以找到一个循环节点。
例如 for a ->b, b->c, c->a
, then'a'
是一个循环节点,因此我想在这条边上注释它,'a@'
并且对其他人类似。
作为示例数据,我使用它:
a = [('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a'), ('a', 'e'), ('e', 'a'), ('f', 'e')]
那么这将变成:
[('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a@'), ('a', 'e'), ('e', 'a@'), ('f', 'e')]
我怎样才能在python中实现这一点?
这是我尝试过的:
collection = {}
data, result = [], []
for i, j in a:
if i in collection.keys():
collection[i].append(j)
else:
collection[i] = [j]
if j in collection.keys():
for item in range(len(collection[i])):
if collection[i][item] == j:
nr += 1
collection[i][item] = j + '@'
print(collection)
它似乎适用于循环,但它也考虑了不是循环的强连接组件。所以我正在寻找类似 networkx 简单循环(无子循环)的东西,我也需要像上面这样以这种方式返回数据。
解决方案
该解决方案构建了它在边缘列表中遇到的所有可能路径,因为我们并不真正知道循环从哪里开始。如果您的图表很大,它还会修剪它创建的路径列表以防止一些内存膨胀。它很丑陋,但可以根据您的需要工作。
a = [('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a'), ('a', 'e'), ('e', 'a'), ('f', 'e')]
annotated = []
paths = []
for edge in a:
new_paths = []
paths.append(''.join(edge))
annotated.append(edge)
cycle = ''
for path in paths[:]:
if path.endswith(edge[0]):
if path.startswith(edge[1]):
annotated[-1] = (annotated[-1][0], annotated[-1][1]+'@')
cycle = path + edge[1]
else:
new_paths.append(path + edge[1])
else:
new_paths.append(path)
paths = [x for x in new_paths if x not in cycle]
print(paths)
print(f'Result: {annotated}')
"""
Out:
['ab']
['abc', 'bc']
['abcd', 'bcd', 'cd']
[]
['ae']
[]
['fe']
Result: [('a', 'b'), ('b', 'c'), ('c', 'd'), ('d', 'a@'), ('a', 'e'), ('e', 'a@'), ('f', 'e')]
"""
推荐阅读
- python - 如何重构代码以使源代码中的每个列表都排序?
- mercurial - 推/拉一个未命名的分支,留下其他(拓扑不相关的)未命名的分支?
- google-apps-script - 如何在提交 Google 表单时生成新的 G-Drive 文件夹并复制模板文件
- java - 两个 LocalDate 对象之间的周期计算似乎已关闭
- c++ - 实例正确声明
- hive - 如何使用 python 连接到 HIVE?
- reactjs - React 和 Jest - 使用 PropTypes.instanceOf 测试组件
- python - 创建后使用 Button 将 HBox 添加到 VBox
- javascript - 如何将 React 组件连接到 Laravel Blade
- angular - Angular 8:router.navigate,跳过状态更改但保持“历史步骤”