« ヒトBACクローンIDのゲノムマッピング | Home | Rまめ知識 »
Rでライフゲームを書いてみる (2次元FFT)
By kmgs | 2 月 2, 2009

最近ふとライフゲーム(Conway's Game of Life)のことを思い出し、アルゴリズムを考えていました。Wikipediaにある通り、
- 誕生: 死んでいるセルの周囲に3つの生きているセルがあれば次の世代では生きる(誕生する)。
- 維持: 生きているセルの周囲に2つか3つの生きているセルがあれば次の世代でも生き残る。
- 死亡: 上以外の場合には次の世代では死ぬ。
なんてルールになっています。なんとなく2次元FFTによるコンボリューションで書けそうだったので、Rでライフゲームを実装してみました。
# life.r
life <- function(nr=64, nc=64, seed=1) {
# ランダムデータの作成
set.seed(seed)
m <- matrix(sample(0:1, nr*nc, rep=T, prob=c(0.6, 0.4)), nr, nc)
# コンボリューション用パターンの作成
# * * *
# * * <- こんな感じのものをずらしたもの
# * * *
pat <- matrix(0, nr, nc)
pat[1,2] <- 1
pat[2,1:2] <- 1
pat[nrow(pat), ncol(pat)] <- 1
pat[nrow(pat), 1:2] <- 1
pat[1:2, ncol(pat)] <- 1
fp <- fft(pat)
# 無限ループ
i <- 1
while (1) {
# 2次元FFTと条件判定
m1 <- round(Re(fft(fft(m) * fp / nr / nc, inv=T)))
m <- m1 == 3 | (m == 1 & m1 == 2)
# 描画
image(1:nr, 1:nc, m, main=i, col=c("white", "black"))
box()
# 全滅したら実行停止
if (sum(m) == 0) {
stop()
}
i <- i+1
}
}上記のソースを"life.r"として保存し、Rで実行します。
> source("life.r")
> life(128, 128, 1) # 128行128列、乱数シード1FFTの都合上、行数・列数は2の倍数のほうが速いです。またR上の描画では、300x300以上は厳しいようです。
こんなものを書いて一人悦に入っていたのですが、[Conway's Game of Life convolution]なんかでググるといろいろ出てきますね。特にこれなんかはFlashで書いてあるらしく、カッコいいし速いです。
Topics: R |
