大学生の雑記

色々なものを書いています 旧:旧帝大生の雑記ブログ

Processingでセルオートマトン②: ビハム・ミドルトン・レヴィン交通モデル


スポンサードリンク

次の記事
coronene.hatenablog.com


ビハムミドルトンレヴィン交通モデルとはセルオートマトンの一種で、二種類のセルを直交するように移動させたときに起きる渋滞が自己組織化する様子が観察できるモデルです。

詳細は以下の記事にあります。
ja.wikipedia.org

色々作っている中で気まぐれに作ったのでオリジナルと違い斜交するモデルになっていますが、同じような挙動を見せてくれます。オリジナルと比べて45°傾いているため渋滞も45°傾きます。

コード

int len;
int col, row;
int[][] c;
boolean pause = false;
int n = 0;
int a = 0;


void setup() {
  size(600, 600);
  frameRate(100);
  len = 3;
  col = width/len;
  row = height/len;


  c = new int[col][row];

  //最初の配置
  for (int i = 0; i < col; i ++) {
    for (int j = 0; j < row; j ++) {
      //c[i][j] = 0; //生命無し

      float p, q;
      p = random(0,1);
      q = 0.37  /2; //セルの密度(0~1)
      
      if(p < q){
        c[i][j] = 1; //緑
      }
      else if(p >= q && p < 2*q){
        c[i][j] = 2; //赤
      }
      
      else{
        c[i][j] = 0;
      }
     
        

    }
  }
}


void draw() {
  background(255);

  //セルの描画
  for (int i = 0; i < col; i ++) {
    for (int j = 0; j < row; j ++) {
      noStroke(); 
      if(c[i][j] == 0){
        fill(0);
      }
      else if(c[i][j] == 1){
        fill(0, 255, 20);
      }
      else if(c[i][j] == 2){
        fill(255, 0, 0);
      }

     
      rect(i*len, j*len, len, len);
    }
  }


  //次のステップでの生命の配置を計算
  if (pause == false) { //描画が動いているとき
    a += 1;
    int[][] next = new int[col][row];
   
    
    for (int i = 2; i <= col+2; i ++) { 
    for (int j = 2; j <= row+2; j ++) {
      
      
        
      if(a % 2 == 0) {   
        if(c[(i) % col][(j) % col] == 1) { //緑のセル
          if(c[(i+1) % col][(j+1) % col] == 0){
            next[(i+1) % col][(j+1) % col] = 1;
            next[(i) % col][(j) % col] = 0;
          }
          else{
            next[(i) % col][(j) % col] = 1;
          }
        }
        
        else if(c[i % col][j % col] == 2){ //赤のセルは
          next[i % col][j % col] = 2; //その場にとどまる
        }
      
        
    }
    
       else if(a % 2 == 1){
         if(c[(i) % col][(j) % col] == 2) { //緑のセル
          if(c[(i-1) % col][(j+1) % col] == 0){
            next[(i-1) % col][(j+1) % col] = 2;
            next[(i) % col][(j) % col] = 0;
          }
          else{
            next[(i) % col][(j) % col] = 2;
          }
        }
        
        else if(c[i % col][j % col] == 1){ //赤のセルは
          next[i % col][j % col] = 1; //その場にとどまる
        }
       

       }
      
        
        }
        }
      

    c = next; //次のステップの配置を適用
  }
}

動画

実際に動かしたものです。
youtube.com


q=0.37で実行するとこのようになりました。