对象详细信息不会被传递到另一个对象指针[Python 3]

时间:2016-02-25 13:17:49

标签: python oop python-3.x

我一直在尝试使用成本6的均匀边缘编写一个简单的广度优先搜索代码,但是当我从队列中调用我的第二个Vertex对象的邻居(我使用邻接列表)时,返回空列表。然而,如果我在代码中的任何其他位置调用相同的列表,则返回正确的列表。我一直试图调试一段时间,但无济于事。

以下是代码:

import queue
import math

#Vertex Class Definition
class Vertex:
    def __init__(self, name):
        self.name=name
        self.neighbors= []
        self.nay=[]

    def addneighbor(self, neigh):
        if not neigh in self.nay:
            self.nay.append(neigh)
            self.neighbors.append(Vertex(neigh))

    def getneigh(self):
        return self.neighbors

    def getname(self):
        return int(self.name)

#Graph Class definition
class Graph:
    def __init__(self):
        self.verts=[]
        self.num= 0

    def addvert(self, node):
        self.verts.append(Vertex(node))

    def addedge(self, fro, to):
        self.verts[fro-1].addneighbor(to)  
        self.verts[to-1].addneighbor(fro)

def bfs(g,s):

    q= queue.Queue(maxsize=0)
    q.put(g.verts[s-1])
    cost= [-1 for yy in range(g.num)]
    cost[s-1]=0

    while(not q.empty()):

        p=q.get()



'''If I check for p.getneigh() here, only the neigbors of 
source element s are returned. Otherwise, the loop stops
after calling the first neighbor of s. However, if I 
explicitly call g.verts and check for neigbors, the list 
is complete.'''

        for vex in p.getneigh():
            if cost[vex.name-1]==-1:
                q.put(vex)
                cost[vex.name-1]= cost [p.name-1]+6

    return cost

t= 1     
for hehe in range (t):
    n, e= 10, 6

    g= Graph()
    #add n vertices
    for i in range (1, n+1):
        g.addvert(i)
        g.num+=1
    arr= [ [3, 1], [10, 1], [10, 1] , [3, 1] , [1, 8], [5, 2]]
    for i in range(e):
        x,y = arr[i][0], arr[i][1]
        g.addedge(x, y)

    s= 3
    #s is the start node of the graph
    c=bfs(g,s)

    del c[s-1] 

    for yoy in c:
        stdout.write(str(yoy))
        stdout.write(" ") 
    stdout.write("\n")

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

根据设置,图表应如下所示:

       3  5   6  4 7 8 9
      /    \
10 - 1      2
     |
     8

问题不在于队列,你的图表是不正确的,这是显示这个的测试代码:

t= 1     
for hehe in range (t):
    n, e= 10, 6

    g= Graph()
    # ...
    # ...
    s= 3
    print('g.verts[s-1] is ', g.verts[s-1].getname())
    print('g.verts[s-1] neigh ', g.verts[s-1].getneigh()[0].getname())
    print('g.verts[s-1] neigh[0] -> neigh', g.verts[s-1].getneigh()[0].getneigh())
    print('------------')

    #s is the start node of the graph
    c=bfs(g,s)
    # ...

输出:

g.verts[s-1] is  3
g.verts[s-1] neigh  1
g.verts[s-1] neigh[0] -> neigh []

你甚至可以看到,在我们进入bfs函数并使用队列之前,顶点3有一个邻居1,但是顶点1没有邻居。 虽然根据设置它应该有3108

问题在于:

def addedge(self, fro, to):
    self.verts[fro-1].addneighbor(to)
    self.verts[to-1].addneighbor(fro)

self.verts[fro-1]Vertex个对象,但to是一个整数(将整数传递给addedge)。 因此,不是将两个顶点相互连接,而是每次都创建新顶点(在Vertex.addneighbor内),因此最终得到3 - > 1 - > []为顶点3。并且图表中还会有另一个顶点1的副本,其中包含3810个邻居,而3将不是与图表中已知的相同。

以下是隐藏在剧透网下的更正代码,因此您可以尝试自行解决问题。

提示:self.verts[fro-1].addneighbor(self.verts[to-1])



from sys import stdin, stdout
import queue
import math
from collections import OrderedDict

#Vertex Class Definition
class Vertex:
    def __init__(self, name):
        self.name = int(name)
        self.neighbors = OrderedDict()

    def add_neighbor(self, neigh):
        assert(isinstance(neigh, Vertex))
        if neigh.get_name() not in self.neighbors:
            self.neighbors[neigh.get_name()] = neigh

    def get_neighbours(self):
        return list(self.neighbors.values())

    def get_name(self):
        return self.name

    def get_neighbours_names(self):
        return [n.get_name() for n in self.get_neighbours()]


#Graph Class definition
class Graph:
    def __init__(self):
        self.verts = []
        self.num = 0

    def add_vert(self, node):
        self.verts.append(Vertex(node))

    def add_edge(self, fro, to):
        print('%s -> %s' % (fro, to))
        self.verts[fro-1].add_neighbor(self.verts[to-1])
        self.verts[to-1].add_neighbor(self.verts[fro-1])

def bfs(g,s):

    q= queue.Queue(maxsize=0)
    q.put(g.verts[s-1])
    cost= [-1 for yy in range(g.num)]
    cost[s-1]=0

    print('g.verts[s-1] is ', g.verts[s-1].get_name())
    print('g.verts[s-1] neigh ', g.verts[s-1].get_neighbours_names())
    print('g.verts[s-1] neigh[0] -> neigh', g.verts[s-1].get_neighbours()[0].get_neighbours_names())
    print('------------')

    while(not q.empty()):

        p=q.get()

        """If I check for p.get_neighbours() here, only the neigbors of
        source element s are returned. Otherwise, the loop stops
        after calling the first neighbor of s. However, if I
        explicitly call g.verts and check for neighbors, the list
        is complete."""

        print('p is ', p)
        print('p name is ', p.get_name())
        print('p nei ', p.get_neighbours_names())
        if len(p.get_neighbours()) > 0:
            print('p nei -> nei ', p.get_neighbours()[0].get_neighbours_names())
        print('------------')

        for vex in p.get_neighbours():
            if cost[vex.name-1]==-1:
                q.put(vex)
                cost[vex.name-1]= cost [p.name-1]+6

    return cost

t= 1
for hehe in range (t):
    n, e= 10, 6

    g= Graph()
    #add n vertices
    for i in range (1, n+1):
        g.add_vert(i)
        g.num+=1
    arr= [ [3, 1], [10, 1], [10, 1] , [3, 1] , [1, 8], [5, 2]]
    for i in range(e):
        x,y = arr[i][0], arr[i][1]
        g.add_edge(x, y)

    s= 3
    #s is the start node of the graph
    c=bfs(g,3)

    c=bfs(g,1)

    del c[s-1]

    for yoy in c:
        stdout.write(str(yoy))
        stdout.write(" ")
    stdout.write("\n")

"""
       3  5   6  4 7 8 9
      /    \
10 - 1      2
     |
     8
"""