cuopt-multi-objective-exploration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Multi-Objective Exploration

多目标探索

cuOpt optimizes one objective per solve. Many real problems have several objectives that pull against each other — cost vs. service level, return vs. risk, makespan vs. overtime, distance vs. vehicle count. A single solve answers "what's optimal for one particular weighting," but it hides the tradeoff the user actually needs to see.
This skill turns a sequence of single-objective cuOpt solves into a Pareto frontier — the set of solutions where you can't improve one objective without giving up another — and gives the discipline to read it. It adds no solver features; it orchestrates the LP / MILP / QP solves already covered by the formulation and API skills.
cuOpt每次求解仅优化一个目标。许多实际问题存在多个相互冲突的目标——成本与服务水平、收益与风险、完工时间与加班时长、行驶距离与车辆数量。单次求解只能回答“针对某一特定权重下的最优解是什么”,但无法展现用户真正需要了解的权衡关系。
本技能将一系列单目标cuOpt求解转化为Pareto前沿——即无法在不牺牲其他目标的前提下优化任一目标的解集——并提供解读方法。它并未新增求解器功能,而是编排已有的LP / MILP / QP求解流程,这些求解的构建与API调用已在公式与API技能中覆盖。

When this applies

适用场景

Reach for this workflow when the problem has two or more objectives with no agreed-upon weighting, signalled by language like:
  • "balance X and Y", "trade off", "as cheap as possible without hurting service"
  • "minimize cost and maximize coverage", "I want options, not one answer"
  • any objective the user is willing to relax in exchange for another
If there is a single clear objective (everything else is a hard constraint), this skill does not apply — formulate and solve once.
当问题存在两个或多个无既定权重的目标时,可采用此工作流,典型信号包括:
  • “平衡X与Y”、“权衡取舍”、“尽可能降低成本且不影响服务质量”
  • “最小化成本同时最大化覆盖范围”、“我需要多种方案,而非单一答案”
  • 用户愿意为优化某一目标而放宽另一目标的任何场景
若问题仅有一个明确目标(其余均为硬约束),则不适用本技能——直接构建模型并单次求解即可。

Core idea — one solve is one point on a curve

核心思路——单次求解对应曲线上的一个点

A single optimum encodes one implicit weighting of the objectives. Change the weighting and the optimum moves. The frontier is the curve traced by all the non-dominated optima.
A solution A dominates B when A is at least as good on every objective and strictly better on one. Dominated solutions are never worth choosing. The Pareto frontier is exactly the non-dominated set; the user's job is to pick a point on it, and yours is to show them the whole curve plus where the tradeoff is sharpest.
Do not collapse a multi-objective problem to a single weighted number and report its optimum as "the answer" — that silently makes the tradeoff decision for the user. Trace the frontier and let them choose.
Objectives and constraints are interchangeable. A requirement currently treated as fixed — a coverage floor, a fairness cap, a budget — is often a latent objective: its level was assumed, not given. Promoting such a constraint to a parametric ε-constraint and sweeping it reveals a tradeoff you'd otherwise hide, so read a single-objective model's hard constraints as candidate objectives, not just limits — but only when the level was an assumption. A genuinely fixed, non-negotiable limit (a hard budget cap, a regulatory minimum) stays a constraint; don't manufacture a tradeoff that isn't there. Express any promoted quantity linearly so it can serve as an ε-constraint (see
cuopt-numerical-optimization-formulation
).
单个最优解隐含了目标间的一种权重分配。改变权重,最优解位置也会随之变化。Pareto前沿就是所有非支配最优解构成的曲线。
当解A在所有目标上至少与解B表现相当,且在至少一个目标上严格更优时,称解A支配解B。被支配的解毫无选择价值。Pareto前沿正是所有非支配解的集合;用户的任务是从中选择一个点,而你的任务是展示整条曲线以及权衡关系最尖锐的区域。
切勿将多目标问题简化为单一加权数值并将其最优解作为“最终答案”——这相当于替用户默默做出了权衡决策。应追踪Pareto前沿,让用户自行选择。
目标与约束可相互转换。当前被视为固定值的要求——如覆盖下限、公平性上限、预算——往往是潜在目标:其取值是假设的,而非给定的。将此类约束提升为参数化ε约束并进行遍历,可揭示原本被隐藏的权衡关系。因此,应将单目标模型中的硬约束视为候选目标,而非仅作为限制条件——但仅适用于取值为假设的情况。真正固定、不可协商的限制(如硬性预算上限、法规要求的最小值)仍应作为约束;不要虚构不存在的权衡关系。将任何被提升的约束表示为线性形式,使其可作为ε约束(详见
cuopt-numerical-optimization-formulation
)。

