スキップしてメイン コンテンツに移動

ダイクストラ法

Introduction

今日は、ダイクストラ法について書きます。ダイクストラ法とは最短距離を求めるアルゴリズムです。地図はグラフで表されます。もし、まだ this pageを見ていない方は先にこちらをご覧ください。今回はこの記事を前提としています。このページでは、グラフの定義と、ヒープ構造について書いています。ダイクストラ法ではヒープ構造を使って、かなりの計算量を落とします。
このスライドはダイクストラ法を説明したスライドです。

Overview

  • アルゴリズム
  • 実装

アルゴリズム

このアルゴリズムは
  1. スタート始点のノードを決める。そして、それをAと名付ける。
  2. 各ノードに$d=\infty$を割り当てる。ただし、スタート地点はd=0
  3. Aの隣接ノードのリストをadj_listと名付ける。
  4.  For adj in adj_list:  If d of adj > d of A + weight to adj -> d = A + weight to adj.
  5. グラフnetworkからAを取り除く
  6. グラフnetworkの中で最初のdを持っているノードをAとし、4に戻る。
となっています。
このアルゴリズムを図を用いて説明します。

 このグラフを使って説明します。
 初めに、スタート地点を決めます。そして、各ノードに$d=\infty$を割り当てます。

 Aから始まります。Aの隣接ノードであるBのdを更新します。もし、現在のBよりもAのdとA->Bへの重みを足したもののほうが小さいならdをその値に更新します。同じようにCnのdを更新します。

次にAを取り除きます。
 次はBから始まります。Aと同じことをやります。


このダイクストラ法では今のような操作をグラフの全てのノードに×がつくまで続きます。


実装

このアルゴリズムでは$O(log(|V|^2))$という計算量を持っています。最小のdを持つノードを探すのに時間がかかります。
しかし、ヒープ構造を使えばO((E+V)log(V))に減らせます。ヒープ構造で現時点でのノードのdをヒープ構造で保存しておけば、ヒープ構造から取り出せば、最小のdを持つノードを簡単に取り出せます。


ダイクストラ法はPython 3で実装しました。
コードはgithubに乗せています。

100個のノードを作り、各ノードに0~30の間からランダムな数を選択しedgeを作ります。



結果は



このgifは各ノードの最短距離の更新を表したものです。



コメント

このブログの人気の投稿

大学院試験 -外部への道しるべ-

始めに この度、 京都大学大学院情報学研究科システム科学専攻 に合格することができました!!! 僕は現在、立命館大学という関西の私立大学に通っているので、外部受験をしたことになります。 さらに、学部は数学専攻で、大学院からは情報学(の中でも機械学習)専攻になるので、専門も変えることになります。 この記事では、外部の大学院、もしくは専攻替えを考えている人向けに書こうと思っているので、目次で気になった項目があれば、ぜひ、読んでいってくださいませ。( *´艸`) ちなみに、予測点数は線形微積6~7割、専門科目満点、英語かなり低いので内緒です。(笑) 得点開示を要求するので、得点がわかったら、また追記します。 目次 外部受験を目指すまで、目指したきっかけ 外部受検の大変さ 専攻替えの大変さ 合格するために 英語が苦手な人へ 数学科の学部から情報学(機械学習)の大学院を目指す人へ 応援 外部受検を目指すまで、目指したきっかけ ここでは、自分の大学生活がどんなだったかを書いてるだけなので、興味のない人は飛ばしましょう。(笑) 僕が学部二回生頃に、当時数理科には機械学習の研究をされている先生が一人だけ所属されていました。その先生に、直接弟子入りさせていただき、僕の機械学習への道は始まりました。。。(メインは遺伝統計学の研究でした。) 弟子入りした直後は、タイピングもなめくじのように遅かったですし、gitもpullする前にpushしたこともありました。。。 しかし、その先生は、目的に最先端で届く道のりを用意してくださいました。 プログラミングを初めて一か月ほどで、t-SNEの実装をしたり(遺伝統計学の研究で必要だった)、四か月ほどで、カーネルc-SVMの実装をしたり(やってみなとゆわれて(笑))することができました。その後も、学部二回生、三回生ながら、論文を読んで実装してきました。 学部二回生冬には、遺伝統計学の研究を 株式会社パーソルキャリア さん主催のハッチングフェスというデータサイエンティストのためのイベントで、発表しました。 このイベントでは、企業の方もたくさん来られて、知り合えるチャンスがかなりあります!! (名刺を作っておくと、「えっ、学生なのに名刺持ってるの?!」ってなるので、覚えてもらえます。...

隣接行列の実装

Introduction sorry, this page is Japanese only.   ここでは隣接行列の実装を行っていきます。Python3を使っています。OSはwindows10です。隣接行列の説明は以下の記事の下の方をご覧ください。 グラフ理論の基礎 実装例 扱うグラフ コマンドでの結果 Code defファイル import numpy as np class directed_Gragh(): def __init__(self,E,V,gragh_map): self.edge = E; self.vertex = V; self.map = gragh_map; def Adjacency_matrix(self): adjacency_matrix = np.zeros((self.vertex.shape[0],self.vertex.shape[0])) for ed in self.edge: P_ = self.map(ed) start = P_[0] end = P_[1] row = np.where(self.vertex == start) column = np.where(self.vertex == end) adjacency_matrix[row,column] = 1 adjacency_matrix[column,row] = 1 return adjacency_matrix mainファイル import numpy as np from Gragh_def import directed_Gragh def main(): vertex = np.array(['house','station','school','hospital']) edge = np.array([1,2,3,4...

最尤推定

Introduction English ver 今日は最尤推定について加工と思います。これは統計的推定でよく使われる手法です。最尤推定の例も書こうと思います。初めに尤度の説明をし、そのあとで最尤推定の説明をします。 概要 尤度 最尤推定 最尤推定の問題点 尤度 前提条件から得られる観察データを考えます。この時、えられた観測データに対して前提条件が尤もらしい条件であるかの値を尤度といいます。 なにをゆっているのかわからない人がほとんどだと思います。。。 尤度の例を扱っていきます。 コインを投げることを考えます。このコインは確率Pで表、確率1-Pで裏を出すコインだとします。 例えば、100回コインを投げたとき、全て表だったとします。この時このコインが表が出る確率はかなり1に近いことが予想されます。 ではもし、表が出る確率PがP=0.5だとします。この時、表が100回連続で出る確率は$0.5^{100} = 7.88860e-31$になります。あり得ない確率ですね。これがP=0.5としたときのもっともらしさです。つまり、あまり現実的ではないということです。 もしP=0.99とするとき、100回とも表が出る確率は$0.99^{100} = 0.3666....$となります。つまり、P=0.99としたときの尤度は0.36くらいということです。よって、P=0.5よりかは現実見があることになります。まだまだ低い数字ではありますが。 観測データである、100回表が出るという事象を固定したとき、尤度はPを変数としたP(100回表|P)を尤度関数と呼びます。この関数の値を尤度と呼びます。 尤度が高いほうが尤もらしい値、つまり理にかなっているなと感じることができる値ということになります。 例えば、先ほどの例でゆうと、 P=0.5としたときの尤度は7.88860e-31でした。P=0.99としたときの尤度は0.3666でした。よってP=0.5より、P=0.99のほうが尤もらしい自然な値ということになります。 最尤推定 最尤推定とは得られた観測データからデータが依存している分布のパラメーターを推測するための手法です。 最尤推定では尤度を最大化して、最も尤もらしいパラメーターを求めます。 確率密度関数...