- 先日の記事の続き
- 作り方
- 原点から第一の要素がランダムウォークする。単位時間後とすれば、ランダムウォークするので、平均0、分散がある値(1としてもよいだろう)の点(t=1,x)に到達する
- 第二以降の要素は、原点から出発し、「分離」イベントが起きるまでは、すでにある道をたどる。複数の道があるときはどれを選ぶかは等確率。したがって、i番目の要素は、i-1個の先行要素のどれかを「親」としてついて歩く
- 「分離イベント」がおきると、そこを始点にランダムウォークする。時刻t (0<= t <= 1)で分離したとすると、その始点からは、平均0、分散が残時間(1-t)に比例した値の正規分布に従う分だけ、ずれて(t=1,x')に到達する
- 「分離」イベントは、「ついて歩いて」いるときに「一緒に歩いている先行要素」の数が多ければ多いほど「離れにくい」。先ほど「親」を一人、選んだが、実際には、「一緒に歩いている先行要素」はみんな親で、「すべての親と別れないといけない」から
- このようなルールを入れると、道の先に行けば行くほど、分離しやすくなる
- 一方、分離イベントを「道連れ人数」によらず、時刻tの関数としてやることで、分離のパターンを作ることもできる。たとえば、時刻0で必ず分離する(ただの独立ランダムウォーク)とか、時刻0で定確率で分離するがそれ以外は分離しない(複数カテゴリに分かれる)とか
- 実際の分離は、この時刻の関数と、道連れ人数のしがらみで決まる
- 以下は、この「関数」と「しがらみ」を無視して(その部分が面倒なので)、分離木を順次成長させる部分だけをアルゴリズムにしたもの
library(igraph)
n.pt <- 17
el <- matrix(c(1,2),nrow=1)
Leaves <- c(2)
Root <- c(1)
g <- graph.edgelist(el)
E(g)$weight <- c(1)
plot(g)
g.hx <- list()
g.hx[[1]] <- g
par(mfcol=c(2,2))
for(i in 2:n.pt){
tmp.leave <- Leaves[sample(1:length(Leaves),1)]
tmp.path <- get.shortest.paths(g, Root, to=tmp.leave, mode = c("out"), weights = NULL, output=c("epath"))
el.now <- get.edgelist(g)
vnum <- vcount(g)
e.weight <- E(g)$weight
tmp.edge <- tmp.path$epath[[1]][sample(1:length(tmp.path$epath[[1]]),1)]
tmp.edge.stend <- el.now[tmp.edge,]
el.next <- el.now[-tmp.edge,]
el.next <- rbind(el.next,matrix(c(tmp.edge.stend[1],vnum+1,vnum+1,tmp.edge.stend[2],vnum+1,vnum+2),byrow=TRUE,ncol=2))
Leaves <- c(Leaves,vnum+2)
g <- graph.edgelist(el.next)
weight.now <- e.weight[tmp.edge]
e.weight.next <- e.weight[-tmp.edge]
r <- runif(1)
e.weight.next <- c(e.weight.next, weight.now * c(r,1-r),1)
E(g)$weight <- e.weight.next
tmp.path <- get.shortest.paths(g, Root, to=vnum+2, mode = c("out"), weights = NULL, output=c("epath"))
tmp.path.weight <- e.weight.next[tmp.path$epath[[1]]]
last.weight <- 1-sum(tmp.path.weight[-length(tmp.path.weight)])
e.weight.next[length(e.weight.next)] <- last.weight
E(g)$weight <- e.weight.next
g.hx[[i]] <- g
col <- rep(5,vnum+2)
col[Leaves] <- 3
col[1] <- 6
dist.from.Root <- shortest.paths(g,1)
tmp.dist <- rep(0,length(e.weight.next))
for(j in 1:length(tmp.dist)){
tmp.dist[j] <- rnorm(1,0,sqrt(e.weight.next[j]))
}
tmp.g <- graph.edgelist(el.next)
E(tmp.g)$weight <- tmp.dist-min(tmp.dist)
dist.random <- shortest.paths(tmp.g,1)
mean.dist.random <- mean(dist.random)
dist.random <- dist.random -mean.dist.random
dist.random[1] <- 0
coords <- matrix(c(dist.random,dist.from.Root),ncol=2)
plot(g.hx[[i]],layout=coords,vertex.color = col)
}
par(mfcol=c(1,1))