2015-11-07 44 views
0

所以我在一個Graph上實現BFS來檢測所有的週期。我通過一個鄰接表實現了圖形。但是當我運行我的代碼時,出現以下錯誤Python認爲對象實例是列表對象

Traceback (most recent call last): 
    File "C:\Python27\Data Structures\Graph\bfstree.py", line 228, in <module> 
    main() 
    File "C:\Python27\Data Structures\Graph\bfstree.py", line 223, in main 
    traverse(g.getVertex(2)) 
    File "C:\Python27\Data Structures\Graph\bfstree.py", line 168, in traverse 
    while (x.getPred()): 
    AttributeError: 'list' object has no attribute 'getPred' 

因此,當我調用traverse()函數時會發生此問題。 這裏是我的主要功能

def main():  

    g = Graph() 

    for i in range(1,9): 

      g.addVertex(i) 

    g.addEdge(1,2) 
    g.addEdge(1,4) 
    g.addEdge(1,8) 
    g.addEdge(2,3) 
    g.addEdge(2,1) 
    g.addEdge(3,2) 
    g.addEdge(3,4) 
    g.addEdge(3,7) 
    g.addEdge(3,8) 
    g.addEdge(4,1) 
    g.addEdge(4,3) 
    g.addEdge(4,5) 
    g.addEdge(5,4) 
    g.addEdge(5,6) 
    g.addEdge(5,7) 
    g.addEdge(6,5) 
    g.addEdge(6,7) 
    g.addEdge(7,3) 
    g.addEdge(7,6) 
    g.addEdge(7,5) 
    g.addEdge(8,3) 
    g.addEdge(8,1) 

    for v in g: 

      for w in v.getConnections(): 

       print("(%s,%s)"%(v.getId(),w.getId())) 




    print("\nDoing BFS...") 

    bfs_tree(g,g.getVertex(1)) 

    a = g.getVertex(2) 

    print(type(a)) 

    traverse(g.getVertex(2)) 




main() 

這裏是遍歷功能:

def traverse(y): 

    x = y 


    while (x.getPred()): 
      print(x.getId()) 

      x = x.getPred() 
    print(x.getId()) 

這裏是鄰接列表實現圖形:

class Graph: 

     def __init__(self): 

      self.vertList = {} #this is the masterlist 
      self.numVertices = 0 

     def addVertex(self,key): #turn something into a Vertex object 

      self.numVertices = self.numVertices + 1 

      newVertex = Vertex(key) 

      self.vertList[key] = newVertex #maps vertex names to vertex objects 

      return newVertex 

     def getVertex(self,n): 

      if n in self.vertList: 

      return self.vertList[n] #returns the Vertex object 
     else: 

      return None 

     def __contains__(self,n):#tweak the built-in operator 'in'(containment check) 

      return n in self.vertList 

     def addEdge(self,f,t,cost = 0): 

      if f not in self.vertList: #if f is not a node in the graph 

       nv = self.addVertex(f) 

      if t not in self.vertList:  #if t is not a node in the graph 

       nv = self.addVertex(t) 

       self.vertList[f].addNeighbor(self.vertList[t], cost) 

     def getVertices(self): 

      return self.vertList.keys() 

     def __iter__(self): # iterate over Vertex objects over the Graph 

      return iter(self.vertList.values()) 
class Vertex: 

    def __init__(self,key): 

      self.id = key 
      self.connectedTo={} #dictionary which contains all the other vertices it is connected to 
      self.pred = [] #for BFS tree/a list because we are dealing with cycles 
      self.color = "white" #for BFS tree 


     def addNeighbor(self,nbr,weight=0): 

      self.connectedTo[nbr] = weight #nbr is another Vertex object 

     def __str__(self): 

      #TODO: lookup how that for loop works 
      return str(self.id) + "connected to " + str([x.id for x in self.connectedTo]) 

     def getConnections(self): 

      return self.connectedTo.keys() 

     def getId(self): 

      return self.id 

     def getWeight(self,nbr): 

      return self.connectedTo[nbr] 

     def getColor(self): 

      return self.color 

     def setColor(self,color): 

      self.color = color 

     def setPred(self,node): 

      self.pred.append(node) 

     def getPred(self): 

      if len(self.pred)>1: 
       return self.pred 
      elif len(self.pred) == 0: 

       return self.pred[0] 
      else: 

       return self.pred 

爲什麼說克getVertex(2)是一個列表對象嗎?我很確定它是一個Vertex對象。我甚至在主函數中打印出這個類型,它說它是一個實例而不是一個列表對象。

+0

將x更改爲另一個對象/類型爲「x = x.getPred()」。它變成getPred()返回的任何東西。 –

+0

如果'len(self.pred)== 0'爲true,那麼'self.pred [0]'會引發一個'IndexError'。除此之外,Python不會僅僅認爲''x'是一個列表,它*知道它是一個列表。在你的代碼中的某處,'x.getPred()'返回一個列表。 –

+1

您從'x.getPred()'返回'self.pred'(一個列表),所以設置'x = x.getPred()'**顯然**將'x'設置爲一個列表,之後是'x。 getPred()'會失敗。 –

回答

1

x = x.getPred()是問題所在。 while循環中的第一個檢查很好,但在第一次更新x後中斷,然後重新檢查。

至於實施,getPred將返回self.pred(它從self.pred返回,而不是整個事情被打破的唯一情況;長度爲0,而你的索引,所以它會提高IndexError)。 self.predlist

1

您與x.getPred()結果這裏更換x

while (x.getPred()): 
     print(x.getId()) 
     x = x.getPred() 

x.getPred()返回self.pred

def getPred(self): 

     if len(self.pred)>1: 
      return self.pred 
     elif len(self.pred) == 0: 

      return self.pred[0] 
     else: 

      return self.pred 

(請注意,len(self.pred) == 0你試圖返回self.pred[0],這將引發IndexError除外) 。

self.pred是一個列表:

class Vertex: 
    def __init__(self,key): 
      # ... 
      self.pred = [] #for BFS tree/a list because we are dealing with cycles 

所以您更換xlist對象,然後環回和列表對象調用x.getPred()