1
2
3
4
5
6
7
8
10 """A directed graph abstraction with labeled edges."""
11
13 """Initializes a new Graph object."""
14 self._adjacency_list = {}
15 for n in nodes:
16 self._adjacency_list[n] = set()
17 self._label_map = {}
18 self._edge_map = {}
19
21 """Returns true if g is equal to this graph."""
22 return isinstance(g, Graph) and \
23 (self._adjacency_list == g._adjacency_list) and \
24 (self._label_map == g._label_map) and \
25 (self._edge_map == g._edge_map)
26
28 """Returns true if g is not equal to this graph."""
29 return not self.__eq__(g)
30
32 """Returns an unique string representation of this graph."""
33 s = "<Graph: "
34 keys = self._adjacency_list.keys()
35 keys.sort()
36 for key in keys:
37 values = [(x,self._edge_map[(key,x)])
38 for x in self._adjacency_list[key].list()]
39 values.sort()
40 s = s + "(" + repr(key) + ": " + ",".join(map(repr, values)) + ")"
41 return s + ">"
42
44 """Returns a concise string description of this graph."""
45 nodenum = len(self._adjacency_list.keys())
46 edgenum = reduce(lambda x,y: x+y,
47 map(len, self._adjacency_list.values()))
48 labelnum = len(self._label_map.keys())
49 return "<Graph: " + \
50 str(nodenum) + " node(s), " + \
51 str(edgenum) + " edge(s), " + \
52 str(labelnum) + " unique label(s)>"
53
55 """Adds a node to this graph."""
56 if node not in self._adjacency_list:
57 self._adjacency_list[node] = set()
58
59 - def add_edge(self, source, to, label = None):
60 """Adds an edge to this graph."""
61 if source not in self._adjacency_list:
62 raise ValueError("Unknown <from> node: " + str(source))
63 if to not in self._adjacency_list:
64 raise ValueError("Unknown <to> node: " + str(to))
65 if (source,to) in self._edge_map:
66 raise ValueError(str(source) + " -> " + str(to) + " exists")
67 self._adjacency_list[source].add(to)
68 if label not in self._label_map:
69 self._label_map[label] = set()
70 self._label_map[label].add((source,to))
71 self._edge_map[(source,to)] = label
72
74 """Returns a list of (child, label) pairs for parent."""
75 if parent not in self._adjacency_list:
76 raise ValueError("Unknown <parent> node: " + str(parent))
77 return [(x, self._edge_map[(parent,x)])
78 for x in sorted(self._adjacency_list[parent])]
79
81 """Returns a list of unique children for parent."""
82 return sorted(self._adjacency_list[parent])
83
85 """Returns a list of all the edges with this label."""
86 if label not in self._label_map:
87 raise ValueError("Unknown label: " + str(label))
88 return self._label_map[label].list()
89
91 """Returns a list of all the edge labels in this graph."""
92 return self._label_map.keys()
93
95 """Returns a list of the nodes in this graph."""
96 return self._adjacency_list.keys()
97
99 """Returns a list of (parent, label) pairs for child."""
100 if child not in self._adjacency_list:
101 raise ValueError("Unknown <child> node: " + str(child))
102 parents = []
103 for parent, children in self._adjacency_list.iteritems():
104 for x in children:
105 if x is child:
106 parents.append((parent, self._edge_map[(parent, child)]))
107 return sorted(parents)
108
110 """Returns a list of unique parents for child."""
111 return sorted(set([x[0] for x in self.parent_edges(child)]))
112
114 """Removes node and all edges connected to it."""
115 if node not in self._adjacency_list:
116 raise ValueError("Unknown node: " + str(node))
117
118 del self._adjacency_list[node]
119
120 for n in self._adjacency_list.keys():
121 self._adjacency_list[n] = set(x for x in self._adjacency_list[n]
122 if x is not node)
123
124 for label in self._label_map.keys():
125 lm = set(x for x in self._label_map[label]
126 if (x[0] is not node) and (x[1] is not node))
127
128 if lm:
129 self._label_map[label] = lm
130 else:
131 del self._label_map[label]
132
133 for edge in self._edge_map.keys():
134 if edge[0] is node or edge[1] is node:
135 del self._edge_map[edge]
136
138 """Removes edge. -- NOT IMPLEMENTED"""
139
140 raise NotImplementedError("remove_edge is not yet implemented")
141