| name | strategies |
| description | AutoSolver 策略方向目录,基于本地基线结果选择、组合和扩展候选求解策略 |
| user-invocable | true |
| allowed-tools | ["Read","Glob","Grep"] |
AutoSolver 策略目录
用于在 loop 中选择下一轮策略方向。先参考已验证贪心基线,再选择高潜力扩展方向;实现文件应放在 AutoSolver 项目根目录下的 candidate_solvers/solver_<strategy_name>.py,并提供 solve(input_text: str) -> list。
项目根目录
本 skill 可以放在 OpenClaw workspace 的公共 skills 目录,例如:
/root/.openclaw/workspace/skills/strategies/SKILL.md
AutoSolver 项目可以独立放在:
/root/.openclaw/workspace/AutoSolver
读取日志、查看数据或实现策略前,先确定 PROJECT_ROOT。优先级如下:
- 用户明确指定的项目路径。
- 当前目录本身是 AutoSolver 项目根目录,即同时存在
data/、candidate_solvers/ 和 tools/recovered_objective.py。
- 当前目录下的
AutoSolver/ 子目录。
/root/.openclaw/workspace/AutoSolver。
/root/projects/AutoSolver。
以下所有相对路径都以 PROJECT_ROOT 为基准;不要在 /root/.openclaw/workspace/skills 下创建候选策略或日志。
使用方式
- 读取
${PROJECT_ROOT}/logs/solver_log.md,排除已经失败且没有新变量的方向。
- 查看本文件的策略方向,优先选择与当前最优相邻的改进。
- 实现后使用
/evaluate skill 或 python tools\evaluate_solver.py <candidate> 对 ${PROJECT_ROOT}/data/*.txt 做本地平均 Penalty 与逐 case 评估。
- 如果额外生成或使用合成样例数据做策略探索,每次评估后都要把样例构造方式、结果摘要和得到的策略启发记录到本文件的对应策略段落中;真实
data/*.txt 的逐轮结果仍记录到 ${PROJECT_ROOT}/logs/solver_log.md。
当前策略状态
- 官方最好实测:
candidate_solvers/solver_round37_adaptive_topn.py,均分 724.07,完成 10/10。
- 当前
solver.py:candidate_solvers/solver_round38_lowtimeout.py 同步版,本地均分 687.94,通过降低 low_willingness 搜索宽度解决 38 轮官方低意愿超时风险。
- 平台风险:39 轮之后的入口/结构改动曾触发前端
Cannot read properties of undefined (reading 'slice')。继续优化时优先保留 38 轮代码形态,只做局部参数、排序 key、预算和场景分支调整。
- 时间策略:官方环境比本地慢很多;本地单 case 超过约
3.5s 就要警惕,scarce 和 low_willingness 不能为了微小均分收益放宽太多。
当前候选保留
根目录 candidate_solvers/ 只保留关键版本;低分旧版本在 candidate_solvers/archive_low_scores/ 中,需要参考历史失败时再读取。
| 文件 | 用途 |
|---|
solver_round37_adaptive_topn.py | 官方 724.07 最好实测锚点 |
solver_round38_diverse_mg.py | 38 轮可测结构,曾因 low_willingness 超时导致官方 842.81 |
solver_platform_restore_round38.py | 回滚排查平台 slice 错误用 |
solver_round38_lowtimeout.py | 当前 solver.py 同步候选,目标恢复到 723.x 档 |
A. 已验证贪心基线
以下结果来自使用 ${PROJECT_ROOT}/tools/strategy.py 中的 11 种策略对 ${PROJECT_ROOT}/data/ 目录下 10 个测试算例进行回放。统计口径为各 case Penalty 的简单平均值,越低越好。
注意:${PROJECT_ROOT}/docs/AutoSolver.md 第 3 节中的策略排名和逐算例明细是真实测试数据回放结果,不是合成样例估算结果。当前 skill 中的基线用于本地迭代选方向,若引用 ${PROJECT_ROOT}/docs/AutoSolver.md 的结果,必须明确标注为真实测试数据结果;若引用 ${PROJECT_ROOT}/data/*.txt 和 ${PROJECT_ROOT}/tools/recovered_objective.py 的结果,则标注为本地复核结果。
| 排名 | 策略 | 核心规则 | 平均 Penalty | 总完成率 | 结论 |
|---|
| 1 | MULTI | 单订单候选按 score / willingness 排序,每单最多 2 个骑手 | 826.87 | 92.10% | 当前最强基线,多骑手降风险有效 |
| 2 | SINGLE_ONLY | 仅单订单,按 score / willingness 排序 | 1,080.72 | 80.76% | 单订单质量高,但覆盖率不足 |
| 3 | RATIO_ALL | 全部候选按 score / (willingness * len(tasks)) 排序 | 1,103.28 | 81.10% | 接近 SINGLE_ONLY,可作为合单排序参考 |
| 4 | DISJOINT_PROB | 全部候选按高 willingness,订单互斥 | 1,242.52 | 93.81% | 覆盖强,但成本控制弱 |
| 5 | CHEAP_ALL | 全部候选按低 score | 1,476.68 | 78.01% | 低成本优先,覆盖不足 |
| 6 | PROB_ALL | 全部候选按高 willingness | 1,517.20 | 79.38% | 概率优先但成本偏高 |
| 7 | HIGH_PROB_EXPENSIVE | willingness >= 0.65,按高概率和高 score | 1,630.77 | 72.16% | 不稳定,低意愿场景退化明显 |
| 8 | DISJOINT_CHEAP | 全部候选按低 score,订单互斥 | 1,728.02 | 93.13% | 覆盖强但不够低罚分 |
| 9 | LOW_PROB_CHEAP | willingness <= 0.25,按低 score | 2,484.17 | 79.73% | 低概率风险过高 |
| 10 | EMPTY | 不分配 | 2,910.00 | 0.00% | 仅作下界/格式对照 |
| 11 | BUNDLE_ONLY | 仅合单,按 score / (willingness * len(tasks)) 排序 | 4,708.50 | 92.10% | 合单单独使用严重退化 |
基线结论:
MULTI 是首要参照,说明“单订单 + 多骑手备份”是当前最有效结构。
SINGLE_ONLY 和 RATIO_ALL 排名接近,说明 score / willingness 类排序仍是强基线。
DISJOINT_PROB 覆盖率最高但平均 Penalty 较高,适合作为补覆盖阶段的组件。
BUNDLE_ONLY 明显失败,合单应作为补充,不宜单独主导。
逐 case 结果用于判断策略是否只在少数场景上取巧。单元格格式为 Penalty | 覆盖订单数/总订单数。
| 测试算例 | MULTI | SINGLE_ONLY | RATIO_ALL | DISJOINT_PROB | CHEAP_ALL | PROB_ALL | HIGH_PROB_EXPENSIVE | DISJOINT_CHEAP | LOW_PROB_CHEAP | EMPTY | BUNDLE_ONLY |
|---|
| high_noise_seed601 | 510.69 | 30/30 | 766.25 | 27/30 | 766.25 | 27/30 | 992.52 | 30/30 | 1,142.97 | 25/30 | 1,312.65 | 26/30 | 1,251.68 | 28/30 | 1,435.60 | 30/30 | 2,394.18 | 25/30 | 3,000.00 | 0/30 | 4,270.82 | 29/30 |
| large_seed301 | 765.74 | 40/40 | 1,243.91 | 34/40 | 1,265.07 | 35/40 | 1,447.82 | 40/40 | 1,857.84 | 32/40 | 1,918.56 | 32/40 | 1,918.56 | 32/40 | 2,097.66 | 40/40 | 3,493.81 | 35/40 | 4,000.00 | 0/40 | 6,275.94 | 39/40 |
| large_seed302 | 692.91 | 40/40 | 1,278.25 | 33/40 | 1,278.25 | 33/40 | 1,471.36 | 40/40 | 1,765.89 | 35/40 | 1,594.53 | 35/40 | 1,594.53 | 35/40 | 2,314.08 | 40/40 | 3,003.73 | 35/40 | 4,000.00 | 0/40 | 6,732.26 | 40/40 |
| low_willingness_seed501 | 1,383.28 | 30/30 | 1,552.21 | 25/30 | 1,552.21 | 25/30 | 1,995.68 | 30/30 | 2,084.65 | 25/30 | 1,921.92 | 22/30 | 3,000.00 | 0/30 | 2,518.47 | 30/30 | 2,488.20 | 26/30 | 3,000.00 | 0/30 | 8,696.71 | 30/30 |
| medium_seed201 | 532.69 | 30/30 | 716.63 | 28/30 | 716.63 | 28/30 | 1,011.74 | 30/30 | 1,188.13 | 26/30 | 1,408.19 | 24/30 | 1,408.19 | 24/30 | 1,517.18 | 30/30 | 2,256.28 | 28/30 | 3,000.00 | 0/30 | 4,921.48 | 29/30 |
| medium_seed202 | 546.08 | 30/30 | 872.90 | 26/30 | 872.90 | 26/30 | 1,048.84 | 30/30 | 1,350.90 | 27/30 | 1,299.84 | 28/30 | 1,300.12 | 28/30 | 1,571.11 | 30/30 | 2,436.84 | 26/30 | 3,000.00 | 0/30 | 4,654.21 | 29/30 |
| medium_seed203 | 551.10 | 30/30 | 996.50 | 25/30 | 996.50 | 25/30 | 1,143.04 | 30/30 | 1,251.13 | 24/30 | 1,592.17 | 28/30 | 1,710.48 | 27/30 | 1,611.54 | 30/30 | 2,486.96 | 25/30 | 3,000.00 | 0/30 | 4,658.79 | 29/30 |
| scarce_couriers_seed401 | 2,777.95 | 17/40 | 2,777.95 | 17/40 | 2,777.95 | 17/40 | 2,552.77 | 22/40 | 3,233.14 | 15/40 | 2,889.84 | 16/40 | 2,889.84 | 16/40 | 3,098.26 | 20/40 | 3,713.90 | 14/40 | 4,000.00 | 0/40 | 3,486.40 | 23/40 |
| small_seed100 | 314.50 | 15/15 | 372.09 | 15/15 | 468.95 | 15/15 | 542.88 | 15/15 | 626.06 | 13/15 | 823.29 | 14/15 | 823.29 | 14/15 | 712.61 | 15/15 | 1,182.35 | 12/15 | 1,500.00 | 0/15 | 2,492.99 | 14/15 |
| tiny_seed42 | 193.75 | 6/6 | 230.47 | 5/6 | 338.10 | 5/6 | 218.52 | 6/6 | 266.09 | 5/6 | 411.02 | 6/6 | 411.02 | 6/6 | 403.71 | 6/6 | 1,385.47 | 6/6 | 600.00 | 0/6 | 895.40 | 6/6 |
如果某策略均值改善但在 scarce_couriers 或 low_willingness 退化,应优先设计分场景规则,而不是只追均值。
B. 期望值贪心
核心公式:
E_single = willingness * score + (1 - willingness) * 100 * len(tasks)
可尝试方向:
EV_GREEDY:按 E_single 升序贪心,维护订单跨分组唯一。
EV_GREEDY_REPAIR:候选探索阶段可临时比较重叠候选的边际收益,但返回前必须修复为合法输出,确保同一订单不跨多个输出分组重复覆盖。
EV_MARGIN:按选中候选带来的边际 Penalty 降低排序。
EV_SINGLE_THEN_REINFORCE:先用期望值覆盖单订单,再对高风险订单追加骑手。
C. 多骑手扩展
从 MULTI 出发优先尝试:
MULTI_ADAPTIVE_K:每个订单动态追加骑手,直到边际收益低于阈值。
MULTI_TOP_K_SEARCH:搜索 K=1..N 和排序参数,比较 ${PROJECT_ROOT}/data/*.txt 平均 Penalty。
MULTI_LOW_CONFIDENCE:只对低 willingness 或高期望惩罚订单追加备选骑手。
MULTI_WITH_DISJOINT_BACKFILL:先做单订单多骑手,再用互斥高概率候选补未覆盖订单。
多骑手边际收益应考虑“无人接起概率”下降,而不是只看单个骑手的 score 或 willingness。
多骑手扩展只表示同一订单集合可追加多个不同备选骑手;所有策略仍必须维护全局 used_couriers,同一个 courier_id 在所有输出分组中最多出现一次。同一个订单不得跨多个输出分组重复覆盖;多个备选骑手必须合并在同一个 task_id_list_str 输出项中。
D. 合单补充策略
BUNDLE_ONLY 基线很差,但合单仍可能用于补覆盖:
SINGLE_FIRST_BUNDLE_BACKFILL:先用强单订单策略覆盖,再用合单补剩余订单。
BUNDLE_ONLY_FOR_UNCOVERED:只允许合单覆盖尚未覆盖的订单集合。
BUNDLE_SCORE_CAP:只接受 score、willingness 和任务数都满足阈值的合单。
BUNDLE_REGRET:当多个未覆盖订单的单订单候选都很差时,才使用合单。
合单策略必须逐 case 检查,特别关注大规模、低意愿和骑手稀缺场景。
E. 两阶段 / 三阶段策略
适合在强基线附近做组合:
PHASE_MULTI_THEN_FILL:MULTI 覆盖主干,DISJOINT_PROB 或合单规则补洞。
PHASE_COVER_THEN_REINFORCE:先最大化覆盖,再对高风险分组追加骑手。
PHASE_SCENARIO_ADAPTIVE:根据输入规模、候选密度、平均 willingness 选择不同子策略。
阶段策略要记录每阶段新增覆盖数、平均风险和是否造成已有 case 退化。
F. 参数搜索策略
优先搜索低成本参数,不要过早引入复杂模型:
- 排序权重:
score / willingness^alpha、score / (willingness * len(tasks)^beta)。
- 多骑手上限:
K=1..4。
- 追加阈值:按边际 Penalty 改善、willingness 下限或订单难度。
- 分场景阈值:订单数、骑手数、候选数、平均 willingness、单订单候选比例。
所有参数搜索都必须用同一批 ${PROJECT_ROOT}/data/*.txt 和同一评估函数比较。
G. 高级策略
在贪心和组合策略连续无改善后再尝试:
BEAM_SEARCH:保留 top-B 个部分解,控制 B 和候选裁剪。
LOCAL_SWAP:从当前最优解出发,尝试替换、删除、追加候选。
RANDOM_GREEDY:随机扰动排序,多次运行保留最优。
ILP_SMALL_CASE:仅对 tiny/small 或候选裁剪后的子问题做精确优化。
HYBRID_GREEDY_ILP:贪心生成候选池,再对局部未覆盖集合求解。
高级策略必须设置规模限制和超时回退,避免违反 10 秒执行约束。
H. 目录外自主探索
当 A-G 方向已经按同一批 ${PROJECT_ROOT}/data/*.txt 充分验证且连续失败时,不要继续在目录内机械枚举。必须从日志中的失败模式提出新的可检验假设,并写明它突破了哪个既有假设。
可探索方向包括:
- 新风险度量:不用单个
score / willingness 或期望值排序,而是估计无人接起概率、接受者数量分布和高分骑手被抽中的尾部风险。
- 新分场景特征:按订单数、候选密度、骑手稀缺度、低意愿比例、单单/合单比例选择不同子策略。
- 新候选裁剪:先删除几乎不可能降低边际 Penalty 的候选,再做局部搜索或组合。
- 新接受模型近似:在现有 recovered objective 之外构造更便宜的边际收益上界,用于指导搜索,但最终仍必须用
tools/recovered_objective.py 复核。
目录外策略仍必须写入 ${PROJECT_ROOT}/candidate_solvers/solver_<strategy_name>.py,使用 /evaluate 做全量本地评估,并在日志中记录“新假设、相对 A-G 的差异、失败或成功原因”。
实现模板
新策略文件放在 ${PROJECT_ROOT}/candidate_solvers/:
def solve(input_text: str) -> list:
rows = parse(input_text)
selected = select(rows)
return group_output(selected)
实现建议:
- 解析逻辑可参考
${PROJECT_ROOT}/tools/strategy.py。
- 本地评估使用
/evaluate skill。
- 选择候选时维护全局
used_couriers 和已覆盖订单集合;输出中的每个 (task_id_list_str, courier_id) 必须精确来自输入候选池,不能跨 task_id_list 混用 score 或 willingness,也不能让同一订单跨多个输出分组重复覆盖。
- 迭代阶段可以参考项目内辅助函数;最终整理成
solver.py 时必须自包含。
- 每个策略文件顶部写明策略名、关键参数和相对基线的预期改进点。