The Diet Problem

The diet problem is one of the earliest real-life problems to be solved using linear programming. This example shows how to use ojAlgo to model and solve a (miniature) instance of this problem. Background information as well as the actual numbers used in this example can be found at NEOS.

The original problem was to feed an army at the lowest possible cost while providing the soldiers with enough nutrients. Different kind of food comes at different prices and contain varying amounts of nutrients.

It should be easy for you to adapt this example code to whatever optimisation problem you want to model.

Example Code

TheDietProblem.java
import org.ojalgo.OjAlgoUtils;
import org.ojalgo.netio.BasicLogger;
import org.ojalgo.optimisation.Expression;
import org.ojalgo.optimisation.ExpressionsBasedModel;
import org.ojalgo.optimisation.Optimisation;
import org.ojalgo.optimisation.Variable;

/**
 * An example of how to implement a simple optimisation problem - The Diet Problem. It's one of the earliest
 * real-life problems to be solved using linear programming.
 *
 * @see https://www.ojalgo.org/2019/05/the-diet-problem/
 * @see https://github.com/optimatika/ojAlgo/wiki/The-Diet-Problem
 */
public class TheDietProblem {

    public static void main(final String[] args) {

        BasicLogger.debug();
        BasicLogger.debug(TheDietProblem.class);
        BasicLogger.debug(OjAlgoUtils.getTitle());
        BasicLogger.debug(OjAlgoUtils.getDate());
        BasicLogger.debug();

        // Create a new model.
        ExpressionsBasedModel model = new ExpressionsBasedModel();

        // Add variables expressing servings of each of the considered foods
        // Set lower and upper limits on the number of servings as well as the weight (cost of a
        // serving) for each variable.
        Variable bread = model.newVariable("Bread").lower(0).upper(10).weight(0.05);
        Variable corn = model.newVariable("Corn").lower(0).upper(10).weight(0.18);
        Variable milk = model.newVariable("Milk").lower(0).upper(10).weight(0.23);

        // Create a vitamin A constraint.
        // Set lower and upper limits and then specify how much vitamin A a serving of each of the
        // foods contain.
        Expression vitaminA = model.newExpression("Vitamin A").lower(5000).upper(50000);
        vitaminA.set(bread, 0).set(corn, 107).set(milk, 500);

        // Create a calories constraint...
        Expression calories = model.newExpression("Calories").lower(2000).upper(2250);
        calories.set(bread, 65).set(corn, 72).set(milk, 121);

        // Solve the problem - minimise the cost
        Optimisation.Result result = model.minimise();

        // Print the result
        BasicLogger.debug();
        BasicLogger.debug(result);
        BasicLogger.debug();

        // Modify the model to require an integer valued solution.
        BasicLogger.debug("Adding integer constraints...");
        bread.integer(true);
        corn.integer(true);
        milk.integer(true);

        // Solve again
        result = model.minimise();

        // Print the result, and the model
        BasicLogger.debug();
        BasicLogger.debug(result);
        BasicLogger.debug();
        BasicLogger.debug(model);
        BasicLogger.debug();
    }

}

Console Output

class TheDietProblem
ojAlgo
2019-05-10


OPTIMAL 3.149999999999999 @ { 1E+1, 1.94444444444444, 1E+1 }

Adding integer constraints...

OPTIMAL 3.16 @ { 1E+1, 2, 1E+1 }

############################################
0 <= Bread: 10 (0.05) <= 10
0 <= Corn: 2 (0.18) <= 10
8 <= Milk: 10 (0.23) <= 10
5000 <= Vitamin A: 5214.0 <= 50000
2000 <= Calories: 2004.0 <= 2250
############################################