Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9312

Lollipop グラフ上のランダムウォークと Metropolis ウォークの hitting time

$
0
0

ノード数 $N$ のグラフ上のノード $i$ からノード $j$ の hitting time $HT(i, j)$ の上限は、ランダムウォークだと $O(N^3)$、Metropolis ウォークだと $O(N^2)$ だと知られている。これを Lollipop グラフ対象に、具体的に実験をしてみた。

Lollipop グラフ

Lollipop グラフは、ノード数 $M$ の clique のひとつのノードが長さ $N$ の path に繋がったもの。詳しくはWikipediaで。以下の画像は Wikipedia にある $M=8, N=4$ の Lollipop グラフ。
Lollipop_graph.png

Lollipop グラフ上の hitting time

clique のノード数を $M$ とし、path のノード数を $N$ とする。簡単のため、これらは十分大きいとする。
初期ノードを clique のノードのうち、path に直接つながっていないノードとし、数字として -1 を割り当てる (上の図でいうと0 ~ 6 のどれか)。clique と path が繋がっているノードに 0 を割り当て (上の図でいうと7)、path の一番遠くを N と割り当てる (上の図でいうと11)。この場合、hitting time の期待値は以下となる。

\begin{align}
HT(-1, N) &= HT(-1, 0) + \sum_{i=0}^{N-1} HT(i, i+1)\\
HT(i, i+1) &= 1 + p(i, i-1) \left(HT(i-1, i) + HT(i, i+1)\right)
\end{align}

ここで$p(a, b)$ はノード $a$ からノード $b$ に遷移する確率。

ランダムウォークの場合

リーディングオーダーをみる。path 上では同じ hitting time ということを使って計算をすると、以下のように $N^3$ のオーダーで振る舞うことがわかる。

\begin{align}
HT(-1, N) &= HT(-1, 0) + \sum_{i=0}^{N-1} HT(i, i+1)\\
&\approx HT(-1, 0) + NHT(0, 1)\\
&\approx HT(-1, 0) + N(N+ (N-1) HT(-1, 0))\\
&\approx N^2 HT(-1, 0)\\
&\approx MN^2
\end{align}

Metropolis ウォークの場合

Metropolis ウォークはノード数と同じ次元を持つ適当な正の成分を持つベクトル $\mu$ に対して、ノード $u$ からノード $v$ に以下の確率で推移する。

p(u, v) = \left\{
\begin{array}{ll}
\frac{1}{deg(u)}\min\left[1, \frac{\deg(u)\mu_v}{\deg(v)\mu_u}\right] & (v \in N(u)) \\
1 - \sum_{v \in N(u)} p(u, v) & (u = v)\\
0 & otherwise
\end{array}
\right.

こで $N(u)$ はノード $u$ と接続されているノードの集合。この方法で歩くと、十分大きな $M$ に対し $p(1, 0) \approx 1/M$ となり非常に小さい。リーディングオーダーのみを見るためにこの項を無視すれば、以下の通りオーダーが $NM$ となり、単純なランダムウォークより効率がよいことがわかる。

\begin{align}
HT(-1, N) &= HT(-1, 0) + \sum_{i=0}^{N-1} HT(i, i+1)\\
&\approx HT(-1, 0) + HT(0, 1)\\
&\approx HT(-1, 0) + (M+ (M-1) HT(-1, 0))\\
&\approx M HT(-1, 0)\\
&\approx MN
\end{align}

数値実験

clique と path のノード数が同じとする。また、Metropolis ウォークで使用するベクトル $\mu$ は定数ベクトルとする。
ノード数 $N$ を2から6までで、シミュレーション回数を1000回とした。

コード

varmaxCliqueSize=10+1;varcliqueSizes=Enumerable.Range(2,maxCliqueSize);varsimulationSize=1000;foreach(varcliqueSizeincliqueSizes){varpathLength=cliqueSize;vargraph=Graph.GraphFamilies.Lollipop(cliqueSize,pathLength);varstart=graph.Nodes.First();varend=graph.Nodes.Last();varsteps=Enumerable.Range(0,simulationSize).AsParallel().Select(i=>{varconfig=newRandomWalkConfig(start);varrandomWalk=newRandomWalk(graph,config);// var stationaryDist = graph.Nodes.ToDictionary(n => (INode)n, n => 1.0);// var config = new MetropolisWalkConfig(start, stationaryDist);// var randomWalk = new MetropolisWalk(graph, config);// var beta = 0.5;// var config = new BetaRandomWalkConfig (start, beta);// var randomWalk = new BetaRandomWalk(graph, config);while(!randomWalk.LocationHistory.Last().Equals(end))randomWalk.Walk();returnrandomWalk.LocationHistory.Count()-1;});varaverage=steps.Average();varstd=steps.StandardDeviation();Console.WriteLine(cliqueSize.ToString()+"\t"+average.ToString()+"\t"+std.ToString());}
// random walkvoidWalk(){varcandidates=NodeToConnectedNodes[LocationHistory.Last()];varcount=candidates.Count();varp=1.0/count;varprobs=Enumerable.Range(0,count).Select(i=>p);varcat=newProbability.Distribution.Discrete.Univariate.Categorical();varcatParam=newProbability.Parameter.Discrete.Univariate.Categorical(probs);varsample=cat.GetSamples(catParam,1).First();LocationHistory=LocationHistory.Concat(newList<INode>(){candidates.ElementAt(sample)});}
// metropolis walkvoidWalk(){// u to vvaru=LocationHistory.Last();varvs=NodeToConnectedNodes[u];vardegu=vs.Count();varvToDegv=vs.ToDictionary(v=>v,v=>NodeToConnectedNodes[v].Count());vartransitionProbabilities=vToDegv.Keys.Select(v=>(newdouble[]{1,degu*Config.NodeToStationaryProbability[v]/(vToDegv[v]*Config.NodeToStationaryProbability[u])}).Min()/degu);varprobs=(newdouble[]{1-transitionProbabilities.Sum()}).Concat(transitionProbabilities);varcat=newProbability.Distribution.Discrete.Univariate.Categorical();varcatParam=newProbability.Parameter.Discrete.Univariate.Categorical(probs);varsample=cat.GetSamples(catParam,1).First();varnext=sample==0?u:vs.ElementAt(sample-1);LocationHistory=LocationHistory.Concat(newList<INode>(){next});}

結果

平均 Hitting time は以下のようになった。

ノード数ランダムウォークMetropolis ウォーク
29.23412.411
328.26128.819
467.88957.211
5126.57389.546
6237.192132.52

おおよそランダムウォークだと $N^3$、Metropolis ウォークだと $3.5 N^2$ と振る舞っている。

参考文献


Viewing all articles
Browse latest Browse all 9312

Latest Images

Trending Articles