def test_vertex_count(): G = DiGraph([(0, 1), (1, 2), (1, 3), (1, 4)], format='list_of_edges') ex = DiGraphExtended(G, keep_removed=True) ex.step('sink') result = ex.current_vertex_count() expected = 2 assert result == expected
def test_neighbors_in(): G = DiGraph([(0, 1), (1, 2), (1, 3), (1, 4), (4, 3)], format='list_of_edges') ex = DiGraphExtended(G, keep_removed=True) ex.step('sink') result = ex.neighbors_in(1) expected = [0] assert result == expected
def test_sinks_then_source_duplicates(): G = DiGraph( [ [0, 1, 2], # wierzchołki [(1, 2)] # krawędzie ], format='vertices_and_edges') ex = DiGraphExtended(G) ex.step('sink') assert ex.sources() == [1]
def has_exactly_one_cycle_tournament(G): '''Zwraca True wtw G jest turniejem skierowanym o dokładnie jednym cyklu skierowanym. ''' if not G.is_directed(): raise ValueError("G musi być grafem skierowanym") for edge in [(1, 0), (2, 1), (0, 2)]: if not G.has_edge(edge): return False G_ex = DiGraphExtended(G, keep_removed=True) while True: if len(G_ex.sinks()) > 0: G_ex.step("sink") elif len(G_ex.sources()) > 0: G_ex.step("source") else: break return G_ex.current_vertex_count() == 3
def rm_sinks_and_sources(G, T, keep_T=False, G_degrees=None, G_vertices=None): '''Zwraca kopię grafu G jako DiGraphExtended, która ma usunięte wszystkie źródła i ujścia, zgodnie z uwagą pod Algorytmem 2 w [1]. :param keep_T: Jeżeli jest True, to funkcja zwraca również graf T, który został pozbawiony źródeł i ujść. :param G_degrees: dict Słownik zawierający listy out_degree i in_degree dla G postaci: {'sink': <lista out_degree dla G>, 'source': <lista in_degree dla G>} Musi być zgodny ze stanem faktycznym. W przeciwnym przypadku funkcja da niepoprawny wynik! :param G_vertices: dict Słownik zawierający listy ujść i źródeł G postaci: {'sink': <lista ujść>, 'source': <lista źródeł>}. Musi być zgodny ze stanem faktycznym. W przeciwnym przypadku funkcja da niepoprawny wynik! ''' exG = DiGraphExtended(G, keep_removed=True, degrees=deepcopy(G_degrees), vertices=deepcopy(G_vertices)) T_vertices = {'sink': T.sinks(), 'source': T.sources()} if len(T_vertices['sink']) == 0 and len(T_vertices['source']) == 0: # tablica degrees jest wtedy bezużyteczna exT = DiGraphExtended(T, keep_removed=keep_T, vertices=T_vertices, degrees={}) else: exT = DiGraphExtended(T, keep_removed=keep_T, vertices=T_vertices) while True: if len(exT.sources()) > 0: next_step = 'source' elif len(exT.sinks()) > 0: next_step = 'sink' else: if keep_T: return exG, exT else: return exG exT.step(next_step) try: exG.step(next_step) except RuntimeError: pass
def test_no_sinks(type): G = DiGraph() G.add_cycle([0, 1, 2]) ex = DiGraphExtended(G) with pytest.raises(RuntimeError): ex.step(type)
def test_sinks_then_source(): G = DiGraph([(0, 1), (0, 2)], format='list_of_edges') ex = DiGraphExtended(G) assert ex.step('sink') == [0]
def test_sinks_sources_simple(): G = DiGraph([(0, 1)], format='list_of_edges') ex = DiGraphExtended(G) assert ex.sources() == [0] assert ex.sinks() == [1]
def test_extended_tournament(case): T = digraphs.TransitiveTournament(5) ex = DiGraphExtended(T) for i in case['vertices']: assert ex.step(case['type']) == [i]