微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python-TypeError:“图形”对象不可下标

如何解决Python-TypeError:“图形”对象不可下标

我正在实现一个 Graph 类,将广度优先搜索与 Prim 的算法进行比较,并且我有我的代码

class Graph:
    def __init__(self,n):

        """This is an initialization function to creat a random graph with a specified number of vertices"""
        self.graph = [[inf for i in range(n)] for i in range(n)]
        self.number = n
        self.edge = tuple(range(n))
        for i in self.edge[1:]:
            j = random.randint(1,i)
            k = random.sample(range(i),j)
            for l in k:
                weight = random.randint(1,100)
                self.graph[i][l] = self.graph[l][i] = weight

    def get_neighbours(self,i):

        """This is a function used to get neighbours of the specified vertex"""
        neighbours = []
        for e in self.edge:
            if self[i][e] < inf:
                neighbours.append(e)
        return neighbours

    def breadth_first_search(self):
        """
        This is a function used to return the total of the weight of the edges from a randomly-selected vertex
        :return: the total of the weight of the edges
        """
        all = set(self.edge)
        q = deque([all.pop()])
        total_weight = 0
        while q:
            i = q.popleft()
            for j in self.get_neighbours(i):
                if j in all:
                    all.remove(j)
                    q.append(j)
                    total_weight = total_weight + self.graph[i][j]
        return total_weight

    def test_bfst(self):
        """
        This function is used to test breadth first search tree
        :return:
        """
        graph = [
            [inf,15,inf,7,10,inf],[15,9,11,9],[inf,12,7],[7,8,14],[10,8],14,inf]
        ]
        self.graph = graph
        print(self.breadth_first_search())

    def prime_mst(self):
        """
        This is prime's minimum spanning tree algorithm
        :return: the total of the weight of the edges
        """
        all = set(self.edge)
        list = [inf for i in self.edge]
        i = all.pop()
        total_weight = 0
        while True:
            for j in self.get_neighbours(i):
                if (i in all) and (k := self.graph[i][j] < list[j]):
                    list[j] = k

            if all:
                average_min,min = sorted([(j,list[j]) for j in all],key=lambda group: group[1])[0]
                all.remove(average_min)
                total_weight += min
                i = average_min
            else:
                break

        return total_weight


if __name__ == "__main__":
    times = int(input("please input an positive integer which represents testing times:"))
    for n in [20,40,60]:
        graph = Graph(n)
        diff = 0
        for i in range(times):
            bfs = graph.breadth_first_search()
            pmst = graph.prime_mst()
            diff = diff + (bfs - pmst) / pmst
        diff = diff / times
        print(diff)

而我运行代码时的错误是这样的:

Traceback (most recent call last):
  File "C:\Users\52799\Desktop\Bsf_Prims\BSFvPRIM.py",line 99,in <module>
    bfs = graph.breadth_first_search()
  File "C:\Users\52799\Desktop\Bsf_Prims\BSFvPRIM.py",line 45,in breadth_first_search
    for j in self.get_neighbours(i):
  File "C:\Users\52799\Desktop\Bsf_Prims\BSFvPRIM.py",line 31,in get_neighbours
    if self[i][e] < inf:
TypeError: 'Graph' object is not subscriptable

我想我在获取顶点邻居时可能会出错,但我不知道为什么会出现这个错误。我的测试图更像是一个带有节点的矩阵。我有点坚持获取邻居,其余两个算法稍后会改进。

解决方法

当你这样说时:

if self[i][e] < inf:

您试图从对象的实例中获取特定项目,就好像它是一个容器,例如序列或映射类型,例如实现 __getitem__() 方法的东西,如列表或字典。

值得注意的是,字符串和字节串也被认为是序列并实现了 __getitem__() 方法,这意味着它们也是可下标的:

In [1]: from typing import Sequence                                             

In [2]: string = "something"                                                    

In [3]: isinstance(string,Sequence)                                            
Out[3]: True

In [4]: string[2]                                                              
Out[4]: 'm'

您可能想在此处指定特定属性,例如:

if self.graph[i][e] < inf:

我对您在做什么还不够熟悉,无法确定您在这里的意图是什么,但您想要类似上面的内容。您不想“下标”类实例本身,而是一些具有可下标容器值的属性。

如果您确实需要该类可下标,则需要添加一个 __getitem__() 方法,如映射或序列。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。