Domanda

responsabilità : si tratta di un progetto semestre che sto attualmente lavorando. La mia domanda è per quanto riguarda un dettaglio livello di implementazione e non fa parte dello schema di classificazione. Sto scrivendo questo codice come un modo per testare la teoria che propongo per la carta che scriverò.

Inoltre, ho considerato le risposte per questa domanda con poca fortuna, quindi per favore non considerare questo come un duplicato di tale questione

Il problema :

Ho un grafico (G = (V, E)). Ad un certo punto il mio algoritmo, ho bisogno di trasformare questo in un ipergrafo (in un certo senso) da "collasso" più nodi (diciamo, v_1, v_2, ..., v_n) in un nodo (diciamo, v). Nel contesto del problema, ciò implica che devo cambiare i bordi E tale che qualsiasi e bordo tra qualsiasi v_1, v_2, v_n e qualsiasi altro u nodo V verrà modificato tale che e è ora tra u e v.

Per cattura che ci possono ora esistere più bordi distinti tra ogni coppia di nodi, ho bisogno di fare un identificatore unico per ciascun bordo. Ho cercato di fare questo per mezzo di e ID, che sono attualmente in grado di applicare correttamente.

Questo è quello che ho provato :

class Edge:
    _ID = 0
    def __init__(self, u, v, w, c,f=0):
        self.id = Edge._ID 
        Edge._ID += 1
        self.src = u
        self.dest = v
        self.weight = w
        self.capacity = c
        self.flow = f

Tuttavia, quando cerco di istanziare un nuovo bordo, ottengo il seguente errore:

>>> e = Edge(1,3,5,10,0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "UnsplittableFlow.py", line 14, in __init__
    self.id = Edge._ID; Edge._ID += 1
UnboundLocalError: local variable '_ID' referenced before assignment

Modifica :

Con i consigli di alcune risposte, sono stato in grado di correggere l'errore di un'istanza-tempo. Tuttavia, un altro errore persiste. Ecco il mio codice e gli errori:

class Edge:
    _ID = 0
    def __init__(self, u, v, w, c,f=0):
        self.id = self._ID; self._ID += 1
        self.src = u
        self.dest = v
        self.weight = w
        self.capacity = c
        self.flow = f

Errore:

>>> e = Edge(1,3,5,10,0)
>>> e.id
0
>>> Edge._ID
0

>>> f = Edge(2,3,5,10,0)
>>> f.id
0
>>> Edge._ID
0

Apprezzerei tutto l'aiuto

Grazie

È stato utile?

Soluzione

È comunque possibile utilizzare self per arrivare al _ID.

self.id = self._ID 
self.__class__._ID += 1

Se stai usando CPython, si può avere ID di un uomo pigro:

class Edge(object):
    @property
    def id(self): return id(self)

Altri suggerimenti

Il codice modificato è trattare _ID come se si trattasse di una variabile di istanza, non è una variabile di classe. Sulla base di risposta di Matt Joiner quello che penso vuoi dire è questo:

class Edge:
    _ID = 0
    def __init__(self, u, v, w, c,f=0):
        self.id = self._ID; self.__class__._ID += 1
        self.src = u
        self.dest = v
        self.weight = w
        self.capacity = c
        self.flow = f

Quando eseguo i tuoi esempi con questa definizione di Edge, ottengo:

>>> e = Edge(1,3,5,10,0)
>>> e.id
0
>>> Edge._ID
1
>>> f = Edge(2,3,5,10,0)
>>> f.id
1
>>> Edge._ID
2

Qual è il risultato desiderato. Tuttavia, altri hanno sottolineato che il codice originale lavorato per loro, proprio come questo codice funziona per me, così ho il sospetto che il vero problema è da qualche altra parte nel codice.

Prima di un'istanza di qualsiasi bordo, è possibile impostare la variabile di classe esplicitamente a 0 in questo modo:

Edge._ID = 0
e = Edge(1,3,5,10,0)
f = Edge(2,3,4,5,0)

E i di id sarà impostato correttamente.

Mentre le altre risposte offerti sono rispondere alla domanda posta (che è il motivo per cui io non sono intollerante con quella che inizialmente accettato), il modo corretto per farlo sarebbe quello di utilizzare itertools.count nel seguente modo:

class Edge:
    _ID = itertools.count()
def __init__(self, u, v, w, c,f=0):
    self.id = self._ID.next()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top