ボルツマン分布の実験

人は世に連れ世は人に連れ、全ては流れ行く世の常を思わずには居られないこの季節、子供たちはいかがお過ごしかな。元気にしてるかい。原発をめぐる話からもわかるように現在の科学技術はこの程度だ。この悔しさを勉強のエネルギーにして君たちはぜひ物理学を勉強してみてはどうか。そしてこんな状況にならない次の世界への扉を開く技術を、未来の技術を、力強く創造していってほしいとおじさんは願っているよ。
さて今日はボルツマン分布(マクスウェル分布とも言うようだ)についての実験だ。これは総量が決まっているある有限の「量」をめぐって、有限数の個体どうし・粒子どうしが健全な奪い合い・交換を行い得るときに、個々の「量」を持つ個々の個体・粒子数の分布は、必ずボルツマン分布になるという有名な宇宙の法則だ。熱力学や統計力学なんていうものでよく目にするわけだが、分布がおきる原理としては、熱とかエネルギーとか気体とか全く関係ない、これは単にいわば世の常なのだってこと、今回はそこを理解してもらえればいいと思うぞ。ではいってみよう。
一体どんな分布になるんだろうね?これを実験するために、r枚のコインを、n人の人に配る配り方(ただし一枚ももらえない人がいてもいいものとする)にはどのような事例がどれだけあるかをすべて列挙するプログラムを考えよう。
今、例えば7枚のコインを5人の人に配り切ることを考える。例えば2枚のコインを最初の人に上げたなら、残りの4人の人に残り5枚のコインを配る配り方だけを数えればよい。つまり、最初の人にあげる枚数だけ決めてしまえば、残りのコインの配り方の組み合わせは自ずと決まる。という具合の漸化式的なアルゴリズムを実装したものが以下の関数だよ。(ここでは再帰を使っているが、子供たちは業務で再帰なんて間違っても使っちゃいけないぞ)

static void lc_calc_distribution( 
                          const int sum, 
                          const int num_slots,
                          vector< int > curr,
                          vector< vector< int > >* result )
{
    // sum 個のものを、num_slots 人に分配する方法
    // 知りたいのは配り方が何通りあるか数えることよりも、実際どんな配り方がどれだけあり得るのか。
    if( num_slots==1 )
    {
        curr.push_back( sum );
        result->push_back( curr );
        return;
    }
    // 一人目にi個与えた場合の、残りの場合のケースを列挙。
    for( int i=0; i<=sum; ++i )
    {
        curr.push_back( i );
        lc_calc_distribution( sum-i, num_slots-1, curr, result );
        curr.pop_back();
    }// i
    return;
}

これの使い方は例えばこうだ。

int main (int argc, const char * argv[])
{
    vector< vector< int > > vv;
    {
       vector< int > curr;
       lc_calc_distribution( 20, 10, curr, &vv );
    }
    // 結果は vv に格納。

例えば20枚のコインを10人の人に配る配り方は、1枚ももらえない人がいていいとすると、実に1001万5005通りあり、そのすべての場合についてどんな分け与え方になったのかも計算ずみだ。これを使って、集団の中から無作為に選ばれたある人がn枚のコインを持てる確率を計算することができる。プログラムにすると、上記mainの中で以下のような感じで続けて集計をとる。

    // ある人がn枚のコインを持てる確率
    vector< int > shuukei(21);
    fill( shuukei.begin(), shuukei.end(), 0 );
    for( vector< int >& iv: vv )
        for( int iSlot: iv )
            ++shuukei[ iSlot ];

上記のshuukeiを規格化すると、結果はこんな風に出たよ。

半分以上の確率で、1枚しかもらえないかあるいは1枚ももらえないということだね。10枚持てる確率なんて1%以下だね。因みにグラフにするとこんなふうになったよ。もらえる枚数が増えるにつれてその確率は指数関数状に小さくなっていくのがわかるね。これがボルツマン分布。言い換えると、世の常だ。これで「ボルツマン分布」の再現実験が完了したよ。(母数の数をもっと増やしていくに連れてこれはシンプルな減衰指数関数に一致していくというわけなのだけどその導出は本稿ではしない。)

さてコインを貰った人たちの家を、コインの枚数に比例するエネルギーの波長を持つ光で輝かせる時、村全体の発する光のスペクトルはどうなるかな。さっきのn枚のコインを得る確率に、対応するコインの枚数をかけてやるだけだ。こんなスペクトルになった。(以下の図をスペクトルと呼ぶ時、横軸に光の波長を、縦軸に光の強度を想像してくれ)

f:id:nurs:20191225004939p:plain:w400
熱力学でよく見るエネルギー分布図みたいなグラフが出現した!
いかがだっただろうか。以上は、20枚のコインを10人の人に無作為に配ったときに起きる状況と考えてもよいし、あるいは10人の人が20枚のコインをめぐって健全な奪い合いを時々刻々と繰り広げている状況の各瞬間について言えることと考えてもよい。誰がコインを奪い取ろうが特定の枚数の保持者の割合は変わらないので、村全体のスペクトルは変わらない。そしてコインの枚数や人の数が増えるに連れて上記確率分布は実際の分布となってくるのだな。
分子の運動エネルギー分布や、分子の回転エネルギー分布が同じようなスペクトル形状を持つことは、あまりに有名だよな。