こんにちはこんにちは、 id:crashrt です。
京都の交差点って命名規則が面白いですよね。 四条河原町とか河原町三条とか、多くの場合は交差する通りの名前を組み合わせたものになっています。 そしてどうやら大きな通りを先にすることが多いみたいです(河原町通よりも四条通の方がでかい、みたいに)。
交差点名から通りの強さを決めたい
交差点名から勝敗が分かるなら、当然「京都最強の通り」が気になってきます。 四条河原町と河原町三条という交差点の名前から、四条>河原町>三条、みたいな順番を作るというのを続けたらランキングができそうです。 実際には他にも順番を決める要素がありそうですが、それらを全部無視して交差点名だけで勝敗を決めたらどうなるのか、というのは気になります。

忘れないうちに一旦KMCのSlackに書いておきました。 KMCには部員ごとにmemoチャンネルというものがあり、ここでは各々自由気ままに発言をしています。 一般的にはtimesとか呼ばれているやつですね。 今回もいつものごとくmemoチャンネルに雑に書き込んでいました。
単純なランキングは作れなかった

すると部員からコメントが来ました。 七条堀川 / 堀川五条 / 五条大宮 / 大宮七条みたいなサイクルがあって推移律が壊れているみたいです。 簡単には順序を決められなさそうですね、残念...
しかも調べてみると、三条御前 / 御前通四条 / 四条河原町 / 河原町三条という別のサイクルもありました。 思ってたより入り乱れている...
そんな話をしていると色々と最強候補の情報が集まってきました。これは最強を見つけたい。




他にも京都の通りに関する知見が集まってきました。


PageRankで強さを決める
最強を決めるからには評価基準を決めないといけません。 一番シンプルなのは順番に並べることだったのですが、推移律が壊れていたので断念。 他には勝敗数とかもありますが、四条とか河原町に勝つのとそこら辺の通りに勝つのが同じ点数なのはちょっと違う気がします。
強い通りに勝ってる通りはより強い、みたいなことができると嬉しいわけです。 なんか強いページにリンクされているページは強い、という構造に似ていますね。 ということでweb検索で有名なPageRankというアルゴリズムを採用することにしました。 情報検索の講義で習ったのが懐かしい。
PageRankは、ざっくり言うと「点数が矢印の向きに流れていく」という感じです。 「負けた通り」→「勝った通り」に矢印を張ると、勝った通りに点数が集まります。 たくさん点数を持っている通りから流れてくる点数は大きいので、「強い通りに勝った通りはより強い」という雰囲気を反映できます。
また、実際のPageRankでは点数の一部を全体に配り直すような処理も入っています。 そのため、今回のようにサイクルがあったり、負けていない通りがあったりしても、とりあえずいい感じに点数を計算できます。
今回のルール
改めてルールを整理しますが至ってシンプルで「交差点で先に名前が来る方が勝ち」です。 百万遍みたいな交差点は引き分けとして扱い、勝敗のカウントには入れません。 もちろん実際の交差点名の順序は様々な要素で決まっていると思いますが、今回はそのあたりの事情をすべて無視し、「名前で先に来たら勝ち」という雑なゲームとして扱います。
なお、交差点名の表記には多少の揺れがあります。 今回は Google Maps の表記を優先し、次に信号、最後に近くのバス停名を見る、という雑な優先順位で決めました。 なので「本当はそっちじゃなくない?」というケースはたぶんあります *1。
ランキングに参加させる通りはかなり雰囲気で選んでいます。 東西/南北の長くて交差点名になるくらいの大きな通り、という感じなので網羅性はありません。 厳密に選んだ訳ではないのでランキングも細かい部分は色々揺れると思います...
実装
ということで実装しました。Codexが。
GitHub - kmc-jp/kyoto-street-rank: 京都で最強の通りを見つけたい · GitHub
やってることはとてもシンプルです。 通りと交差点をSQLiteで管理して、そこからグラフを作り、NetworkXでPageRankを計算する、という感じです。 弱い通りから強い通りに点数を渡すようにしたいので、各交差点について「弱い通り」→「強い通り」の向きにエッジを張っています。
あとはデータベースを操作したり結果を確認するためのいい感じのWeb UIを作ってもらいました。 こういうのがサクッと作れるのはCoding Agentの良い部分ですね。