Step 1 — define the objectives

步骤1——定义目标

An informative frontier needs objectives that genuinely conflict: if they don't pull against each other, it collapses to a single point with nothing to trade off. And each objective has to be formulated correctly, since a wrong form, sense, or scale distorts the tradeoff and shifts where the knee falls. Formulate each one with
cuopt-numerical-optimization-formulation
before sweeping.
有价值的Pareto前沿要求目标间存在真实冲突:若目标间无相互制约,前沿会坍缩为单一点,不存在权衡空间。此外,每个目标必须正确构建,错误的形式、方向或规模会扭曲权衡关系,并改变“拐点”的位置。在遍历前,需使用
cuopt-numerical-optimization-formulation
构建每个目标。

Step 2 — build a payoff table (anchor each objective)

步骤2——构建收益表(锚定每个目标)

Solve each objective on its own first. For k objectives this is k solves. Record, for each, the value of every objective at that optimum:
text
              f1        f2        f3
min f1   →   f1*       f2(at f1*) f3(at f1*)
min f2   →   ...       f2*        ...
min f3   →   ...       ...        f3*
The diagonal (
f1*
,
f2*
, …) is each objective's best achievable value; the off-diagonals give the range each objective spans across the others' optima. This table does double duty:
  • It sets the sweep bounds for the ε-constraint method (the feasible range of each constrained objective).
  • It supplies the scales for normalization — objectives in dollars, percent, and hours can't be weighted meaningfully until divided by their ranges.
If any single-objective solve is already infeasible, stop and fix the model before sweeping — the frontier doesn't exist yet.
首先单独求解每个目标。对于k个目标,需执行k次求解。记录每个最优解下所有目标的取值:
text
              f1        f2        f3
min f1   →   f1*       f2(at f1*) f3(at f1*)
min f2   →   ...       f2*        ...
min f3   →   ...       ...        f3*
对角线值(
f1*
,
f2*
, …)是每个目标可达到的最优值;非对角线值给出了每个目标在其他目标最优解下的取值范围。该表有双重作用:
  • 为ε约束法设置遍历边界(每个被约束目标的可行范围)。
  • 提供归一化的尺度——以美元、百分比、小时为单位的目标,需先除以各自的取值范围,才能进行有意义的加权。
若任一单目标求解不可行,需先修正模型再进行遍历——此时Pareto前沿不存在。

Step 3 — choose a scalarization

步骤3——选择标量化方法

Weighted sum

加权和法

Combine the objectives into one and sweep the weights:
text
minimize  w1·f1(x) + w2·f2(x) + ... ,   for a grid of weight vectors w
Cheap and trivial with any solver. Two limitations to respect:
  • It only finds points on the convex hull of the frontier. Concave (non-convex) regions of the frontier are unreachable no matter how you choose weights, and for MILP the reachable points can be sparse with large gaps. A frontier that looks suspiciously linear or has only a few clustered points is the symptom.
  • Weights are not priorities until the objectives are normalized. Divide each
    f_k
    by its payoff-table range first; otherwise the largest-magnitude objective dominates regardless of intent.
