A useful first optimization model begins with a decision small enough to check by hand. Turning that sentence into an optimization model is less mysterious than it sounds. The first model need not involve an industrial-scale solver, and it certainly does not need thousands of variables. A small, inspectable example is often the best way to understand how an algorithm thinks about decisions.

Consider a community workshop choosing which of four activities to run on Saturday. Each activity uses some of the eight staff-hours available for preparation, and each has an estimated benefit for participants. The workshop can run any combination of activities, provided preparation fits within the staffing limit. For now, assume the benefits are independent, the estimates are meaningful, and partial activities are not allowed. Those assumptions are simplistic, but stating them makes the model honest.

Turn descriptions into decisions

We can represent the choice for each activity with a yes-or-no variable. A value of 1 means the activity runs; 0 means it does not. That is the complete decision space. With four activities, there are only sixteen possible combinations, small enough to check manually or by a short program.

Its importance is not the workshop story but the underlying structure, which appears in resource allocation, project selection and capacity planning.
ActivityPreparation hoursEstimated benefit
A49
B37
C24
D510

The constraint is that total preparation cannot exceed eight hours. The objective is to maximize the sum of the benefits of the chosen activities. We have deliberately chosen a tiny form of the knapsack problem: select items that consume a limited resource while maximizing value. Its importance is not the workshop story but the underlying structure, which appears in resource allocation, project selection and capacity planning.

Solve a model you can inspect

The following Python code uses only the standard library. It checks all sixteen combinations, rejects any that use more than eight hours, and keeps the feasible combination with the largest benefit.

from itertools import product

activities = [
    ("A", 4, 9),
    ("B", 3, 7),
    ("C", 2, 4),
    ("D", 5, 10),
]
capacity = 8
best = None

for chosen in product((0, 1), repeat=len(activities)):
    hours = sum(flag * item[1] for flag, item in zip(chosen, activities))
    benefit = sum(flag * item[2] for flag, item in zip(chosen, activities))
    if hours <= capacity:
        candidate = (benefit, -hours, chosen)
        if best is None or candidate > best:
            best = candidate

benefit, negative_hours, chosen = best
selected = [item[0] for flag, item in zip(chosen, activities) if flag]
print(selected, -negative_hours, benefit)
# ['B', 'D'] 8 17

Why B and D? Together they use all eight staff-hours and deliver an estimated benefit of 17. A and B use seven hours for a benefit of 16, while A and C use six for 13. Checking all combinations confirms that no feasible selection scores higher under our assumptions. The tie-breaking rule in the code prefers fewer hours when the benefits are equal; it does not affect the winning combination here.

More importantly, real workshops do not have a perfect, additive measure of benefit.

From toy problem to real decision

What changes when we move beyond four activities? The number of combinations doubles with every additional yes-or-no choice. With a few dozen decisions, exhaustive enumeration can become impractical, even though real-world structure may allow specialist algorithms to solve some instances efficiently. That is where mathematical programming, constraint programming, dynamic programming and optimization heuristics enter the picture. They exploit information about the problem rather than blindly enumerating everything.

More importantly, real workshops do not have a perfect, additive measure of benefit. An activity might require a particular staff member, two activities may conflict over a room, or one might be mandatory. Adding such requirements changes the model. Some become additional constraints; others demand a more thoughtful objective. A realistic optimization project therefore involves two kinds of work: ensuring that the mathematical description reflects the operation, and finding useful solutions to that description.

The first model teaches a habit worth keeping: write down what can change, what must be true and what improvement means. A solver can then help with the search. It cannot decide whether those assumptions describe the world accurately.

Continue learning

New to Optimization, part 6 of 6. Previous: How optimization algorithms search. You have completed the introductory path. View the full learning path.