![見出し画像](https://assets.st-note.com/production/uploads/images/123684300/rectangle_large_type_2_30f707cc558752e0822d1a48a26072db.png?width=1200)
友だちPython ep8. networkx
はじめに
友だちPython シリーズのご紹介
友だちPython シリーズは、Python の小ネタを短文でお届けします。
小さなエピソードを重ねてPythonと仲良しになれたら、と願ってシリーズ名を付けました。
話題
Pythonによる実務で役立つ最適化問題100+ (1)
書籍「Pythonによる実務で役立つ最適化問題100+ (1)」(朝倉書店)をご紹介いたします。
この書籍シリーズは、いわゆる「最適化問題」について、コードを写経しつつ、基礎から学べる良書です。
数式とPythonコード中心の硬派な一冊です。
対象の書籍は3巻構成の第1巻(初版第1刷)です。
この記事は networkx と 私の戯れの記録です。
記事中のイラストは「いらすとや」さんからお借りしました。
ありがとうございます!
![](https://assets.st-note.com/img/1701772472503-XZLnChGb3k.png)
今回の友だち
■ networkx (ねっとわーくえっくす)
「グラフ理論」をビジュアル面でサポートする精鋭です。
NetworkX 公式サイトの Gallery ページをご覧ください。
話題の概要
第2章「最短路問題」の「2.2.2 1対全の最適化問題」で networkx の数理的な使い方を学びました。
2つの遊びポイントを描きます。
実行環境
・networkx ver. 2.8.8
![](https://assets.st-note.com/img/1701772442242-f9kBrJnfrc.png)
遊んだ内容1
networkx を用いて、Dijkstra法による「1つの始点から他の全点に対する最短路」を算出し、迷路のような図を描画します。
■ 遊び方
書籍の28~31ページのコードを混ぜ混ぜして次のサンプルコードを作りました。
コメントだらけになってしまいました\(^o^)/
### 5×7の格子グラフの最短路木を描画
import networkx as nx
from networkx import DiGraph
import matplotlib.pyplot as plt
import random
### 乱数を用いて2次元格子グラフを作成
# 初期値設定
x, y = 5, 7 # 格子の数を設定(x, y)
lower, upper = 1, 30 # 重み:コストの範囲を設定
random.seed(123) # 乱数シード
# networkxの2次元格子グラフGridの初期化
Grid = nx.grid_2d_graph(x, y)
# Gridの辺に重み:コストを設定(ランダムな整数値)
for (i, j) in Grid.edges():
Grid[i][j]['weight'] = random.randint(lower, upper)
### Gridの最短絡とコストを計算: 始点の座標は(0, 0)
pred, distance = nx.dijkstra_predecessor_and_distance(Grid, source=(0, 0))
print('predの一部 '
f'{[{k: v} for k, v in pred.items() if k in ((0, 0), (1, 0), (2, 0))]}')
### 最短路木の描画
# networkxの有向グラフDirectedの初期化
Directed = nx.DiGraph()
# predに保持する最短路をDirectedの辺に追加
for i in pred:
if len(pred[i]) >= 1:
Directed.add_edge(pred[i][0], i)
# Gridの頂点の座標情報の取得
pos = {(i, j): (i, j) for (i, j) in Grid.nodes()}
# Gridの辺の重み:コスト情報の取得
edge_labels = {}
for (i, j) in Grid.edges():
edge_labels[i, j] = f'{ Grid[i][j]["weight"] }'
## Directedを用いて最短路木を描画
plt.figure(figsize=(5, 7))
# 有向グラフの描画
nx.draw(
Directed, pos=pos, width=2,
node_color='tomato', edge_color='tab:blue', node_size=50,
with_labels=True, font_size=10, # 座標ラベルを表示する
)
# 辺の重み:コストの描画
nx.draw_networkx_edge_labels(
Directed, pos=pos,
edge_labels=edge_labels, font_size=10, # 重みラベルを表示する
)
plt.show()
【実行結果】
![](https://assets.st-note.com/img/1701770541308-v2U9QWJMTy.png?width=1200)
![](https://assets.st-note.com/img/1701770547328-5HIYMTfx29.png)
【図の見方】
左下の 頂点 (0,0) からスタートして、青い線(辺です)の上の数字(コストです)が小さくなるように(最小化です)、全頂点を青い矢印線で結んでいます。
【経路は pred に格納】
最小化の計算を networkx の dijkstra_predecessor_and_distance() が行って、経路情報を pred に格納しています。
実行結果の最初の pred の一部に注目しましょう。
predの一部 [{(0, 0): []}, {(1, 0): [(0, 0)]}, {(2, 0): [(1, 0)]}]
始点 (0, 0) の前ステップには何もなし([])です。
頂点 (1, 0) の前ステップは (0, 0)、つまり始点です。
右下の (0, 0) から (1, 0) へ青い線(辺です)が矢印付きで(有向です)繋がっています。
同じく、頂点 (2, 0) の前ステップは (1, 0) です。
(1, 0) から (2, 0) へ青い線(辺です)が矢印付きで(有向です)繋がっています。
「predに保持する最短路をDirectedの辺に追加」して、図を描いています!
【感想】
networkx はグラフィックツールだと思って今まで使ってきました。
この書籍を学んだことによって、最適化問題を解けるのだと知りました。
networkx は凄いです!!!
![](https://assets.st-note.com/img/1701772521486-spzm98q0Vh.png)
遊んだ内容2
「2.4 ベンチマーク問題例の読み込みとDial法」で紹介されている道路ネットワークのデータ取得方法について、お知らせしたいことがあります。
テキスト掲載のURLではデータ取得サイトにアクセスできないようです。
![](https://assets.st-note.com/img/1701771531575-QZkM1hvVqf.png?width=1200)
次のリンクでダウンロードサイトに飛んでくださいね🚀
https://www.diag.uniroma1.it/challenge9/download.shtml
ダウンロードするファイルは下図の「2箇所の赤枠のファイル」です!
「NY のデータ」です。
![](https://assets.st-note.com/img/1701771721777-5OOjkoAG7U.png?width=1200)
ダウンロードした gzip ファイルを解凍して、読み込みフォルダ(作業フォルダ等)に適切に配置することで、書籍39ページの コードが正しく作動するようになります。
次の2つのコードは、Python でローカルPCにダウンロードしてファイルを解凍するコードです。参考まで。
### ファイルのダウンロード
# 設定:ダウンロードファイルの格納先パス+ファイル名
filename1 = r'./USA-road-d.NY.gr'
filename2 = r'./USA-road-d.NY.co'
ext = '.gz'
# ダウンロードの実行 filename1
url1 = r'https://www.diag.uniroma1.it/challenge9/data/USA-road-d/USA-road-d.NY.gr.gz'
res1 = requests.get(url1)
with open(filename1 + ext, mode='wb') as f:
f.write(res1.content)
# ダウンロードの実行 filename2
url2 = r'https://www.diag.uniroma1.it/challenge9/data/USA-road-d/USA-road-d.NY.co.gz'
res2 = requests.get(url2)
with open(filename2 + ext, mode='wb') as f:
f.write(res2.content)
### gzファイルの解凍
# 参考サイト: https://wannabe-data-engineer.net/python-gunzip/
# ライブラリのインポート
import gzip
import shutil
# ファイルの解凍 filename1
with gzip.open(filename1 + ext, mode='rb') as gz_file:
with open(filename1, mode='wb') as file:
shutil.copyfileobj(gz_file, file)
# ファイルの解凍 filename2
with gzip.open(filename2 + ext, mode='rb') as gz_file:
with open(filename2, mode='wb') as file:
shutil.copyfileobj(gz_file, file)
続いて、もう一つお知らせがあります。
書籍39ページの「データを読み込むコード」でワーニングが出ます。
【ワーニングメッセージ例】
DeprecationWarning: `np.int0` is a deprecated alias for `np.intp`. (Deprecated NumPy 1.24)
settled = np.zeros(n, np.int0)
ワーニングの原因はNumPyの「np.int0」が廃止予定入りしたためです。
ワーニング回避コードを置いておきます!
### 実行
filename = 'USA-road-d.NY'
G, n, m, C = ReadDimacs(filename)
print(f'num of nodes in the largest connected componet={n}, max length+1={C}')
source = 0 # 始点
sink = 50000 # 終点
settled = np.zeros(n, np.intp) # ワーニング回避
reached = np.zeros(n, np.intp) # ワーニング回避
dist = np.zeros(n, np.intp) # ワーニング回避
prev = np.zeros(n, np.intp) # ワーニング回避
settled = [0 for i in range(n)]
reached = [0 for i in range(n)]
dist = [0 for i in range(n)]
prev = [0 for i in range(n)]
これで無事に書籍39~40ページのコードを動かせます!
40ページのコードで描画した networkx の「NYの最短路のパス図」をご覧ください!
![](https://assets.st-note.com/img/1701772339000-V45lwIRxrY.png?width=1200)
みなさんも最適化問題を存分に堪能してください!
おわり
![](https://assets.st-note.com/img/1701772537647-VBpPh6K9o7.png)
ブログの紹介
noteで5つのシリーズ記事を書いています。
ぜひ覗いていってくださいね!
1.のんびり統計
統計検定2級の問題集を手がかりにして、確率・統計をざっくり掘り下げるブログです。
雑談感覚で大丈夫です。ぜひ覗いていってくださいね。
統計検定2級公式問題集CBT対応版に対応しています。
2.実験!たのしいベイズモデリングをPyMC Ver.5で
書籍「たのしいベイズモデリング」の心理学研究に用いられたベイズモデルを PyMC Ver.5で描いて分析します。
この書籍をはじめ、多くのベイズモデルは R言語+Stanで書かれています。
PyMCの可能性を探り出し、手軽にベイズモデリングを実践できるように努めます。
身近なテーマ、イメージしやすいテーマですので、ぜひぜひPyMCで動かして、一緒に楽しみましょう!
3.RとStanではじめる心理学のための時系列分析入門 を PythonとPyMC Ver.5 で
書籍「RとStanではじめる心理学のための時系列分析入門」の時系列分析トピックを PythonとPyMC Ver.5で取り組みます。
豊富なテーマ(お題)を実践することによって、PythonとPyMCの基礎体力づくりにつながる、そう信じています。
日々、Web検索に勤しみ、時系列モデルの理解、Pythonパッケージの把握、R・Stanコードの翻訳に励んでいます!
このシリーズがPython時系列分析の入門者の参考になれば幸いです🍀
4.Python機械学習プログラミング実践記
書籍「Python機械学習プログラミング PyTorch & scikit-learn編」を学んだときのさまざまな思いを記事にしました。
この書籍は、scikit-learn と PyTorch の教科書です。
よかったらぜひ、お試しくださいませ。
5.データサイエンスっぽいことを綴る
統計、データ分析、AI、機械学習、Python のコラムを不定期に綴っています。
「統計」「Python」「数学とPython」「R」のシリーズが生まれています。
最後までお読みいただきまして、ありがとうございました。