Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x MST挑战给出了“答案”;“超过时间”;错误_Python 3.x_Algorithm_Priority Queue_Minimum Spanning Tree - Fatal编程技术网

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.keyMST循环中的
sorted
调用使解决方案效率低下。您有一些注释掉的代码依赖于
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))