将多个目标合并为一个目标,并遍历权重:
text
minimize  w1·f1(x) + w2·f2(x) + ... ,   针对一系列权重向量w
该方法适用于任何求解器,成本低且实现简单。但需注意两个局限性:
  • 仅能找到前沿凸包上的点。前沿的凹(非凸)区域无论如何选择权重都无法触及;对于MILP问题,可触及的点可能稀疏且存在较大间隙。若前沿看似异常线性或仅有少数聚集点,即为该问题的表现。
  • 目标归一化前,权重不等同于优先级。需先将每个
    f_k
    除以其在收益表中的取值范围;否则,数值量级最大的目标会无视意图主导结果。

ε-constraint (preferred for a complete frontier)

ε约束法(推荐用于获取完整前沿)

Keep one objective; move the rest to constraints and sweep their right-hand sides:
text
minimize  f1(x)
subject to  f2(x) ≤ ε2
            f3(x) ≤ ε3
            (original constraints)
Sweep each
ε_k
across the range from the payoff table. Each
(ε2, ε3, …)
combination is a single standard cuOpt solve. This recovers the full frontier, including the concave regions weighted-sum cannot reach, which is why it's the default when completeness matters. The cost is more solves (a grid over the constrained objectives) and bookkeeping of the ε values.
ε-constrain linear objectives directly. A quadratic objective (e.g. risk
xᵀΣx
) is simplest kept as the objective
f1
while you ε-constrain the linear ones. A convex quadratic objective can instead be ε-constrained directly: add it as a quadratic constraint
xᵀQx ≤ ε
, which cuOpt supports. Non-convex or equality quadratic constraints are unsupported, and the MILP path stays linear-constraint only.
Spot it in existing code: a hand-coded loop over a target or budget value (a return target, a cost cap) is already the ε-constraint method — name it as such, filter dominated points, and read the swept constraint's dual (LP/QP only).
Read that dual as the local exchange rate. Where the frontier is smooth, the dual on a swept ε-constraint is its slope — how much the kept objective
f1
moves per unit of the bound — at no cost beyond the solve already run; at a kink it gives only a one-sided rate. A zero dual means the bound is slack: the sweep has run past the frontier's edge. This reading needs LP/QP and a linear ε-constraint (MILP optima and problems with quadratic constraints return no duals) — where duals are unavailable, difference adjacent frontier points instead.
Picking a method: weighted-sum for a quick convex sketch or when you know the frontier is convex (e.g. a pure-LP/QP tradeoff); ε-constraint when the problem is MILP, when the frontier may be non-convex, or when the user needs a faithful and complete curve.
保留一个目标,将其余目标转为约束并遍历其右侧取值:
text
minimize  f1(x)
subject to  f2(x) ≤ ε2
            f3(x) ≤ ε3
            (原始约束)
遍历每个
ε_k
在收益表中的取值范围。每个
(ε2, ε3, …)
组合对应一次标准cuOpt求解。该方法可还原完整前沿,包括加权和法无法触及的凹区域,因此在需要完整性时是默认选择。代价是需要更多求解次数(对被约束目标进行网格遍历)以及对ε值的记录管理。
直接对线性目标应用ε约束。对于二次目标(如风险
xᵀΣx
),最简单的方式是将其保留为目标
f1
,同时对线性目标应用ε约束。二次目标也可直接应用ε约束:将其作为二次约束
xᵀQx ≤ ε
添加,cuOpt支持该操作。非凸或等式二次约束不受支持,MILP路径仅支持线性约束。
在现有代码中识别该方法:手动遍历目标值或预算值(如收益目标、成本上限)的循环本质上就是ε约束法——明确命名该方法,过滤被支配点,并读取遍历约束的对偶值(仅LP/QP支持)。
将对偶值解读为局部兑换率。当前沿平滑时,遍历ε约束的对偶值即为其斜率——每单位约束边界变化时,保留目标
f1
的变化量——无需额外求解即可获取;在拐点处,仅能获取单侧兑换率。对偶值为零意味着约束边界松弛:遍历已超出前沿范围。该解读仅适用于LP/QP及线性ε约束(MILP最优解及含二次约束的问题不返回对偶值)——当无法获取对偶值时,可通过相邻前沿点的差值估算。
方法选择:若需快速绘制凸性草图,或已知前沿为凸形(如纯LP/QP权衡问题),选用加权和法;若问题为MILP、前沿可能非凸,或用户需要真实完整的曲线,选用ε约束法。

