The teststring represents the structure given in euler project problem 18. Trying to solve it using graph theory. The graph structure I am trying to create is as below. Every number given in the string is a node in the graph.
3->(7,4)
7->(2,4)
4->(4,6)
2->(8,5)
mytesttring='''
3
7 4
2 4 6
8 5 9 3'''
The node class object accepts a tuple as position and value. In the above string mytesttring the first number 3 the position is (0,0) and value is 3 , similarily 7 position is (1,0) and value is 7
class node(object):
def __init__(self,position,value):
'''
position : gives the position of the node wrt to the test string as a tuple
value : gives the value of the node
'''
self.value=value
self.position=position
def getPosition(self):
return self.position
def getvalue(self):
return self.value
def getNodeHash(self):
return hash(str(self.position)+str(self.value))
def __str__(self):
return 'P:'+str(self.position)+' V:'+str(self.value)
The edge class is as below accepts a source node and a destination node.
class edge(object):
def __init__(self,src,dest):
'''src and dest are nodes'''
self.src = src
self.dest = dest
def getSource(self):
return self.src
def getDestination(self):
return self.dest
#return the destination nodes value as the weight
def getWeight(self):
return self.dest.getvalue()
def __str__(self):
return (self.src.getPosition(),)+'->'+(self.dest.getPosition(),)
The directed graph class is as below,it stores the edges in the form of a python dictionary, where key is the source node and value is a list of destination nodes. While adding an edge to the graph through the method addEdge , it checks if the node is present as a key in the edges dictionary. if the source of destination node is not present as a key in the edges dictionary, then 'Node not in graph' error is thrown.
class Diagraph(object):
'''the edges is a dict mapping node to a list of its destination'''
def __init__(self):
self.edges = {}
def addNode(self,node):
if node in self.edges:
raise ValueError('Duplicate node')
else:
self.edges[node]=[]
def addEdge(self,edge):
src = edge.getSource()
dest = edge.getDestination()
if not (src in self.edges and dest in self.edges):
raise ValueError('Node not in graph')
self.edges[src].append(dest)
def getChildrenof(self,node):
return self.edges[node]
def hasNode(self,node):
return node in self.edges
Converting the input string into a list of lists containing the individual numbers.
testlist2=[ list(map(int,elements.split())) for elements in mytesttring.strip().split("\n")]
print(testlist2)
out: [[3], [7, 4], [2, 4, 6], [8, 5, 9, 3]]
I am able to add the nodes to the Diagraph object in the below way.
y=Diagraph()
for i in range(len(testlist2)):
for j in range(len(testlist2)):
if i<=j:
y.addNode(node((j,i),testlist2[j][i]))
The 10 nodes are present in the edges dictionary. But when I try to add the edges using the method addEdge ,its raising the 'Node not in graph'. Can anyone suggest the proper way of adding the edges. The keys to the dictionary is an object of class node
.
The code I had for adding the edge was failing with 'Node not in graph'
as I was creating the nodes again node((j,i),testlist2[j][i])
and trying to add it to the edge. The point I forgot was the it creates a new node object
even though the inputs are the same.
Each node is present as the key of the dictionary edges
. We could convert the keys of the dictionary edges
into a list listofkeys=list(y.edges.keys())
and then based on the getPosition
method of the node class
create a diagraph structure or we could capture the nodes created in a list and then make use of this list emplist
to create the edge. I modified the code to add the nodes such that it's captured inside a list. I can make use of this list emplist
to create the edge and the diagraph.
emplist=[]
for i in range(len(testlist2)):
for j in range(len(testlist2)):
if i<=j:
mynode=node((j,i),testlist2[j][i])
emplist.append(mynode)
y.addNode(mynode)
code to add all the edges.
for node in emplist:
# iterate through all the nodes again and form a logic add the edges
for allnodes in emplist:
if node.getPosition()[0]==allnodes.getPosition()[0]-1 and node.getPosition()[1]==allnodes.getPosition()[1]-1:
y.addEdge(edge(node,allnodes))
if node.getPosition()[0]==allnodes.getPosition()[0]-1 and node.getPosition()[1]==allnodes.getPosition()[1]:
y.addEdge(edge(node,allnodes))