永夜君王吧 关注:544,754贴子:11,147,931
  • 10回复贴,共1

弱弱的问一句,有人看过《自私的基因》吗?感觉这个会有点意思

只看楼主收藏回复

话说烟男还没有更新,我就建个只有四个物种的世界和你们分享每次运行结果都很不一样
这是关于ESS的一个模拟实验,用C语言对书中“鸽子与鹰”的例子进行一次模拟。
为此,我设计了一个C语言程序,在程序中分别用x[1][ ]、x[2][ ]、x[3][ ]、x[4][ ]代表鹰、鸽子、还击策略者、恃强凌弱的策略者,M、N、O、P代表他们的数量。程序中的规则按照《自私的基因》中的假设。程序运行需先输入初始个体数,一至四列分别代表代表鹰、鸽子、还击策略者、恃强凌弱的策略者的数量,每一排是一个世代,每十个世代计算一次期间各物种的总数。当物种只剩一个时,程序结束。
以下是程序
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
int t(void);
void jisuan(int a1,int a2,int b1,int b2,int A1,int A2);
void boyi(int a1,int a2,int b1,int b2);
void shidai(long g);
void shengcun(long i,int j,int k);
int order(int k);
int x[5][10000]={0};
int M=250;//进攻性物种数(鹰)
int N=250;//防御性物种数(鸽子)
int O=250;//还击策略者
int P=250;//恃强凌弱的策略者
int main(void)
{
long g,i,n;
int j,k;
n=100000;//运行重复次数
g=500000;//每次运行时间
j=10;//输出平均值间隔(以期间物种个体总数表示)
k=1000;//个体总数
scanf("%d%d%d%d",&M,&N,&O,&P);
for(i=1;i<=n;i++)
{
shidai(g);
shengcun(i,j,k);
if((M+P)==0||(N+P)==0||(M+N+O)==0)//模拟结束判定
{
printf("\n\t\t\t\tgame over!\n");
i=n+1;
}
}
return 0;
}
void boyi(int a1,int a2,int b1,int b2)//计算该两个个体的对战策略
{
int A1,A2;
A1=a1;
A2=a2;
if(a1==3)
{
if(a2!=4)
A1=a2;
}
if(a2==3)
{
if(a1!=4)
A2=a1;
}
if(a1==3)
{
A1=1+t()%2;
A2=A1;
}
if(a1==4)
{
if(a2==1||a2==2)
A1=3-a2;
}
if(a2==4)
{
if(a1==1||a1==2)
A2=3-a1;
}
if(a1==4&&a2==4)
{
A1=1+t()%2;
A2=3-A1;
}
if ((a1+a2)==7)
{
A1=1+t()%2;
A2=1+t()%2;
}
jisuan(a1,a2,b1,b2,A1,A2);//进行计算函数
}
void jisuan(int a1,int a2,int b1,int b2,int A1,int A2)//比赛规则(按照《自私的基因》)
{
int i;
i=t()%2;
if(A1==1&&A2==1)
{
x[a1][b1]=50-150*i+x[a1][b1];
x[a2][b2]=-100+150*i+x[a2][b2];
}else if(A1==1&&A2==2)
{
x[a1][b1]=50+x[a1][b1];
x[a2][b2]=0+x[a2][b2];
}else if(A1==2&&A2==2)
{
x[a1][b1]=40-50*i+x[a1][b1];
x[a2][b2]=-10+50*i+x[a2][b2];
}else if(A1==2&&A2==1)
{
x[a2][b2]=50+x[a2][b2];
x[a1][b1]=0+x[a2][b2];
}
}
void shidai(long g)//选出两个个体进行得分计算
{
int a[3],b[3],d,i;
long c;
for(c=1;c<=g;c++)
{
for(i=1;i<=2;i++)
{
d=t()%(M+N+O+P);
if(d<M)
{
a[i]=1;
b[i]=t()%M;
}else if(d<(M+N))
{
a[i]=2;
b[i]=t()%N;
}else if(d<(M+N+O))
{
a[i]=3;
b[i]=t()%O;
}else
{
a[i]=4;
b[i]=t()%P;
}
}
if(a[1]==a[2]&&b[1]==b[2])
c=c-1;
else
boyi(a[1],a[2],b[1],b[2]);//进行博弈函数
}
}
void shengcun(long i,int j,int k)//计算存活的个体数
{
int a,b,c,e[5]={0,M,N,O,P},f;
a=order(k);//以超过分数中位数作为存活标准
for(f=1;f<=4;f++)
{
c=e[f];
e[f]=0;
if(c!=0)
{
for(b=0;b<=c;b++)
{
if(x[f][b]>=a)
{
e[f]=e[f]+1;
}
}
}
}
c=e[1]+e[2]+e[3]+e[4];
M=k*((float)e[1]/(float)c);
N=k*((float)e[2]/(float)c);
O=k*((float)e[3]/(float)c);
P=k*((float)e[4]/(float)c);
static int E[5]={0};//将个体数恢复为原来的数量
E[1]=M+E[1];
E[2]=N+E[2];
E[3]=O+E[3];
E[4]=P+E[4];
printf("\n%d\t%d\t%d\t%d",M,N,O,P);
if((i+j)%j==0)//输出期间物种总数
{
for(f=1;f<=4;f++)
{
printf("\t%d",E[f]);
E[f]=0;
}
}
}
int t(void)//随机数计算函数
{
int i;
srand(time(0)+rand());
i=rand();
return i;
}
int order(int k)//求分数中位数函数
{
int i,j;
for(i=0;i<M;i++)
x[0][i]=x[1][i];
for(i=M;i<(M+N);i++)
x[0][i]=x[2][i-M];
for(i=(M+N);i<(M+N+O);i++)
x[0][i]=x[3][i-M-N];
for(i=(M+N+O);i<200;i++)
x[0][i]=x[4][i-M-N-O];
for(i=0;i<k;i++)//排序
{
for(j=0;j<1001;j++)
{
if(x[0][i]<x[0][j])
{
x[0][i]=x[0][i]+x[0][j];
x[0][j]=x[0][i]-x[0][j];
x[0][i]=x[0][i]-x[0][j];
}
}
}
return(x[0][k/2]);
}
求有空的大佬完善一下


IP属地:上海1楼2017-05-17 20:17回复
    自顶


    IP属地:上海来自Android客户端2楼2017-05-17 20:22
    回复


      IP属地:云南来自Android客户端3楼2017-05-17 20:32
      回复
        这是一次运行的结果





        IP属地:上海来自Android客户端5楼2017-05-17 20:38
        回复
          额滴神呐,明明有能力看懂的,却没耐心


          IP属地:广东来自手机贴吧7楼2017-05-17 22:11
          收起回复
            上帝是最伟大的程序员


            IP属地:辽宁来自Android客户端9楼2017-05-17 22:19
            收起回复
              在高中生物书上看到过


              IP属地:陕西10楼2017-05-17 23:09
              回复
                厉害额


                IP属地:辽宁来自Android客户端11楼2018-09-17 23:44
                回复
                  想问下各位看这本书花了多长时间呀👀


                  来自iPhone客户端12楼2019-10-10 20:34
                  回复