blood test

             Blood Test

A. Second Edition
This is the second edition of my little test program. In this edition, I changed the initial 
settings. I assume:
1) The original blood type are A,B and O. 
2) Each blood type has two element. i.e. type A may be {A,O} or {A,A}
Similarly B = {B,O} or {B,B}; O={O,O}; AB={A,B}
B.The problem

I heard that the original blood type of human kind is O type. However, I am not sure. Otherwise, it

is quite unexplainable that O type is majority of people in the world because from perspective of

purely generic O type has smallest chances to be inherited.

My base knowledge is from what I learned from middle school:

There are only THREE inheritable blood elements: A, B, O.

  A element B element O element
A element A blood type AB blood type A blood type
B element AB blood type B blood type B blood type
O element A blood type B blood type O blood type

That is O is an insignificant element that only combination of O and O will give you child of O

type. Please note that I am not talking about blood type here!!! What I am saying is that each

blood type can split into two basic elements:

Blood Type choice 1 choice 2
A A, A A,O
B B,O B,B
AB A,B  
O O,O  

Originally there will be a certain number of people with averagely equal number of blood type which

is called generation 1. Every male and female sex has a number of chances to find his/her match

among opposite sex of same generation. (After a while, I allow them to find older generations who

is not married. :)) Every couple cannot divorce and can have maximum three children.

For the mating function, I make each person to randomly search from some point in people chain so

that there is some small chances that this person cannot find match at first time or, say for

his/her whole life.

You know the basic data structure is just a "people chain", or array of "Person".

 

C.The idea of program
 

I was regarded as mad or stupid to this kind of thing while I was expected to do something more

meaningful. I am happy to do what I like to do as long as it enjoys me and gives me some meaningful

enlights. The result is quite unexpected to me. The previous result puzzled me for a couple of days

and I kept debugging because I thought the result was wrong. Finally, I suddenly realized that it

might be correct because the reason of O type increasing so fast is due to the fact that type A and

B are highly dependent on increasing of AB. And AB is very slow in previous model. So, O is

increasing very fast.

However, things changed completely now. The result shows that AB increases faster than O, why?

Here is the previous discussion in Chinese.

D.The major functions
 
E.Further improvement
The problem that puzzled me is that type AB is increasing faster than type O and type A,B are now become the highest ones.
This is a great difference from my previous one test.
F.File listing
1. blood.cpp
 
file name: blood.cpp
#include <iostream>
#include <time.h>
using namespace std;

const int MaxPersonNumber=400000;
const int SexNumber=2;
const int BloodTypeNumber=4;
const int MaxGeneration=50;
const int BloodItemNumber=3;
const int MaxBirthNumber=3;//assume couples can have 3 kids since first mating
const int InitialNumber=40;
const int RunGenerationNumber=20;
const int TestRunNumber=5;

enum Blood 
{
	A, B, O, AB
};

enum Sex
{
	Male, Female
};

const char* bloodName[BloodTypeNumber]=
{"A","B","O","AB"};

class Person
{
	friend void initialize();
private:
	Blood factor1, factor2;
	Blood blood;
	Sex sex;
	int generation;
	Blood splitBlood(Blood theBlood, int choice);
	Blood splitBlood(int choice) const;
public:
	int father;
	int mother;
	int indexNo;
	int match;
	Sex getSex(){ return sex;}
	Blood getBlood(){ return blood;}
	void setSex(Sex theSex){sex=theSex;}
	void setBlood(Blood theBlood){ blood=theBlood;}
	void giveBirth(const Person& spouse);
	int getGeneration(){return generation;}
	void setGeneration(int theGeneration){generation=theGeneration;}
	int getMatch(){return match;}
	void setMatch(int theMatch){match=theMatch;}
	bool mate();
};



int index;
Person people[MaxPersonNumber];
int generations[MaxGeneration];
int bloodCount[MaxGeneration][BloodTypeNumber]={0};

//pls note that the below is not blood type
//but the blood item which is the genetic factor of blood
Blood bloodTable[BloodItemNumber][BloodItemNumber]=
{
	//A   B  O   
//A
	{A, AB, A},
//B
	{AB, B, B},
//O
	{A, B, O}
};



void initialize();
int first(int theGeneration);

void nextGeneration(int theGeneration);
void run();

int main()
{
	srand(time(0));
	for (int i=0; i<TestRunNumber; i++)
	{
		cout<<"test no."<<i+1<<" and result is\n";
		run();
	}

	return 0;
}

