This example shows how to build, solve, and explore the results of a simple
linear program (LP) using MathOpt. Information about installing OR-Tools is
available in the [install guide](https://developers.google.com/optimization/install). Additional notes on how to build and run
from [source](https://github.com/google/or-tools/tree/stable/ortools/math_opt) are deferred to the end.

## Build a MathOpt model

In your source, you typically *only* need to add a single MathOpt dependency:

### Python

```python
from ortools.math_opt.python import mathopt
```

### C++

```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"
```

The following linear programming problem is used throughout this guide, and it
is solved with 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}$$

First, build the model:

### Python

```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++

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

## Solve and inspect the solution

Next, set the parameters for the solve. Solving optimization models with MathOpt
is highly configurable. There are solver-independent parameters (e.g. enable
output), solver-specific parameters (e.g. GlopParameters.optimization_rule),
parameters that depend on properties of the model (e.g. branching priority), a
callback for the solver logs, and a callback to monitor and control the
optimization. The following code turns the solver logs on.

### Python

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

### C++

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

To solve the problem using GLOP, Google's simplex-based LP solver, use the
`Solve()` function.

### Python

```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++

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

Last, inspect the objective value of the optimal solution and the optimal
variable values. Note that because the termination reason was optimal, it is
safe to assume these values exist, but for other termination reasons (for
example, infeasible or unbounded) calling these methods can `CHECK fail` (in
C++) or `raise an exception` (in Python).

### 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++

```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 on building and running your code with **Bazel**

If you are building MathOpt from source using
[bazel](https://bazel.build/), this example needs the following
dependencies in the build target:

### Python

```python
"//ortools/math_opt/python:mathopt"
```

### C++

```c++
"//ortools/math_opt/cpp:math_opt"
"//ortools/math_opt/solvers:glop_solver"
```

> [!NOTE]
> **Note:** If you are using Python, you need to pass the flag `--with_glop=true` when building your target so that the solver is compiled. By default, many of the solvers in OR-Tools are enabled. We recommend disabling the solvers you are not using to get smaller binaries and avoid unnecessary dependencies. For example, you can also pass the flags `--with_scip=false --with_cp_sat=false
> --with_glpk=false --with_glop=true`.

To run your code, the following bazel command builds and runs your target.

### Python

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

### C++

```c++
bazel run path/to/you:target -- --your_flags
```