2014-04-25 32 views
5

Jak utworzyć wykres za pomocą narzędzia graficznego w python, poza macierzą sąsiedztwa? Załóżmy, że mamy matrycę adj jako macierz sąsiedztwa.Tworzenie ważonego wykresu z macierzy sąsiedztwa w narzędziu graficznym, interfejsie Pythona

Co mam teraz zrobić to tak:

 g = graph_tool.Graph(directed = False) 
     g.add_vertex(len(adj)) 
     edge_weights = g.new_edge_property('double') 
     for i in range(adj.shape[0]): 
      for j in range(adj.shape[1]): 
       if i > j and adj[i,j] != 0: 
        e = g.add_edge(i, j) 
        edge_weights[e] = adj[i,j] 

Ale to nie w porządku, czy mamy jakieś lepsze rozwiązanie?

(i myślę, że właściwy tag byłoby graph-tool, ale nie mogę go dodać, niektóre osoby z rodzaju wystarczających uprawnień mogłoby tag?)

Odpowiedz

7

Graph-narzędzie zawiera teraz funkcję dodawania listę krawędzi na wykresie. Teraz można zrobić, na przykład:

adj = numpy.random.randint(0, 2, (100, 100)) # a random directed graph 
g = Graph() 
g.add_edge_list(transpose(adj.nonzero())) 
+0

A dla tych, którzy zastanawiać, 'transpozycji()' 'jest numpy.transpose()' – zm0

3

grap-narzędzie nie zapewnia bezpośredni sposób zbudować wykres z macierzy sąsiedztwa. AFAIK, używa reprezentacji wykresów z listy przyległej z biblioteki Boost Graph, co może być przyczyną tego (chociaż może autor zapewni jej implementację w przyszłości).

Musiałem pracować z graf-narzędziem budującym wykres z macierzy sąsiedztwa, a mój kod wyglądał bardzo podobnie do twojego - i nie czuł się tak źle. Jeśli macierz sąsiedztwa jest wynikiem niektórych wcześniejszych obliczeń, nie sądzę, że można wypracować więcej rozwiązań kosmetycznych. Jeśli jednak są odczytywane z pliku, można rozważyć użyć tego kodu raz czytać wykres i zapisać go w jakimś formacie wykres narzędziem akceptuje (patrz save(), load() i load_graph() w graph_tool documentation i the Graph I/O section of the quickstart).

BTW, niepotwierdzona porada. W twoim kodzie, biorąc pod uwagę, że budujesz nieukierunkowany wykres, możesz uniknąć przechodzenia przez połowę macierzy, zmieniając zakresy j. Zakładając, że adj jest macierzą kwadratową, można to zrobić w następujący sposób (co powinno być, prawda?):

g = graph_tool.Graph(directed = False) 
g.add_vertex(len(adj)) 
edge_weights = g.new_edge_property('double') 
num_vertices = adj.shape[0] 
for i in range(num_vertices - 1): 
    for j in range(i + 1, num_vertices): 
     if adj[i,j] != 0: 
      e = g.add_edge(i, j) 
      edge_weights[e] = adj[i,j] 
1

ten powinien być komentarz do Tiago's answer, ale nie mam wystarczająco dużo reputację tego.

Dla najnowszej wersji (2.26) z graph_tool Uważam, że brakuje tam transpozycji. Wpis i,j na macierz sąsiedztwa oznacza ciężar krawędź przechodząc od wierzchołka do wierzchołka ij, więc powinno być

g.add_edge_list(transpose(transpose(adj).nonzero()))