دليل البدء

يوضح هذا المثال كيفية إنشاء نتائج برنامج خطي بسيط (LP) وحلها واستكشافها باستخدام علامة MathOpt. تتوفر معلومات حول تثبيت أدوات OR في دليل التثبيت. يتم تأجيل الملاحظات الإضافية حول كيفية إنشاء المصدر وتنفيذه حتى النهاية.

إنشاء نموذج 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;

يمكنك استخدام الدالة Solve() لحلّ المشكلة باستخدام GLOP، وهي أداة حلّ LP بسيطة من Google.

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

# 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

إذا كنت تنشئ MathOpt من المصدر باستخدام bazel، يحتاج هذا المثال إلى التبعيات التالية في هدف الإصدار:

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