跳转至
1.2.1

求解与配置

先阅读路径选择确认模型兼容性。一次性求解返回 Solution 并将本次解的值写入模型;业务代码应先检查 feasible。交互式入口返回会话,在 finish() 时写回最终解。

solve · 本地搜索

solution = model.solve(
    time_limit_s=30.0,
    objective_threshold=None,
    log_level="on",
    external_evaluation_limit=None,
    memory_limit_bytes=None,
    deterministic=True,
    evaluation_limit=None,
    random_seed=1,
    worker_threads=None,
)
参数 默认值 约束 / 含义
time_limit_s 30.0 正数且有限;秒,包含序列化和编译
objective_threshold None 目标索引到有限数值的映射;索引从零开始
log_level "on" "off"、"on"、"debug"
external_evaluation_limit None 可选正整数,限制实际启动的外部回调次数(失败也计入),已知结果和复用不额外计费
memory_limit_bytes None 默认自动管理内存;正整数可设置管理内存的字节上限,最大为 sys.maxsize
deterministic True 按固定逻辑顺序推进并行搜索,内部修复使用工作限额;设为 False 使用吞吐模式
evaluation_limit None 可选正整数,限制搜索评价和内部试算;不包含初始化评价
random_seed 1 随机种子,整数,范围为 0 到 2**64 - 1
worker_threads None 可选正整数,范围为 1 到 1024;默认采用机器报告的硬件并发数

需要重复得到相同结果时,固定模型、种子、线程配置、运行版本和评价预算,并为完成工作留出足够时间:

solution = model.solve(
    deterministic=True,
    evaluation_limit=10000,
    random_seed=1,
    worker_threads=4,
    time_limit_s=120,
)

solution.diagnostics["deterministic_completed"] 表示本次确定性工作正常完成。 若时间到期、取消、发生资源压力或执行失败,该值为 False,返回已有认证解,但不保证终态与其他运行相同。 相同秒数可能完成不同数量的工作,因此仅固定时间和种子不能保证完全相同的结果。

确定性模式暂不支持外部 Python 回调,也不运行依赖时间预算的 HiGHS 搜索路径; 模型包含外部回调时需显式传入 deterministic=False。它保留并行计算,但同步和搜索反馈顺序可能影响耗时与解质量。 默认启用确定性模式;model.solve(deterministic=False) 可切回吞吐模式。 该模式尚未通过性能与解质量无回退验收,是否适合业务模型应通过同时间预算的对照验证。

默认根据系统和容器可用内存调整搜索并发,在压力出现时回收缓存、降低并发,余量恢复后逐步增加并发。 例如 model.solve(memory_limit_bytes=2 * 1024**3) 将管理内存的目标限制在 2 GiB 以内;系统余量不足时实际目标可能更低。

该参数覆盖搜索工作区、候选存储和算法辅助空间,是协作式估算目标,不是整个进程的硬内存上限。 模型编译、Python、外部求解器和单次临时分配仍可能产生额外占用。资源不足时会保留已有的已验证结果, 通过 solution.diagnostics["termination_reason"] 报告 memory_limit,不表示模型无解。 solution.diagnostics["memory_policy"] 提供实际预算、资源来源、探测回退以及并发收缩和恢复次数。 系统资源无法探测时使用至多 256 MiB 的保护目标,并标记 probe_fallback。

interactive_solve · 暂停、改解与续跑

交互式求解沿用支持暂停、改解和续跑的异步吞吐路径。

from optagent import OptModel, interactive_solve

model = OptModel()
x = model.int(0, 100, default=80)
model.minimize(x * x)

with interactive_solve(model, wall_time_limit_s=60, log_level="off") as session:
    outcome = session.run_for(0.1)
    if not outcome.finished:
        outcome[x] = max(0, outcome[x] - 1)
        evaluated = session.evaluate(outcome)
        if evaluated.feasible and evaluated.improves_incumbent:
            receipt = session.submit(outcome)
            print(receipt.status)
        outcome = session.run_for(0.1)
    result = session.finish()

使用建模时声明的变量定位值:outcome[x] 读取,outcome[x] = value 修改。 已有业务索引可以直接使用,例如 outcome[start_times[job]] = 20。 修改立即可读;x.value 在会话结束前仍表示上一次终态解。

入口参数按名称传入:

参数 默认值 含义
wall_time_limit_s None 可选正数,单位秒;总墙钟预算,包含序列化、初始化、搜索、暂停和评价;默认不限总时间
objective_threshold None 与 solve 相同;提交达到阈值后也会终结搜索
log_level "on" "off"、"on"、"debug"
external_evaluation_limit None 搜索和交互评价共用的外部函数调用额度
memory_limit_bytes None 与 solve 相同的受管内存预算,包含交互评价;Python 导出的值不计入该预算

会话操作

