cuopt-numerical-optimization-api-python
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesecuOpt Numerical Optimization Skill (Python)
cuOpt 数值优化技能(Python)
Model and solve LP, MILP, and QP problems using NVIDIA cuOpt's GPU-accelerated solver. The Python API surface (, , ) is shared across all three problem classes — only the objective form and a few rules change.
ProblemSolverSettingssolve使用NVIDIA cuOpt的GPU加速求解器建模并求解LP、MILP和QP问题。三种问题类型共享Python API接口(、、)——仅目标形式和少数规则有所不同。
ProblemSolverSettingssolveBefore You Start
开始之前
Use a formulation summary (parameters, constraints, decisions, objective) if available; otherwise ask for decision variables, objective, and constraints. Then confirm problem type (LP / MILP / QP — see below) and variable types.
如果有公式概要(参数、约束、决策变量、目标)请使用;否则请询问决策变量、目标函数和约束条件。然后确认问题类型(LP / MILP / QP — 见下文)和变量类型。
Choosing LP vs MILP vs QP
选择LP、MILP还是QP
Decide from the objective and variables:
| If the objective is... | And variables are... | Use |
|---|---|---|
Linear (sum of | All continuous | LP |
| Linear | Some integer or binary | MILP |
Has squared ( | Continuous (integer QP not supported) | QP (beta) |
Prefer LP when the problem allows it. LP solves faster and has stronger optimality guarantees. Use MILP only when the problem logically requires whole numbers or yes/no decisions. Use QP only when the objective is genuinely quadratic (variance, squared error, kinetic energy).
Problem types that need extra care: Multi-period planning and goal programming are easy to misinterpret. Double-check that rates and constraints apply to the right time period or priority level (AGENTS.md: verify understanding before code).
- Use LP when every quantity can meaningfully be fractional: flows, proportions, rates, dollars, hours, tonnes of material, etc.
- Use MILP when the problem mentions counts of discrete entities, yes/no choices, or either/or decisions (e.g. open a facility or not, assign a person to a shift, number of trucks).
- Use QP when the objective minimizes variance, squared error, or any expression with or
x*xterms (portfolio optimization, least squares, regularized regression).x*y
根据目标函数和变量类型判断:
| 若目标为... | 且变量为... | 使用 |
|---|---|---|
线性( | 全部为连续型 | LP |
| 线性 | 部分为整数或二进制 | MILP |
包含平方项( | 连续型(不支持整数QP) | QP(测试版) |
在问题允许的情况下优先选择LP。LP求解速度更快,且有更强的最优性保证。仅当问题逻辑上需要整数或是非决策时才使用MILP。仅当目标函数确实为二次型(方差、平方误差、动能)时才使用QP。
需要特别注意的问题类型: 多周期规划和目标规划容易被误解。请仔细检查速率和约束是否适用于正确的时间段或优先级(AGENTS.md:编写代码前先确认理解)。
- 使用LP:当所有数量都可以是分数时,例如流量、比例、速率、金额、小时、物料吨数等。
- 使用MILP:当问题涉及离散实体的数量、是非选择或二选一决策时(例如是否开设设施、是否安排人员值班、卡车数量)。
- 使用QP:当目标函数最小化方差、平方误差或任何包含或
x*x项的表达式时(投资组合优化、最小二乘法、正则化回归)。x*y
Integer vs continuous from wording
从表述判断整数型vs连续型变量
Choose variable type from what the problem describes.
| Problem wording / concept | Variable type | Examples |
|---|---|---|
| Discrete entities (counts) | INTEGER | Workers, cars, trucks, machines, pilots, facilities, units to manufacture (when "units" means whole items), trainees, vehicles |
| Yes/no or on/off | INTEGER (binary, lb=0 ub=1) | Open a facility, run a machine, produce a product line, assign a person to a shift |
| Amounts that can be fractional | CONTINUOUS | Tonnes, litres, dollars, hours, kWh, proportion of capacity, flow volume, weight |
| Rates or fractions | CONTINUOUS | Utilization, percentage, share of budget |
| Unclear | Prefer INTEGER if the noun is a countable thing (a worker, a car); prefer CONTINUOUS if it's a measure (amount of steel, hours worked). If the problem says "whole" or "integer" or "number of", use INTEGER. |
Rule of thumb: If the quantity is "how many things" (people, vehicles, items, sites), use INTEGER. If it's "how much" (mass, volume, money, time) or a rate, use CONTINUOUS unless the problem explicitly requires whole numbers.
根据问题描述选择变量类型。
| 问题表述/概念 | 变量类型 | 示例 |
|---|---|---|
| 离散实体(数量) | INTEGER(整数型) | 工人、汽车、卡车、机器、飞行员、设施、生产单位(当“单位”指完整物品时)、实习生、车辆 |
| 是非或开关型 | INTEGER(整数型,二进制,下界=0 上界=1) | 开设设施、运行机器、生产产品线、安排人员值班 |
| 可分数化的数量 | CONTINUOUS(连续型) | 吨、升、美元、小时、千瓦时、容量比例、流量、重量 |
| 速率或比例 | CONTINUOUS(连续型) | 利用率、百分比、预算份额 |
| 表述模糊 | 若名词是可数事物(工人、汽车)优先选INTEGER;若是度量值(钢材量、工作时长)优先选CONTINUOUS。如果问题提到“整数”“数量”,则使用INTEGER。 |
经验法则: 如果是“多少个事物”(人、车辆、物品、场地),使用INTEGER。如果是“多少量”(质量、体积、资金、时间)或速率,除非问题明确要求整数,否则使用CONTINUOUS。
Quick Reference: Python API
Python API快速参考
LP Example
LP示例
python
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MAXIMIZE
from cuopt.linear_programming.solver_settings import SolverSettingspython
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MAXIMIZE
from cuopt.linear_programming.solver_settings import SolverSettingsCreate problem
Create problem
problem = Problem("MyLP")
problem = Problem("MyLP")
Decision variables
Decision variables
x = problem.addVariable(lb=0, vtype=CONTINUOUS, name="x")
y = problem.addVariable(lb=0, vtype=CONTINUOUS, name="y")
x = problem.addVariable(lb=0, vtype=CONTINUOUS, name="x")
y = problem.addVariable(lb=0, vtype=CONTINUOUS, name="y")
Constraints
Constraints
problem.addConstraint(2x + 3y <= 120, name="resource_a")
problem.addConstraint(4x + 2y <= 100, name="resource_b")
problem.addConstraint(2x + 3y <= 120, name="resource_a")
problem.addConstraint(4x + 2y <= 100, name="resource_b")
Objective
Objective
problem.setObjective(40x + 30y, sense=MAXIMIZE)
problem.setObjective(40x + 30y, sense=MAXIMIZE)
Solve
Solve
settings = SolverSettings()
settings.set_parameter("time_limit", 60)
problem.solve(settings)
settings = SolverSettings()
settings.set_parameter("time_limit", 60)
problem.solve(settings)
Check status (CRITICAL: use PascalCase!)
Check status (CRITICAL: use PascalCase!)
if problem.Status.name in ["Optimal", "PrimalFeasible"]:
print(f"Objective: {problem.ObjValue}")
print(f"x = {x.getValue()}")
print(f"y = {y.getValue()}")
undefinedif problem.Status.name in ["Optimal", "PrimalFeasible"]:
print(f"Objective: {problem.ObjValue}")
print(f"x = {x.getValue()}")
print(f"y = {y.getValue()}")
undefinedMILP Example (with integer variables)
MILP示例(含整数变量)
python
from cuopt.linear_programming.problem import Problem, CONTINUOUS, INTEGER, MINIMIZE
problem = Problem("FacilityLocation")python
from cuopt.linear_programming.problem import Problem, CONTINUOUS, INTEGER, MINIMIZE
problem = Problem("FacilityLocation")Binary variable (integer with bounds 0-1)
Binary variable (integer with bounds 0-1)
open_facility = problem.addVariable(lb=0, ub=1, vtype=INTEGER, name="open")
open_facility = problem.addVariable(lb=0, ub=1, vtype=INTEGER, name="open")
Continuous variable
Continuous variable
production = problem.addVariable(lb=0, vtype=CONTINUOUS, name="production")
production = problem.addVariable(lb=0, vtype=CONTINUOUS, name="production")
Linking constraint: can only produce if facility is open
Linking constraint: can only produce if facility is open
problem.addConstraint(production <= 1000 * open_facility, name="link")
problem.addConstraint(production <= 1000 * open_facility, name="link")
Objective: fixed cost + variable cost
Objective: fixed cost + variable cost
problem.setObjective(500open_facility + 2production, sense=MINIMIZE)
problem.setObjective(500open_facility + 2production, sense=MINIMIZE)
MILP-specific settings
MILP-specific settings
settings = SolverSettings()
settings.set_parameter("time_limit", 120)
settings.set_parameter("mip_relative_gap", 0.01) # 1% optimality gap
problem.solve(settings)
settings = SolverSettings()
settings.set_parameter("time_limit", 120)
settings.set_parameter("mip_relative_gap", 0.01) # 1% optimality gap
problem.solve(settings)
Check status
Check status
if problem.Status.name in ["Optimal", "FeasibleFound"]:
print(f"Open facility: {open_facility.getValue() > 0.5}")
print(f"Production: {production.getValue()}")
undefinedif problem.Status.name in ["Optimal", "FeasibleFound"]:
print(f"Open facility: {open_facility.getValue() > 0.5}")
print(f"Production: {production.getValue()}")
undefinedQP Example (beta — MINIMIZE only)
QP示例(测试版 — 仅支持MINIMIZE)
python
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MINIMIZE
from cuopt.linear_programming.solver_settings import SolverSettingspython
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MINIMIZE
from cuopt.linear_programming.solver_settings import SolverSettingsPortfolio variance minimization
Portfolio variance minimization
problem = Problem("Portfolio")
x1 = problem.addVariable(lb=0, ub=1, vtype=CONTINUOUS, name="stock_a")
x2 = problem.addVariable(lb=0, ub=1, vtype=CONTINUOUS, name="stock_b")
x3 = problem.addVariable(lb=0, ub=1, vtype=CONTINUOUS, name="stock_c")
problem = Problem("Portfolio")
x1 = problem.addVariable(lb=0, ub=1, vtype=CONTINUOUS, name="stock_a")
x2 = problem.addVariable(lb=0, ub=1, vtype=CONTINUOUS, name="stock_b")
x3 = problem.addVariable(lb=0, ub=1, vtype=CONTINUOUS, name="stock_c")
Quadratic objective (variance) — MUST be MINIMIZE
Quadratic objective (variance) — MUST be MINIMIZE
problem.setObjective(
0.04x1x1 + 0.02x2x2 + 0.01x3x3
+ 0.02x1x2 + 0.01x1x3 + 0.016x2x3,
sense=MINIMIZE,
)
problem.setObjective(
0.04x1x1 + 0.02x2x2 + 0.01x3x3
+ 0.02x1x2 + 0.01x1x3 + 0.016x2x3,
sense=MINIMIZE,
)
Linear constraints
Linear constraints
problem.addConstraint(x1 + x2 + x3 == 1, name="budget")
problem.addConstraint(0.12x1 + 0.08x2 + 0.05*x3 >= 0.08, name="min_return")
problem.solve(SolverSettings())
if problem.Status.name in ["Optimal", "PrimalFeasible"]:
print(f"Variance: {problem.ObjValue}")
**QP rules:**
- **MINIMIZE only** — solver rejects MAXIMIZE for quadratic objectives. To maximize `f(x)`, minimize `-f(x)`.
- **Continuous variables only** — integer QP is not supported.
- **Q should be PSD** (positive semi-definite) for a convex problem; otherwise the solver may return a non-optimal stationary point.
- **Beta** — API may evolve; treat as production-capable for typical convex QP but expect occasional changes.
See `resources/qp_examples.md` for least-squares, maximization-workaround, and matrix-form examples.problem.addConstraint(x1 + x2 + x3 == 1, name="budget")
problem.addConstraint(0.12x1 + 0.08x2 + 0.05*x3 >= 0.08, name="min_return")
problem.solve(SolverSettings())
if problem.Status.name in ["Optimal", "PrimalFeasible"]:
print(f"Variance: {problem.ObjValue}")
**QP规则:**
- **仅支持MINIMIZE** — 求解器会拒绝二次目标的MAXIMIZE请求。要最大化`f(x)`,请最小化`-f(x)`。
- **仅支持连续变量** — 不支持整数QP。
- **Q矩阵应为半正定(PSD)**,以保证问题是凸性的;否则求解器可能返回非最优的驻点。
- **测试版** — API可能会演进;对于典型的凸QP可视为生产可用,但可能会有偶尔的变更。
如需最小二乘法、最大化变通方法和矩阵形式示例,请查看`resources/qp_examples.md`。CRITICAL: Status Checking
重要提示:状态检查
Status values use PascalCase, NOT ALL_CAPS:
python
undefined状态值使用帕斯卡命名法(PascalCase),而非全大写:
python
undefined✅ CORRECT
✅ CORRECT
if problem.Status.name in ["Optimal", "FeasibleFound"]:
print(problem.ObjValue)
if problem.Status.name in ["Optimal", "FeasibleFound"]:
print(problem.ObjValue)
❌ WRONG - will silently fail!
❌ WRONG - will silently fail!
if problem.Status.name == "OPTIMAL": # Never matches!
print(problem.ObjValue)
**LP Status Values:** `Optimal`, `NoTermination`, `NumericalError`, `PrimalInfeasible`, `DualInfeasible`, `IterationLimit`, `TimeLimit`, `PrimalFeasible`
**MILP Status Values:** `Optimal`, `FeasibleFound`, `Infeasible`, `Unbounded`, `TimeLimit`, `NoTermination`
**QP Status Values:** Same set as LP. For QP debugging, print `f"Actual status: '{problem.Status.name}'"` and check that `Q` is PSD and variables are reasonably scaled.if problem.Status.name == "OPTIMAL": # Never matches!
print(problem.ObjValue)
**LP状态值:** `Optimal`、`NoTermination`、`NumericalError`、`PrimalInfeasible`、`DualInfeasible`、`IterationLimit`、`TimeLimit`、`PrimalFeasible`
**MILP状态值:** `Optimal`、`FeasibleFound`、`Infeasible`、`Unbounded`、`TimeLimit`、`NoTermination`
**QP状态值:** 与LP相同。调试QP时,打印`f"Actual status: '{problem.Status.name}'"`并检查Q矩阵是否为半正定、变量缩放是否合理。Common Modeling Patterns
常见建模模式
Binary Selection
二进制选择
python
undefinedpython
undefinedSelect exactly k items from n
Select exactly k items from n
items = [problem.addVariable(lb=0, ub=1, vtype=INTEGER) for _ in range(n)]
problem.addConstraint(sum(items) == k)
undefineditems = [problem.addVariable(lb=0, ub=1, vtype=INTEGER) for _ in range(n)]
problem.addConstraint(sum(items) == k)
undefinedBig-M Linking
Big-M关联约束
python
undefinedpython
undefinedIf y=1, then x <= 100; if y=0, x can be anything up to M
If y=1, then x <= 100; if y=0, x can be anything up to M
M = 10000
problem.addConstraint(x <= 100 + M*(1 - y))
undefinedM = 10000
problem.addConstraint(x <= 100 + M*(1 - y))
undefinedIf-then "must also produce"
条件约束“若生产X则必须生产Y”
When the problem says if we do X then we must also do Y, enforce both (i) the binary link and (ii) that Y is actually produced:
python
undefined当问题表述为若我们生产X则必须同时生产Y时,需同时约束(i)二进制关联和(ii)Y的实际生产:
python
undefinedy_X <= y_Y (if we do X, we must "do" Y)
y_X <= y_Y (if we do X, we must "do" Y)
problem.addConstraint(y_X <= y_Y)
problem.addConstraint(y_X <= y_Y)
Production of Y when Y is chosen: produce at least 1 (or a minimum) when y_Y=1
Production of Y when Y is chosen: produce at least 1 (or a minimum) when y_Y=1
problem.addConstraint(production_Y >= 1 * y_Y) # or min_amount * y_Y
Otherwise the solver can set y_Y=1 but production_Y=0, satisfying the binary link but not the intent.problem.addConstraint(production_Y >= 1 * y_Y) # or min_amount * y_Y
否则求解器可能会设置y_Y=1但production_Y=0,满足二进制关联但不符合实际需求。Building large expressions
构建大型表达式
Chained over many terms can hit recursion limits in the API. Prefer building objectives and constraints with LinearExpression:
+python
from cuopt.linear_programming.problem import LinearExpression链式连接多个项可能会触发API的递归限制。建议使用LinearExpression构建目标函数和约束:
+python
from cuopt.linear_programming.problem import LinearExpressionBuild as list of (vars, coeffs) instead of v1c1 + v2c2 + ...
Build as list of (vars, coeffs) instead of v1c1 + v2c2 + ...
vars_list = [x, y, z]
coeffs_list = [1.0, 2.0, 3.0]
expr = LinearExpression(vars_list, coeffs_list, constant=0.0)
problem.addConstraint(expr <= 100)
See reference models in this skill's `assets/` for examples.vars_list = [x, y, z]
coeffs_list = [1.0, 2.0, 3.0]
expr = LinearExpression(vars_list, coeffs_list, constant=0.0)
problem.addConstraint(expr <= 100)
请查看本技能`assets/`目录中的参考模型示例。Piecewise Linear (SOS2)
分段线性(SOS2)
python
undefinedpython
undefinedApproximate nonlinear function with breakpoints
Approximate nonlinear function with breakpoints
Use lambda variables that sum to 1, at most 2 adjacent non-zero
Use lambda variables that sum to 1, at most 2 adjacent non-zero
undefinedundefinedSolver Settings
求解器设置
python
settings = SolverSettings()python
settings = SolverSettings()Time limit
Time limit
settings.set_parameter("time_limit", 60)
settings.set_parameter("time_limit", 60)
MILP gap tolerance (stop when within X% of optimal)
MILP gap tolerance (stop when within X% of optimal)
settings.set_parameter("mip_relative_gap", 0.01)
settings.set_parameter("mip_relative_gap", 0.01)
Logging
Logging
settings.set_parameter("log_to_console", 1)
undefinedsettings.set_parameter("log_to_console", 1)
undefinedCommon Issues
常见问题
| Problem | Likely Cause | Fix |
|---|---|---|
| Status never "OPTIMAL" | Using wrong case | Use |
| Integer var has fractional value | Defined as CONTINUOUS | Use |
| Infeasible | Conflicting constraints | Check constraint logic |
| Unbounded | Missing bounds | Add variable bounds |
| Slow solve | Large problem | Set time limit, increase gap tolerance |
| Maximum recursion depth | Building big expr with chained | Use |
| QP rejected with MAXIMIZE | QP only supports MINIMIZE | Negate the objective: minimize |
| QP returns non-optimal | Q not PSD or variables badly scaled | Check Q is PSD; rescale variables to similar magnitudes |
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 状态始终不为"Optimal" | 使用了错误的大小写 | 使用 |
| 整数变量出现分数值 | 被定义为CONTINUOUS | 使用 |
| 无解(Infeasible) | 约束条件冲突 | 检查约束逻辑 |
| 无界(Unbounded) | 缺少变量边界 | 添加变量边界 |
| 求解缓慢 | 问题规模过大 | 设置时间限制、增大间隙容差 |
| 达到最大递归深度 | 使用链式 | 使用 |
| QP请求MAXIMIZE被拒绝 | QP仅支持MINIMIZE | 对目标函数取反:最小化 |
| QP返回非最优解 | Q矩阵非半正定或变量缩放不合理 | 检查Q矩阵是否为半正定;将变量缩放到相似数量级 |
Getting Dual Values (LP only)
获取对偶值(仅LP支持)
python
if problem.Status.name == "Optimal":
constraint = problem.getConstraint("resource_a")
shadow_price = constraint.DualValue
print(f"Shadow price: {shadow_price}")python
if problem.Status.name == "Optimal":
constraint = problem.getConstraint("resource_a")
shadow_price = constraint.DualValue
print(f"Shadow price: {shadow_price}")Reference Models
参考模型
All reference models live in this skill's directory. Use them as reference when building new applications; do not edit them in place.
assets/所有参考模型都位于本技能的****目录中。构建新应用时可将其作为参考,但请勿直接修改。
assets/Minimal / canonical examples (LP, MILP, QP)
最简/标准示例(LP、MILP、QP)
| Model | Type | Description |
|---|---|---|
| lp_basic | LP | Minimal LP: variables, constraints, objective, solve |
| lp_duals | LP | Dual values and reduced costs |
| lp_warmstart | LP | PDLP warmstart for similar problems |
| milp_basic | MILP | Minimal MIP; includes incumbent callback example |
| milp_production_planning | MILP | Production planning with resource constraints |
| portfolio | QP | Minimize portfolio variance; budget and min-return constraints |
| least_squares | QP | Minimize (x-3)² + (y-4)² (closest point) |
| maximization_workaround | QP | Maximize quadratic via minimize -f(x) |
| 模型 | 类型 | 描述 |
|---|---|---|
| lp_basic | LP | 最简LP:变量、约束、目标函数、求解 |
| lp_duals | LP | 对偶值和缩减成本 |
| lp_warmstart | LP | 针对相似问题的PDLP热启动 |
| milp_basic | MILP | 最简MIP;包含可行解回调示例 |
| milp_production_planning | MILP | 带资源约束的生产计划 |
| portfolio | QP | 最小化投资组合方差;含预算和最小收益约束 |
| least_squares | QP | 最小化(x-3)² + (y-4)²(最近点) |
| maximization_workaround | QP | 通过最小化-f(x)实现二次目标最大化 |
Other reference
其他参考
| Model | Type | Description |
|---|---|---|
| mps_solver | LP/MILP | Solve any problem from standard MPS file format |
Quick command to list models: (from this skill's directory).
ls assets/| 模型 | 类型 | 描述 |
|---|---|---|
| mps_solver | LP/MILP | 求解标准MPS文件格式的任意问题 |
快速列出模型的命令: (在本技能目录下执行)。
ls assets/When to Escalate
何时升级处理
Use troubleshooting and diagnostic guidance if:
- Infeasible and you can't determine why
- Numerical issues
出现以下情况时,请使用故障排查和诊断指南:
- 问题无解且无法确定原因
- 数值问题