All pastes #913428 Raw Edit

memeshare2

public text v1 · immutable
·published 2008-02-22 01:44 UTC
rendered paste body
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define N 100  // population size
#define L 100 // max memory size
#define G 10000 // max number of different genes in the world

double s=0.1; //selection strength
double v=1.0; //prob of inventing new gene per generation
double p=1.0; //prob of dependency of memes
int nl=100; //number of opportunities to learn
int ngen=10000; //number of generations
int iseed=9095;
double wmax,wbar,nbar;
int gmax;

void one_generation(int meme[N][L],int nmeme[N],double w[N],double h[N],int dep[G],int copy[G]);
void fitness(int meme[N][L],int nmeme[N],double w[N],int dep[G],int copy[G]); 
void print_stuff(int meme[N][L],int nmeme[N],double w[N],double h[N],int dep[G],int copy[G]);

int main(){
	int i,j,igen;
	int meme[N][L],nmeme[N];
	int dep[G],copy[G];
	double w[N],h[N];
	
	srand48(iseed); //seed random number generator
	
	for(i=0;i<N;i++) {
	for(j=0;j<L;j++) {
		meme[i][j]=0; //this is the list of memes in each individual
	}}
	for(i=0;i<G;i++) {
		dep[i]=-1; //if dep[i]>0 meme i depends on meme dep[i]
			// if dep[i]=-1, meme i is independent
		copy[i]=0;
	}
	copy[1]=N; //N copies of meme 1
	
	for(i=0;i<N;i++) {
		meme[i][0]=1; //everyone has meme 1 to start
		nmeme[i]=1; //everyone has 1 meme
		w[i]=1.0+s;
		h[i]=1.0;
	}
	wmax=1.0+s;
	gmax=1;
	
	for(igen=1;igen<=ngen;igen++) {
	one_generation(meme,nmeme,w,h,dep,copy);
	printf("%d %f %f\n",igen,wbar,nbar);
	//print_stuff(meme,nmeme,w,h,dep,copy);
	}
	
	exit(0);
}
//-----------------------------------------------------------------------
void one_generation(int meme[N][L],int nmeme[N],double w[N],double h[N],int dep[G],int copy[G]) 
{
	int i,j,j1,j2,k,ipar,jpar,same,icul,new;
	int meme1[N][L],nmeme1[N];
	double r,w1[N],h1[N],vert;
	

	struct i_parent{
		int group;
		int value;
	};

	struct i_parent a1[1000];

	int flip_value = 0;


	for(i=0;i<N;i++) {
		//choose parent with prob proportional to w[ipar]
		do{
			ipar=drand48()*N;
			flip_value = drand48()*N;

			a1[N].value = ipar;

			if(flip_value > 0.5){
				a1[N].group = 1;
			}else if(flip_value < 0.5){
				a1[N].group = 0;
			}
			r=drand48();
		} while(r>w[ipar]/wmax); 
		do{
			flip_value = drand48()*N;
			
			if(flip_value > 0.5){
				flip_value = 1;
			}else flip_value = 0;
			
			if(a1[N].group == 0){ 
				jpar=drand48()*N;
			}
			if(a1[N].group == 1){
				
				if(flip_value == 1){
					jpar=drand48()*N;
				}
				else {
					while(flip_value!=1){
						flip_value = drand48()*N;
						if(flip_value == 1){
							jpar=drand48()*N;
						}
					}
				}

			}

			r=drand48();
		} while((r>w[jpar]/wmax)||(jpar==ipar)); //two parents must be different
		
		h1[i]=h[ipar];
		//h = prob of horizontal descent of meme (learn from parent)
		//initially this probability is copied without changing from ipar.
		
		//now have M chances of learning a meme
		//with prob vert/2 learn from ipar, prob vert/2 learn from jpar, prob h=1-vert learn from anyone
		j1=0;
		k=0;
		do{
			r=drand48();
			vert=(1.0-h[i])/2.0;
			if(r<vert) { //learn from ipar
				j2=drand48()*nmeme[ipar];
				new=meme[ipar][j2];
			}
			else if(r<vert*2.0) { //learn from jpar
				j2=drand48()*nmeme[jpar];
				new=meme[jpar][j2];
			}
			else { //learn from a random individual
				do{
					icul=drand48()*N;
				} while((drand48()>w[icul]/wmax)||(icul==ipar)||(icul==jpar));
				j2=drand48()*nmeme[icul];
				new=meme[icul][j2];
			}
			//now check whether the new meme is already known
			//if not, learn it
			same=0;
			for(j=0;j<j1;j++) if(meme1[i][j]==new) same=1;
			if(same==0) {
				meme1[i][j1]=new;
				j1++;
			}
			k++;
		} while((k<nl)&&(j1<L));
		nmeme1[i]=j1;
	}
	
	//v is possibility of inventing one new meme per generation
	if(drand48()<v) {
		gmax=1;
		while((copy[gmax]>0)&&(gmax<G)) gmax++;
		if(gmax==G) {
			printf("reached max meme array size\n");
			exit(0);
		}
		i=drand48()*N;
		if(drand48()<p) {
			j=drand48()*nmeme1[i];
			dep[gmax]=meme1[i][j];
		}
		else dep[gmax]=-1;
		
		if(nmeme1[i]==L) {
			meme1[i][L-1]=gmax;//prevents memory overflow
		}
		else {
			meme1[i][nmeme1[i]]=gmax;
			nmeme1[i]++;
		}
	}		
	
	//copy offspring into main array - offspring grow up
	for(i=0;i<N;i++) {
		nmeme[i]=nmeme1[i];
		for(j=0;j<nmeme[i];j++) meme[i][j]=meme1[i][j];
		h[i]=h1[i];
	}
	fitness(meme,nmeme,w,dep,copy);
}
//-------------------------------------------------------------------------
void fitness(int meme[N][L],int nmeme[N],double w[N],int dep[G],int copy[G]) 
{
	int i,j,j1,k,count,g;
	
	wmax=1.0;
	wbar=0.0;
	nbar=0.0;
	
	for(i=0;i<N;i++) {
		if(nmeme[i]==0) w[i]=0.0;
		else {
			w[i]=1.0;
			for(j=0;j<nmeme[i];j++) {
			g=meme[i][j];
			if(dep[g]<0) w[i]*=(1.0+s);
			else {
			for(j1=0;j1<nmeme[i];j1++) if(meme[i][j1]==dep[g]) w[i]*=(1.0+s);
			}
			}
		}
		if(w[i]>wmax) wmax=w[i];
		wbar+=w[i];
		nbar+=nmeme[i];
	}
	wbar/=N;
	nbar/=N;
	
	for(i=1;i<G;i++) copy[i]=0;
	for(i=0;i<N;i++) {
		for(j=0;j<nmeme[i];j++) copy[meme[i][j]]++;
	}
}
//--------------------------------------------------------------------
void print_stuff(int meme[N][L],int nmeme[N],double w[N],double h[N],int dep[G],int copy[G]) 
{
	//prints out lots of details for checking purposes
	int i,j;
	
	for(i=1;i<G;i++) {
	if(copy[i]>0) printf("meme %4d depends on %4d -- copies %d\n",i,dep[i],copy[i]);
	}
	
	for(i=0;i<N;i++) {
	printf("ind %4d fitness %f h %f has memes",i,w[i],h[i]);
	for(j=0;j<nmeme[i];j++) printf(" %4d",meme[i][j]);
	printf("\n");
	}
	
	printf("\n");
}
//--------------------------------------------------------------------