操作 返回及约束
session.run_for(seconds) 返回 SolveOutcome;从可搜索状态开始计时,到期请求安全暂停,保留搜索资源
session.evaluate(outcome, timeout_s=None) 返回 EvaluationReport;对当前暂停轮次的完整候选原生验解,不改变全局最优
session.submit(outcome) 返回 SubmissionReceipt;只能提交最后一次修改后已成功验解的当前候选
session.cancel() 非阻塞请求终结,可在另一线程或外部函数中调用;之后用 finish/close 等待清理
session.finish() 终结并返回最后一个认证的 Solution;重复调用返回同一个结果
session.close() 幂等关闭;with 退出时自动调用

暂停和取消均为协作式操作;在途任务、外部函数及结果排空可能延长返回时间。 timeout_s 只限制本次评价;到期的评价不提交,若会话总预算仍有效,可继续修改和评价。 已经执行的 Python 外部函数必须自行返回,无法被硬中断。

outcome 的读写与认证

SolveOutcome.finished 表示返回时搜索已终结,与可行性分开。 feasible、objectives 是当前版本的认证结果;修改后均变为 None,成功评价后恢复。 revision 记录成功修改次数,incumbent_version 记录创建 outcome 时的全局版本。 非法赋值不改变原值、版本或证书;无认证赋值的终结结果读取决策时抛出 RuntimeError。

标量遵守声明的类型和范围。list 读取返回 tuple,set 返回 frozenset;区间读取为不可变映射, 缺席的可选区间为 None。修改集合需要整体赋值,例如:

order = list(outcome[route])
order.reverse()
outcome[route] = order

变量必须属于原模型且是决策变量。跨变量约束在完整评价时检查,因此可以先修改多个变量再评价。 EvaluationReport 提供 feasible、objectives、improves_incumbent、revision,以及 constraint_violations、hard_structure_violations、undefined_constraints、 undefined_objectives 四项计数。

SubmissionReceipt.accepted 表示实际接纳,status 为 accepted、infeasible 或 not_improving,incumbent_version 是提交后的全局版本。相等目标默认不替换。 未评价、过期或已经终结的提交抛出 RuntimeError,其他会话的 outcome 抛出 ValueError。 每次赋值会使旧证书失效;修改 Python 中的评价报告不会改变原生认证结果。

续跑不会自动提交修改。旧 outcome 保留原值供读取,但不能在之后的暂停轮次提交。 评价和提交期间修改该 outcome 会立即失败;同时运行第二个控制操作也会失败,cancel 除外。 模型声明在整个会话中冻结;外部函数对相同输入的含义也必须保持稳定。 当前仅原生搜索支持此会话接口,其他求解入口仍使用各自的一次性调用方式。

最终 result.diagnostics["interactive"] 包含暂停数、评价尝试/完成数、接纳数, 以及主动搜索、暂停排空、暂停等待、交互评价和 outcome 导出的纳秒计时。 暂停等待包含交互评价时间,两者不能重复相加。

solve_optx · HiGHS

from optagent import OptxConfig

solution = model.solve_optx(
    config=OptxConfig(time_limit=30.0, mip_rel_gap=0.01, threads=4),
    objective_threshold=None,
)

config=None 使用默认配置;包装层未配置时间限制时采用 30 秒。mip_rel_gap 必须有限且非负,threads 为正整数。其他 HiGHS 选项可通过关键字传入 OptxConfig;有效性由求解路径与后端检查。

不支持的模型抛出 OptxUnsupportedError,可读取 .issues 中的约束 / 目标名称、表达式路径和限制说明。该入口不回退到本地搜索。

solve_cpsat · OR-Tools CP-SAT

from optagent import CpSatConfig

solution = model.solve_cpsat(
    config=CpSatConfig(num_search_workers=4, random_seed=1),
    time_limit_s=30.0,
)
CpSatConfig 参数 说明
max_time_in_seconds 未显式传入 time_limit_s 时的总预算来源
num_search_workers CP-SAT 工作线程设置
random_seed 后端随机种子
relative_gap_limit / absolute_gap_limit 相对 / 绝对间隙限制
log_search_progress / log_to_stdout 后端日志设置
其他关键字参数 传递给 CP-SAT 原生参数

配置中值为 None 的选项不传递。显式 time_limit_s 优先,未设置时依次使用配置中的时间限制和 30 秒默认值。

solve_mathopt · OR-Tools MathOpt

from optagent import MathOptConfig

solution = model.solve_mathopt(
    config=MathOptConfig(solver_type="GSCIP", threads=4),
    time_limit_s=30.0,
)
MathOptConfig 参数 说明
solver_type 默认 "GSCIP",所选后端须可用且支持模型
time_limit 秒数或 datetime.timedelta;显式总预算未设置时采用
threads 后端线程设置
relative_gap_tolerance / absolute_gap_tolerance 相对 / 绝对间隙容差
其他关键字参数 传递给 MathOpt 原生求解参数

CP-SAT 和 MathOpt 的顶层入口不接受 objective_threshold。预算覆盖整个转换、求解与验证流程;验证前超时返回 UNKNOWN,没有可读变量值。

检查配置与结果

CpSatConfig.to_parameters()、MathOptConfig.to_parameters() 和 OptxConfig.to_options() 返回已设置选项的字典。MathOpt 的后端选择单独保存在 solver_type 中,不在 to_parameters() 字典内。

结果字段与状态处理见结果与诊断。