#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_POP_SIZE 10000
int popB[MAX_POP_SIZE], popR[MAX_POP_SIZE];
void GetPara(int *popSizePtr, double *freqPtr);
void InitPop(int *popPtr, int popSize, double initFreq);
void CreateNextGenPanmictic(int *curPop, int *nextPop, int popSize);
int RandInt(int max);
int MyRound(double x);
int main(void) {
int gen, *currentPtr, *nextPtr;
int popSize, numGen = 100000;
double initFreq;
GetPara(&popSize, &initFreq); /* get the values from the user */
if (popSize > MAX_POP_SIZE) { /* Make sure we have big enough arrays */
fprintf(stderr, "pop size: %d is bigger than the max: %d\n",
popSize, MAX_POP_SIZE);
exit(EXIT_FAILURE);
}
srand(time(NULL));
InitPop(popB, popSize, initFreq); /* randomly assign alleles */
for (gen = 0; gen < numGen; gen++) {
if (gen % 2 == 0) {
currentPtr = popB;
nextPtr = popR;
} else {
currentPtr = popR;
nextPtr = popB;
}
CreateNextGenPanmictic(currentPtr, nextPtr, popSize);
}
return 0;
}
/* Initialize the parameters */
void GetPara(int *popSizePtr, double *freqPtr) {
fprintf(stderr, "Population Size?: ");
scanf("%d", popSizePtr);
fprintf(stderr, "Init freq. of allele 1?: ");
scanf("%lf", freqPtr);
return;
}
/*
* Assume that there are two alleles: 0 and 1
* Initialize the population, so that the allele frequency of allele 1
* is initFreq.
*/
void InitPop(int *popPtr, int popSize, double initFreq) {
int i, numAlleles, cntr, index;
numAlleles = MyRound(popSize * initFreq);
for (i = 0; i < popSize; i++) {
popPtr[i] = 0;
}
cntr = 0;
while (cntr < numAlleles) {
index = RandInt(popSize - 1);
if (popPtr[index] == 0) {
popPtr[index] = 1;
cntr++;
}
}
return;
}
void CreateNextGenPanmictic(int *curPop, int *nextPop, int popSize) {
int i, parent;
for (i = 0; i < popSize; i ++) {
parent = RandInt(popSize - 1);
nextPop[i] = curPop[parent];
}
return;
}
/*
* Returns a uniform random integer between 0 and max (ends inclusive)
* It uses rand(), so you need to srand() in main()
*/
int RandInt(int max) {
int r = rand();
return r % (max+1);
}
/*
* Round the floating points to the nearest integer
* For example, 9.5 <= x < 10.5 become 10
* This function can cause integer over-flow when x is large
*/
int MyRound(double x) {
int intPart;
if (x > 0) {
return (int) (x + 0.5);
} else {
return (int) (x - 0.5);
}
}