Step 4 — sweep, collect, and filter

步骤4——遍历、收集与过滤

text
frontier = []
for each weight vector (or ε vector) in the grid:
    set the combined objective (or ε right-hand sides)
    solve with cuOpt              # reuse the prior solution as a warm start
    if status is Optimal/Feasible:
        record (objective values, solution)
discard dominated and duplicate points
sort the survivors to form the frontier
Practical notes:
  • Warm-start LP sweeps. For an LP frontier, carry the previous solve's PDLP warmstart data into the next to cut solve time. Per cuOpt this is LP-only: a MILP solve doesn't take a PDLP warmstart (you can optionally seed a MIP start instead). See
    cuopt-numerical-optimization-api
    for the calls.
  • Cap each MILP solve. Set a per-solve time limit on MILP sweeps (see
    cuopt-numerical-optimization-api
    ) — a sweep is many solves, and branch-and-bound can over-spend certifying optimality past a tiny gap, while cuOpt sets no limit by default and won't warn. Report the points as optimal to the gap you set, not certified optimal.
  • Filter dominated points. A correct sweep can still emit dominated points (especially weighted-sum near the hull, or MILP). Drop them; they are not part of the frontier.
  • Resolution is a budget. Curve fidelity trades against solve count. Start coarse to see the shape, then refine the grid only where the curve bends.
  • Spend the budget where the slope changes (LP/QP). Because the ε-constraint dual is the frontier's local slope, compare it across solved points: where it barely changes, the curve is nearly straight — interpolate rather than add solves; where it jumps by more than the solve tolerance, the frontier bends between those points — refine there (smaller differences are solver noise, not curvature). This concentrates solves where the curve actually bends instead of spreading them over a uniform grid. On MILP, judge where to refine from the gaps between primal objective values instead.
  • Verify, don't assume. When you claim one method beats another, measure it — e.g. count the efficient points ε-constraint recovered that weighted-sum missed — rather than asserting it; and flag any solve returning feasible-but-not-
    Optimal
    so a non-certified point is never read as exact.
text
frontier = []
for each weight vector (or ε vector) in the grid:
    设置合并目标(或ε约束右侧值)
    使用cuOpt求解              # 复用前一次求解结果作为暖启动
    if 求解状态为Optimal/Feasible:
        记录(目标取值,解)
丢弃被支配点与重复点
对剩余点排序以形成前沿
实用注意事项:
  • LP遍历的暖启动。对于LP前沿,将前一次求解的PDLP暖启动数据带入下一次求解,可减少求解时间。根据cuOpt的规则,这仅适用于LP:MILP求解不支持PDLP暖启动(可选择性提供MIP初始解)。详见
    cuopt-numerical-optimization-api
    中的调用方法。
  • 限制每次MILP求解时间。在MILP遍历中设置单次求解时间限制(详见
    cuopt-numerical-optimization-api
    )——遍历包含多次求解,分支定界法可能在极小间隙后过度消耗时间以验证最优性,而cuOpt默认无时间限制且不会发出警告。需将这些点报告为“在设置的间隙内最优”,而非“经过验证的最优”。
  • 过滤被支配点。即使是正确的遍历仍可能输出被支配点(尤其在加权和法靠近凸包时,或MILP问题中)。需丢弃这些点,它们不属于前沿。
  • 分辨率是一种预算。曲线精度与求解次数需权衡。先采用粗粒度网格观察曲线形状,仅在曲线弯曲处细化网格。
  • 在斜率变化处分配预算(LP/QP)。由于ε约束的对偶值是前沿的局部斜率,可比较不同求解点的对偶值:对偶值变化极小处,曲线近乎直线——可采用插值而非新增求解;对偶值变化超过求解容差处,前沿在两点间发生弯曲——需在此处细化网格(较小的变化属于求解器噪声,而非曲率)。这种方式可将求解次数集中在曲线实际弯曲的区域,而非均匀分布在整个网格上。对于MILP问题,可根据原始目标值的间隙判断细化位置。
  • 验证而非假设。当声称一种方法优于另一种时,需进行测量——例如统计ε约束法恢复但加权和法遗漏的有效点数量——而非直接断言;同时标记任何返回“可行但非Optimal”的求解,避免将未验证的点视为精确解。

