# Effective Population Size: Population Size Bottlenecks

The effective population size, N_{e}, is the size of a population that behaves like an
ideal (Wright-Fisher) population of size N_{e}. Let's demonstrate what that means.

The first graph shows the evolutionary dynamics of a population of size N=1000. The
effective population size is calculated as the harmonic mean, and shown in the
legend. Because the population size is constant at N=1000, the effective population
size is N_{e}=1000 as well.

Let's go ahead and introduce a population size bottleneck of N=10 at every 10th
generation. What is the effective population size of such a population?

Our population is of size N=1000 for 9 generations, then N=10 for one generation (the bottleneck),
then N=1000 for 9 generations again, then N=10 for one generation, etc. The average
population size over time is 0.9*1000 + 0.1*10, or 901. We could be tempted to think
that the population thus behaves like an ideal population at a constant size N=901, which would look
as follows:

However, the harmonic mean of the population size is only 92. What would an ideal population at constant size N=92 look like? Let's take a look:

At N=92, the effect of genetic drift has strongly increased compared to N=1000. Let's now take a look at the evolutionary dynamics of the population with N=1000, but with bottlenecks of N=10 every 10th generation:

Thus, despite having an average size of N=901, this population behaves like an ideal population of
N=92. In other words, while its census population size is N=901, its effective population size
is N_{e}=92.

#### Code

```
var p;
var N = 1000;
var generations = 100;
var data = [];
var simulations = 10;
var population_sizes = [];
function next_generation(simulation_data, current_N) {
var draws = 2 * current_N;
var a1 = 0;
var a2 = 0;
for (var i = 0; i < draws; i = i + 1) {
if (Math.random() <= p) {
a1 = a1 + 1;
}
else {
a2 = a2 + 1;
}
}
p = a1/draws;
simulation_data.push(p);
}
function simulation(simulation_counter) {
p = 0.5;
var population_size;
for (var i = 0; i < generations; i = i + 1) {
if (i%10 == 9) {
population_size = 10;
}
else {
population_size = N;
}
population_sizes.push(population_size);
next_generation(data[simulation_counter],population_size);
}
}
function effective_population_size(all_Ns) {
var denominator = 0;
for (var i = 0; i < all_Ns.length; i = i + 1) {
denominator = denominator + (1 / all_Ns[i]);
}
return Math.round(all_Ns.length / denominator);
}
for (var i = 0; i < simulations; i = i + 1) {
data.push([]);
simulation(i);
}
Ne = effective_population_size(population_sizes);
draw_line_chart(data,"Generation","p",["Eff. Population Size:",Ne,"Generations:",generations]);
```

Note: the draw_line_chart function is built with D3.js
and can be found here.