void run()
{
	initialize();
	for (int i=0; i<RunGenerationNumber; i++)
	{
	/*
		for (int j=0; j<BloodTypeNumber; j++)
		{
			cout<<bloodName[j]<<":";
			cout<<bloodCount[i][j]<<"\t";
		}
		cout<<"\n";
		*/
		nextGeneration(i);
	}
	cout<<"after 10 generations, the total number of people is:"
		<<index<<endl;
	for (i=0; i<RunGenerationNumber; i++)
	{
		cout<<"for "<<i+1<<"th generation the blood distribution is\n";

		for (int j=0; j<BloodTypeNumber; j++)
		{
			cout<<bloodName[j]<<":";
			cout<<bloodCount[i][j]<<"\t";
		}
		cout<<"\n";
	}
}

Blood Person::splitBlood(int choice) const
{
	if (choice==0)
	{
		return factor1;
	}
	else
	{
		return factor2;
	}
}

Blood Person::splitBlood(Blood theBlood, int choice)
{
	Blood result;
	switch (theBlood)
	{
	case A:
		if (choice==0)
		{
			result= O;
		}
		else
		{
			result= A;
		}
		break;
	case B:
		if (choice==0)
		{
			result= O;
		}
		else
		{
			result= B;
		}
		break;
	case O:
		result= O;
		break;
	case AB:
		if (choice==0)
		{
			result= A;
		}
		else
		{
			result= B;
		}
		break;
	}
	return result;
}


int first(int theGeneration)
{
	if (theGeneration==0)
	{
		return 0;
	}
	else
	{
		return generations[theGeneration-1]+1;
	}
}

void initialize()
{
	index=0;
	//there are a fixed number of people created by God
	for (int i=0; i<MaxGeneration; i++)
	{
		for (int j=0; j<BloodTypeNumber; j++)
		{
			bloodCount[i][j]=0;
		}
	}

	for (i=0; i<InitialNumber; i++)
	{
		//the number of woman and man are equal
		//and the original blood type is only A,B, and O
		people[index].setSex((Sex)(i%2));
		//the original blood is pure which means
		//A type is A and A instead of A and O
		people[index].setBlood((Blood)(i%BloodItemNumber));
		//this means the two blood item is exact same as blood type
		people[index].factor1=people[index].factor2=people[index].blood;
		people[index].setGeneration(0);
		people[index].indexNo=index;
		people[index].match=-1;
		people[index].father=people[index].mother=-1;
		bloodCount[0][people[index].getBlood()]++;
		index++;
	}
	generations[0]=index-1;

}

void Person::giveBirth(const Person& spouse)
{
	int choice;
	Blood self, theOther;
	choice=rand()%2;
	//splite blood to blooditem
	//self=splitBlood(blood, choice);
	self=splitBlood(choice);
	choice=rand()%2;
	//theOther=splitBlood(spouse.blood, choice);
	theOther=spouse.splitBlood(choice);
	people[index].factor1=self;
	people[index].factor2=theOther;
	//choice=rand()%2;
	people[index].setBlood(bloodTable[self][theOther]);
	//choice=rand()%2;
	people[index].setGeneration(generation+1);
	choice=rand()%2;
	people[index].setSex((Sex)choice);
	bloodCount[generation+1][people[index].blood]++;
	people[index].match=-1;
	people[index].indexNo=index;
	people[index].father=sex==Male?indexNo:spouse.indexNo;
	people[index].mother=sex==Female?indexNo:spouse.indexNo;
	index++;
}
	
bool Person::mate()
{
	int length;

	if (match!=-1)//married
	{
		return false;
	}
	length=generations[generation]-first(generation)+1;
	//randomly start from some place where he might marry older generations
	//who happened to be unmarried
	for (int i=rand()%length+first(generation); i<=generations[generation]; i++)
	{
		if (i!=indexNo)
		{
			if (people[i].match==-1)
			{			
				if (sex!=people[i].sex)//we don't allow gay to be married, right?
				{
					people[i].match=indexNo;
					match=i;
					return true;
				}	
			}
		}
	}
	return false;
}