Step 5 — interpret the frontier

步骤5——解读前沿

  • Report tradeoffs, not single numbers. A frontier point means nothing in isolation. Quote the exchange rate — "≈ $4k of extra cost per 1% of added coverage in this region" — so the user can judge whether a move is worth it. On an LP/QP frontier this exchange rate is the swept constraint's dual at that point — the local slope of the frontier, accurate to the solve's optimality tolerance (tighten it before relying on a dual); on MILP, estimate it from the gap to the adjacent frontier point.
  • Flag knee points; don't auto-pick them. The "knee" is where the curve bends most sharply — beyond it you pay a lot for a little. It's often the best-balanced compromise and worth highlighting, but the final choice is the user's preference, not a rule. At the knee the slope is two-sided — the dual just below differs from just above — so quote the exchange rate there as a range, not one number.
  • Treat dominated or gappy output as a diagnostic. If dominated points survive filtering, or the frontier is implausibly sparse or perfectly linear, suspect the sweep or the model — most often weighted-sum hiding a concave region (switch to ε-constraint) or a normalization mistake.
  • State the weighting/ε you used. Every reported point is conditional on its scalarization. Make that explicit so a single solve is never mistaken for "the" optimum. On LP/QP, the ε-constraint duals are the implicit weights at that point — the effective price the solution puts on each constrained objective, and the weights a weighted-sum solve would need to reproduce that tradeoff. Reporting them makes the accepted tradeoff ratio explicit.
  • 报告权衡关系,而非单一数值。孤立的前沿点毫无意义。需给出兑换率——例如“在该区域,每提升1%的覆盖范围,需额外花费约4000美元”——以便用户判断是否值得做出取舍。对于LP/QP前沿,该兑换率即为该点处遍历约束的对偶值——前沿的局部斜率,精度等同于求解的最优性容差(依赖对偶值前需收紧容差);对于MILP问题,可通过相邻前沿点的间隙估算。
  • 标记拐点,但不要自动选择。“拐点”是曲线弯曲最剧烈的位置——越过该点后,需付出极高代价才能获得微小提升。它通常是最平衡的折中方案,值得重点关注,但最终选择取决于用户偏好,而非规则。在拐点处,斜率是双侧的——拐点下方的对偶值与上方不同——因此此处的兑换率应报告为范围,而非单一数值。
  • 将被支配或间隙较大的输出视为诊断信号。若过滤后仍存在被支配点,或前沿异常稀疏、完全线性,需怀疑遍历过程或模型存在问题——最常见的情况是加权和法隐藏了凹区域(需切换至ε约束法),或归一化错误。
  • 明确说明所使用的权重/ε值。每个报告的点都依赖于其标量化方法。需明确这一点,避免将单次求解误认为“唯一”最优解。对于LP/QP问题,ε约束的对偶值是该点处的隐含权重——即解对每个被约束目标的有效定价,也是加权和法求解重现该权衡关系所需的权重。报告这些值可明确已接受的权衡比率。

Interfaces

接口

This skill is solver- and interface-agnostic. The per-solve mechanics — building the objective, adding the ε constraints, passing a warm start, reading status — live in the API skills:
  • cuopt-numerical-optimization-api
    — LP, MILP, QP solves (Python, C, CLI).
  • cuopt-routing-api-python
    — the same frontier workflow applies to routing tradeoffs (distance vs. vehicles vs. time).
本技能与求解器及接口无关。单次求解的具体机制——构建目标、添加ε约束、传递暖启动数据、读取求解状态——均在API技能中:
  • cuopt-numerical-optimization-api
    ——LP、MILP、QP求解(Python、C、CLI)。
  • cuopt-routing-api-python
    ——相同的前沿工作流适用于路径规划权衡问题(距离与车辆数量与时间的权衡)。