Disclaimer: This is for a semester project that I am currently working on. My question is regarding an implementation level detail and is not part of the grading scheme. I am only writing this code as a way to test the theory that I am proposing for the paper that I will write.
Also, I have considered the answers for this question with little luck, so please do not consider this as a duplicate of that question
The Problem:
I have a graph (G=(V,E)). At some point in my algorithm, I need to turn this into a hypergraph (in a sense) by "collapsing" multiple nodes (say, v_1, v_2, ..., v_n
) into one node (say, v
). In the context of the problem, this implies that I need to change the edges in E
such that any edge e
between any of v_1, v_2, v_n
and any other node u
in V
will be changed such that e
is now between u
and v
.
In order to capture that there may now exist multiple distinct edges between any pair of nodes, I need to make a unique identifier for each edge. I have tried to do this by means of and ID, which I am currently unable to properly implement.
This is what I've tried:
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
However, when I try to instantiate a new edge, I get the following error:
>>> 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
EDIT:
With the suggestions of some answers, I have been able to fix the instantiation-time error. However, another error persists. Here is my code and the errors:
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
Error:
>>> 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
I'd appreciate any help
Thank you
You can still use self
to get at the _ID
.
self.id = self._ID
self.__class__._ID += 1
If you're using CPython, you can have a lazy man's ID:
class Edge(object):
@property
def id(self): return id(self)
Your edited code is treating _ID
as though it were a instance variable, not a class variable. Based on Matt Joiner's answer what I think you mean is this:
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
When I run your examples with this definition of Edge
, I get:
>>> 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
Which is the desired result. However, others have pointed out that your original code worked for them, just like this code works for me, so I suspect the real problem is somewhere else in your code.
Before instantiating any Edge, you could set the class variable explicitly to 0 like so:
Edge._ID = 0
e = Edge(1,3,5,10,0)
f = Edge(2,3,4,5,0)
And the id's will be properly set.
While the other answers offered are answer the asked question (which is why I am not unaccepting the one I originally accepted), the correct way to do this would be to use itertools.count
as follows:
class Edge:
_ID = itertools.count()
def __init__(self, u, v, w, c,f=0):
self.id = self._ID.next()
来源:https://stackoverflow.com/questions/8319910/auto-incrementing-ids-for-class-instances