Source code for obci.control.common.graph

#!/usr/bin/python
# -*- coding: utf-8 -*-


[docs]class Graph(object): def __init__(self, bidirectional=False): self._edges = [] self._nlist = {} self._bidir = bidirectional
[docs] def copy(self): gr = Graph(self._bidir) # print "bef copy: ", self.vertices() # print "edges_bef: ", self._edges copied = {} for (v1, v2) in self._edges: for v in (v1, v2): if v._model not in copied: copied[v._model] = v.copy(gr) cv1 = copied[v1._model] cv2 = copied[v2._model] gr.add_edge(cv1, cv2) for v in self._nlist: if self._nlist[v] == [] and not v.in_edges(): gr.add_vertex(v.copy(gr)) # print "copied: ", gr.vertices() # print "edges copied: ", gr._edges return gr
[docs] def is_bidirectional(self): return False
[docs] def vertices(self): return list(self._nlist.keys())
def _edges_(self): return self._edges def _neighbours(self, vertex): return self._nlist[vertex]
[docs] def add_vertex(self, vertex): if vertex not in self._nlist: self._nlist[vertex] = []
[docs] def add_edge(self, v_a, v_z): for v in [v_a, v_z]: if v not in self._nlist: self._nlist[v] = [] if v_z not in self._nlist[v_a]: self._nlist[v_a].append(v_z) self._edges.append((v_a, v_z))
[docs] def remove_edge(self, edge): v_a, v_z = edge if (v_a, v_z) in self._edges: self._edges.remove((v_a, v_z)) self._nlist[v_a].remove(v_z) else: raise Exception("edge not in graph")
[docs] def remove_vertex(self, vertex): if vertex not in self._nlist: raise Exception("vertex not in graph") ins = vertex.in_edges() outs = vertex.out_edges() for e in ins + outs: self.remove_edge(e) del self._nlist[vertex]
[docs] def topo_sort(self): # print "****************************" gr = self.copy() vertices = gr.vertices() result = [] len_res = 0 cycle = False while not len_res == len(vertices): sinks = [v for v in gr.vertices() if not v.out_edges()] # print 'sinks: ', sinks if not sinks: print('cycle :(') cycle = True break result.append(sinks) # print "now:",result len_res += len(sinks) for s in sinks: for ine in s.in_edges(): gr.remove_edge(ine) for i in range(len(sinks)): gr.remove_vertex(sinks[i]) if gr._edges: print('cycle...') cycle = True # print "topo sort result:", not cycle, result return not cycle, result
[docs]class Vertex(object): def __init__(self, graph, model, id_method=None): self._model = model self._graph = graph def __str__(self): return self._model.__str__() def __repr__(self): return self._model.__str__()
[docs] def copy(self, new_graph): return Vertex(new_graph, self._model)
[docs] def neighbours(self): return self._graph._neighbours(self)
[docs] def out_edges(self): return [(self, n) for n in self.neighbours()]
[docs] def in_edges(self): return [(ver, self) for ver in self._graph.vertices() if (ver, self) in self._graph._edges_()]