def setUp(self): self.dg = SimpleGraph() self.one = Vertex('one') self.two = Vertex('two') self.three = Vertex('three') self.four = Vertex('four') self.five = Vertex('five') self.six = Vertex('six') self.disconnected = Vertex('disconnected') self.dg.add_vertex(self.one) self.dg.add_vertex(self.two) self.dg.add_vertex(self.three) self.dg.add_vertex(self.four) self.dg.add_vertex(self.five) self.dg.add_vertex(self.six) self.dg.add_vertex(self.disconnected) self.dg.add_edge(self.one, self.two, 7.0) self.dg.add_edge(self.two, self.one, 7.0) self.dg.add_edge(self.one, self.six, 14.0) self.dg.add_edge(self.six, self.one, 14.0) self.dg.add_edge(self.one, self.three, 9.0) self.dg.add_edge(self.three, self.one, 9.0) self.dg.add_edge(self.two, self.three, 10.0) self.dg.add_edge(self.three, self.two, 10.0) self.dg.add_edge(self.two, self.four, 15.0) self.dg.add_edge(self.four, self.two, 15.0) self.dg.add_edge(self.three, self.four, 11.0) self.dg.add_edge(self.four, self.three, 11.0) self.dg.add_edge(self.three, self.six, 2.0) self.dg.add_edge(self.six, self.three, 2.0) self.dg.add_edge(self.four, self.five, 6.0) self.dg.add_edge(self.five, self.four, 6.0) self.dg.add_edge(self.five, self.six, 9.0) self.dg.add_edge(self.six, self.five, 9.0)
def setUp(self): self.size = 5 self.sg = SimpleGraph(self.size) self.sg.AddVertex("A") self.sg.AddVertex("B") self.sg.AddVertex("C") self.sg.AddVertex("D") self.sg.AddVertex("E")
def setUp(self): self.cc = SimpleGraph() self.a = Vertex('a') self.b = Vertex('b') self.c = Vertex('c') self.d = Vertex('d') self.e = Vertex('e') self.f = Vertex('f')
def fully_connected_graph(nodes): g = SimpleGraph() for node in nodes: g.add_node(node) for other_node in nodes: if other_node is not node: g.add_edge(node, other_node) return g
def test_del_error(): """error raised when non-existant value deleted""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') with pytest.raises(KeyError): g.del_node('p')
def test_edge_error(): """delete non-existant edge""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') with pytest.raises(KeyError): g.del_edge('a', 'z')
def test_adjacent_error(): """error raised when nodes non-existant""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') with pytest.raises(KeyError): g.adjacent('l', 'm')
def test_del_edge(): """other edges preserved when one deleted""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') g.del_edge('a', 'c') assert g.neighbors('a') == {'b': 0}
def test_adjacent(): """adjacent correctly identify edges, new edge add node""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'd') g.add_edge('a', 'f') assert 'f' in g.nodes() assert g.adjacent('a', 'd') assert not g.adjacent('a', 'b')
def test_add_nodes(): """nodes are added""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') assert 'a' in g.nodes() assert 'b' in g.nodes() assert 'c' in g.nodes()
def test_sgraph_edges(self): # Checks for irreflexivity g = SimpleGraph.rand(5) self.assertTrue(g.is_irreflexive()) # Checks for loops with self.assertRaises(IsNotSimpleGraphError): SimpleGraph(3, [[0, 0], [1, 0], [0, 2]]) # Checks for simetry with self.assertRaises(IsNotSimpleGraphError): SimpleGraph(3, [[0, 2], [1, 0], [0, 1]])
def test_depth(): g = SimpleGraph() g.add_edge('a', 'b') g.add_edge('a', 'c') g.add_edge('b', 'd') g.add_edge('b', 'e') g.add_edge('e', 'f') g.add_edge('f', 'g') assert g.depth_first_traversal('a') == ['a', 'c', 'b', 'e', 'f', 'g', 'd']
def test_has_node(): """edge added, new node added""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') assert g.has_node('b')
def __init__(self, width, height=None): height = height or width assert width > 0 and height > 0 self._width = width self._height = height self._graph = SimpleGraph() self._locationMap = {} # vertex : location for x, y in product(range(self._width), range(self._height)): v = self.pushVertex((x, y)) if x > 0: self._graph.addEdge(v, self.singleVertexAt((x - 1, y))) if y > 0: self._graph.addEdge(v, self.singleVertexAt((x, y - 1)))
def test_edges(): """edges prints correct edges as tuples""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') assert ('a', 'c') in g.edges() assert ('a', 'b') in g.edges()
def setUp(self): self.g = SimpleGraph() self.a = Vertex('a') self.b = Vertex('b') self.c = Vertex('c') self.d = Vertex('d') self.e = Vertex('e') self.f = Vertex('f') self.g.add_vertex(self.a) self.g.add_vertex(self.b) self.g.add_vertex(self.c) self.g.add_vertex(self.d) self.g.add_vertex(self.e) self.g.add_edge(self.a, self.b) self.g.add_edge(self.b, self.c) self.g.add_edge(self.c, self.b) self.g.add_edge(self.c, self.d)
def setUp(self): self.b = SimpleGraph() self.l1 = Vertex('l1') self.l2 = Vertex('l2') self.l3 = Vertex('l3') self.l4 = Vertex('l4') self.r1 = Vertex('r1') self.r2 = Vertex('r2') self.r3 = Vertex('r3') self.b.add_vertex(self.l1) self.b.add_vertex(self.l2) self.b.add_vertex(self.l3) self.b.add_vertex(self.r1) self.b.add_vertex(self.r2) self.b.add_edge(self.l1, self.r1) self.b.add_edge(self.l1, self.r2) self.b.add_edge(self.l2, self.r1) self.b.add_edge(self.l2, self.r2) self.b.add_edge(self.l3, self.r1) self.b.add_edge(self.l3, self.r2)
def blockForest(self): bf = SimpleGraph() vertexmap = {} # vertex: vertex in block forest articulations = set() # separators mapped to block forest for sv in self._separators: av = bf.pushVertex() articulations.add(av) vertexmap[sv] = av for bc_k, bc in self._biconComponents.items(): seps = self._separatorMap[bc_k] if len(bc) == 2 and len(seps) == 2: it = iter(bc) bf.addEdge(vertexmap[next(it)], vertexmap[next(it)]) else: bcv = bf.pushVertex() for v in bc - seps: vertexmap[v] = bcv for sv in seps: bf.addEdge(bcv, vertexmap[sv]) return bf, vertexmap, articulations
class DijkstrasAlgorithmTests(unittest.TestCase): def setUp(self): self.dg = SimpleGraph() self.one = Vertex('one') self.two = Vertex('two') self.three = Vertex('three') self.four = Vertex('four') self.five = Vertex('five') self.six = Vertex('six') self.disconnected = Vertex('disconnected') self.dg.add_vertex(self.one) self.dg.add_vertex(self.two) self.dg.add_vertex(self.three) self.dg.add_vertex(self.four) self.dg.add_vertex(self.five) self.dg.add_vertex(self.six) self.dg.add_vertex(self.disconnected) self.dg.add_edge(self.one, self.two, 7.0) self.dg.add_edge(self.two, self.one, 7.0) self.dg.add_edge(self.one, self.six, 14.0) self.dg.add_edge(self.six, self.one, 14.0) self.dg.add_edge(self.one, self.three, 9.0) self.dg.add_edge(self.three, self.one, 9.0) self.dg.add_edge(self.two, self.three, 10.0) self.dg.add_edge(self.three, self.two, 10.0) self.dg.add_edge(self.two, self.four, 15.0) self.dg.add_edge(self.four, self.two, 15.0) self.dg.add_edge(self.three, self.four, 11.0) self.dg.add_edge(self.four, self.three, 11.0) self.dg.add_edge(self.three, self.six, 2.0) self.dg.add_edge(self.six, self.three, 2.0) self.dg.add_edge(self.four, self.five, 6.0) self.dg.add_edge(self.five, self.four, 6.0) self.dg.add_edge(self.five, self.six, 9.0) self.dg.add_edge(self.six, self.five, 9.0) def test_dijkstras_algo(self): self.assertTrue( self.dg.dijkstras_algorithm(self.one, self.five) == (20.0, [self.one, self.three, self.six, self.five])) def test_dijkstras_unconnected(self): self.assertTrue( self.dg.dijkstras_algorithm(self.one, self.disconnected) == (math.inf, []))
def _build4by4(): # makes a grid structure like: # 0 - 1 - 2 - 3 # ! ! ! ! # 4 - 5 - 6 - 7 # ! ! ! ! # 8 - 9 - 10- 11 # ! ! ! ! # 12- 13- 14- 15 g = SimpleGraph() g.addVertices(range(16)) for k in range(0, 16, 4): for i in range(k, k + 3): g.addEdge(i, i + 1) for k in range(4): for i in range(k, 12, 4): g.addEdge(i, i + 4) for i in [0, 3, 12, 15]: assert g.degree(i) == 2 for i in [1, 2, 7, 11, 14, 13, 8, 4]: assert g.degree(i) == 3 for i in [5, 6, 9, 10]: assert g.degree(i) == 4 return g
class GraphOntoRectangularGrid(object): """ Locations in the grid are tuples (x, y), 0-based. Each vertex maps to one grid location. It is possible for a grid location to map to multiple vertices. """ def __init__(self, width, height=None): height = height or width assert width > 0 and height > 0 self._width = width self._height = height self._graph = SimpleGraph() self._locationMap = {} # vertex : location for x, y in product(range(self._width), range(self._height)): v = self.pushVertex((x, y)) if x > 0: self._graph.addEdge(v, self.singleVertexAt((x - 1, y))) if y > 0: self._graph.addEdge(v, self.singleVertexAt((x, y - 1))) @property def width(self): return self._width @property def height(self): return self._height @property def graph(self): return self._graph.asReadOnly() def getLocationMap(self): return dict((v, tuple(c)) for v, c in self._locationMap.items()) def pushVertex(self, xy): x, y = xy assert 0 <= x < self._width assert 0 <= y < self._height v = self._graph.pushVertex() self._locationMap[v] = xy return v def removeVertex(self, v): self._graph.removeVertex(v) del self._locationMap[v] def removeVertexAt(self, xy): self.removeVertex(self.singleVertexAt(xy)) def addEdge(self, v1, v2): self._graph.addEdge(v1, v2) def removeUniqueEdge(self, xy1, xy2): v1, v2 = map(self.singleVertexAt, (xy1, xy2)) self._graph.removeEdge(v1, v2) def verticesAt(self, xy): """Get the set of any/all vertices mapped to location.""" return set(k for k, v in self._locationMap.items() if v == xy) def singleVertexAt(self, xy): """Get the single vertex mapped to location. Error if not 1-to-1.""" v = self.verticesAt(xy) assert len(v) == 1 return v.pop() def adjacenciesAt(self, xy): return self._graph.adjacencies(self.singleVertexAt(xy)) def orthogonalAdjacencies(self, xy): x, y = xy a = self.adjacenciesAt(xy) xa = a & (self.verticesAt((x - 1, y)) | self.verticesAt((x + 1, y))) ya = a & (self.verticesAt((x, y - 1)) | self.verticesAt((x, y + 1))) return xa, ya
class TestUM(unittest.TestCase): def setUp(self): self.size = 5 self.sg = SimpleGraph(self.size) self.sg.AddVertex("A") self.sg.AddVertex("B") self.sg.AddVertex("C") self.sg.AddVertex("D") self.sg.AddVertex("E") def test_init(self): sg = SimpleGraph(3) self.assertEqual(sg.max_vertex, 3) self.assertEqual(sg.m_adjacency, [[0, 0, 0], [0, 0, 0], [0, 0, 0]]) self.assertEqual(sg.vertex, [None, None, None]) def test_add_vertex_without_adjacency(self): self.sg.AddVertex("F") self.assertEqual(len(self.sg.vertex), self.size) self.assertEqual([x.Value for x in self.sg.vertex], ["A", "B", "C", "D", "E"]) self.assertEqual(self.sg.m_adjacency, [[0] * self.size for _ in range(self.size)]) self.assertEqual( self.sg.m_adjacency, [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ], ) def test_add_edge(self): self.assertEqual(self.sg.m_adjacency, [[0] * self.size for _ in range(self.size)]) self.sg.AddEdge(0, 2) # A + C self.assertEqual(self.sg.m_adjacency[0][2], 1) self.assertEqual(self.sg.m_adjacency[2][0], 1) self.assertEqual(self.sg.IsEdge(0, 2), True) self.sg.AddEdge(0, 1) # A + B self.assertEqual(self.sg.m_adjacency[0][1], 1) self.assertEqual(self.sg.m_adjacency[1][0], 1) self.assertEqual(self.sg.IsEdge(0, 1), True) self.sg.AddEdge(0, 3) # A + D self.assertEqual(self.sg.m_adjacency[0][3], 1) self.assertEqual(self.sg.m_adjacency[3][0], 1) self.assertEqual(self.sg.IsEdge(0, 3), True) self.sg.AddEdge(3, 3) # D + D self.assertEqual(self.sg.m_adjacency[3][3], 1) self.assertEqual(self.sg.m_adjacency[3][3], 1) self.assertEqual(self.sg.IsEdge(3, 3), True) self.sg.AddEdge(1, 4) # B + E self.assertEqual(self.sg.m_adjacency[1][4], 1) self.assertEqual(self.sg.m_adjacency[4][1], 1) self.assertEqual(self.sg.IsEdge(1, 4), True) self.sg.AddEdge(3, 4) # D + E self.assertEqual(self.sg.m_adjacency[3][4], 1) self.assertEqual(self.sg.m_adjacency[3][4], 1) self.assertEqual(self.sg.IsEdge(3, 4), True) self.sg.AddEdge(1, 3) # B + D self.assertEqual(self.sg.m_adjacency[1][3], 1) self.assertEqual(self.sg.m_adjacency[3][1], 1) self.assertEqual(self.sg.IsEdge(1, 3), True) self.sg.AddEdge(2, 3) # C + D self.assertEqual(self.sg.m_adjacency[2][3], 1) self.assertEqual(self.sg.m_adjacency[3][2], 1) self.assertEqual(self.sg.IsEdge(2, 3), True) self.assertEqual( self.sg.m_adjacency, [ [0, 1, 1, 1, 0], [1, 0, 0, 1, 1], [1, 0, 0, 1, 0], [1, 1, 1, 1, 1], [0, 1, 0, 1, 0], ], ) def test_delete_vertex(self): self.assertEqual(self.sg.m_adjacency, [[0] * self.size for _ in range(self.size)]) self.sg.AddEdge(0, 2) # A + C self.assertEqual(self.sg.m_adjacency[0][2], 1) self.assertEqual(self.sg.m_adjacency[2][0], 1) self.assertEqual(self.sg.IsEdge(0, 2), True) self.assertEqual( self.sg.m_adjacency, [ [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ], ) self.sg.RemoveVertex(2) self.assertEqual(self.sg.vertex[2], None) self.assertEqual(self.sg.m_adjacency[0][2], 0) self.assertEqual(self.sg.m_adjacency[2][0], 0) self.assertEqual(self.sg.IsEdge(0, 2), False) self.assertEqual( self.sg.m_adjacency, [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ], ) def test_delete_edge(self): self.assertEqual(self.sg.m_adjacency, [[0] * self.size for _ in range(self.size)]) self.sg.AddEdge(0, 2) # A + C self.assertEqual(self.sg.m_adjacency[0][2], 1) self.assertEqual(self.sg.m_adjacency[2][0], 1) self.assertEqual(self.sg.IsEdge(0, 2), True) self.assertEqual( self.sg.m_adjacency, [ [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ], ) self.sg.RemoveEdge(0, 2) self.assertEqual(self.sg.m_adjacency[0][2], 0) self.assertEqual(self.sg.m_adjacency[2][0], 0) self.assertEqual(self.sg.IsEdge(0, 2), False) self.assertEqual( self.sg.m_adjacency, [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ], )
def _testGraph(): g = SimpleGraph() assert isinstance(g, QueryableSimpleGraph) assert not isinstance(g.asReadOnly(), SimpleGraph) assert isinstance(g.asReadOnly(), QueryableSimpleGraph) g.assertSimple() verts = [] for i in range(10): verts.append(g.pushVertex()) try: g.addVertex(verts[0]) raise AssertionError except ValueError: pass assert len(set(verts)) == len(verts) for v in verts: assert not g.adjacencies(v) assert g.connectedComponent(v) == {v} assert not g.isSeparator(v) assert g.isConnectedSet([v]) parts = g.disjointPartitions() assert len(parts) == len(verts) s = set() for p in parts: assert len(p) == 1 s.add(p.pop()) assert s == set(verts) edgeCount = 0 assert g.edgeCount() == edgeCount assert g.edgeCount(without=set()) == g.edgeCount() for i in range(len(verts) - 1): edgeCount += 1 g.addEdge(verts[i], verts[i + 1]) for v in verts[i + 2:]: assert not g.connected(verts[i + 1], v) assert not g.connected(v, verts[i + 1]) for j in range(i + 1): if j > 0: assert g.connected(verts[0], verts[j]) assert g.connected(verts[j], verts[0]) assert g.connectedComponent(verts[j]) == set(verts[:i + 2]) assert g.edgeCount() == edgeCount assert g.edgeCount(without=set()) == g.edgeCount() assert g.edgeCount(mask=verts) == g.edgeCount() for v in verts: assert g.edgeCount(mask={v}) == 0 assert g.connectedComponent(v) == set(verts) assert g.isConnectedSet(verts) assert g.isConnectedSet([verts[2], verts[4]], verts[2:5]) assert not g.isConnectedSet([verts[2], verts[4]], [verts[2], verts[4]]) assert g.isConnectedSet(verts[:4] + verts[5:]) assert not g.isConnectedSet(verts[:4] + verts[5:], verts[:4] + verts[5:]) assert not g.isSeparator(verts[0]) assert not g.isSeparator(verts[-1]) assert all(g.isSeparator(v) for v in verts[1:-1]) assert g.shortestPath(verts[0], verts[-1]) == verts assert g.shortestPath(verts[-1], verts[0]) == list(reversed(verts)) assert g.shortestPath(verts[3], verts[3]) == [verts[3]] shortcut = g.pushVertex() edgeCount += 2 g.addEdge(verts[0], shortcut) g.addEdge(verts[-1], shortcut) assert g.shortestPath(verts[0], verts[-1]) == \ [verts[0], shortcut, verts[-1]] assert verts[0] == 0 edgeCount -= 1 g.removeEdge(verts[-1], shortcut) assert g.shortestPath(shortcut, verts[1]) == [shortcut, verts[0], verts[1]] edgeCount -= len(g.adjacencies(shortcut)) assert g.edgeCount(without={shortcut}) == edgeCount g.removeVertex(shortcut) assert g.edgeCount() == edgeCount # noinspection PyUnusedLocal edgeCount = None g.addEdge(verts[0], verts[-1]) assert g.shortestPath(verts[0], verts[-1]) == [verts[0], verts[-1]] assert not any(g.isSeparator(v) for v in verts) g.removeEdge(verts[0], verts[-1]) g.asReadOnly() mask = verts[:2] + verts[3:] parts = g.disjointPartitions(mask) assert len(parts) == 2 assert not parts[0].intersection(parts[1]) assert g.isConnectedSet(parts[0]) assert g.isConnectedSet(parts[1]) for v1 in parts[0]: for v2 in parts[1]: assert g.shortestPath(v1, v2, mask) == [] assert not g.isConnectedSet(mask, mask) assert verts[2] not in parts[0].union(parts[1]) assert parts[0].union(parts[1]) == set(verts) - set(verts[2:3]) drops = [verts[i] for i in [2, 5, 8]] for v in drops: g.removeVertex(v) verts.remove(v) assert not g.adjacencies(verts[-1]) for v in verts[:-1]: assert len(g.adjacencies(v)) == 1 assert not g.isSeparator(v) g.assertSimple() assert len(g.disjointPartitions()) == 4 assert len(g.disjointPartitions(verts[1:])) == 4 assert len(g.disjointPartitions(verts[2:])) == 3 assert g.connectedComponent(verts[-1]) == set(verts[-1:]) assert g.connectedComponent(verts[1], verts[1:]) == set(verts[1:2]) backbone = [list(p)[0] for p in g.disjointPartitions()] for i in range(len(backbone) - 1): g.addEdge(backbone[i], backbone[i + 1]) g.addEdge(backbone[0], backbone[-1]) assert len(g.disjointPartitions()) == 1 assert g.connectedComponent(verts[0]) == set(verts) assert g.connected(verts[0], verts[-1]) assert g.isConnectedSet(set(verts[:1] + verts[-1:])) assert g.edgeCount(without={3, 6}) == g.edgeCount() - 5 assert g.edgeCount(without={0, 9}) == g.edgeCount() - 4
def main(): """ Função main. """ mais = 's' while mais != 'n': print("""\n ===== Gerador de Grafos ===== [S] Simple [U] Não orientado [M] Multigrafo [O] Ordenado [R] Randômico """) tipo = input('Selecione o tipo de grafo (R padrão): ').lower() arestas = [] if tipo in ['r', '']: tipo = random.choice(['m', 's', 'u', 'o']) v_qty = random.randint(2, 7) else: pattern = re.compile(r'\d{1,}') v_qty = int(input('\nQuantidade de vértices: ')) print('Vértices: {}'.format(list(range(v_qty)))) a_qty = int(input('\nQuantidade de arestas: ')) print('Ingrese as arestas no formato "a,b":\n') for i in range(a_qty): padding = (len(str(a_qty)) - len(str(i + 1))) * ' ' aresta = input('{}[{}] '.format(padding, i + 1)) match = re.findall(pattern, aresta) if match and len(match) == 2: match[0] = int(match[0]) match[1] = int(match[1]) arestas.append(match) if tipo == 'm': graph = Graph(v_qty, arestas) if arestas else Graph.rand(v_qty) elif tipo == 'u': graph = UndirectedGraph( v_qty, arestas) if arestas else UndirectedGraph.rand(v_qty) elif tipo == 's': graph = SimpleGraph( v_qty, arestas) if arestas else SimpleGraph.rand(v_qty) elif tipo == 'o': if arestas: opt = '' while opt not in ['m', 'M']: opt = input('\nInforme minofidade ou maioridade (m/M): ') minority = opt == 'm' graph = OrderedGraph(v_qty, arestas, minority) \ if arestas else OrderedGraph.rand(v_qty) else: return order = "" if isinstance(graph, OrderedGraph) and graph.is_order(): order = """\n Máximo: {} Mínimo: {} Maximais: {} Minimais: {} """.format(graph.max(), graph.min(), graph.maximal(), graph.minimal()) print(""" Tipo: {} Vértices: {} Arestas: {} Reflexiva: {} Irreflexiva: {} Simétrica: {} Antisimétrica: {} Transitiva: {} Relação de ordem: {}{} Matriz de adjacência: {} Matriz de incidência: {} """.format(graph.__class__, graph.vertices, graph.edges, graph.is_reflexive(), graph.is_irreflexive(), graph.is_symmetric(), graph.is_antisymmetric(), graph.is_transitive(), graph.is_order(), order, graph.to_adjacency(), graph.to_incidence())) mais = input('\nMais um (S/n)? ').lower()
class IsBipartiteTests(unittest.TestCase): def setUp(self): self.b = SimpleGraph() self.l1 = Vertex('l1') self.l2 = Vertex('l2') self.l3 = Vertex('l3') self.l4 = Vertex('l4') self.r1 = Vertex('r1') self.r2 = Vertex('r2') self.r3 = Vertex('r3') self.b.add_vertex(self.l1) self.b.add_vertex(self.l2) self.b.add_vertex(self.l3) self.b.add_vertex(self.r1) self.b.add_vertex(self.r2) self.b.add_edge(self.l1, self.r1) self.b.add_edge(self.l1, self.r2) self.b.add_edge(self.l2, self.r1) self.b.add_edge(self.l2, self.r2) self.b.add_edge(self.l3, self.r1) self.b.add_edge(self.l3, self.r2) def test_is_bipartite(self): self.assertTrue(self.b.is_bipartite()) self.bl1 = Vertex('bl1') self.bl2 = Vertex('bl2') self.br1 = Vertex('br1') self.b.add_vertex(self.bl1) self.b.add_vertex(self.bl2) self.b.add_vertex(self.br1) self.b.add_edge(self.bl1, self.br1) self.b.add_edge(self.bl2, self.br1) self.assertTrue(self.b.is_bipartite()) def test_is_not_bipartite(self): self.c1 = Vertex('c1') self.b.add_vertex(self.c1) self.b.add_edge(self.l1, self.c1) self.b.add_edge(self.r1, self.c1) self.assertFalse(self.b.is_bipartite())
def test_weighted_edges_with_node_delete(): g = SimpleGraph() g.add_edge('a', 'b', 5) g.add_edge('a', 'c', 2) g.del_node('c') assert g.dict_graph['a'] == {'b': 5}
def _testMatching(): g = SimpleGraph() verts = list(range(7)) g.addVertices(verts) assert g.isMatching() g.addEdge(0, 1) assert g.isMatching() g.addEdge(1, 2) assert not g.isMatching() g.addEdge(2, 3) g.addEdge(4, 5) assert not g.isMatching() g.removeEdge(1, 2) assert g.isMatching() assert not g.isPerfectMatching() g.addEdge(6, g.pushVertex()) assert g.isPerfectMatching() g = _build4by4() assert not g.isMatching() assert g.maximumMatching().isPerfectMatching() v_a = g.pushVertex() g.addEdge(0, v_a) m = g.maximumMatching() assert m.isMatching() assert not m.isPerfectMatching() v_b = g.pushVertex() g.addEdge(v_a, v_b) assert g.maximumMatching().isPerfectMatching() g.addEdge(v_b, 4) assert g.maximumMatching().isPerfectMatching() g = SimpleGraph() A = _makeChain(g, 9) assert not g.isCycle(A) assert g.maximumMatching().edgeCount() == 4 g.addEdge(A[0], A[-1]) assert g.isCycle(A) assert g.maximumMatching().edgeCount() == 4 hub = g.pushVertex() for Av in A: g.addEdge(hub, Av) assert g.maximumMatching().isPerfectMatching() for Av in A: g.addEdge(Av, _makeLoop(g, 5)[0]) assert not g.maximumMatching().isPerfectMatching() g.removeVertex(hub) assert g.maximumMatching().isPerfectMatching() g = _build4by4() g.removeVertices([4, 8, 3, 15]) assert g.maximumMatching().isPerfectMatching()
class LargestConnectedComponentTests(unittest.TestCase): def setUp(self): self.cc = SimpleGraph() self.a = Vertex('a') self.b = Vertex('b') self.c = Vertex('c') self.d = Vertex('d') self.e = Vertex('e') self.f = Vertex('f') def test_no_connected_components(self): self.assertTrue(self.cc.largest_connected_component() == 0) def test_single_vertex_cc(self): self.cc.add_vertex(self.a) self.cc.add_vertex(self.b) self.cc.add_vertex(self.c) self.assertTrue(self.cc.largest_connected_component() == 1) def test_cc_of_size_3(self): self.cc.add_vertex(self.a) self.cc.add_vertex(self.b) self.cc.add_vertex(self.c) self.cc.add_vertex(self.d) self.cc.add_vertex(self.e) self.cc.add_vertex(self.f) self.cc.add_edge(self.a, self.b) self.cc.add_edge(self.a, self.c) self.cc.add_edge(self.d, self.e) self.assertTrue(self.cc.largest_connected_component() == 3)
def test_one_depth(): g = SimpleGraph() g.add_node('a') assert g.depth_first_traversal('a') == ['a']
def test_add_edge(): """edge added, new node added""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') g.add_edge('q', 'a') assert g.has_node('q') assert g.neighbors('q') == {'a': 0}
def test_one_loop_depth(): g = SimpleGraph() g.add_edge('a', 'a') assert g.depth_first_traversal('a') == ['a']
class SimpleGraphTests(unittest.TestCase): def setUp(self): self.g = SimpleGraph() self.a = Vertex('a') self.b = Vertex('b') self.c = Vertex('c') self.d = Vertex('d') self.e = Vertex('e') self.f = Vertex('f') self.g.add_vertex(self.a) self.g.add_vertex(self.b) self.g.add_vertex(self.c) self.g.add_vertex(self.d) self.g.add_vertex(self.e) self.g.add_edge(self.a, self.b) self.g.add_edge(self.b, self.c) self.g.add_edge(self.c, self.b) self.g.add_edge(self.c, self.d) def test_is_empty(self): self.assertFalse(self.g.is_empty()) self.g.remove_edge(self.a, self.b) self.g.remove_edge(self.b, self.c) self.g.remove_edge(self.c, self.b) self.g.remove_edge(self.c, self.d) self.g.remove_vertex(self.a) self.g.remove_vertex(self.b) self.g.remove_vertex(self.c) self.g.remove_vertex(self.d) self.g.remove_vertex(self.e) self.assertTrue(self.g.is_empty()) def test_contains_vertex(self): self.assertTrue(self.g.contains_vertex(self.a)) self.assertFalse(self.g.contains_vertex(self.f)) def test_size(self): self.assertTrue(self.g.size() == (5, 4)) self.g.add_edge(self.a, self.e) self.assertTrue(self.g.size() == (5, 5)) self.g.remove_edge(self.a, self.e) self.assertTrue(self.g.size() == (5, 4)) self.g.add_edge(self.a, self.b) self.assertTrue(self.g.size() == (5, 4)) def test_get_neighbors(self): b_neighbors = self.g.get_neighbors(self.b) self.assertTrue(len(b_neighbors) == 2) self.assertTrue(self.a in b_neighbors) self.assertTrue(self.c in b_neighbors) self.assertTrue(self.g.is_neighbor(self.a, self.b)) self.assertFalse(self.g.is_neighbor(self.a, self.d)) self.assertTrue(all([not self.g.is_neighbor(self.e, v) for v in self.g.verts])) self.g.add_vertex(self.f) self.assertTrue(len(self.g.get_neighbors(self.f)) == 0) def test_is_reachable(self): self.assertTrue(self.g.is_reachable(self.a, self.d)) self.assertTrue(self.g.is_reachable(self.a, self.d)) self.assertFalse(self.g.is_reachable(self.d, self.a)) self.assertFalse(self.g.is_reachable(self.a, self.e)) self.g.remove_vertex(self.b) self.assertTrue(self.g.size() == (4, 1)) self.assertFalse(self.g.is_reachable(self.a, self.d))
def test_init(self): sg = SimpleGraph(3) self.assertEqual(sg.max_vertex, 3) self.assertEqual(sg.m_adjacency, [[0, 0, 0], [0, 0, 0], [0, 0, 0]]) self.assertEqual(sg.vertex, [None, None, None])
def _testGraphBiconnected(): random.seed('consistent seed') edgesets = 3 * [{ 0: set(), 2: {3, 13}, 3: {2, 4, 14}, 4: {3, 15}, 13: {2, 14}, 14: {25, 3, 13, 15}, 15: {4, 14}, 17: {18, 28}, 18: {17, 29}, 22: {23}, 23: {34, 22}, 25: {36, 14}, 28: {17, 29, 39}, 29: {18, 28}, 34: {35, 45, 23}, 35: {34, 36}, 36: {25, 35, 37, 47}, 37: {36, 38}, 38: {37, 39}, 39: {28, 38}, 42: {119}, 44: {45}, 45: {34, 44}, 47: {58, 36}, 52: {120, 63}, 54: {120, 65}, 57: {58, 68}, 58: {57, 59, 47}, 59: {58, 70}, 63: {52, 118}, 65: {118, 54}, 66: {77}, 68: {57, 79}, 70: {81, 59}, 72: set(), 75: {117}, 77: {66}, 79: {80, 68}, 80: {81, 91, 79}, 81: {80, 70}, 84: {95}, 91: {80, 102}, 94: {105, 95}, 95: {96, 106, 84, 94}, 96: {95}, 99: {100}, 100: {99, 111}, 102: {91}, 104: {105, 115}, 105: {104, 106, 116, 94}, 106: {105, 95}, 111: {100}, 115: {104, 116}, 116: {105, 115}, 117: {75, 119}, 118: {65, 63}, 119: {42, 117}, 120: {52, 54} }, { 2: {3}, 3: {2, 4, 10}, 4: {3}, 10: {17, 3}, 14: {21}, 16: {17, 23}, 17: {16, 24, 10, 18}, 18: {17, 25}, 20: {27}, 21: {28, 22, 14}, 22: {21, 23}, 23: {16, 24, 30, 22}, 24: {17, 31, 25, 23}, 25: {24, 32, 18, 26}, 26: {25, 27}, 27: {26, 20, 34}, 28: {21}, 30: {31, 23}, 31: {24, 32, 38, 30}, 32: {25, 31}, 34: {27}, 38: {45, 31}, 44: {45}, 45: {44, 46, 38}, 46: {45} }, { 20: {31}, 24: {35}, 31: {42, 20}, 34: {35, 45}, 35: {24, 34, 46}, 39: {40}, 40: {41, 51, 39}, 41: {40, 42, 52}, 42: {41, 53, 31}, 44: {45, 55}, 45: {56, 34, 44, 46}, 46: {57, 35, 45}, 51: {40, 52, 62}, 52: {41, 51, 53, 63}, 53: {64, 42, 52}, 55: {56, 66, 44}, 56: {57, 67, 45, 55}, 57: {56, 68, 46}, 62: {73, 51, 63}, 63: {64, 74, 52, 62}, 64: {53, 63}, 66: {67, 55}, 67: {56, 66, 68, 78}, 68: {57, 67, 69, 79}, 69: {80, 68}, 72: {73, 83}, 73: {72, 74, 62}, 74: {73, 63}, 78: {67, 79}, 79: {80, 90, 68, 78}, 80: {81, 91, 69, 79}, 81: {80, 82, 92}, 82: {81, 83}, 83: {72, 82}, 90: {91, 79}, 91: {80, 90, 92}, 92: {81, 91} }] for es in edgesets: es = deepcopy(es) g = SimpleGraph(es) g2 = SimpleGraph(g) assert set(g.vertices) == set(g2.vertices) g2.removeVertex(list(g2.vertices)[0]) assert set(g.vertices) != set(g2.vertices) verts = set(g.vertices) vertlist = list(verts) random.shuffle(vertlist) rgstack = [OnlineReducedGraph(QueryableSimpleGraph(deepcopy(es)))] for v in vertlist: rgstack.append(rgstack[-1].copy()) rgstack[-1].maskVertex(v) while vertlist: assert set(es) == verts bcs, seps = g.biconnectedComponents() for bc1, bc2 in combinations(bcs, 2): assert len(bc1 & bc2) < 2 assert not bc1.issubset(bc2) assert not bc2.issubset(bc1) rg = rgstack.pop(0) # noinspection PyProtectedMember rg._assertValidState() rg_bcs, rg_seps = rg.biconnectedComponents() assert _equalSetSets(bcs, rg_bcs) assert seps == rg_seps assert reduce(set.union, bcs) == verts innerbcs = [bc - seps for bc in bcs] assert sum(map(len, innerbcs)) + len(seps) == len(verts) memberbcs = dict((v, set()) for v in verts) for i, bc in enumerate(bcs): for v in bc: memberbcs[v].add(i) parts = g.disjointPartitions() assert _equalSetSets(parts, rg.disjointPartitions()) for part in parts: for v in part: assert rg.connectedComponent(v) == part for v in verts: novparts = g.disjointPartitions(verts - {v}) if g.isSeparator(v): assert rg.isSeparator(v) assert v in seps assert len(memberbcs[v]) > 1 assert len(novparts) == len(parts) + len(memberbcs[v]) - 1 else: assert not rg.isSeparator(v) assert v not in seps assert len(memberbcs[v]) == 1 if len(g.connectedComponent(v)) == 1: assert len(novparts) == len(parts) - 1 else: assert len(novparts) == len(parts) for bc in bcs: bcs_, seps_ = g.biconnectedComponents(bc) assert len(bcs_) == 1 assert bcs_[0] == bc assert not seps_ for v in bc: assert bc.issubset(g.connectedComponent(v)) assert bc == g.connectedComponent(v, bc) v = vertlist.pop(0) verts.remove(v) g.removeVertex(v)
def test_dijkstra(): graph = SimpleGraph([('a', 'b', 6), ('b', 'a', 5), ('a', 'g', 1), ('g', 'b', 1)]) assert graph.dijkstra('a') == {'a': 0, 'b': 2, 'g': 1}
def test_weighted_edges(): g = SimpleGraph() g.add_edge('a', 'b', 5) g.add_edge('a', 'c', 2) g.add_edge('b', 'c', 1) assert g.dict_graph['a'] == {'b': 5, 'c': 2}
if __name__ == '__main__': from graph import SimpleGraph parser = argparse.ArgumentParser( description='Given site map, build a graph and find its diameter') parser.add_argument('input', metavar='FILE', type=str, default='sitemap.json', help='input file name') args = parser.parse_args() logging.basicConfig( level=logging.DEBUG, datefmt='%Y-%m-%d %H:%M:%S', format='%(asctime)s - %(levelname)-8s - %(message)s', ) try: g = SimpleGraph.from_json(args.input) path = find_diameter(g) if path: d = (len(path) - 1) print('Length: %d' % d) print('\n-->'.join(path)) else: print('Empty!') except KeyboardInterrupt: logging.warn('Interrupted.') except Exception as ex: logging.error(ex, exc_info=True)
def test_del_nodes(): """nodes are deleted""" g = SimpleGraph() g.add_node('a') g.add_node('b') g.add_node('c') g.add_edge('a', 'c') g.add_edge('a', 'b') g.del_node('a') assert 'a' not in g.nodes() assert g.has_node('a') is False