Dieser Artikel wurde von der Huawei Cloud Community „ A Complete Guide to Implementing Graph Data Processing in Python from Original Edge List to Adjacency Matrix “ von Lemony Hug geteilt.
In der Graphentheorie und Netzwerkanalyse ist ein Graph eine sehr wichtige Datenstruktur, die aus Knoten (oder Eckpunkten) und den diese Knoten verbindenden Kanten besteht. In Python können wir einen Graphen mithilfe einer Adjazenzmatrix darstellen, wobei die Zeilen und Spalten der Matrix Knoten darstellen und die Werte in der Matrix darstellen, ob es Kanten zwischen Knoten gibt.
Originale Kantenliste
Angenommen, wir haben eine Liste primitiver Kanten, in der jedes Element eine Kante darstellt, zum Beispiel:
Kanten = [(0, 1), (0, 2), (1, 2), (2, 3)]
In diesem Beispiel stellt jedes Tupel die Existenz einer Kante zwischen dem Knoten und dem Knoten dar . (a, b)
a
b
Konvertieren Sie in eine Adjazenzmatrix
Wir müssen zunächst die Anzahl der Knoten im Diagramm bestimmen und dann eine Nullmatrix entsprechender Größe erstellen. Als nächstes durchlaufen wir die ursprüngliche Kantenliste und setzen das entsprechende Matrixelement basierend auf den beiden Knoten jeder Kante auf 1. Die endgültige erhaltene Matrix ist die Adjazenzmatrix, die wir benötigen.
Sehen wir uns an, wie dieser Prozess im Python-Code implementiert wird:
def Edges_to_adjacency_matrix(edges): # Finden Sie die Anzahl der Knoten im Diagramm max_node = max(max(edge) für Kante in Kanten) + 1 #Nullmatrix erstellen adjacency_matrix = [[0] * max_node für _ in range(max_node)] # Durchlaufen Sie die ursprüngliche Kantenliste und aktualisieren Sie die Adjazenzmatrix für Kante in Kanten: adjacency_matrix[edge[0]][edge[1]] = 1 adjacency_matrix[edge[1]][edge[0]] = 1 # Wenn es sich um einen ungerichteten Graphen handelt, sind die Kanten bidirektional gibt adjacency_matrix zurück # prüfen Kanten = [(0, 1), (0, 2), (1, 2), (2, 3)] adjacency_matrix = Edges_to_adjacency_matrix(edges) für Zeile in adjacency_matrix: drucken(Zeile)
In diesem Code edges_to_adjacency_matrix
akzeptiert die Funktion die ursprüngliche Kantenliste als Argument und gibt die entsprechende Adjazenzmatrix zurück. Anschließend führten wir den Test für die gegebene Kantenliste durch und gaben die resultierende Adjazenzmatrix aus.
Erweitern und optimieren
Obwohl der obige Code die Konvertierung der ursprünglichen Kantenliste in die Adjazenzmatrix abschließen kann, sind in praktischen Anwendungen möglicherweise einige Erweiterungen und Optimierungen erforderlich.
-
Verarbeitung gerichteter und ungerichteter Graphen : Der aktuelle Code verarbeitet standardmäßig ungerichtete Graphen. Wenn es sich um einen gerichteten Graphen handelt, muss der Code entsprechend den spezifischen Anforderungen geändert werden und die Adjazenzbeziehung wird nur in eine Richtung festgelegt.
-
Umgang mit Gewichten : Manchmal ist eine Kante nicht nur eine Beziehung zwischen Existenz und Abwesenheit, sondern kann auch ein Gewicht haben. Code geändert, um gewichtete Diagramme zu unterstützen.
-
Verwenden Sie dünn besetzte Matrizen : Bei großen Diagrammen können Adjazenzmatrizen viel Speicher beanspruchen, um Speicherplatz zu sparen.
-
Leistungsoptimierung : Bei umfangreichen Kantenlisten muss die Leistung des Codes berücksichtigt werden. Sie können versuchen, effizientere Datenstrukturen oder Algorithmen zu verwenden, um den Konvertierungsprozess zu implementieren.
Hier sind einige Beispiele für Optimierungen an Ihrem Code:
numpy als np importieren def Edges_to_adjacency_matrix(Edges, gerichtet=False): max_node = max(max(edge) für Kante in Kanten) + 1 adjacency_matrix = np.zeros((max_node, max_node)) für Kante in Kanten: wenn angewiesen: adjacency_matrix[edge[0]][edge[1]] = 1 anders: adjacency_matrix[edge[0]][edge[1]] = 1 adjacency_matrix[edge[1]][edge[0]] = 1 gibt adjacency_matrix zurück # prüfen Kanten = [(0, 1), (0, 2), (1, 2), (2, 3)] adjacency_matrix = Edges_to_adjacency_matrix(edges) print("Adjazenzmatrix eines ungerichteten Graphen:") print(adjacency_matrix) gerichtete_Kanten = [(0, 1), (0, 2), (1, 2), (2, 3)] gerichtete_adjacency_matrix = Edges_to_adjacency_matrix(directed_edges, gerichtet=True) print("\nAdjazenzmatrix des gerichteten Graphen:") print(directed_adjacency_matrix)
Im optimierten Code verwenden wir die NumPy-Bibliothek, um Matrizen zu erstellen und zu bearbeiten, was die Leistung und Lesbarkeit des Codes verbessern kann. Gleichzeitig haben wir einen Parameter hinzugefügt, der den Diagrammtyp angibt und die Konvertierung gerichteter und ungerichteter Diagramme unterstützt. directed
Optimieren Sie den Speicherbedarf mithilfe dünn besetzter Matrizen
Beim Umgang mit großen Diagrammen kann die Adjazenzmatrix sehr spärlich werden, da die meisten ihrer Elemente Nullen sind. Um die Speichernutzung zu optimieren, kann eine dünn besetzte Matrix zur Darstellung von Adjazenzbeziehungen verwendet werden.
In Python gibt es eine Reihe von Bibliotheken, die mit dünn besetzten Matrizen umgehen können. Die Scipy-Bibliothek bietet unter anderem verschiedene Operationen und Algorithmen für dünn besetzte Matrizen. Werfen wir einen Blick darauf, wie Sie Ihren Code mithilfe dünn besetzter Matrizen in Scipy optimieren:
numpy als np importieren aus scipy.sparse lil_matrix importieren def Edges_to_adjacency_matrix(Edges, gerichtet=False): max_node = max(max(edge) für Kante in Kanten) + 1 adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.int8) für Kante in Kanten: wenn angewiesen: adjacency_matrix[edge[0], edge[1]] = 1 anders: adjacency_matrix[edge[0], edge[1]] = 1 adjacency_matrix[edge[1], edge[0]] = 1 gibt adjacency_matrix zurück # prüfen Kanten = [(0, 1), (0, 2), (1, 2), (2, 3)] adjacency_matrix = Edges_to_adjacency_matrix(edges) print("Adjazenzmatrix eines ungerichteten Graphen:") print(adjacency_matrix.toarray()) gerichtete_Kanten = [(0, 1), (0, 2), (1, 2), (2, 3)] gerichtete_adjacency_matrix = Edges_to_adjacency_matrix(directed_edges, gerichtet=True) print("\nAdjazenzmatrix des gerichteten Graphen:") print(directed_adjacency_matrix.toarray())
In dieser Version des Codes erstellen wir eine spärliche Matrix. Es kann große, dünn besetzte Matrizen effizient verarbeiten und speichert nur Elemente ungleich Null, wodurch Speicherplatz gespart wird. scipy.sparse.lil_matrix
Durch diese Optimierung können wir größere Diagrammdaten verarbeiten, ohne dass es zu Leistungseinbußen oder Problemen mit unzureichendem Arbeitsspeicher aufgrund übermäßiger Speichernutzung kommt.
Gewichtete Kantenlisten verarbeiten
In einigen Fällen stellen die Kanten des Diagramms nicht nur die Verbindungsbeziehungen zwischen Knoten dar, sondern können auch Gewichtsinformationen enthalten. In einem Verkehrsnetz können Kanten beispielsweise Straßen darstellen und Gewichte können die Länge oder Fahrzeit einer Straße darstellen.
Sehen wir uns an, wie wir den Code ändern können, um gewichtete Kantenlisten zu unterstützen:
numpy als np importieren aus scipy.sparse lil_matrix importieren def Kanten_to_adjacency_matrix(Kanten, gerichtet=Falsch, gewichtet=Falsch): max_node = max(max(edge[0], edge[1]) für Kante in Kanten) + 1 adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.float32) für Kante in Kanten: wenn angewiesen: wenn gewichtet: Adjazenzmatrix[Kante[0], Kante[1]] = Kante[2] anders: adjacency_matrix[edge[0], edge[1]] = 1 anders: wenn gewichtet: Adjazenzmatrix[Kante[0], Kante[1]] = Kante[2] Adjazenzmatrix[Kante[1], Kante[0]] = Kante[2] anders: adjacency_matrix[edge[0], edge[1]] = 1 adjacency_matrix[edge[1], edge[0]] = 1 gibt adjacency_matrix zurück # prüfen gewichtete_Kanten = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)] weighted_adjacency_matrix = Edges_to_adjacency_matrix(weighted_edges,weighted=True) print("Gewichtete Adjazenzmatrix:") print(weighted_adjacency_matrix.toarray())
In dieser Version des Codes haben wir einen Parameter hinzugefügt, der angibt, ob die Kante gewichtet ist. Wenn das Argument lautet , werden die Gewichtsinformationen aus der Kantenliste extrahiert und in der Adjazenzmatrix gespeichert. Ansonsten repräsentieren die Werte in der Adjazenzmatrix immer noch das Vorhandensein oder Fehlen der Kante. weighted
weighted
True
Mit dieser Modifikation können wir Diagrammdaten mit Gewichtsinformationen verarbeiten und diese Informationen für spätere Analysen und Berechnungen in der Adjazenzmatrix behalten.
Visualisierung von Diagrammen
Beim Umgang mit Diagrammdaten ist die Visualisierung ein leistungsstarkes Werkzeug, das uns helfen kann, die Struktur und Eigenschaften des Diagramms intuitiv zu verstehen. Es gibt viele Bibliotheken in Python, die zur Visualisierung von Diagrammdaten verwendet werden können, darunter NetworkX, eine häufig verwendete Bibliothek, die umfangreiche Funktionen zum Erstellen, Bearbeiten und Visualisieren von Diagrammen bietet.
Sehen wir uns an, wie Sie NetworkX verwenden, um unsere generierte Adjazenzmatrix zu visualisieren:
Netzwerkx als NX importieren matplotlib.pyplot als plt importieren def visualize_adjacency_matrix(adjacency_matrix): G = nx.from_numpy_matrix(adjacency_matrix) pos = nx.spring_layout(G) # Knotenposition definieren nx.draw(G, pos, with_labels=True, node_color='skyblue', node_size=500, font_size=10) # 制图 edge_labels = {(i, j): w['weight'] for i, j, w in G.edges(data=True)} # Kantengewichte abrufen nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=10) # Kantengewichte zeichnen plt.title("Grafikvisualisierung") plt.show() # prüfen gewichtete_Kanten = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)] weighted_adjacency_matrix = Edges_to_adjacency_matrix(weighted_edges,weighted=True) print("Gewichtete Adjazenzmatrix:") print(weighted_adjacency_matrix.toarray()) visualize_adjacency_matrix(weighted_adjacency_matrix.toarray())
In diesem Code konvertieren wir zunächst die Adjazenzmatrix mithilfe der Funktionen von NetworkX in ein Diagrammobjekt. Verwenden Sie dann die Position des definierten Knotens und zeichnen Sie den Graphen mithilfe der Funktion. Abschließend zeichnen wir die Kantengewichte mithilfe einer Funktion auf. from_numpy_matrix
spring_layout
draw
draw_networkx_edge_labels
Durch die Visualisierung können wir die Struktur des Diagramms klar erkennen und die Verbindungsbeziehungen und Gewichtsinformationen zwischen Knoten intuitiv verstehen.
Konvertieren Sie die Adjazenzmatrix in eine Rohkantenliste
Bei der Verarbeitung von Diagrammdaten müssen wir manchmal die Adjazenzmatrix zurück in ihre ursprüngliche Kantenlistenform konvertieren. Dies kann bei bestimmten Algorithmen und Anwendungen nützlich sein, da einige Algorithmen möglicherweise besser für die Verwendung von Kantenlisten zur Darstellung des Diagramms geeignet sind.
Sehen wir uns an, wie man Code schreibt, um diese Konvertierung zu erreichen:
numpy als np importieren def adjacency_matrix_to_edges(adjacency_matrix): Kanten = [] für i in range(adjacency_matrix.shape[0]): für j im Bereich(adjacency_matrix.shape[1]): wenn adjacency_matrix[i, j] != 0: Kanten.append((i, j, adjacency_matrix[i, j])) Kanten zurückgeben # prüfen adjacency_matrix = np.array([[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]], dtype=np.float32) print("Ursprüngliche Adjazenzmatrix:") print(adjacency_matrix) Kanten = adjacency_matrix_to_edges(adjacency_matrix) print("\nKonvertierte Kantenliste:") Drucken (Kanten)
In diesem Code durchlaufen wir jedes Element der Adjazenzmatrix und konvertieren es in eine Kante in der Kantenliste, wenn der Wert des Elements ungleich Null ist. Bei Diagrammen mit Gewichten speichern wir die Gewichtsinformationen auch in der Kantenliste.
Durch diesen Konvertierungsprozess können wir den durch die Adjazenzmatrix dargestellten Graphen in die Form einer Kantenliste umwandeln und so die Implementierung und Anwendung einiger Algorithmen erleichtern.
Zusammenfassung und Ausblick
In diesem Artikel wird erläutert, wie Sie mit Python die ursprüngliche Kantenliste in eine Adjazenzmatrix konvertieren und eine Reihe von Erweiterungen und Optimierungen durchführen, um den Anforderungen verschiedener Szenarien gerecht zu werden. Wir decken mehrere Aspekte der Diagrammdatenverarbeitung ab, von der Verarbeitung ungerichteter und gerichteter Diagramme und gewichteter Kantenlisten über die Verwendung dünnbesetzter Matrizen zur Optimierung der Speichernutzung bis hin zur Diagrammvisualisierung und Adjazenzmatrixkonvertierung in Rohkantenlisten.
In praktischen Anwendungen ist die Verarbeitung von Diagrammdaten ein sehr wichtiges und weit verbreitetes Gebiet, das Netzwerkanalyse, soziale Netzwerke, Verkehrsplanung, Bioinformatik und viele andere Bereiche umfasst. Die Beherrschung der Fähigkeiten der Diagrammdatenverarbeitung kann uns helfen, komplexe Datenstrukturen besser zu verstehen und zu analysieren, um praktische Probleme zu lösen.
Da der Umfang und die Komplexität der Daten in Zukunft weiter zunehmen, wird der Bereich der Diagrammdatenverarbeitung vor weiteren Herausforderungen und Chancen stehen. Wir können davon ausgehen, dass effizientere, flexiblere und funktionsreichere Tools und Algorithmen entstehen, um den sich ändernden Anforderungen und Herausforderungen gerecht zu werden. Gleichzeitig können wir weiterhin lernen und erforschen, unsere Fähigkeiten und unser Niveau im Bereich der Grafikdatenverarbeitung ständig verbessern und einen größeren Beitrag zur Lösung praktischer Probleme leisten.
Ich hoffe, dass dieser Artikel Ihnen hilft, die Verarbeitung von Diagrammdaten zu verstehen und anzuwenden. Sie sind auch herzlich eingeladen, dieses Gebiet weiter zu studieren und zu erforschen und zur Entwicklung der Datenwissenschaft und -technik beizutragen.
Das Team der Google Python Foundation wurde entlassen , und die an Flutter, Dart und Python beteiligten Teams stürmten auf die GitHub-Hotlist – Wie können Open-Source-Programmiersprachen und Frameworks so süß sein? Xshell 8 startet Betatest: Unterstützt das RDP-Protokoll und kann eine Fernverbindung zu Windows 10/11 herstellen. Wenn Passagiere eine Verbindung zum Hochgeschwindigkeits-WLAN der Bahn herstellen , taucht der „35 Jahre alte Fluch“ chinesischer Programmierer auf, wenn sie sich mit Hochgeschwindigkeit verbinden Rail WiFi. MySQLs erstes KI-Suchtool mit Langzeitunterstützung für Version 8.4 GA : Vollständig Open Source und kostenlos, eine Open-Source-Alternative zu Perplexity. Hongmeng: Es verfügt trotz anhaltender Unterdrückung immer noch über ein eigenes Betriebssystem Das deutsche Automobilsoftwareunternehmen Elektrobit hat eine auf Ubuntu basierende Automobil-Betriebssystemlösung als Open Source bereitgestellt .