# 求解与策略

`solve(...)` 是 kernel strategy 路径的公开入口。Direct exact API 用于调用方明确选择 CP-SAT、MILP 或 OptX 的场景；它们不会作为 `solve(...)` 的隐式 fallback。

<div class="api-note">
本页的调用形式省略 Python 的关键字参数分隔符。除第一个模型参数外，其余求解控制和配置均应按名称传入，例如 <code>solve(builder, strategy=GaConfig(), time_limit_s=10)</code>。
</div>

## Strategy solve

<span id="optagent.solve"></span>

<code class="api-call">solve(model_or_program, strategy=None, max_iterations=None, time_limit_s=30.0, seed=0, threads=None, log_level="on", trace_output=None, trace_limit=None, reproduction_path=None)</code>

| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `model_or_program` | 必需 | `ModelBuilder`、`ProgramSpec`、`ExecutableProgram` 或其他提供 `to_program_spec()` 的对象。`SchedulingModel` 在创建时写入同一个 Builder；校验后传 `schedule.builder`。 |
| `strategy` | `None` | `GaConfig`；`None` 使用默认 `GaConfig()`。 |
| `max_iterations` | `None` | 本次求解的最大迭代数；`None` 由策略和时间预算决定。 |
| `time_limit_s` | `30.0` | wall-clock 时间上限，单位为秒。 |
| `seed` | `0` | 随机种子，用于复现实验。 |
| `threads` | `None` | worker 线程数；`None` 由执行计划决定。 |
| `log_level` | `"on"` | 日志级别：`"off"`、`"on"` 或 `"debug"`。`"on"` 输出紧凑求解进度，`"debug"` 增加诊断信息。其他值会直接被拒绝。 |
| `trace_output` | `None` | trace 内容：`"none"`、`"summary"`、`"full"`；`None` 使用 `"summary"`。 |
| `trace_limit` | `None` | 最多保留的 trace 条目数。 |
| `reproduction_path` | `None` | 手动生成本次执行的可重放 `.optrepro` 文件；不传时不写文件。 |

返回 `UnifiedSolution`。内核不可用、模型类型错误或参数非法时会显式抛出对应异常，不会静默切换到其他求解路径。

### 求解日志

默认 `log_level="on"` 输出模型摘要、初始构造改善、搜索改善和最终结果。初始构造使用 `init#N`，正式搜索独立使用 `#N`；搜索行中的 operator 来自真正刷新 incumbent 的 candidate。

```text
Starting OptAgent GA
Parameters: time_limit=5s threads=auto seed=42 population=12
Model: variables=1 constraints=0 objective=min

Constructing initial population
init#1  0.00s best:120
init#2  0.00s best:16
Starting search
#1  0.20s best:15 iteration:718 operator:ruin_and_repair
#4  3.19s best:12 iteration:10341 operator:ruin_and_repair

Solve summary:
  status: FEASIBLE
  objective: 12
  improvements: initial=2 search=4
  evaluated: 516012
  wall_time: 5.03s
  termination: wall_time_limit
```

实时文本最多每 500ms 渲染一条改善，并始终显示每个阶段的首个和最终改善。编号表示真实改善序号，因此采样合并后可以跳号。`log_level="debug"` 额外输出每 500ms 聚合的搜索 checkpoint；`log_level="off"` 不输出实时日志。

`trace_output` 独立控制返回结果中的结构化 trace：`"summary"` 保留 incumbent 事件，`"full"` 还保留周期 checkpoint，`"none"` 不保留。默认最多保留 1,000 条 summary 事件；`full` 不额外截断。

## StrategyConfig

`StrategyConfig` 是封闭的公开策略配置基类。当前发布只接受具体的 `GaConfig`，不要直接构造基类。

### GaConfig

<code class="api-call">GaConfig(max_iterations=None, unimproved_iteration_limit=None, population_size=8, crossover_rate=0.35)</code>

| 参数 | 说明 |
| --- | --- |
| `max_iterations` | 最大代数；`None` 允许由本次 solve controls 决定。 |
| `unimproved_iteration_limit` | 连续未改进代数上限。 |
| `population_size` | 种群大小，至少为 2。 |
| `crossover_rate` | 交叉概率，范围为 0 到 1。 |

变异组合、候选宽度、去重重试、局部改进、停滞扰动和领域自适应参数由 kernel 根据 compiler 已证明的模型能力在一次 solve 内管理，不属于稳定公开配置。

```python
from optagent import GaConfig, solve

solution = solve(
    builder,
    strategy=GaConfig(
        population_size=16,
        crossover_rate=0.5,
    ),
    time_limit_s=20,
    seed=42,
)
```

## Direct exact

### CP-SAT

<span id="optagent.solve_cpsat"></span>

<code class="api-call">solve_cpsat(model_or_program, config=None, warm_start=None, time_limit_s=None, workers=None, random_seed=None, relative_gap_limit=None, absolute_gap_limit=None, reproduction_path=None, ...)</code>

`CpSatConfig` 集中声明 CP-SAT 运行控制。函数级参数用于一次性覆盖配置；额外 backend 参数只有在公开兼容层允许时才会继续传递。

| `CpSatConfig` 参数 | 说明 |
| --- | --- |
| `time_limit_s` | 求解时间上限。 |
| `workers` | 并行 worker 数。 |
| `random_seed` | 随机种子。 |
| `relative_gap_limit` / `absolute_gap_limit` | 相对或绝对 gap 停止阈值。 |
| `log_search_progress` / `log_to_stdout` | 搜索日志控制。 |
| `profile_solve` | 是否记录求解 profile。 |
| `enable_solution_callback` / `solution_event_limit` | 中间解事件开关及数量上限。 |

### MILP

<span id="optagent.solve_milp"></span>

<code class="api-call">solve_milp(model_or_program, config=None, warm_start=None, reproduction_path=None)</code>

`MilpConfig(time_limit_s=None, threads=None, mip_rel_gap=None, backend=None)` 控制时间、线程、相对 MIP gap 和已支持的 MP backend。

### OptX

<span id="optagent.solve_optx"></span>

<code class="api-call">solve_optx(model_or_program, config=None, warm_start=None, reproduction_path=None)</code>

`OptxConfig(time_limit_s=None, mip_rel_gap=None, threads=None)` 控制 OptX 的时间、MIP gap 和线程数。

Direct exact 路径只接受可保持语义的 DAG 子集。具体接口范围见[精确求解兼容性](exact-compatibility.md)。

<!-- public-api: optagent.solve -->
<!-- public-api: optagent.StrategyConfig -->
<!-- public-api: optagent.GaConfig -->
<!-- public-api: optagent.solve_cpsat -->
<!-- public-api: optagent.CpSatConfig -->
<!-- public-api: optagent.solve_milp -->
<!-- public-api: optagent.MilpConfig -->
<!-- public-api: optagent.solve_optx -->
<!-- public-api: optagent.OptxConfig -->
