# 选择求解路径

四个公开入口共用 `OptModel`，但拥有不同的模型兼容性和配置。显式入口不自动互相回退。

## 路径对照

| 路径 | 接受的模型 | 额外依赖 | 不兼容时 |
| --- | --- | --- | --- |
| 本地搜索 `solve()` | 标量、集合、序列、区间及外部函数等搜索模型 | 内置原生内核 | 报告失败或抛出对应异常 |
| OptX `solve_optx()` | HiGHS 精确 MILP 转换 / 连续凸 QP | 内置 HiGHS | `OptxUnsupportedError`，附带问题位置 |
| CP-SAT `solve_cpsat()` | 可转换的整数兼容、有限域模型 | `optagent[ortools]` | 违反转换约定时 `ValueError` |
| MathOpt `solve_mathopt()` | 可转换且所选后端可处理的模型 | `optagent[ortools]` | 违反转换或后端约定时 `ValueError` |

CP-SAT 与 MathOpt 路径会先编译模型，再交给 OR-Tools，最后按原模型验证候选。支持部分集合、序列、区间与表达式的有限域展开，并不意味着支持任意模型；变量域、展开规模、算子和所选后端仍有限制。外部 Python 函数应使用本地搜索路径。

## 本地搜索如何使用模型

内核根据声明的集合关系、序列、时间与数值依赖生成候选，并通过原模型评价。结构化修复会联动分配、顺序和时间，无法利用的结构仍交给通用搜索处理。

这些机制不要求用户选择“调度模式”或特定问题模板。结构化修复只提出候选，不构成全局可行或最优证明。`feasible=False` 也不能单独证明模型无解。

## 配置时间预算

=== "本地搜索"

    ```python
    solution = model.solve(time_limit_s=10.0, log_level="off")
    ```

    默认 30 秒，包含序列化与原生编译。可选日志为 `off`、`on`（默认）、`debug`。

=== "OptX / HiGHS"

    ```python
    from optagent import OptxConfig

    solution = model.solve_optx(config=OptxConfig(time_limit=10.0))
    ```

    `time_limit` 覆盖原生模型解析、转换、求解及结果验证；Python 侧模型序列化不计入。停止为协作式检查，单次原生调用可能延后返回；当前 HiGHS QP 不提供中断回调，运行期间依靠原生时间上限停止。

=== "CP-SAT"

    ```python
    from optagent import CpSatConfig

    solution = model.solve_cpsat(
        config=CpSatConfig(num_search_workers=4),
        time_limit_s=10.0,
    )
    ```

    显式 `time_limit_s` 优先；否则读取 `config.max_time_in_seconds`，未配置时为 30 秒。

=== "MathOpt"

    ```python
    from optagent import MathOptConfig

    solution = model.solve_mathopt(
        config=MathOptConfig(solver_type="GSCIP"),
        time_limit_s=10.0,
    )
    ```

    显式 `time_limit_s` 优先；否则读取 `config.time_limit`，未配置时为 30 秒。

CP-SAT / MathOpt 的预算覆盖准备、序列化、转换、后端构造、求解和验证。验证前耗尽预算时返回 `UNKNOWN`，不发布未验证的变量值。取消是协作式的，单次原生调用或清理可能超过指定时刻。

## 目标阈值和外部评价次数

本地搜索与 OptX 支持 `objective_threshold`，用从零开始的目标索引映射到数值阈值，例如 `{0: 100}`。阈值必须有限，索引必须存在；OptX 的整数阈值还须落在 `[-2^53, 2^53]` 内。

本地搜索的 `external_evaluation_limit` 是可选的正整数，用于限制实际启动的外部回调次数，失败调用也计入；排队后取消、已知结果、缓存命中和合并等待不额外计费。默认 `None` 表示不设置该次数上限；它不替代时间预算。

[查询完整求解参数 →](../api/solve.md)

## OptX 的转换边界

OptX 复用共享建模语义，将有限集合、序列、整数区间、逻辑、索引、符号函数、分段线性表达式及有界离散非线性展开为 MILP。新增辅助列和约束受展开预算限制；条件行必须有可证明的有限界，生成系数必须通过数值检查。普通仿射模型保留原有无界变量支持。

原生 QP 支持显式标量连续凸二次最小化或凹二次最大化目标，约束须为线性，所有未固定变量须为连续变量。线性目标可以排在 QP 之前；QP 必须是最后优先级，以免锁定目标时产生二次约束。一般连续双线性约束、MIQP、非凸 QP、连续非线性函数和外部回调仍不支持。

多目标仅在前级证实最优且没有启用正 gap 时继续，以等式锁定前级线性目标；达到阈值、时间上限或 gap 停止不会升级为完整词典序最优。声明的初始值作为求解提示；返回值重建为原始决策类型，并在原模型中验证。OptX 使用内置 HiGHS，无需安装 OR-Tools extra。逐接口条件见[求解器支持矩阵](../api/solver-support.md)。
