混合整数线性规划#

考虑以下示例,

给定系统约束

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

最大化目标函数

f(x) = 5x + 3y

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

problem_data = {}

设置约束矩阵#

如果约束条件是

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

约束条件在 CSR 格式中描述。约束条件可以转换为如下 CSR 矩阵

offsets = [0, 2, 4]
indices = [0, 1, 0, 1]
coefficients = [2.0, 4.0, 3.0, 2.0]

problem_data["csr_constraint_matrix"] = {
    "offsets" : offsets,
    "indices" : indices,
    "values"  :coefficients
}

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

设置约束边界#

如果约束条件如下

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

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

upper_bounds = ["inf", 190.0]
lower_bounds = [230.0, "ninf"]

problem_data["constraint_bounds"] = {
   "upper_bounds" : upper_bounds,
   "lower_bounds" : lower_bounds
}

inf - 无穷大,ninf - 负无穷大,用于表示没有明确的上限或下限。

设置变量边界#

变量

x >= 0
y >= 0

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

var_upper_bounds = ["inf", "inf"]
var_lower_bounds = [0.0, 0.0]

problem_data["variable_bounds"] = {
   "upper_bounds" : var_upper_bounds,
   "lower_bounds" : var_lower_bounds
}

设置目标数据#

目标

f(x) = 5x + 3y

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

objective_coefficients = [5.0, 3.0]
maximize = True

problem_data["objective_data"] = {
    "coefficients" : objective_coefficients,
    "scalability_factor" : 1.0,
    "offset" : 0.0
}

problem_data["maximize"] = maximize

设置变量名称#

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

problem_data["variable_names"] = ["x", "y"]

设置变量类型#

设置变量类型,I - Integer 和 C - Continuous

problem_data["variable_types"] = ["I", "C"]

设置求解器配置#

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

solver_config  = {
    "time_limit" : 1.0,
    "tolerances": {
        "optimality" : 0.0001
    }
}

problem_data["solver_config"] = solver_config

解决问题#

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

对于自托管服务,可以触发 cuOpt 端点,如自托管的瘦客户端示例中所示。

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

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

from cuopt_sh_client import CuOptServiceSelfHostClient
import json

# 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(problem_data, response_type="dict")

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

Status - 1 对应于 Optimal solution is available

{
    "response": {
        "solver_response": {
            "status": 1,
            "solution": {
                "primal_solution": [
                    0.0,
                    57.5
                ],
                "dual_solution": [],
                "solver_time": 0.0,
                "primal_objective": -172.49999999999997,
                "dual_objective": -172.49999999999997,
                "vars": {
                    "x": 0.0,
                    "y": 57.5
                },
                "lp_statistics": {
                    "primal_residual": 0.0,
                    "dual_residual": 0.0,
                    "gap": 0.0,
                    "reduced_cost": []
                }
            }
        },
        "perf_times": null,
        "total_solve_time": null
    },
    "reqId": "260e0957-4977-4626-b42d-0d3b8912d925"
}