渋滞のASEPモデルたるものをCUIで作ってみた

前のセルオートマトンに感動できなかったので、他のをやってみることにした。僕が読んでもあんまり分からなかった渋滞学 (新潮選書)に載っている中で数少ない分かったものをやってみる。どんなやつかは下のほうを見てもらうとして。

一応動いている様をデジカメで取ってみた。ぶれぶれですけど。

僕にしては珍しくライブラリとか使っていないので、コピペして動かせば準備なしで動くはずです*1。@listの1の数を増やすと渋滞が逆に進んでいるように見えて面白い。コマンドライン上をちかちかと動いていくのを見るのもまあ悪くないです。

循環リストを作るってのを思い付くまで結構大変なことをしようとしていた。

#!/usr/bin/perl
use strict;
use warnings;

my @list = (
    1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1,
    1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1
);

system("clear");

&print_array(@list);
sleep(1);
system("clear");

for(1..50){
  &print_array( &next(@list) );
  @list = &next(@list);
  sleep(1);
  system("clear");
}

sub next {
    my @old = @_;
    my @new;
    $new[$#old]=0;
    for ( reverse(0 .. $#old-1)) {
      #先から見ないとだめっぽい
        if ( $old[$_] == 1 ) {
            #いまのところに誰かいたら
            if ( $old[ $_ + 1 ] == 1 ) {
	      #いっこ先にもいたら、今のところにいる
                $new[$_] = 1;
            }
            else {
	      #いっこ先にいなかったら
                $new[$_] = 0;
                $new[ $_ + 1 ] = 1;
            }
        }
        else {
	  #いまのところに誰もいなかったら
	  $new[$_] = 0;
        }
    $new[0] =$old[$#old-1];
    }
    return (@new);
}

sub print_array {
    my @array = @_;
    foreach (@array[0..$#array-1]) {
        if ( $_ == 0 ) {
            print "○";
        }
        else {
            print "●";
        }
    }
    print "\n";
}

これを機会に渋滞学 (新潮選書)を読み直すってのもいいかもね。ちょうど僕周辺でにわかに複雑系が人気らしいし*2

プログラムはなんかおかしいかもだけど、放置。寝ます。