How can I create another object without taking the same values?

0

I have my graph implementation program. The issue is that I would like to try other graphs with the same classes but to declare more graphs I always print the same. But I have no idea how this is done in Python, could someone advise me?

class Vertice:
    def __init__(self,n):
        self.nombre = n
        self.vecinos = list()
        self.distancia = 9999
        self.color = 'white'
        self.pred = -1

    def agregarVecino(self, v):
        if v not in self.vecinos:
            self.vecinos.append(v)
            self.vecinos.sort()

class Grafo:
vertices = {}

def agregarVertice(self, vertice):
    if isinstance(vertice, Vertice) and vertice.nombre not in self.vertices:
        self.vertices[vertice.nombre] = vertice
        return True
    else:
        return False

def agregarArista(self, u, v):
    if u in self.vertices and v in self.vertices:
        for key, value in self.vertices.items():
            if key == u:
                value.agregarVecino(v)
            if key == v:
                value.agregarVecino(u)
        return True
    else:
        return False

def bfs(self, vert):
    vert.distancia = 0
    vert.color = 'gray'
    vert.pred = -1
    q = list()

    q.append(vert.nombre)

    while len(q) > 0:

        u = q.pop()
        node_u  = self.vertices[u]
        for v in node_u.vecinos:
            node_v = self.vertices[v]
            if node_v.color == 'white':
                node_v.color = 'gray'
                node_v.distancia = node_u.distancia + 1
                node_v.pred = node_u.nombre
                q.append(v)
        self.vertices[u].color = 'black'        

def imprimeGrafo (self):
    for key in sorted(list(self.vertices.keys())):
        print ("Vertice " + key + " sus vecinos son "+ str(self.vertices[key].vecinos) )
        print("La distancia de A a " + key + " es: "+ str(self.vertices[key].distancia))
        print()
class Controladora:
def main(self):
    g = Grafo()
    a = Vertice('A')
    g.agregarVertice(a)

    for i in range(ord('A'), ord('K')):
        g.agregarVertice(Vertice(chr(i)))


    edges = ['AB','AE','BF','CG','DE','DH','EH','FG','FI','FJ','GJ']

    for edge in edges:
        g.agregarArista(edge[:1], edge[1:])
    g.bfs(a)
    g.imprimeGrafo()    

obj = Controladora()
obj.main()
    
asked by Johan Cancino 20.03.2017 в 22:16
source

2 answers

1

I do not know if I have correctly understood your question, I think what you want is to know how you can create several different graphs (with different nodes and edges) and work with them. Based on this I will try to answer.

In your code you create a single graph that is instantiated in your class Controladora , this class just as it makes little sense. To create several graphs you simply have to create several objects of the class Grafo with different names and attributes as you do with the vertices. To not change your code much I have added two methods to your class Grafo :

  • agregarVertices allows you to create the vertices you want from a list or sets with the names, instance for each an object of the class Vertice and then call your method crearVertice . You could join everything in one method, I preferred to do it that way to touch your code as little as possible.

  • agregarAristas creates the edges that we pass in the form of list or set of strings of the form 'AB' where A is the name of one vertex and B the other. If you decide to create vertices of more than one character as a name, I advise you to modify this and pass the edges in the form of tuples: [('A', 'B'), ('AA', 'BB')] .

I have modified the bfs method, now receive as parameter the name of the node to which you want to calculate the distances, not the instance itself. In general, your main class, which you should work on should be the class Grafo and that is the one that instants and manages the vertices. The code could look like this:

class Vertice:

    def __init__(self, n):
        self.nombre = n
        self.vecinos = list()
        self.distancia = 9999
        self.color = 'white'
        self.pred = -1

    def agregarVecino(self, v):
        if v not in self.vecinos:
            self.vecinos.append(v)
            self.vecinos.sort()

class Grafo:
    def __init__(self):
        self.vertices = dict()

    def agregarVertices(self, vertices):
        for v in vertices:
            n = Vertice(v)
            self.agregarVertice(n)

    def agregarAristas(self, aristas):
        for arista in aristas:
            self.agregarArista(arista[0], arista[1])

    def agregarVertice(self, vertice):
        if isinstance(vertice, Vertice) and vertice.nombre not in self.vertices:
            self.vertices[vertice.nombre] = vertice
            return True
        else:
            return False

    def agregarArista(self, u, v):
        if u in self.vertices and v in self.vertices:
            for key, value in self.vertices.items():
                if key == u:
                    value.agregarVecino(v)
                if key == v:
                    value.agregarVecino(u)
            return True
        else:
            return False

    def bfs(self, vert):
        vert = self.vertices[vert]
        vert.distancia = 0
        vert.color = 'gray'
        vert.pred = -1
        q = list()

        q.append(vert.nombre)

        while len(q) > 0:

            u = q.pop()
            node_u  = self.vertices[u]
            for v in node_u.vecinos:
                node_v = self.vertices[v]
                if node_v.color == 'white':
                    node_v.color = 'gray'
                    node_v.distancia = node_u.distancia + 1
                    node_v.pred = node_u.nombre
                    q.append(v)
            self.vertices[u].color = 'black'        

    def imprimeGrafo (self):
        for key in sorted(list(self.vertices.keys())):
            print ("Vertice " + key + " sus vecinos son "+ str(self.vertices[key].vecinos) )
            print("La distancia de A a " + key + " es: "+ str(self.vertices[key].distancia))
            print()



#Creamos un grafo como en tu ejemplo al que llamamos g1:
vertices = [chr(i) for i in range(ord('A'), ord('K'))]
edges = ['AB','AE','BF','CG','DE','DH','EH','FG','FI','FJ','GJ']
g1 = Grafo()
g1.agregarVertices(vertices)
g1.agregarAristas(edges)
g1.bfs('A')


#Creamos otro un grafo al que llamamos g2:
vertices = [chr(i) for i in range(ord('L'), ord('T'))]
edges = ['LM','LP','QT','MJ','NK','OQ','QT','TP']
g2 = Grafo()
g2.agregarVertices(vertices)
g2.agregarAristas(edges)
g2.bfs('L')

#Ahora tenemos dos grafos distintos y podemos trabajar con ellos usando sus nombres, vamos a imprimirlos:
print(print('='*50+'\nGRAFO G1:\n'+'='*50))
g1.imprimeGrafo()

print('='*50+'\nGRAFO G2:\n'+'='*50)
g2.imprimeGrafo()

As you see in the example we have created two different graphs called g1 and g2, we can create the ones we want and then access them using those names.

    
answered by 21.03.2017 / 10:26
source
1

In Python, multiple names can be linked to the same object. This is known as aliasing. Normally aliasing can be ignored without problems when handling immutable basic types (numbers, strings, tuples). However, aliasing, or renaming, has a surprising effect on the semantics of Python code that involves mutable objects such as lists, dictionaries, and most other types.

obj = Controladora()
obj2 = obj

obj2 is the same instance as obj . To obtain a different instance it is necessary to make a copy

import copy

otro = copy.copy(obj)
    
answered by 20.03.2017 в 22:55