我有一个X和Y点的列表,这些点将被导入到程序中。我想知道是否可以建立一个目录以连接它们?几乎像树形图,但不是使用边,而是使用x和y点。
示例中的[0]
将作为起点,数字将是导入文件中的点。
例如
----4------5
|
8------7-----6----[0]------1-------2-----3
|
9---
我发现了一种称为Breadth-first search
的算法,如果给出起点和终点,它就能确定最佳路径。我知道算法是用于搜索可能的路径,而不是确定路径。如果给出了上面示例中的要点。
point X Y
0 0 0
1 1 0
2 2 0
3 3 0
4 1.5 0.5
5 2.5 0.5
6 -1 0
7 -2 0
8 -3 0
9 -2.5 -0.5
我希望以上几点产生一个类似的目录。
graph = {
'0': ['1', '6'],
'1': ['2', '4'],
'2': ['3'],
'4': ['5'],
'6': ['7'],
'7': ['8','9']
}
我为here找到了一个很好的示例Breadth-first Search,但是它需要已经构造的目录构造函数。任何帮助或建议,我们感激不尽。
宽度优先Search.py
def bfs(graph, start, end):
queue = []
queue.append([start])
while queue:
path = queue.pop(0)
node = path[-1]
if node == end:
return path
for adjacent in graph.get(node, []):
new_path = list(path)
new_path.append(adjacent)
queue.append(new_path)
print(bfs(graph, '0', '5'))
答案 0 :(得分:0)
假设您打算在结果中包含5
作为键,则可以使用递归来创建所需的字典:
import math, collections
data = {0.0: [0.0, 0.0], 1.0: [1.0, 0.0], 2.0: [2.0, 0.0], 3.0: [3.0, 0.0], 4.0: [1.5, 0.5], 5.0: [2.5, 0.5], 6.0: [-1.0, 0.0], 7.0: [-2.0, 0.0], 8.0: [-3.0, 0.0], 9.0: [-2.5, -0.5]}
def group(d, start, seen = []):
x, y = d[start]
r = [a for a, [j, k] in d.items() if a != start and a not in seen and math.hypot(abs(x-j), abs(y-k)) <= 1]
if not r:
return {}
result = {start:r}
for i in r:
result.update(group(d, i, seen+[start, *r]))
return result
result = group(data, 0)
输出:
{0: [1.0, 6.0], 1.0: [2.0, 4.0], 2.0: [3.0, 5.0], 4.0: [5.0], 5.0: [3.0], 6.0: [7.0], 7.0: [8.0, 9.0]}
将值转换为字符串:
new_result = {str(int(a)):list(map(str, map(int, b))) for a, b in result.items()}
输出:
{'0': ['1', '6'], '1': ['2', '4'], '2': ['3', '5'], '4': ['5'], '5': ['3'], '6': ['7'], '7': ['8', '9']}
答案 1 :(得分:0)
正如您所说,广度优先搜索并不是找到给定两个节点的最佳路径的算法,它只会告诉您是否存在连接它们的路径。如果您想要最佳路径,则可以使用三种著名的算法:Dijkstra,Bellman-Ford和Floyd-Warshall。对于您而言,我相信Dijkstra将是最佳选择。
Python中有一个易于使用且很棒的库来处理图形,它称为Networkx。对于涉及图的几乎每个问题,它都有很多方法,包括我提到的算法。这是在此库上实现的Dijkstra's algorithm的链接。