此示例展示了如何使用 MathOpt 构建、求解和探索简单线性程序 (LP) 的结果。如需了解如何安装 OR-Tools,请参阅安装指南。有关如何从 source 构建和运行的其他说明推迟到最后。
构建 MathOpt 模型
在您的源代码中,您通常只需要添加一个 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"
本指南通篇使用了以下线性编程问题,并通过 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}$$
首先,构建模型:
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);
求解和检查解法
接下来,设置求解的参数。使用 MathOpt 解决优化模型的高度可配置。其中包括独立于求解器的参数(例如启用输出)、特定于求解器的参数(例如 GlopParameters.optimization_rule)、依赖于模型属性的参数(例如分支优先级)、求解器日志的回调,以及用于监控和控制优化的回调。以下代码可打开求解器日志。
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;
如需使用 Google 基于单工的 LP 求解器 GLOP 解决问题,请使用 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());
最后,检查最优解决方案的目标值和最优变量值。请注意,由于终止原因是最佳的,因此您可以放心地假定这些值存在,但由于其他终止原因(例如,不可行或无限制),调用这些方法时可以 CHECK fail
(在 C++ 中)或 raise an exception
(在 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;
有关使用 Bazel 构建和运行代码的说明
如果您使用 bazel 从源代码构建 MathOpt,此示例需要构建目标中的以下依赖项:
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"
为了运行您的代码,以下 bazel 命令将构建并运行您的目标。
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