人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

バタフライ効果

ロジスティック写像族と分岐図(2011/2/25)のつづき。

「中国で蝶々が羽ばたくとアメリカでトルネードが起きる」というあれ。日本だと「風が吹けば桶屋が儲かる」かな?専門的には初期値鋭敏性と呼ぶようだ。カオス系において初期値のほんのわずかな誤差が、時間が経つにつれ拡大していき結果に大きな違いをもたらす効果のこと。つまり、無限の精度で初期値を計測することは実質的に不可能なので遠い未来は予測不可能であるという結論になる。

というわけで、カオス 第1巻 - 力学系入門 の例をいくつか試してみよう。まずは、例1.9から。この例では新しい写像が登場する。

f(x) = 3x (mod 1)

mod 1の意味は、xが浮動小数点数でもOKなので整数のmodとちょっと違う。xが正の場合は、0以上1未満になるまで1を引き続ける。yが負の場合は、0以上1未満になるまで1を足し続ければよいそうだ。たとえば、14.92 (mod 1) = 0.92、-14.92 (mod 1) = 0.08になる。この写像に対してフィードバックループを続けるとカオスになるという。表1.4と同じく初期値を0.25と0.2501で初めて軌道を見てみると、

f:id:aidiary:20110305093438p:plain

おー、最初は一致していたのに途中からずれまくって最後はまったく似ていない!一応、プログラムも。

#coding:utf-8
import numpy as np
from pylab import *

def drawModel(func, initial):
    """写像funcで初期値をinitialとしたときの軌道を描画"""
    nList = []
    yList = []
    nList.append(0)
    yList.append(initial)
    for n in range(1, 21):
        nList.append(n)
        yList.append(func(yList[n-1]))
    print nList
    print yList
    plot(nList, yList)

def mod1(x):
    if x >= 0:
        while not 0 <= x < 1:
            x -= 1
    elif x < 0:
        while not 0 <= x < 1:
            x += 1
    return x

if __name__ == "__main__":
    for initial in [0.25, 0.2501]:
        drawModel(lambda x: mod1(3 * x), initial)
    xlabel("n")
    ylabel("f^n (x)")
    show()

次に、前回まで使っていたロジスティック写像で試してみよう。初期値を0.2と0.2000001としたときの軌道を見てみる。

f:id:aidiary:20110305100136p:plain

初期値の差は、0.0000001なのにその後の軌道は大きく変わる。プログラムは、

#coding:utf-8
import numpy as np
from pylab import *

"""ロジスティックモデルの初期値鋭敏性"""

def drawModel(func, initial):
    """写像funcで初期値をinitialとしたときの軌道を描画"""
    nList = []
    yList = []
    nList.append(0)
    yList.append(initial)
    for n in range(1, 51):
        nList.append(n)
        yList.append(func(yList[n-1]))
    print nList
    print yList
    plot(nList, yList)

if __name__ == "__main__":
    # ロジスティックモデル g(x) = 4x(1-x)
    # 初期値をわずかに変えて複数の軌跡を描画
    for initial in [0.2, 0.2000001]:
        drawModel(lambda x: 4 * x * (1 - x), initial)
    xlabel("n")
    ylabel("g^n (x)")
    show()

過去に少しだけ違う行動をしていれば未来は大きく変わっていたということかな?実際には広がっていく誤差を抑えるようなメカニズムがありそうな気がするんだけど?このテーマを題材にした『バタフライ・エフェクト』という映画もあるようだ。まだ見たことないので今度見ようかな。

バタフライ・エフェクト プレミアム・エディション [DVD]

バタフライ・エフェクト プレミアム・エディション [DVD]

参考リンク