Python 3.x MST挑战给出了“答案”;“超过时间”;错误
我正在做我需要找到最小生成树的代价的地方。我应该遵循带有Python 3.x MST挑战给出了“答案”;“超过时间”;错误,python-3.x,algorithm,priority-queue,minimum-spanning-tree,Python 3.x,Algorithm,Priority Queue,Minimum Spanning Tree,我正在做我需要找到最小生成树的代价的地方。我应该遵循带有边和顶点实例的结构。在这种情况下,顶点表示城市 我得到了一个“超时”错误,我觉得循环迭代次数太多是原因,但这是我能做的最好的了。我想尝试一下二进制排序,看看它是否适用于此,但这并不容易,因为它应该使用City类中的key属性进行排序 样本输入 样本的输出 我的代码 导入系统 进口heapq 级别城市: 定义初始(自我,城市id): self.city\u id=city\u id self.key=float('inf') self.par
边
和顶点
实例的结构。在这种情况下,顶点表示城市
我得到了一个“超时”错误,我觉得循环迭代次数太多是原因,但这是我能做的最好的了。我想尝试一下二进制排序,看看它是否适用于此,但这并不容易,因为它应该使用City
类中的key
属性进行排序
样本输入
样本的输出
我的代码
导入系统
进口heapq
级别城市:
定义初始(自我,城市id):
self.city\u id=city\u id
self.key=float('inf')
self.parent=None
self.edge_list=list()
自我访问=错误
#self.city\u name=无
def未被访问(自身):
如果self.visited为False:
返回真值
返回错误
def添加_邻居(自身、边缘):
self.edge\u list.append(边缘)
定义(自身、其他):
返回self.keysorted
调用使解决方案效率低下。您有一些注释掉的代码依赖于heapq
,这确实是避免每次更改队列时必须对其进行排序的方法。无论如何,我不明白为什么要按城市id对队列进行排序。如果有的话,应该按键进行排序
虽然它可以像您那样使用键
属性,但对我来说,将边添加到队列(堆)而不是顶点似乎更自然,因此您可以将边成本作为堆属性的基础。此外,该队列不应该从一开始就包含所有项,而是在算法期间选择它们时添加它们。这与MST构建算法相对应,MST构建算法一个接一个地添加边,每次都添加成本最低的边
如果边被推到堆上,则它们必须具有可比性。因此,必须像对Vertex类所做的那样,在Edge类上实现\uUlt\uUu
class Edge:
# ... your code remains unchanged... Just add:
def __lt__(self, other):
return self.cost < other.cost
def MST(vertices_list):
# first edge in the queue is a virtual one with zero cost.
queue = [Edge(vertices_list[0], 0)] # heap of edges, ordered by cost
total_weight = 0
while queue:
mst_edge = heapq.heappop(queue) # pop both cost & vertex
current = mst_edge.to_vertex
if current.visited: continue
for edge in current.edge_list:
if not edge.to_vertex.visited:
heapq.heappush(queue, edge)
current.visited = True
total_weight += mst_edge.cost
sys.stdout.write("{0}\n".format(total_weight))
类边缘:
# ... 您的代码保持不变。。。只需添加:
定义(自身、其他):
返回自成本<其他成本
def MST(顶点列表):
#队列中的第一条边是零成本的虚拟边。
队列=[边(顶点列表[0],0)]#边堆,按成本排序
总重量=0
排队时:
mst_edge=heapq.heapop(队列)#同时弹出成本和顶点
当前=mst_边到_顶点
如果当前已访问:继续
对于current.edge_列表中的边:
如果未访问edge.to_vertex.visited:
heapq.heappush(队列,边缘)
当前访问量=真
总重量+=mst\U边缘成本
sys.stdout.write(“{0}\n”.format(总重量))
Tip:搜索最小生成树。那么你的问题是什么?我正在进行MST,正如你所看到的,如果没有访问顶点,则更新键值。总重量仅用于输出。但是,我得到了超出时间的错误,我不知道是什么原因造成的。您使用的是哪种算法?按键值排序是错误的,但我将尝试使用您的算法。非常感谢您的回答,尽管这个问题很糟糕,为什么在lt中返回0?还有“heapq.heappush(queue,(path_weight+edge.cost,edge)),我不明白这部分。路径权重可能是关键,即来源和边缘的成本。成本可能意味着
3
4
import sys
import heapq
class City:
def __init__(self, city_id):
self.city_id = city_id
self.key = float('inf')
self.parent = None
self.edge_list = list()
self.visited = False
#self.city_name = None
def is_not_visited(self):
if self.visited is False:
return True
return False
def add_neighbor(self, edge):
self.edge_list.append(edge)
def __lt__(self, other):
return self.key < other.key
class Edge:
def __init__(self, to_vertex, cost):
self.to_vertex = to_vertex
self.cost = cost
#
# def find_and_pop(queue):
# min = queue[0]
# index = 0
# for a in range(0, len(queue)):
# if queue[a].key < min.key:
# min = queue[a]
# index = a
# return queue.pop(index)
#
def MST(vertices_list):
queue = vertices_list
current = queue[0]
current.key = 0
#visited_list = list()
#heapq.heapify(queue)
total_weight = 0
while queue:
#current = find_and_pop(queue)
current = queue.pop(0)
for edge in current.edge_list:
if edge.to_vertex.is_not_visited():
if edge.cost < edge.to_vertex.key:
edge.to_vertex.key = edge.cost
edge.to_vertex.parent = current
total_weight = total_weight + current.key
current.visited = True
queue = sorted(queue, key=lambda x: x.city_id)
#heapq.heapify(queue)
#visited_list.append(current)
# total_weight = 0
# for x in visited_list:
# total_weight = total_weight + x.key
sys.stdout.write("{0}\n".format(total_weight))
class TestCase:
def __init__(self, vertices):
self.vertices = vertices
testcases = []
def main():
case_num = int(sys.stdin.readline())
#skip_line = sys.stdin.readline()
for n_case in range(0, case_num):
sys.stdin.readline()
vertices_list = list()
number_of_city = int(sys.stdin.readline())
#interate and make for the time of number of cities
for n_city in range(0, number_of_city):
city = City(n_city)
vertices_list.append(city)
for n_city in range(0, number_of_city):
c_name = sys.stdin.readline()
#vertices_list[n_city].city_name = c_name
num_neighbor = int(sys.stdin.readline())
for n_neigh in range(0, num_neighbor):
to_city_cost = sys.stdin.readline()
to_city_cost = to_city_cost.split(" ")
to_city = int(to_city_cost[0])
cost = int(to_city_cost[1])
edge = Edge(vertices_list[to_city-1], cost)
vertices_list[n_city].edge_list.append(edge)
testcase = TestCase(vertices_list)
testcases.append(testcase)
count = 0
for testcase in testcases:
MST(testcase.vertices)
# if count < case_num -1:
# print()
# count = count + 1
if __name__ == "__main__":
main()
class Edge:
# ... your code remains unchanged... Just add:
def __lt__(self, other):
return self.cost < other.cost
def MST(vertices_list):
# first edge in the queue is a virtual one with zero cost.
queue = [Edge(vertices_list[0], 0)] # heap of edges, ordered by cost
total_weight = 0
while queue:
mst_edge = heapq.heappop(queue) # pop both cost & vertex
current = mst_edge.to_vertex
if current.visited: continue
for edge in current.edge_list:
if not edge.to_vertex.visited:
heapq.heappush(queue, edge)
current.visited = True
total_weight += mst_edge.cost
sys.stdout.write("{0}\n".format(total_weight))