The objective of the project was to determine the optimal area allocation for three crops to maximize total nutritional yield (kilocalories) within strict resource constraints, while meeting a baseline protein requirement for the community.
Let the decision variables represent the area allocated to each crop in square feet:
To ensure a diverse yield, no single crop may exceed 40% of the total allocated area:
The garden was modeled to provide a supplemental food source (20% of total dietary requirements) for 10 adults.
Protein yield per square foot is calculated as: * Tomatoes (\(x_1\)): 2 lbs/sq ft \(\times\) 4g/lb = 8g/sq ft * Carrots (\(x_2\)): 1 lb/sq ft \(\times\) 4g/lb = 4g/sq ft * Beans (\(x_3\)): 0.5 lbs/sq ft \(\times\) 90g/lb = 45g/sq ft
The minimum protein constraint is formulated as: \[8x_1 + 4x_2 + 45x_3 \ge 700\]
Applying standard caloric densities to the physical yield rates normalizes the objective function to maximize total kilocalories (\(Z\)):
\[\max Z = 160x_1 + 185x_2 + 70x_3\]
The optimal crop allocation was computed using the simplex algorithm
via the lpSolve package in R.
# Load lpSolve
library(lpSolve)
# Objective function coefficients (kcal/sq ft)
obj <- c(160, 185, 70)
# Constraint matrix (Area, Water, Labor, Max T, Max C, Max B, Min Protein)
con <- matrix(c(
1, 1, 1,
1, 0.5, 0.5,
0.1, 0.05, 0.05,
0.6, -0.4, -0.4,
-0.4, 0.6, -0.4,
-0.4, -0.4, 0.6,
8, 4, 45
), nrow = 7, byrow = TRUE)
# Constraint directions
dir <- c("<=", "<=", "<=", "<=", "<=", "<=", ">=")
# Constraint bounds
rhs <- c(1000, 800, 80, 0, 0, 0, 700)
# Execute optimization
sol <- lp("max", obj, con, dir, rhs)
# Output results
cat("Maximized Nutritional Yield (kcal):", sol$objval, "\n\n")
## Maximized Nutritional Yield (kcal): 152000
cat("Optimal Area Allocation (sq ft):\n")
## Optimal Area Allocation (sq ft):
cat("Tomatoes:", sol$solution[1], "\n")
## Tomatoes: 400
cat("Carrots: ", sol$solution[2], "\n")
## Carrots: 400
cat("Beans: ", sol$solution[3], "\n")
## Beans: 200
# Calculate resulting protein
total_protein <- (8 * sol$solution[1]) + (4 * sol$solution[2]) + (45 * sol$solution[3])
cat("\nTotal Protein Yield (g):", total_protein, "\n")
##
## Total Protein Yield (g): 13800
# Visualize optimal allocation
crops <- c("Tomatoes", "Carrots", "Beans")
barplot(
sol$solution,
names.arg = crops,
col = c("#ff6347", "#ffa500", "#90ee90"),
main = "Optimal Crop Allocation with Proportional & Nutritional Limits",
ylab = "Area (Square Feet)",
ylim = c(0, 1000)
)
The solver determined the optimal crop distribution to be \(x_1 = 400\) sq ft (Tomatoes), \(x_2 = 400\) sq ft (Carrots), and \(x_3 = 200\) sq ft (Beans).
The \(700\)g minimum protein constraint is “non-binding” because the optimal solution natively exceeds it.
Cornell University Cooperative Extension. (n.d.). Recommended spacing and expected yield for garden vegetables in New York. https://gardening.cals.cornell.edu/files/Recommended-spacing-and-expected-yield-for-garden-vegetables-in-New-York-1iozy2c.pdf
Kansas State University Agricultural Experiment Station and Cooperative Extension Service. (n.d.). Vegetable garden planting guide. https://bookstore.ksre.ksu.edu/pubs/vegetable-garden-planting-guide-revised_MF315.pdf
Penn State Extension. (n.d.). Vegetable seed planting guide. Pennsylvania State University. https://extension.psu.edu/programs/master-gardener/counties/york/vegetable-guides/vegetable-seed-planting-guide/@@download/file/Vegetable-Seed-Planting-Guide.pdf