Python 平面上的点的最短连线网

本文介绍了作者两年前用Python解决平面上点的最短连线问题的方法,即寻找最小生成树,该问题也可通过Prim算法解决。文章提到,通过计算每个未连接点与已连接点之间的最短距离,逐步构建最短连线集合,时间复杂度为O(n^3),空间复杂度为O(n)。
摘要由CSDN通过智能技术生成

说明:

各位大佬,这篇文章是小弟两年前写的,才疏学浅,那时是当做一道面试题来做的,解决办法和正确性证明都是我自己想出来的。两年过去我已成长不少,原来这类问题叫做「最小生成树问题」,而我用的解法叫做「Prim 算法」,在 CLRS 中都有讲解。

未曾想此文今日还有人评论,故作此说明,方便想深挖的朋友按图索骥。——20201029

以下为原文↓↓

 

Python3.6.3

 如下图所示,平面上有一些点,需要将所有点连起来,使任何一个点都可以和其他点连通(直接或间接),且连接线段长度总和最短。

点

例:下面的四个点,相互连通,并且总长度是最短的。

4点

思路:共有n个点,最短连线集合f(n)一定存在。

假设有m (1≤m<n)个点,它们的最短连线集合是f(m),并且满足在f(n)中这m个点的连线也可以是f(m)。

计算剩余n-m个点与m个点的距离,最短的那条就是要求的下一条连线。

  • 9
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
下面是一个Python实现的最连线程序,可以自定义的数量和地图大小。这个程序使用了Prim算法来生成最小生成树,然后使用Dijkstra算法来找到最路径。 ```python import random import math import heapq class Point: def __init__(self, x, y): self.x = x self.y = y class Edge: def __init__(self, a, b, weight): self.a = a self.b = b self.weight = weight def distance(p1, p2): return math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2) def generate_points(num_points, map_size): points = [] for i in range(num_points): x = random.randint(0, map_size) y = random.randint(0, map_size) points.append(Point(x, y)) return points def generate_edges(points): edges = [] for i in range(len(points)): for j in range(i + 1, len(points)): distance_between_points = distance(points[i], points[j]) edges.append(Edge(i, j, distance_between_points)) return edges def prim(points): visited = [False] * len(points) visited[0] = True heap = [] for edge in generate_edges(points): if edge.a == 0: heapq.heappush(heap, (edge.weight, edge)) while heap: weight, edge = heapq.heappop(heap) if visited[edge.b]: continue visited[edge.b] = True yield edge for next_edge in generate_edges(points): if next_edge.a == edge.b and not visited[next_edge.b]: heapq.heappush(heap, (next_edge.weight, next_edge)) def dijkstra(start, end, edges): distances = [float('inf')] * len(edges) distances[start] = 0 heap = [(0, start)] while heap: current_distance, current_vertex = heapq.heappop(heap) if current_vertex == end: return current_distance if current_distance > distances[current_vertex]: continue for edge_index in range(len(edges)): if edges[edge_index].a == current_vertex: next_vertex = edges[edge_index].b distance = edges[edge_index].weight total_distance = current_distance + distance if total_distance < distances[next_vertex]: distances[next_vertex] = total_distance heapq.heappush(heap, (total_distance, next_vertex)) return float('inf') def shortest_path(points): edges = list(prim(points)) total_distance = sum(edge.weight for edge in edges) shortest_distance = float('inf') for i in range(len(edges)): edge = edges[i] distance = dijkstra(edge.a, edge.b, edges[:i] + edges[i+1:]) if distance < shortest_distance: shortest_distance = distance return total_distance, shortest_distance if __name__ == '__main__': num_points = int(input("请输入的数量:")) map_size = int(input("请输入地图大小:")) points = generate_points(num_points, map_size) total_distance, shortest_distance = shortest_path(points) print("生成的:") for point in points: print("({}, {})".format(point.x, point.y)) print("最小生成树的总距离为:{}".format(total_distance)) print("最路径的距离为:{}".format(shortest_distance)) ``` 这个程序使用了Prim算法来生成最小生成树,然后使用Dijkstra算法来找到最路径。它首先生成一个包含指定数量的的随机地图,然后计算最小生成树的总距离。接下来,它遍历所有可能的边,找到最路径的距离。 你可以通过输入的数量和地图大小来运行这个程序。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值