Per iniziare

Questo esempio mostra come creare, risolvere ed esplorare i risultati di un semplice programma lineare (LP) utilizzando MathOpt. Le informazioni sull'installazione di OR-Tools sono disponibili nella guida all'installazione. Le note aggiuntive su come creare ed eseguire da source sono rimandate alla fine.

Creare un modello MathOpt

Nell'origine, in genere devi aggiungere solo una singola dipendenza 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"

In questa guida viene utilizzato il seguente problema di programmazione lineare e viene risolto con 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}$$

Per prima cosa, crea il modello:

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);

Risolvi e analizza la soluzione

Quindi, imposta i parametri per la soluzione. La soluzione dei modelli di ottimizzazione con MathOpt è altamente configurabile. Esistono parametri indipendenti dal risolutore (ad es. abilita l'output), parametri specifici per il risolutore (ad es. GlopParameters.approval_rule), parametri che dipendono dalle proprietà del modello (ad es. priorità di diramazione), un callback per i log del risolutore e un callback per monitorare e controllare l'ottimizzazione. Il codice seguente attiva i log del risolutore.

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;

Per risolvere il problema utilizzando GLOP, il risolutore LP simplex di Google, utilizza la funzione 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());

Infine, controlla il valore obiettivo della soluzione ottimale e i valori della variabile ottimali. Tieni presente che, poiché il motivo della terminazione era ottimale, è sicuro che questi valori esistano, ma per altri motivi di terminazione (ad esempio, non fattibile o non limitati), la chiamata a questi metodi può CHECK fail (in C++) o raise an exception (in 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;

Note sulla creazione e sull'esecuzione del codice con Bazel

Se crei Mathopt dall'origine utilizzando bazel, questo esempio richiede le seguenti dipendenze nella destinazione della build:

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"

Per eseguire il codice, il seguente comando bazel crea ed esegue la destinazione.

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