void nextGeneration(int theGeneration)
{
	for (int birth=0; birth<MaxBirthNumber; birth++)
	{
		for (int i=first(theGeneration); i<=generations[theGeneration]; i++)
		{
			if (people[i].mate())//first married and...
			{
				people[i].giveBirth(people[people[i].getMatch()]);
			}
			else
			{
				//he/she is married and his/her spouse is younger than he/she
				if (people[i].match>people[i].indexNo)
				{
					people[i].giveBirth(people[people[i].match]);
				}
			}

		}
	}
	generations[theGeneration+1]=index-1;//records the end of generation
}



The result is like following:
test no.1 and result is
after 10 generations, the total number of people is:228627
for 1th generation the blood distribution is
A:14 B:13 O:13 AB:0
for 2th generation the blood distribution is
A:24 B:30 O:0 AB:6
for 3th generation the blood distribution is
A:21 B:21 O:7 AB:20
for 4th generation the blood distribution is
A:30 B:22 O:13 AB:33
for 5th generation the blood distribution is
A:61 B:42 O:6 AB:38
for 6th generation the blood distribution is
A:90 B:68 O:15 AB:40
for 7th generation the blood distribution is
A:111 B:93 O:24 AB:75
for 8th generation the blood distribution is
A:184 B:114 O:37 AB:100
for 9th generation the blood distribution is
A:276 B:158 O:67 AB:141
for 10th generation the blood distribution is
A:395 B:247 O:106 AB:212
for 11th generation the blood distribution is
A:581 B:357 O:152 AB:332
for 12th generation the blood distribution is
A:908 B:571 O:203 AB:436
for 13th generation the blood distribution is
A:1350 B:821 O:328 AB:663
for 14th generation the blood distribution is
A:1979 B:1106 O:473 AB:1035
for 15th generation the blood distribution is
A:2914 B:1683 O:725 AB:1524
for 16th generation the blood distribution is
A:4390 B:2460 O:1020 AB:2222
for 17th generation the blood distribution is
A:6660 B:3636 O:1547 AB:3268
for 18th generation the blood distribution is
A:9888 B:5527 O:2171 AB:4920
for 19th generation the blood distribution is
A:14746 B:8053 O:3394 AB:7509
for 20th generation the blood distribution is
A:22006 B:12155 O:5124 AB:11181
test no.2 and result is
after 10 generations, the total number of people is:213940
for 1th generation the blood distribution is
A:14 B:13 O:13 AB:0
for 2th generation the blood distribution is
A:21 B:18 O:6 AB:15
for 3th generation the blood distribution is
A:31 B:23 O:9 AB:24
for 4th generation the blood distribution is
A:41 B:31 O:14 AB:34
for 5th generation the blood distribution is
A:72 B:61 O:17 AB:27
for 6th generation the blood distribution is
A:93 B:68 O:27 AB:73
for 7th generation the blood distribution is
A:139 B:100 O:34 AB:78
for 8th generation the blood distribution is
A:214 B:129 O:35 AB:96
for 9th generation the blood distribution is
A:266 B:193 O:65 AB:169
for 10th generation the blood distribution is
A:396 B:253 O:87 AB:230
for 11th generation the blood distribution is
A:582 B:391 O:120 AB:329
for 12th generation the blood distribution is
A:805 B:533 O:189 AB:504
for 13th generation the blood distribution is
A:1179 B:773 O:260 AB:704
for 14th generation the blood distribution is
A:1728 B:1181 O:420 AB:1039
for 15th generation the blood distribution is
A:2694 B:1777 O:566 AB:1494
for 16th generation the blood distribution is
A:3922 B:2496 O:908 AB:2331
for 17th generation the blood distribution is
A:5890 B:3696 O:1267 AB:3466
for 18th generation the blood distribution is
A:8735 B:5442 O:2002 AB:4980
for 19th generation the blood distribution is
A:12831 B:8092 O:2902 AB:7564
for 20th generation the blood distribution is
A:19393 B:12158 O:4281 AB:10986
test no.3 and result is
after 10 generations, the total number of people is:195243
for 1th generation the blood distribution is
A:14 B:13 O:13 AB:0
for 2th generation the blood distribution is
A:18 B:18 O:3 AB:21
for 3th generation the blood distribution is
A:27 B:25 O:10 AB:16
for 4th generation the blood distribution is
A:42 B:32 O:13 AB:21
for 5th generation the blood distribution is
A:57 B:45 O:19 AB:23
for 6th generation the blood distribution is
A:76 B:58 O:22 AB:47
for 7th generation the blood distribution is
A:124 B:77 O:28 AB:56
for 8th generation the blood distribution is
A:168 B:103 O:54 AB:86
for 9th generation the blood distribution is
A:249 B:171 O:76 AB:101
for 10th generation the blood distribution is
A:352 B:204 O:123 AB:158
for 11th generation the blood distribution is
A:523 B:348 O:147 AB:197
for 12th generation the blood distribution is
A:756 B:457 O:216 AB:347
for 13th generation the blood distribution is
A:1128 B:664 O:317 AB:498
for 14th generation the blood distribution is
A:1590 B:1036 O:483 AB:764
for 15th generation the blood distribution is
A:2453 B:1445 O:743 AB:1128
for 16th generation the blood distribution is
A:3592 B:2173 O:1113 AB:1672
for 17th generation the blood distribution is
A:5351 B:3185 O:1608 AB:2675
for 18th generation the blood distribution is
A:8101 B:4846 O:2376 AB:3874
for 19th generation the blood distribution is
A:12134 B:7196 O:3656 AB:5802
for 20th generation the blood distribution is
A:18193 B:10820 O:5555 AB:8590
test no.4 and result is
after 10 generations, the total number of people is:168574
for 1th generation the blood distribution is
A:14 B:13 O:13 AB:0
for 2th generation the blood distribution is
A:15 B:12 O:12 AB:21
for 3th generation the blood distribution is
A:36 B:30 O:5 AB:19
for 4th generation the blood distribution is
A:31 B:38 O:16 AB:29
for 5th generation the blood distribution is
A:43 B:40 O:23 AB:29
for 6th generation the blood distribution is
A:57 B:72 O:21 AB:33
for 7th generation the blood distribution is
A:72 B:96 O:42 AB:45
for 8th generation the blood distribution is
A:98 B:123 O:57 AB:76
for 9th generation the blood distribution is
A:156 B:179 O:76 AB:102
for 10th generation the blood distribution is
A:220 B:277 O:105 AB:157
for 11th generation the blood distribution is
A:339 B:411 O:156 AB:228
for 12th generation the blood distribution is
A:480 B:533 O:231 AB:319
for 13th generation the blood distribution is
A:719 B:761 O:335 AB:474
for 14th generation the blood distribution is
A:1169 B:1154 O:461 AB:633
for 15th generation the blood distribution is
A:1673 B:1725 O:737 AB:977
for 16th generation the blood distribution is
A:2457 B:2571 O:1097 AB:1438
for 17th generation the blood distribution is
A:3602 B:3764 O:1658 AB:2139
for 18th generation the blood distribution is
A:5491 B:5573 O:2507 AB:3106
for 19th generation the blood distribution is
A:8193 B:8345 O:3621 AB:4681
for 20th generation the blood distribution is
A:12170 B:12375 O:5571 AB:6943
test no.5 and result is
after 10 generations, the total number of people is:237559
for 1th generation the blood distribution is
A:14 B:13 O:13 AB:0
for 2th generation the blood distribution is
A:24 B:24 O:6 AB:6
for 3th generation the blood distribution is
A:34 B:31 O:12 AB:13
for 4th generation the blood distribution is
A:38 B:35 O:18 AB:26
for 5th generation the blood distribution is
A:55 B:48 O:23 AB:36
for 6th generation the blood distribution is
A:79 B:67 O:32 AB:50
for 7th generation the blood distribution is
A:110 B:106 O:41 AB:67
for 8th generation the blood distribution is
A:152 B:147 O:65 AB:116
for 9th generation the blood distribution is
A:219 B:227 O:95 AB:173
for 10th generation the blood distribution is
A:311 B:338 O:138 AB:215
for 11th generation the blood distribution is
A:439 B:508 O:194 AB:320
for 12th generation the blood distribution is
A:620 B:797 O:301 AB:442
for 13th generation the blood distribution is
A:925 B:1213 O:440 AB:608
for 14th generation the blood distribution is
A:1414 B:1769 O:651 AB:936
for 15th generation the blood distribution is
A:2095 B:2564 O:969 AB:1410
for 16th generation the blood distribution is
A:3146 B:3928 O:1418 AB:2047
for 17th generation the blood distribution is
A:4707 B:5769 O:2143 AB:3107
for 18th generation the blood distribution is
A:7025 B:8639 O:3255 AB:4514
for 19th generation the blood distribution is
A:10392 B:12892 O:4858 AB:6919
for 20th generation the blood distribution is
A:15726 B:19304 O:7242 AB:10234
Press any key to continue			
				 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)