使用数据模型的线性规划#

考虑以下示例,

给定系统约束

2x + 4y >= 230
3x + 2y <= 190
x >= 0
y >= 0,

最大化目标函数

f(x) = 5x + 3y

您需要找到实数 x 和 y,使其满足约束条件并最大化目标函数。

import numpy as np
import cuopt_mps_parser
import solver_settings

from data_model import DataModel
from solver_settings import SolverSettings

problem_data = {}

dm = DataModel()
ss = SolverSettings()

设置约束矩阵#

如果约束条件是

2x + 4y >= 230
3x + 2y <= 190

约束以 CSR 格式描述。约束可以转换为如下所示的 CSR 矩阵

offsets = np.array([0, 2, 4], dtype=np.int32)
indices = np.array([0, 1, 0, 1], dtype=np.int32)
coefficients = np.array([2.0, 4.0, 3.0, 2.0], dtype=np.float64)

dm.set_csr_constraint_matrix(coefficients, indices, offsets)

偏移量表示约束的长度,索引表示变量。

设置约束边界#

如果约束如下所示

2x + 4y >= 230
3x + 2y <= 190

您需要定义所有约束的 upper_boundslower_bounds,每个值表示每个约束相对于其索引的上限或下限。

upper_bounds = np.array([np.PINF, 190], dtype=np.float64)
lower_bounds = np.array([230, np.NINF], dtype=np.float64)

dm.set_constraint_lower_bounds(lower_bounds)
dm.set_constraint_upper_bounds(upper_bounds)

PINF - 无穷大,NINF - 负无穷大,用于没有明确的上限或下限时。

设置变量边界#

变量

x >= 0
y >= 0

定义变量边界,类似于约束边界。

var_upper_bounds = np.array([np.PINF, np.PINF], dtype=np.float64)
var_lower_bounds = np.array([0, 0], dtype=np.float64)

dm.set_variable_lower_bounds(var_lower_bounds)
dm.set_variable_upper_bounds(var_upper_bounds)

设置目标数据#

目标

f(x) = 5x + 3y

传递目标数据的系数,并设置是否需要最大化或最小化。

objective_coefficients = np.array([5, 3], dtype=np.float64)

dm.set_objective_coefficients(objective_coefficients)
dm.set_maximize(True)

设置变量名称#

这是可选的,但它有助于用户浏览结果。

dm.set_variable_names(np.array(["x", "y"]))

设置求解器配置#

可以微调求解器配置以进行优化和运行时。

ss.set_time_limit(1)
ss.set_optimality_tolerance(0.0001)

解决问题#

对于托管服务,可以按照托管服务的瘦客户端示例中所示的方式触发 cuOpt 端点。

对于自托管,可以按照自托管的瘦客户端示例中所示的方式触发 cuOpt 端点。

使用此数据并调用 cuOpt 端点,这将返回 xy 的值。

以下示例使用本地托管的服务器

data = cuopt_mps_parser.toDict(dm)
data["solver_config"] = solver_settings.toDict(ss)
import json
from cuopt_sh_client import CuOptServiceSelfHostClient

# If cuOpt is not running on localhost:5000, edit ip and port parameters
cuopt_service_client = CuOptServiceSelfHostClient(
    ip="localhost",
    port=5000
)

solution = cuopt_service_client.get_LP_solve(data, response_type="dict")

print(json.dumps(solution, indent=4))

Status - 1 对应于 Optimal solution is available

{
    "response": {
        "solver_response": {
            "status": 1,
            "solution": {
                "primal_solution": [
                    37.50083870322277,
                    38.7492566784616
                ],
                "dual_solution": [
                    0.12490361527659652,
                    -1.7498895880181375
                ],
                "primal_objective": 303.75196355149865,
                "dual_objective": 303.7511902098289,
                "solver_time": 29.0,
                "vars": {
                    "x": 37.50083870322277,
                    "y": 38.7492566784616
                },
                "lp_statistics": {
                    "primal_residual": 0.0016550243746766345,
                    "dual_residual": 0.00013846649878068717,
                    "gap": 0.000773341669741967,
                    "reduced_cost": [
                        0.0,
                        0.00016471492988889835
                    ]
                }
            }
        }
    },
    "reqId": "6dc42e0b-4209-4690-87ec-647e1e79e7ce"
}