Calculating growth rate of a population of Minecraft chickens
Well, this is well above my capabilities to solve the problem analytically but I can do a nice simulation using the following code:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
public class Chicken {
public static final int STARTING_CHICKENS = 1;
public static final int TOTAL_MINUTES = 400;
public static final int REPORTING_PERIOD = 5; // minutes
public static final int LAYING_START = 5; // minutes
public static final int LAYING_END = 10; // minutes
public static final int MATURING_PERIOD = 20; // minutes
public static final int TICKS_PER_SECOND = 20; // 0.05 seconds
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
public static final int LAYING_START_TICKS = LAYING_START * TICKS_PER_MINUTE;
public static final int LAYING_END_TICKS = LAYING_END * TICKS_PER_MINUTE;
public static final int MATURING_TICKS = MATURING_PERIOD * TICKS_PER_MINUTE;
public static final int TOTAL_TICKS = TOTAL_MINUTES * TICKS_PER_MINUTE;
public static final int REPORTING_TICKS = REPORTING_PERIOD * TICKS_PER_MINUTE;
public static final double ONE_CHICK_PROBABILITY = 3D / 32D;
public static final double FOUR_CHICKS_PROBABILITY = 1D / 32D;
private static Random rnd = new Random();
private int ticks;
private int nextEggTick;
public Chicken() {
this.ticks = 0;
this.nextEggTick = MATURING_TICKS;
}
public List<Chicken> tick() {
ticks++;
if(ticks == nextEggTick) {
// update next egg time
nextEggTick = ticks + LAYING_START_TICKS + rnd.nextInt(LAYING_END_TICKS - LAYING_START_TICKS + 1);
// lay an egg
double r = rnd.nextDouble();
if (r < FOUR_CHICKS_PROBABILITY) {
return Arrays.asList(new Chicken(), new Chicken(), new Chicken(), new Chicken());
}
else if (r < FOUR_CHICKS_PROBABILITY + ONE_CHICK_PROBABILITY) {
return Arrays.asList(new Chicken());
}
}
return Arrays.asList();
}
public static void main(String[] args) {
StringBuffer output = new StringBuffer("{");
List<Chicken> chickens = new ArrayList<>();
for(int i = 0; i < STARTING_CHICKENS; i++) {
chickens.add(new Chicken());
}
int ticks = 0;
while(ticks <= TOTAL_TICKS) {
if(ticks % REPORTING_TICKS == 0) {
report(output, ticks, chickens);
}
ticks++;
List<Chicken> newChickens = new ArrayList<>();
for(Chicken chicken: chickens) {
newChickens.addAll(chicken.tick());
}
chickens.addAll(newChickens);
}
output.append("}");
System.out.println(output.toString());
}
private static void report(StringBuffer output, int ticks, List<Chicken> chickens) {
int minutes = ticks / TICKS_PER_MINUTE;
String msg = String.format("{%d, %d}", minutes, chickens.size());
System.out.println(msg);
if(output.length() > 1) {
output.append(", ");
}
output.append(msg);
}
}
I did run 10 simulations and got exponential growth of chickens:
...which becomes perfectly clear when you use logarithmic scale:
Actually, it looks like the process "struggles" in the beginning. With a small number number of chickens it might take considerable time for population to reach, say, 10 chickens. After that, the population is big enough and reproduction starts to go smoothly, always at the same exponential rate.
It can be stated empirically that, for a big enough number of minutes $X$, the number of chickens $Y$ changes according to:
$$\ln Y=\ln (\text{const}) + 0.021 X$$
$$Y = \text{const}\cdot e^{0.021 X}$$