cuopt-numerical-optimization-api-python

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

cuOpt 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 (
Problem
,
SolverSettings
,
solve
) is shared across all three problem classes — only the objective form and a few rules change.
使用NVIDIA cuOpt的GPU加速求解器建模并求解LP、MILP和QP问题。三种问题类型共享Python API接口(
Problem
SolverSettings
solve
)——仅目标形式和少数规则有所不同。

Before 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
c_i * x_i
)
All continuousLP
LinearSome integer or binaryMILP
Has squared (
x*x
) or cross (
x*y
) terms
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
    x*x
    or
    x*y
    terms (portfolio optimization, least squares, regularized regression).
根据目标函数和变量类型判断:
若目标为...且变量为...使用
线性(
c_i * x_i
的和)
全部为连续型LP
线性部分为整数或二进制MILP
包含平方项(
x*x
)或交叉项(
x*y
连续型(不支持整数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 / conceptVariable typeExamples
Discrete entities (counts)INTEGERWorkers, cars, trucks, machines, pilots, facilities, units to manufacture (when "units" means whole items), trainees, vehicles
Yes/no or on/offINTEGER (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 fractionalCONTINUOUSTonnes, litres, dollars, hours, kWh, proportion of capacity, flow volume, weight
Rates or fractionsCONTINUOUSUtilization, percentage, share of budget
UnclearPrefer 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 SolverSettings
python
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MAXIMIZE
from cuopt.linear_programming.solver_settings import SolverSettings

Create 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()}")
undefined
if problem.Status.name in ["Optimal", "PrimalFeasible"]: print(f"Objective: {problem.ObjValue}") print(f"x = {x.getValue()}") print(f"y = {y.getValue()}")
undefined

MILP 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()}")
undefined
if problem.Status.name in ["Optimal", "FeasibleFound"]: print(f"Open facility: {open_facility.getValue() > 0.5}") print(f"Production: {production.getValue()}")
undefined

QP Example (beta — MINIMIZE only)

QP示例(测试版 — 仅支持MINIMIZE)

python
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MINIMIZE
from cuopt.linear_programming.solver_settings import SolverSettings
python
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MINIMIZE
from cuopt.linear_programming.solver_settings import SolverSettings

Portfolio 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
undefined
python
undefined

Select 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)
undefined
items = [problem.addVariable(lb=0, ub=1, vtype=INTEGER) for _ in range(n)] problem.addConstraint(sum(items) == k)
undefined

Big-M Linking

Big-M关联约束

python
undefined
python
undefined

If 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))
undefined
M = 10000 problem.addConstraint(x <= 100 + M*(1 - y))
undefined

If-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
undefined

y_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 LinearExpression

Build 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
undefined
python
undefined

Approximate 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

undefined
undefined

Solver 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)
undefined
settings.set_parameter("log_to_console", 1)
undefined

Common Issues

常见问题

ProblemLikely CauseFix
Status never "OPTIMAL"Using wrong caseUse
"Optimal"
not
"OPTIMAL"
Integer var has fractional valueDefined as CONTINUOUSUse
vtype=INTEGER
InfeasibleConflicting constraintsCheck constraint logic
UnboundedMissing boundsAdd variable bounds
Slow solveLarge problemSet time limit, increase gap tolerance
Maximum recursion depthBuilding big expr with chained
+
Use
LinearExpression(vars_list, coeffs_list, constant)
QP rejected with MAXIMIZEQP only supports MINIMIZENegate the objective: minimize
-f(x)
QP returns non-optimalQ not PSD or variables badly scaledCheck Q is PSD; rescale variables to similar magnitudes
问题可能原因解决方法
状态始终不为"Optimal"使用了错误的大小写使用
"Optimal"
而非
"OPTIMAL"
整数变量出现分数值被定义为CONTINUOUS使用
vtype=INTEGER
无解(Infeasible)约束条件冲突检查约束逻辑
无界(Unbounded)缺少变量边界添加变量边界
求解缓慢问题规模过大设置时间限制、增大间隙容差
达到最大递归深度使用链式
+
构建大型表达式
使用
LinearExpression(vars_list, coeffs_list, constant)
QP请求MAXIMIZE被拒绝QP仅支持MINIMIZE对目标函数取反:最小化
-f(x)
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
assets/
directory. Use them as reference when building new applications; do not edit them in place.
所有参考模型都位于本技能的**
assets/
**目录中。构建新应用时可将其作为参考,但请勿直接修改。

Minimal / canonical examples (LP, MILP, QP)

最简/标准示例(LP、MILP、QP)

ModelTypeDescription
lp_basicLPMinimal LP: variables, constraints, objective, solve
lp_dualsLPDual values and reduced costs
lp_warmstartLPPDLP warmstart for similar problems
milp_basicMILPMinimal MIP; includes incumbent callback example
milp_production_planningMILPProduction planning with resource constraints
portfolioQPMinimize portfolio variance; budget and min-return constraints
least_squaresQPMinimize (x-3)² + (y-4)² (closest point)
maximization_workaroundQPMaximize quadratic via minimize -f(x)
模型类型描述
lp_basicLP最简LP:变量、约束、目标函数、求解
lp_dualsLP对偶值和缩减成本
lp_warmstartLP针对相似问题的PDLP热启动
milp_basicMILP最简MIP;包含可行解回调示例
milp_production_planningMILP带资源约束的生产计划
portfolioQP最小化投资组合方差;含预算和最小收益约束
least_squaresQP最小化(x-3)² + (y-4)²(最近点)
maximization_workaroundQP通过最小化-f(x)实现二次目标最大化

Other reference

其他参考

ModelTypeDescription
mps_solverLP/MILPSolve any problem from standard MPS file format
Quick command to list models:
ls assets/
(from this skill's directory).
模型类型描述
mps_solverLP/MILP求解标准MPS文件格式的任意问题
快速列出模型的命令:
ls assets/
(在本技能目录下执行)。

When to Escalate

何时升级处理

Use troubleshooting and diagnostic guidance if:
  • Infeasible and you can't determine why
  • Numerical issues
出现以下情况时,请使用故障排查和诊断指南:
  • 问题无解且无法确定原因
  • 数值问题