この記事は、Lemony Hug によるHuawei クラウド コミュニティ「元のエッジ リストから隣接行列まで Python でグラフ データ処理を実装するための完全なガイド」から共有されたものです。
グラフ理論とネットワーク解析において、グラフはノード (または頂点) とこれらのノードを接続するエッジで構成される非常に重要なデータ構造です。 Python では、隣接行列を使用してグラフを表すことができます。行列の行と列はノードを表し、行列内の値はノード間にエッジがあるかどうかを表します。
元のエッジリスト
たとえば、各要素がエッジを表すプリミティブ エッジ リストがあるとします。
エッジ = [(0, 1), (0, 2), (1, 2), (2, 3)]
この例では、各タプルは、ノードとノードの間のエッジの存在を表します。 (a, b)
a
b
隣接行列に変換する
まずグラフ内のノードの数を決定し、次に対応するサイズのゼロ行列を作成する必要があります。次に、元のエッジ リストを調べ、各エッジの 2 つのノードに基づいて、対応する行列要素を 1 に設定します。得られた最終行列が、必要な隣接行列です。
このプロセスを Python コードで実装する方法を見てみましょう。
defedges_to_adjacency_matrix(エッジ): # グラフ内のノードの数を見つける max_node = max(エッジ内のエッジの最大(エッジ)) + 1 #ゼロ行列の作成 adjacency_matrix = [[0] * 範囲内の _ の max_node(max_node)] # 元のエッジ リストを走査し、隣接行列を更新します エッジ内のエッジの場合: 隣接行列[エッジ[0]][エッジ[1]] = 1 adjacency_matrix[edge[1]][edge[0]] = 1 # 無向グラフの場合、エッジは双方向です 隣接関係マトリックスを返す # テスト エッジ = [(0, 1), (0, 2), (1, 2), (2, 3)] 隣接行列 = エッジと隣接行列(エッジ) adjacency_matrix の行の場合: 印刷(行)
このコードでは、edges_to_adjacency_matrix
関数は元のエッジ リストを引数として受け取り、対応する隣接行列を返します。次に、指定されたエッジ リストに対してテストを実行し、結果の隣接行列を出力しました。
拡張と最適化
上記のコードは元のエッジ リストから隣接行列への変換を完了できますが、実際のアプリケーションではいくつかの拡張と最適化が必要になる場合があります。
-
有向グラフと無向グラフの処理: 現在のコードは、デフォルトで無向グラフを処理します。有向グラフの場合は、特定のニーズに応じてコードを変更する必要があり、隣接関係は一方向にのみ設定されます。
-
重みの処理: エッジは単に存在するか存在しないかの関係だけでなく、重みを持つ場合もあります。加重グラフをサポートするようにコードが変更されました。
-
スパース行列を使用する: 大きなグラフの場合、隣接行列が大量のメモリを消費する可能性があるため、メモリ スペースを節約するためにスパース行列の使用を検討してください。
-
パフォーマンスの最適化: 大規模なエッジ リストの場合、コードのパフォーマンスを考慮する必要があります。より効率的なデータ構造またはアルゴリズムを使用して、変換プロセスを実装してみることができます。
コードの最適化の例をいくつか示します。
numpyをnpとしてインポート defedges_to_adjacency_matrix(edges、directed=False): max_node = max(エッジ内のエッジの最大(エッジ)) + 1 adjacency_matrix = np.zeros((max_node, max_node)) エッジ内のエッジの場合: 指示された場合: 隣接行列[エッジ[0]][エッジ[1]] = 1 それ以外: 隣接行列[エッジ[0]][エッジ[1]] = 1 隣接行列[エッジ[1]][エッジ[0]] = 1 隣接関係マトリックスを返す # テスト エッジ = [(0, 1), (0, 2), (1, 2), (2, 3)] 隣接行列 = エッジと隣接行列(エッジ) print("無向グラフの隣接行列:") print(隣接行列) Directed_edges = [(0, 1), (0, 2), (1, 2), (2, 3)] Directed_adjacency_matrix = エッジ対隣接マトリックス(directed_edges、directed=True) print("\n有向グラフの隣接行列:") print(directed_adjacency_matrix)
最適化されたコードでは、NumPy ライブラリを使用して行列を作成および操作します。これにより、コードのパフォーマンスと読みやすさが向上します。同時に、有向グラフと無向グラフの変換をサポートするために、グラフのタイプを示すパラメーターを追加しました。 directed
スパース行列を使用してメモリ フットプリントを最適化する
大きなグラフを扱う場合、隣接行列が非常に疎になり、要素のほとんどが 0 になることがあります。メモリ使用量を最適化するために、スパース行列を使用して隣接関係を表すことができます。
Python にはスパース行列を処理できるさまざまなライブラリがあり、その中でも Scipy ライブラリはスパース行列用のさまざまな演算とアルゴリズムを提供します。 Scipy でスパース行列を使用してコードを最適化する方法を見てみましょう。
numpyをnpとしてインポート scipy.sparse から lil_matrix をインポート defedges_to_adjacency_matrix(edges、directed=False): max_node = max(エッジ内のエッジの最大(エッジ)) + 1 adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.int8) エッジ内のエッジの場合: 指示された場合: 隣接行列[エッジ[0], エッジ[1]] = 1 それ以外: 隣接行列[エッジ[0], エッジ[1]] = 1 隣接行列[エッジ[1]、エッジ[0]] = 1 隣接関係マトリックスを返す # テスト エッジ = [(0, 1), (0, 2), (1, 2), (2, 3)] 隣接行列 = エッジと隣接行列(エッジ) print("無向グラフの隣接行列:") print(adjacency_matrix.toarray()) Directed_edges = [(0, 1), (0, 2), (1, 2), (2, 3)] Directed_adjacency_matrix = エッジ対隣接マトリックス(directed_edges、directed=True) print("\n有向グラフの隣接行列:") print(directed_adjacency_matrix.toarray())
このバージョンのコードでは、 を使用してスパース行列を作成します。大規模な疎行列を効率的に処理でき、ゼロ以外の要素のみを格納するため、メモリを節約できます。 scipy.sparse.lil_matrix
この最適化により、過剰なメモリ使用量によるパフォーマンスの低下やメモリ不足の問題を引き起こすことなく、より大きなグラフ データを処理できます。
加重エッジリストを処理する
場合によっては、グラフのエッジはノード間の接続関係を表すだけでなく、重み情報も持つことがあります。たとえば、交通ネットワークでは、エッジは道路を表し、重みは道路の長さまたは移動時間を表すことができます。
加重エッジ リストをサポートするようにコードを変更する方法を見てみましょう。
numpyをnpとしてインポート scipy.sparse から lil_matrix をインポート defedges_to_adjacency_matrix(edges、directed=False、weighted=False): max_node = max(max(edge[0],edge[1]) (エッジ内のエッジの場合)) + 1 adjacency_matrix = lil_matrix((max_node, max_node), dtype=np.float32) エッジ内のエッジの場合: 指示された場合: 重み付けされている場合: 隣接行列[エッジ[0], エッジ[1]] = エッジ[2] それ以外: 隣接行列[エッジ[0], エッジ[1]] = 1 それ以外: 重み付けされている場合: 隣接行列[エッジ[0], エッジ[1]] = エッジ[2] 隣接行列[エッジ[1], エッジ[0]] = エッジ[2] それ以外: 隣接行列[エッジ[0], エッジ[1]] = 1 隣接行列[エッジ[1]、エッジ[0]] = 1 隣接関係マトリックスを返す # テスト 重み付けエッジ = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)] Weighted_adjacency_matrix = エッジ対隣接マトリックス(weighted_edges、weighted=True) print("加重隣接行列:") print(weighted_adjacency_matrix.toarray())
このバージョンのコードでは、エッジに重みが付けられているかどうかを示すパラメーターを追加しました。引数が の場合、重み情報がエッジ リストから抽出され、隣接行列に保存されます。それ以外の場合、隣接行列の値は依然としてエッジの有無を表します。 weighted
weighted
True
この変更により、重み情報を含むグラフ データを処理し、その後の分析と計算のためにこの情報を隣接行列に保持できるようになります。
グラフの可視化
グラフ データを扱う場合、視覚化はグラフの構造と特性を直感的に理解するのに役立つ強力なツールです。 Python には、グラフ データを視覚化するために使用できるライブラリが多数あります。その中でも、NetworkX は、グラフを作成、操作、視覚化するための豊富な機能を提供する一般的に使用されるライブラリです。
NetworkX を使用して、生成された隣接行列を視覚化する方法を見てみましょう。
ネットワークxをnxとしてインポート matplotlib.pyplotをpltとしてインポート def Visualize_adjacency_matrix(adjacency_matrix): G = nx.from_numpy_matrix(隣接行列) pos = nx.spring_layout(G) # ノードの位置を定義 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)} # エッジの重みを取得 nx.draw_networkx_edge_labels(G, pos,edge_labels=edge_labels, font_size=10) # エッジの重みを描画します plt.title("グラフの視覚化") plt.show() # テスト 重み付けエッジ = [(0, 1, 5), (0, 2, 3), (1, 2, 2), (2, 3, 7)] Weighted_adjacency_matrix = エッジ対隣接マトリックス(weighted_edges、weighted=True) print("加重隣接行列:") print(weighted_adjacency_matrix.toarray()) Visualize_adjacency_matrix(weighted_adjacency_matrix.toarray())
このコードでは、まずNetworkX の関数を使用して隣接行列をグラフ オブジェクトに変換します。次に、定義したノードの位置を使用して、関数を使用してグラフを描画します。最後に、関数を使用してエッジの重みをプロットします。 from_numpy_matrix
spring_layout
draw
draw_networkx_edge_labels
可視化することでグラフの構造を明確に把握でき、ノード間の接続関係や重み情報を直感的に把握できます。
隣接行列を生のエッジ リストに変換する
グラフ データ処理では、隣接行列を元のエッジ リスト形式に変換する必要がある場合があります。一部のアルゴリズムはエッジ リストを使用してグラフを表現するのに適している場合があるため、これは特定のアルゴリズムやアプリケーションで役立つ場合があります。
この変換を実現するコードの記述方法を見てみましょう。
numpyをnpとしてインポート def adjacency_matrix_to_edges(adjacency_matrix): エッジ = [] 範囲内の i の場合 (adjacency_matrix.shape[0]): range(adjacency_matrix.shape[1]) の j の場合: adjacency_matrix[i, j] != 0 の場合: edges.append((i, j, adjacency_matrix[i, j])) リターンエッジ # テスト adjacency_matrix = np.array([[0, 1, 0, 0], [1、0、1、0]、 [0、1、0、1]、 [0, 0, 1, 0]]、dtype=np.float32) print("元の隣接行列:") print(隣接行列) エッジ = adjacency_matrix_to_edges(adjacency_matrix) print("\n変換されたエッジのリスト:") プリント(エッジ)
このコードでは、隣接行列の各要素を反復処理し、要素の値がゼロ以外の場合、それをエッジ リスト内のエッジに変換します。重みのあるグラフの場合、重み情報もエッジ リストに保存します。
この変換プロセスを通じて、隣接行列によって表されるグラフをエッジ リストの形式に変換することができ、それによって一部のアルゴリズムの実装と適用が容易になります。
概要と展望
この記事では、Python を使用して元のエッジ リストを隣接行列に変換する方法を紹介し、さまざまなシナリオのニーズを満たすために一連の拡張と最適化を実行します。無向グラフと有向グラフ、重み付きエッジ リストの処理から、メモリ使用量を最適化するためのスパース行列の使用、グラフの視覚化と生のエッジ リストへの隣接行列の変換まで、グラフ データ処理のさまざまな側面をカバーします。
実際のアプリケーションでは、グラフ データ処理は非常に重要で広く使用されている分野であり、ネットワーク分析、ソーシャル ネットワーク、交通計画、バイオインフォマティクス、その他多くの分野が含まれます。グラフ データ処理のスキルを習得すると、複雑なデータ構造をよりよく理解して分析し、実際的な問題を解決することができます。
将来的には、データの規模と複雑さが増大し続けるにつれて、グラフ データ処理の分野はより多くの課題と機会に直面することになります。変化するニーズや課題に対処するために、より効率的で柔軟性があり、機能が豊富なツールやアルゴリズムが登場すると予想されます。同時に、学習と探索を継続し、グラフデータ処理の分野における能力とレベルを常に向上させ、実際的な問題の解決にさらに貢献することもできます。
この記事がグラフ データ処理の理解と応用に役立つことを願っています。また、この分野をさらに研究し、データ サイエンスとエンジニアリングの発展に貢献することも歓迎します。
クリックしてフォローし、できるだけ早くHuawei Cloudの新しいテクノロジーについて学びましょう~
Google Python Foundation チームが解雇されたことを Google が確認し、Flutter、Dart、Python に関与するチームが GitHub のホット リストに殺到しました - オープンソースのプログラミング言語とフレームワークはどうしてこんなにも魅力的なのでしょうか? Xshell 8 が ベータ テストを開始: RDP プロトコルをサポートし、Windows 10/11 にリモート接続 できる Rail WiFi の最初の長期サポート バージョン 8.4 GA AI 検索ツール Perplexica : 完全にオープンソースで無料、Perplexity の代替となるオープンソースの価値をファーウェイ幹部が評価 : 継続的な抑制にもかかわらず、依然として独自のオペレーティング システムを持っています。ドイツの自動車ソフトウェア会社 Elektrobit が、Ubuntu をベースとした自動車オペレーティング システム ソリューションをオープンソース化しました。