aikif/toolbox/data_structures.py
# data_structures.py written by Duncan Murray 26/1/2015
#----------------------------
# Classes for Data Structures
class Node(object):
"""
Node data structure
"""
def __init__(self, name, data=None):
"""
takes a name and optional data
"""
self.name = name
self.data = data
self.parent = None
self.depth = 0
self.links = []
def __str__(self):
res = self.name + ' : ( ' + str(len(self.links)) + ' links)\n'
for link in self.links:
res += ' ' + link.name + ''
return res
def __eq__(self, other):
if not isinstance(other, Node):
return False
return self.name == other.name
def add_link(self, node):
self.links.append(node)
node.parent = self
def get_children(self):
""" returns list of child nodes """
return self.links
def get_parent(self):
""" returns parent node """
return self.parent
class Graph(object):
def __init__(self, graph):
""" takes a graph definition as input
e.g. the following tree is encoded as follows:
A
/ \
B E
/ | \ \
H C D M
would be entered as
{ 'A': ['B', 'E'],
'B': ['H', 'C', 'D'],
'E': ['M'] }
"""
self.graph = graph
self.nodes = []
self.links = []
self.adj_matrix = []
def __str__(self):
""" display as raw data """
return str(self.graph)
def get_adjacency_matrix(self, show_in_console=False):
""" return the matrix as a list of lists
raw graph = {'1': ['2', '3', '4'], '2': ['6', '7']}
6 nodes: ['1', '2', '3', '4', '6', '7']
5 links: [['1', '2'], ['1', '3'], ['1', '4'], ['2', '6'], ['2', '7']]
[0, 1, 1, 1, 0, 0]
[1, 0, 0, 0, 1, 1]
[1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0]
"""
self.links = [[i,j] for i in self.graph for j in self.graph[i]]
all_nodes = []
op = []
for node in self.graph:
all_nodes.append(node) # to get the root node
for connection in self.graph[node]:
all_nodes.append(connection)
self.nodes = sorted(list(set(all_nodes)))
if show_in_console is not False:
print (len(self.nodes), 'nodes:', self.nodes)
print (len(self.links), 'links:', self.links)
for y in range(len(self.nodes)):
row = []
for x in range(len(self.nodes)):
match = False
for l in self.links:
if self.nodes[x] == l[0] and self.nodes[y] == l[1]:
match = True
if self.nodes[x] == l[1] and self.nodes[y] == l[0]:
match = True
if match is True:
row.append(1)
else:
row.append(0)
op.append(row)
if show_in_console is not False:
for row in op:
print(row)
return op