关于 cuopt-numerical-optimization-api-python
cuopt-numerical-optimization-api-python 是使用 NVIDIA cuOpt Python API 建模和求解优化问题的技能,面向需要处理线性、混合整数线性或二次规划的开发者。它提供问题类型选择、建模模式、求解状态检查及常见问题指导。
主要功能
- 01构建 LP、MILP 和 QP 模型
- 02按目标函数与变量选择问题类型
- 03设置求解器参数与时间限制
- 04检查求解状态及 LP/QP 对偶值
- 05参考常见建模模式与示例模型
适用场景
- 01制定资源约束下的生产计划
- 02选择设施或分配人员等离散决策
- 03求解投资组合方差或最小二乘问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nvidia/ skills --skill cuopt-numerical-optimization-api-python安装后在 Claude Code 中输入/cuopt-numerical-optimization-api-python确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
BENCHMARK.mdskill-card.mdskill.oms.sigassets/README.mdassets/least_squares/model.pyREADME.mdassets/lp_basic/model.pyREADME.mdassets/lp_duals/model.pyREADME.mdassets/lp_warmstart/model.pyREADME.mdassets/maximization_workaround/model.pyREADME.mdassets/milp_basic/incumbent_callback.pymodel.pyREADME.mdassets/milp_production_planning/model.pyREADME.mdassets/mps_solver/model.pyREADME.mdresults.mdassets/mps_solver/data/README.mdsample.mpsassets/portfolio/model.pyREADME.mdbenchmark/evals.jsonSOURCES.mdevals/evals.jsonreferences/qp_examples.md详细介绍
cuOpt 数值优化技能(Python)
使用 NVIDIA cuOpt 的 GPU 加速求解器对 LP、MILP 和 QP 问题建模并求解。三类问题共用同一套 Python API(Problem、SolverSettings、solve),只有目标函数形式和少数规则有所不同。
开始之前
如果有问题摘要(参数、约束、决策、目标),请使用;否则,请询问决策变量、目标和约束。然后确认问题类型(LP / MILP / QP,见下文)和变量类型。
选择 LP、MILP 还是 QP
根据目标函数和变量进行判断:
| 如果目标函数是…… | 且变量是…… | 使用 |
|---|---|---|
线性(c_i * x_i 之和) | 全部为连续变量 | LP |
| 线性 | 部分为整数或二进制变量 | MILP |
含平方项(x*x)或交叉项(x*y) | 连续变量(不支持整数 QP) | QP(beta) |
问题允许时优先使用 LP。 LP 求解速度更快,最优性保证也更强。只有当问题在逻辑上要求整数或是/否决策时,才使用 MILP。只有当目标函数确实是二次函数(方差、平方误差、动能)时,才使用 QP。
需要格外留意的问题类型: 多期规划和目标规划很容易被误解。请仔细确认费率和约束适用于正确的时间段或优先级(AGENTS.md:编码前确认理解无误)。
- 使用 LP:当每个数量都可以有意义地取小数时,例如流量、比例、费率、金额、小时数、吨材料等。
- 使用 MILP:当问题提到离散实体的数量、是/否选择或二选一决策时(例如,是否开放设施、安排人员上班次、卡车数量)。
- 使用 QP:当目标是最小化方差、平方误差,或包含
x*x或x*y项的任何表达式时(投资组合优化、最小二乘、正则化回归)。
根据措辞判断整数变量与连续变量
根据问题描述选择变量类型。
| 问题措辞 / 概念 | 变量类型 | 示例 |
|---|---|---|
| 离散实体(数量) | INTEGER | 工人、汽车、卡车、机器、飞行员、设施、待制造的单位(当“单位”指完整物品时)、实习生、车辆 |
| 是/否或开/关 | INTEGER(二进制,lb=0 ub=1) | 开放设施、运行机器、生产某条产品线、安排人员上班次 |
| 可取小数的数量 | CONTINUOUS | 吨、升、金额、小时、kWh、容量占比、流量、重量 |
| 费率或比例 | CONTINUOUS | 利用率、百分比、预算份额 |
| 不明确 | 如果名词表示可计数的事物(如工人、汽车),优先选择 INTEGER;如果表示一种度量(如钢材用量、工作小时数),则优先选择 CONTINUOUS。如果问题中出现“整”“整数”或“数量”,则使用 INTEGER。 |
经验法则: 如果问的是“有多少个事物”(人、车辆、物品、站点),使用 INTEGER。如果问的是“有多少”(质量、体积、金钱、时间)或费率,则使用 CONTINUOUS,除非问题明确要求使用整数。
快速参考:Python API
LP 示例
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MAXIMIZE
from cuopt.linear_programming.solver_settings import SolverSettings
# Create problem
problem = Problem("MyLP")
# Decision variables
x = problem.addVariable(lb=0, vtype=CONTINUOUS, name="x")
y = problem.addVariable(lb=0, vtype=CONTINUOUS, name="y")
# Constraints
problem.addConstraint(2*x + 3*y <= 120, name="resource_a")
problem.addConstraint(4*x + 2*y <= 100, name="resource_b")
# Objective
problem.setObjective(40*x + 30*y, sense=MAXIMIZE)
# Solve
settings = SolverSettings()
settings.set_parameter("time_limit", 60)
problem.solve(settings)
# 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()}")
MILP 示例(含整数变量)
from cuopt.linear_programming.problem import Problem, CONTINUOUS, INTEGER, MINIMIZE
problem = Problem("FacilityLocation")
# Binary variable (integer with bounds 0-1)
open_facility = problem.addVariable(lb=0, ub=1, vtype=INTEGER, name="open")
# Continuous variable
production = problem.addVariable(lb=0, vtype=CONTINUOUS, name="production")
# Linking constraint: can only produce if facility is open
problem.addConstraint(production <= 1000 * open_facility, name="link")
# Objective: fixed cost + variable cost
problem.setObjective(500*open_facility + 2*production, sense=MINIMIZE)
# 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)
# Check status
if problem.Status.name in ["Optimal", "FeasibleFound"]:
print(f"Open facility: {open_facility.getValue() > 0.5}")
print(f"Production: {production.getValue()}")
QP 示例(beta — 仅限 MINIMIZE)
from cuopt.linear_programming.problem import Problem, CONTINUOUS, MINIMIZE
from cuopt.linear_programming.solver_settings import SolverSettings
# 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")
# Quadratic objective (variance) — MUST be MINIMIZE
problem.setObjective(
0.04*x1*x1 + 0.02*x2*x2 + 0.01*x3*x3
+ 0.02*x1*x2 + 0.01*x1*x3 + 0.016*x2*x3,
sense=MINIMIZE,
)
# Linear constraints
problem.addConstraint(x1 + x2 + x3 == 1, name="budget")
problem.addConstraint(0.12*x1 + 0.08*x2 + 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(半正定),以保证问题为凸问题;否则,求解器可能返回非最优驻点。
- Beta — API 可能会演进;对于典型的凸 QP,可按生产就绪的功能使用,但要预期偶尔会有变化。
请参阅 references/qp_examples.md,了解最小二乘、最大化变通方案和矩阵形式示例。
关键:检查状态
状态值使用 PascalCase,而非全大写:
# ✅ CORRECT
if problem.Status.name in ["Optimal", "FeasibleFound"]:
print(problem.ObjValue)
# ❌ WRONG - will silently fail!
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 是否为半正定矩阵,以及变量的缩放是否合理。
常见建模模式
二元选择
# Select exactly k items from n
items = [problem.addVariable(lb=0, ub=1, vtype=INTEGER) for _ in range(n)]
problem.addConstraint(sum(items) == k)
Big-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))
If-then“必须同时生产”
当问题表述为如果我们做 X,那么还必须做 Y时,请同时施加(i)二元变量关联约束,以及(ii)确保实际生产 Y 的约束:
# y_X <= y_Y (if we do X, we must "do" 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
problem.addConstraint(production_Y >= 1 * y_Y) # or min_amount * y_Y
否则,求解器可以令 y_Y=1,但 production_Y=0。这样虽满足二元变量关联约束,却不符合预期。
构建大型表达式
API 中对许多项连续使用 + 可能会触及递归限制。构建目标函数和约束时,优先使用 LinearExpression:
from cuopt.linear_programming.problem import LinearExpression
# Build as list of (vars, coeffs) instead of v1*c1 + v2*c2 + ...
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/ 目录中的参考模型示例。
分段线性(SOS2)
# Approximate nonlinear function with breakpoints
# Use lambda variables that sum to 1, at most 2 adjacent non-zero
求解器设置
settings = SolverSettings()
# Time limit
settings.set_parameter("time_limit", 60)
# MILP gap tolerance (stop when within X% of optimal)
settings.set_parameter("mip_relative_gap", 0.01)
# Logging
settings.set_parameter("log_to_console", 1)
常见问题
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 状态从未为 "OPTIMAL" | 大小写错误 | 使用 "Optimal",而非 "OPTIMAL" |
| 整数变量的值是小数 | 定义为 CONTINUOUS | 使用 vtype=INTEGER |
| 不可行 | 约束冲突 | 检查约束逻辑 |
| 无界 | 缺少边界 | 添加变量边界 |
| 求解缓慢 | 问题规模过大 | 设置时间限制,提高间隙容差 |
| 达到最大递归深度 | 使用连续的 + 构建大型表达式 | 使用 LinearExpression(vars_list, coeffs_list, constant) |
| QP 因 MAXIMIZE 被拒绝 | QP 仅支持 MINIMIZE | 对目标函数取负:最小化 -f(x) |
| QP 返回非最优结果 | Q 不是半正定矩阵,或变量缩放不佳 | 检查 Q 是否为半正定矩阵;重新缩放变量,使其量级相近 |
获取对偶值(LP / QP)
LP 和 QP 会返回对偶值和约化成本。带二次约束的问题不会返回这些值(所有值都会变成 NaN),因此只有在所有约束都是线性约束时才读取它们。MILP 不会返回对偶值。
if problem.Status.name == "Optimal":
constraint = problem.getConstraint("resource_a") # linear constraint
print(f"Dual value: {constraint.DualValue}") # NaN if the model has quadratic constraints
参考模型
所有参考模型都位于此技能的 assets/ 目录中。构建新应用时,请将其用作参考;不要直接修改这些模型。
最小化 / 规范示例(LP、MILP、QP)
| 模型 | 类型 | 描述 |
|---|---|---|
| lp_basic | LP | 最小化 LP:变量、约束、目标函数、求解 |
| lp_duals | LP | 对偶值和约化成本 |
| lp_warmstart | LP | 用于相似问题的 PDLP 热启动 |
| milp_basic | MILP | 最小化 MIP;包含 incumbent 回调示例 |
| milp_production_planning | MILP | 带资源约束的生产计划 |
| portfolio | QP | 最小化投资组合方差;包含预算和最低收益约束 |
| least_squares | QP | 最小化 (x-3)² + (y-4)²(最近点) |
| maximization_workaround | QP | 通过最小化 -f(x) 实现二次函数最大化 |
其他参考
| 模型 | 类型 | 描述 |
|---|---|---|
| mps_solver | LP/MILP | 求解任意标准 MPS 文件格式的问题 |
列出模型的快速命令: ls assets/(在此技能目录中运行)。
何时升级处理
遇到以下情况时,请使用故障排查和诊断指导:
- 问题不可行,且无法确定原因
- 数值问题