Premiers pas

Cet exemple montre comment créer, résoudre et explorer les résultats d'un programme linéaire simple à l'aide de MathOpt. Des informations sur l'installation des outils OR sont disponibles dans le guide d'installation. Les notes supplémentaires sur la compilation et l'exécution à partir de la source sont reportées à la fin.

Créer un modèle MathOpt

Dans votre source, il vous suffit généralement d'ajouter une seule dépendance MathOpt:

Python

from ortools.math_opt.python import mathopt

C++

#include <iostream>
#include <ostream>

#include "absl/log/check.h"
#include "absl/status/statusor.h"
#include "ortools/base/init_google.h"
#include "ortools/math_opt/cpp/math_opt.h"

Le problème de programmation linéaire suivant est utilisé tout au long de ce guide, et il est résolu avec GLOP.

$$\begin{aligned} &\max &x + 2 \cdot y\\ &\text{subject to} &x + y &\leq 1.5 \\ &&-1 \leq x &\leq 1.5 \\ &&0 \leq y &\leq 1 \end{aligned}$$

Commencez par créer le modèle:

Python

# Build the model.
model = mathopt.Model(name="getting_started_lp")
x = model.add_variable(lb=-1.0, ub=1.5, name="x")
y = model.add_variable(lb=0.0, ub=1.0, name="y")
model.add_linear_constraint(x + y <= 1.5)
model.maximize(x + 2 * y)

C++

// Build the model.
namespace math_opt = ::operations_research::math_opt;
math_opt::Model lp_model("getting_started_lp");
const math_opt::Variable x = lp_model.AddContinuousVariable(-1.0, 1.5, "x");
const math_opt::Variable y = lp_model.AddContinuousVariable(0.0, 1.0, "y");
lp_model.AddLinearConstraint(x + y <= 1.5, "c");
lp_model.Maximize(x + 2 * y);

Résoudre et inspecter la solution

Ensuite, définissez les paramètres de la solution. Avec MathOpt, la résolution de modèles d'optimisation est hautement configurable. Il existe des paramètres indépendants du résolveur (par exemple, "enable_output"), des paramètres spécifiques au résolveur (par exemple, GlopParameters.optimization_rule), des paramètres qui dépendent des propriétés du modèle (par exemple, une priorité d'embranchement), un rappel pour les journaux du résolveur et un rappel pour surveiller et contrôler l'optimisation. Le code suivant active les journaux du résolveur.

Python

# Set parameters, e.g. turn on logging.
params = mathopt.SolveParameters(enable_output=True)

C++

// Set parameters, e.g. turn on logging.
math_opt::SolveArguments args;
args.parameters.enable_output = true;

Pour résoudre le problème à l'aide de GLOP, le résolveur de page de destination basé sur le format simplex de Google, utilisez la fonction Solve().

Python

# Solve and ensure an optimal solution was found with no errors.
# (mathopt.solve may raise a RuntimeError on invalid input or internal solver
# errors.)
result = mathopt.solve(model, mathopt.SolverType.GLOP, params=params)
if result.termination.reason != mathopt.TerminationReason.OPTIMAL:
    raise RuntimeError(f"model failed to solve: {result.termination}")

C++

// Solve and ensure an optimal solution was found with no errors.
const absl::StatusOr<math_opt::SolveResult> result =
    math_opt::Solve(lp_model, math_opt::SolverType::kGlop, args);
CHECK_OK(result.status());
CHECK_OK(result->termination.EnsureIsOptimal());

Enfin, inspectez la valeur d'objectif de la solution optimale et les valeurs de variables optimales. Notez que, comme le motif d'arrêt était optimal, il est possible de supposer que ces valeurs existent. Toutefois, pour d'autres raisons d'arrêt (par exemple, impossibles ou illimités), l'appel de ces méthodes peut être CHECK fail (en C++) ou raise an exception (en Python).

Python

# Print some information from the result.
print("MathOpt solve succeeded")
print("Objective value:", result.objective_value())
print("x:", result.variable_values()[x])
print("y:", result.variable_values()[y])

C++

// Print some information from the result.
std::cout << "MathOpt solve succeeded" << std::endl;
std::cout << "Objective value: " << result->objective_value() << std::endl;
std::cout << "x: " << result->variable_values().at(x) << std::endl;
std::cout << "y: " << result->variable_values().at(y) << std::endl;

Notes sur la création et l'exécution de votre code avec Bazel

Si vous compilez MathOpt à partir de la source à l'aide de bazel, les dépendances suivantes doivent être ajoutées à la cible de compilation dans cet exemple:

Python

"//util/operations_research/math_opt/python:mathopt"

C++

"//util/operations_research/math_opt/cpp:math_opt"
"//util/operations_research/math_opt/solvers:glop_solver"

Pour exécuter votre code, la commande Bagel suivante crée et exécute votre cible.

Python

bazel run path/to/you:target --with_scip=false --with_cp_sat=false
--with_glpk=false --with_glop=true -- --your_flags

C++

bazel run path/to/you:target -- --your_flags