How Many People Can a Village Feed and House?
A village of 100 people owns a fixed amount of land. Every hectare turned into a field produces food, and every hectare turned into housing raises the population cap. Ten years from now, how many people can the village support, and what split of land gets it there?
This is a small problem, but it shows how two limiting factors, food and housing, pull against each other. In this post I model the village, solve it by brute-force search, and plot the result in 2D and 3D.
1. The Problem
The village has:
| Item | Value |
|---|---|
| Total land $L$ | 60 ha |
| Initial population $P_0$ | 100 people |
| Planning horizon | 10 years |
| Farming productivity $A$ | 8.0 |
| Diminishing-returns exponent $\alpha$ | 0.85 |
| Housing density $D$ | 10 people/ha |
| Maximum growth rate $r$ | 0.35 per year |
| Starvation severity $m$ | 0.60 |
| Food needed per person $c$ | 1.0 per year |
The decision variable is $x$, the hectares of farmland. The remaining $L - x$ hectares become residential land. The goal is to maximize the population after 10 years.
2. The Model
Food production shows diminishing returns, since extra fields need more labor, are less fertile and so on:
$$
F(x) = A,x^{\alpha}
$$
Housing capacity is linear in residential land:
$$
H(x) = D,(L - x)
$$
Each year the population grows logistically toward the housing capacity, and it shrinks if food runs short. The food sufficiency ratio is
$$
q_t = \frac{F(x)}{c,P_t}, \qquad s_t = \max\bigl(0,\ 1 - q_t\bigr)
$$
and the population update is
$$
P_{t+1} = P_t + r,P_t\left(1 - \frac{P_t}{H(x)}\right) - m,P_t,s_t
$$
The optimization problem is
$$
\max_{0 \le x \le L}\ P_{10}(x)
$$
Why is there an interior optimum? Too little farmland starves the village. Too little housing caps the population. At a long-run equilibrium with food shortage, the growth term and the starvation term balance:

so the best split balances the two constraints rather than maximizing either one.
3. The Complete Source Code
Everything is in one script. The search evaluates thousands of candidate land splits simultaneously with NumPy array operations instead of a Python loop over candidates.
1 | import numpy as np |
4. Code Walkthrough
Section 1: Parameters
All constants of the model are defined at the top, so you can experiment by changing a single number. ALPHA < 1 encodes diminishing returns on farmland. M controls how brutally the population shrinks when food runs short.
Section 2: The vectorised simulator
simulate(x, A, D) implements the update rule
$$
P_{t+1} = P_t + r,P_t\left(1 - \frac{P_t}{H}\right) - m,P_t,s_t
$$
Key details:
np.broadcast_arraysgivesx,AandDa common shape. You can pass a single farmland value, an array of 6,001 candidates, or a 2D grid of farmland × productivity, and the same function handles all of them.np.maximum(..., 1e-9)guards against division by zero. When farmland is 0 hectares, food is 0, and when it is 60 hectares, housing is 0. Without the guard you would getNaNvalues or warnings.np.clip(1.0 - q, 0.0, 1.0)implements $s_t = \max(0, 1-q_t)$ and also caps the shortage at 100%, so the population cannot drop by more than $m$ in a year.P = np.maximum(P, 0.0)prevents negative populations.- The loop runs only 10 times (one per year). The “loop” over candidate land splits is handled by NumPy internally.
Section 3: Optimisation
The search space is one-dimensional, so exhaustive search is both simple and reliable. np.linspace(0, L, 6001) creates 6,001 candidates with 0.01 ha resolution. A single call to simulate evaluates them all at once, and np.argmax picks the best. A scalar optimizer could be fooled by a flat plateau or an unusual shape, while a dense grid cannot.
The code then prints a summary, a table of selected land splits, and the year-by-year trajectory at the optimum. It also prints the food production and housing capacity at the optimum, which shows which constraint is binding.
Section 4: Data for the figures
sample_xcontains the farmland values whose trajectories will be compared in panel (b).T3, X3, Z3build the grid for the first 3D surface.simulate(x_3d)returns an array of shape(11, 70)(years × candidates), so it is transposed to(70, 11)to match the meshgrid.XX, AA, ZZbuild the second surface by evaluating the final population over a grid of farmland and productivityA. This works only becausesimulateaccepts array-valuedA.best_x_for_afinds, for each productivity level, the farmland that maximizes the final population, which gives the “optimal ridge” for the heat map.
Section 5: One combined figure
All six panels are drawn into a single fig with a 2 × 3 layout, so one plt.show() displays everything:
- (a) the objective function $P_{10}(x)$ with the optimum marked,
- (b) population trajectories for different land splits,
- (c) the food limit versus the housing limit,
- (d) a 3D surface of population over time and farmland,
- (e) a 3D surface of final population over farmland and productivity,
- (f) a heat map of (e) with the optimal ridge overlaid.
5. Console Output
============================================================
Village land-allocation problem
============================================================
Total land L = 60 ha, initial population = 100, horizon = 10 years
Optimal farmland : 36.81 ha (61.4% of the land)
Optimal housing : 23.19 ha
Population in year 10: 191.08
------------------------------------------------------------
Farmland [ha] Housing [ha] Pop. (year 10)
10 50 105.00
15 45 135.00
20 40 157.78
25 35 174.43
30 30 185.40
35 25 190.66
40 20 189.70
45 15 148.77
50 10 100.00
------------------------------------------------------------
Food production at optimum : 171.46 (feeds 171.5 people)
Housing capacity at optimum: 231.90 people
Year-by-year population at the optimum:
year 0: 100.00
year 1: 119.91
year 2: 140.17
year 3: 159.58
year 4: 177.00
year 5: 188.34
year 6: 190.59
year 7: 191.00
year 8: 191.06
year 9: 191.08
year 10: 191.08
Reading the numbers
The search finds that the best allocation is about 36.8 hectares of farmland (61.4% of the land) and 23.2 hectares of housing, giving a population of about 191 people after 10 years, nearly double the starting 100.
The comparison table shows the shape of the trade-off:
- With 10 ha of farmland, food is the bottleneck and the population barely moves (about 105).
- With 50 ha of farmland, only 10 ha remain for housing. The cap of $10 \times 10 = 100$ people is exactly the starting population, so the village never grows (100.00).
- The best results sit in a narrow band around 35–40 ha, where the final population is about 190.
At the optimum the village produces food for about 171 people but has housing for about 232. The binding constraint is food, but housing must be large enough that it does not choke growth. Substituting the equilibrium population $P^{*} \approx 191$ into the balance condition from Section 2 gives about $0.0616$ on both sides, so the simulation has settled at the equilibrium predicted by the formula.
The year-by-year trajectory rises quickly at first (100 → 120 → 140 → 160 → 177 → 188) and then flattens out around 191 from year 6 on. In other words, the village reaches its carrying capacity well before the ten years are up, and the optimization is really about choosing which carrying capacity it reaches.
6. Graph Output

