I'm trying to do a depth first search of a directed graph, and while doing that I'm also trying to keep track of data about the graph. First, here are the classes I used to construct the digraph.
class Node(object):
def __init__(self, name):
self.name = str(name)
def getName(self):
return self.name
def __str__(self):
return self.name
def __repr__(self):
return self.name
def __eq__(self, other):
return self.name == other.name
def __ne__(self, other):
return not self.__eq__(other)
class Edge(object):
def __init__(self, src, dest,distance,distance_out):
self.src = src
self.dest = dest
self.distance = distance
self.distance_out = distance_out
def getSource(self):
return self.src
def getDestination(self):
return self.dest
def getDistance(self):
return self.distance
def getDistance_Outdoors(self):
return self.distance_out
def __str__(self):
return str(self.src) + '--'+'Total Distance:(' +str(self.distance)+')' + ' '+ 'Outside Distance:('+str(self.distance_out)+')'+'-->' + str(self.dest)
class Digraph(object):
"""
A directed graph
"""
def __init__(self):
self.nodes = set([])
self.edges = {}
def addNode(self, node):
if node in self.nodes:
raise ValueError('Duplicate node')
else:
self.nodes.add(node)
self.edges[node] = []
def addEdge(self, edge):
src = edge.getSource()
dest = edge.getDestination()
distance = edge.getDistance()
distance_out = edge.distance_out
if not(src in self.nodes and dest in self.nodes):
raise ValueError('Node not in graph')
self.edges[src].append([dest,[distance,distance_out]])
def childrenOf(self, node):
return self.edges[node]
def hasNode(self, node):
return node in self.nodes
def testDict(self):
return self.edges
def __str__(self):
res = ''
for k in self.edges:
for d in self.edges[k]:
res = res + str(k) + '->' + str(d[0]) + str(d[1])+ '\n'
return res[:-1]
The digraph I'm currently working on has 37 nodes and 129 edges.
Here's the code for my search functions.
import string
from graph import Digraph, Edge, Node
def depthFirstSearchVisit(digraph, time, node,discovered, undiscovered ,
explored , nodes , hierarchy ):
time = time + 1 #While vertex has just been discovered
nodes[node].append(time) ##Mark the discovery time for the node in the nodes dictionary
discovered.append(node)##Mark the node as discovered
if node in undiscovered: ## Remove node from undiscovered after it's discovery
undiscovered.remove(node)
for adjacent_node in digraph.childrenOf(node):##Explore edge (node, adjacent_node)
if adjacent_node[0] in undiscovered: ##The adjacent node is a predecessor of the node
hierarchy[node].append(adjacent_node[0])##Mark it as such in the hierarchy dictionary
depthFirstSearchVisit(digraph,time,adjacent_node[0],discovered,
undiscovered,explored,nodes,hierarchy)##Then recursively visit that adjacent_node
explored.append(node) ##After exploring all of the nodes adjacent
nodes[node].append(time)
return nodes
def depthFirstSearch(digraph,time, discovered = [], undiscovered = [],
explored = [], nodes = {}, hierarchy = {}):
if len(nodes) == 0: ## If nodes is empty
for i in digraph.nodes: ##Initialize a dictionary where nodes are the keys and
nodes[i] = [] ##An empty list for values, so they can be filled with discovery and exploration times
for key in nodes: ##For each node in the digraph mark them all as undiscovered.
undiscovered.append(key)
for key2 in nodes:##Construct hierarchy dict for later use in DepthFirstSearchVisit
hierarchy[key2] = []
##Time initialized to zero in parameter call
for node in nodes:
if node in undiscovered:
depthFirstSearchVisit(digraph,time,node,discovered, undiscovered, explored,nodes,hierarchy)
return nodes
Right now I'm testing to see if a dictionary nodes is outputting the correct information. Here is the structure of the nodes dictionary.
{node: [time of discovery, time of exploration]}
The time of discovery is when the DepthFirsTSearchVisit first encounters a node, and the time of exploration is when that node's descendants and so forth all the way down are all discovered.
Here is what I get as output:
{32: [1, 1], 48: [4, 4], 50: [9, 9], 37: [17, 17], 13: [15, 15], 10: [25, 25], 64: [9, 9], 35: [18, 18], 5: [22, 22], 24: [14, 14], 6: [10, 10], 57: [2, 2], 9: [20, 20], 68: [6, 6], 39: [16, 16], 1: [23, 23], 38: [16, 16], 62: [8, 8], 4: [12, 12], 16: [4, 4], 34: [15, 15], 2: [9, 9], 54: [7, 7], 7: [21, 21], 66: [8, 8], 56: [5, 5], 46: [3, 3], 76: [7, 7], 18: [6, 6], 3: [24, 24], 36: [2, 2], 12: [13, 13], 33: [19, 19], 14: [8, 8], 8: [11, 11], 26: [3, 3], 31: [18, 18]}
What output I think I should be getting: The time values shouldn't be the same. There should be a large difference between discovery and exploration.
Thanks in advance for any help.