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