西大路通が最強だった
結果は1位が西大路通、2位が葛野大路通、3位が高辻通となりました。 四条通とか河原町通、烏丸通、堀川通あたりの強そうなとこがTOP3に全く入らないのはちょっと意外ですね。
ランキング全体は以下の表のような感じでした *2 。
| 順位 | 通り | PageRank | 勝利数 | 敗退数 | 勝敗差 |
|---|---|---|---|---|---|
| 1 | 西大路通 | 0.080767 | 6 | 0 | 6 |
| 2 | 葛野大路通 | 0.078373 | 5 | 1 | 4 |
| 3 | 高辻通 | 0.077880 | 1 | 5 | -4 |
| 4 | 四条通 | 0.077449 | 4 | 4 | 0 |
| 5 | 九条通 | 0.072799 | 6 | 2 | 4 |
| 6 | 七条通 | 0.068038 | 5 | 5 | 0 |
| 7 | 烏丸通 | 0.062804 | 9 | 2 | 7 |
| 8 | 河原町通 | 0.048416 | 7 | 3 | 4 |
| 9 | 堀川通 | 0.048103 | 8 | 2 | 6 |
| 10 | 大宮通 | 0.043909 | 3 | 7 | -4 |
| 11 | 壬生川通 | 0.040963 | 2 | 3 | -1 |
| 12 | 五条通 | 0.039209 | 4 | 6 | -2 |
| 13 | 東大路通 | 0.033690 | 4 | 0 | 4 |
| 14 | 御前通 | 0.027723 | 1 | 5 | -4 |
| 15 | 八条通 | 0.027659 | 2 | 3 | -1 |
| 16 | 千本通 | 0.022212 | 4 | 3 | 1 |
| 17 | 白川通 | 0.021610 | 3 | 0 | 3 |
| 18 | 三条通 | 0.021310 | 2 | 7 | -5 |
| 19 | 下鴨本通 | 0.018789 | 2 | 0 | 2 |
| 20 | 北山通 | 0.016597 | 1 | 3 | -2 |
| 21 | 北大路通 | 0.016597 | 1 | 5 | -4 |
| 22 | 今出川通 | 0.016597 | 1 | 5 | -4 |
| 23 | 丸太町通 | 0.015978 | 1 | 5 | -4 |
| 24 | 油小路通 | 0.011265 | 0 | 2 | -2 |
| 25 | 御池通 | 0.011265 | 0 | 4 | -4 |
ちなみにグラフはこんな感じです。 矢印は「負けた通り」→「勝った通り」の方向、色はPageRankを表していて赤 > 黄 > 青の順で強いです。

四条とか五条とか九条とか広い通りに勝ちまくってる西大路通はやっぱり強いですね。 東大路通も同じく無敗ではあるのですが、四条とかとは引き分けなのであまり点数を稼げなかったみたいです。
面白いのが高辻通で、勝敗数は1勝5敗なのですがPageRankでは3位になっています。 これはSlackで出てきた
四条と五条の両方に勝ってるのが西大路と葛野大路だけで、葛野大路は高辻に負けてるという感じ
が理由だと言えそうです。
四条とか五条みたいな広い通りにも勝っている葛野大路は当然強くて、今回も2位になっています。 高辻通はそんな葛野大路に唯一勝っている通りなので葛野大路から流れてくる点数を大きく受け取ることになり、点数が高くなったんだと考えられます。 とてもPageRankらしい結果ですね。
烏丸通や堀川通は勝利数だけ見るとかなり強いのですが、PageRankでは西大路通や葛野大路通ほど伸びませんでした。 単にたくさん勝つだけでなく、「誰に勝ったか」がかなり効いていることが分かります。
おわり
ということで、交差点名だけをもとに雑にランキングを作ってみたところ、京都最強の通りは西大路通ということになりました。 もちろんデータの選び方や交差点名の決め方で結果は変わりそうですが、思っていたよりそれっぽくなったしPageRankらしい動きも見れたのでかなり満足です。
京都の通り、奥が深いですね。