使用数据模型的混合整数线性规划#
考虑以下示例,
给定系统约束
2x + 4y >= 230
3x + 2y <= 190
x >= 0, x - Integer
y >= 0, y - Continuous/Floating/non-Integer
最大化目标函数
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_bounds
和 lower_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"]))
设置变量类型#
设置变量类型,“I” - Integer
“C” - Continuous
dm.set_variable_types(np.array(["I", "C"]))
设置求解器配置#
可以微调求解器配置以进行优化和运行时。
ss.set_time_limit(1)
ss.set_optimality_tolerance(0.0001)
解决问题#
对于托管服务,可以按照托管服务瘦客户端示例中所示的方式触发 cuOpt 端点。
对于自托管服务,可以按照自托管瘦客户端示例中所示的方式触发 cuOpt 端点。
使用此数据并调用 cuOpt 端点,这将返回 x
和 y
的值。
以下示例使用本地托管服务器
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
)
data['variable_bounds']['upper_bounds'] = ["inf", "inf"]
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": 27.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": "09bdb6e2-2deb-4e84-9ebd-9a779740017a"
}