空間的囚人のジレンマゲーム ( Spatial Prisoner's Dilemma Game)

次のように作り、 Gnuplotで表示させる。 ちなみに、ここでファイルを分割するには、次を使うと便利。

split -51 pattern.txt sh_

のコマンドでOK.
この場合、51行ごとに分割 (50行×50行の行列の後、一つの空白のため)



#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LAT 69 // lattice size LAT*LAT

double ransuu01();
int bc();
double pm();
int change();

main(){
  double b;//payoff
  double p; //density of defectors
  int s[LAT][LAT];
  int next_s[LAT][LAT],color[LAT][LAT];
  int i,j,k,h,t,nt;
  double score,hp;
  double payoff[LAT][LAT];//payoff of each site
  int candidate,coop,defe;

  srand(time(0));// seed for random number
  FILE *fpc,*fpd;
  fpc=fopen("color_change.text","w");
  fpd=fopen("density.text","w");

  p=0.1;
  b=1.7;

/*initial distribution of cooperators and defectors*/
  for(i=0;i<LAT;i++){
  for(j=0;j<LAT;j++){
  s[i][j]=1;// cooperator
  if(ransuu01()< p) s[i][j]=2;//defector
     }// for j
   }//for i

  for(t=0;t<1000;t++){
/*density*/
  coop=0;defe=0;
  for(i=0;i<LAT;i++){
    for(j=0;j<LAT;j++){
     if(s[i][j]==1) coop=coop+1;
         else if(s[i][j]==2) defe=defe+1;
         }
      }
    fprintf(fpd,"%d %f %f\n",t,(double)coop/(double)(LAT*LAT),(double)defe/(double)(LAT*LAT));

//printf("%d %f %f\n",t,(double)coop/(double)(LAT*LAT),(double)defe/(double)(LAT*LAT));

/*calculate each site's payoff*/
  for(i=0;i<LAT;i++){
    for(j=0;j<LAT;j++){
     score=0.0;
      for(k=-1;k<=1;k++){
        for(h=-1;h<=1;h++){
      //printf("i=%d, j=%d, k=%d, h=%d, i+k=%d,j+h=%d, %d %d\n",i,j,k,h,i+k,j+h,bc(i+k),bc(j+h));
         score=score+pm(s[i][j],s[bc(i+k)][bc(j+h)],b);
         }
       }// for k
         score=score-pm(s[i][j],s[i][j],b);
         payoff[i][j]=score;
        }// for j
      }// for i

/*update*/
  for(i=0;i<LAT;i++){
    for(j=0;j<LAT;j++){
       hp=payoff[i][j];
        candidate=s[i][j];
         for(k=-1;k<=1;k++){
          for(h=-1;h<=1;h++){
            if(payoff[bc(i+k)][bc(j+h)]>hp){
                hp=payoff[bc(i+k)][bc(j+h)];
                candidate=s[bc(i+k)][bc(j+h)];
                }// if
              }// for h
            }// for k
         next_s[i][j]=candidate;
        }// for j
      }// for i

     for(i=0;i<LAT;i++){
         for(j=0;j<LAT;j++) color[i][j]=change(s[i][j],next_s[i][j]);
         }// for i
    for(i=0;i<LAT;i++){
      for(j=0;j<LAT;j++) s[i][j]=next_s[i][j];
        }// for i

/*lattice pattern change*/
    /*if(t==100){*/
       for(i=0;i<LAT;i++){
         for(j=0;j<LAT;j++) fprintf(fpc,"%d ",color[i][j]);
         fprintf(fpc,"\n");
        }// for i
        fprintf(fpc,"\n");
       /*}*///if(t)
    fprintf(fpc,"\n");
      } //for t
     fclose(fpd);
     fclose(fpc);
   return 0;
}//main end


double ransuu01()
{
return (double)rand()/((double)RAND_MAX+1.0);
}

int bc(i)// boudnary condition
int i;
{
   if(0<=i && i<LAT) return i;
   if(i<0) return i+LAT;
   else if(i>=LAT) return i-LAT;
   return 0;
}

double pm(site,nei,b)
  int site,nei;
  double b;
{
   if(site==1){
      if(nei==1) return 1.0;// a coooperator's payoff with a cooperator
        else if(nei==2) return 0.0;// a cooperator's payoff with a defector
        }
      else if(site==2){
      if(nei==1) return b;// a defector's payoff with a cooperator
     else if(nei==2) return 0.0;// a defector's payoff with a defector
   }
   return 0;
} // double pm

int change(site,next_site)
int site,next_site;
{
  if(site==1){
  if(next_site==1) return 1; //blue
   else if(next_site==2) return 2;//yellow
   }
   else if(site==2){
   if(next_site==1) return 3;//green
    else if(next_site==2) return 4;//red
   }
 return 0;
}


Gnuplotで表示させるためのファイルとして次のように書けば、ちゃんと表示される。
set yrange [] reverse
set palette defined (1 "blue",2 "yellow", 3 "green", 4 "red")
plot 'sh_aa' matrix with image
pause 1
plot 'sh_ab' matrix with image
pause 1
plot 'sh_ac' matrix with image
pause 1
plot 'sh_ad' matrix with image
pause 1

略

[出力結果]



Back to C Language

Google






進化のダイナミクス 生命の謎を解き明かす方程式

コンピュータのなかの人工社会―マルチエージェントシミュレーションモデルと複雑系