Reading the graphs
(a) Final population vs. farmland. The curve rises steeply while food is scarce, peaks near 37 ha, and then falls sharply as housing shrinks. The drop on the right is much steeper than the climb on the left, which shows that over-farming is more dangerous than under-farming: housing vanishes linearly, and a population cannot live in fields it has no room to inhabit.
(b) Population trajectories. Each line is a different land split. Splits near the optimum (30–45 ha) all climb toward about 190. Small farmland shares flatten at low levels because of famine. The 50 ha line stays flat at 100 because the housing cap equals the starting population.
(c) Food limit vs. housing limit. The orange curve (people the farmland can feed) rises with diminishing returns. The blue line (people the housing can hold) falls linearly. The dotted black curve is the minimum of the two, which is the theoretical ceiling. The two curves cross at roughly 41 ha, but the red dashed optimum sits to the left of that crossing, at about 37 ha. The reason is that a population does not suddenly stop at its ceiling. Near the housing cap, logistic growth slows down, so giving up a little food to gain more room is worth it.
(d) 3D surface: time × farmland. The ridge of high population runs along the farmland axis near 35–40 ha and grows with time, then flattens by year 6 or so. The cliff on the high-farmland side marks housing exhaustion, and the low plateau on the low-farmland side marks famine. This is the whole dynamic of the problem in one picture.
(e) 3D surface: farmland × productivity. As productivity $A$ rises, the whole surface lifts and the peak moves toward less farmland. The land needed to feed a given number of people shrinks when each hectare is more productive, so the freed land can become housing.
(f) Heat map with optimal ridge. The white line is the optimal farmland as a function of productivity. It bends toward smaller farmland as $A$ grows, confirming the 3D picture. Better farming technology is not a reason to farm more land. It is a reason to build more houses.
7. Conclusion
With the 60 ha village in this example, the best strategy is to devote roughly 61% of the land to farming and 39% to housing, which brings the population from 100 to about 191 in ten years. The central lesson is that the answer is neither “maximize food” nor “maximize housing”. Growth is capped by the scarcer of the two resources, and the optimum balances them, tilted slightly toward food because starvation is more punishing than crowding. As farming becomes more productive, the best allocation shifts toward housing.
















