SuperAPI AI 工具集

conf-schedule-optimization

办公与效率

查看项目

更新于 10-16 04:27

技能介绍

用途

会议日程优化(Conference Schedule Optimization)把“该参加哪些场次”当作一个约束优化问题来处理,而不是列一张愿望清单。活动是变量,时间段是它们的取值域;硬约束定义什么是可行的,加权目标定义什么是好的。最终输出是一份最优可行方案,并诚实说明它无法决定的部分以及为了得高分而放弃了什么。

主要能力

硬约束与软目标分离

硬约束(可行性,绝不违反):任意两个选择在时间上不重叠;不同房间的相邻选择之间至少间隔房间间步行时间(来自配置);容量受限的场次只有在参会者能现实地获得座位时才计入;来自偏好档案的硬约束(必参加场次强制纳入,禁排/保留空闲块强制排除)。违反硬约束的方案不是更差的方案,而是根本不算方案——先过滤,再优化。

软目标(质量,最大化):加权求和。

四项相互冲突的加权目标

方案得分 = w_interest·兴趣 + w_breadth·广度 + w_pacing·节奏 + w_serendipity·偶遇性,权重来自偏好档案:

  • 兴趣:所选场次的参会者兴趣之和(主题亲和度 × 区域),即“看我关心的内容”项。
  • 广度:跨不同主题的覆盖度(同一主题第 4 场收益递减),即“不要钻牛角尖”项。
  • 节奏:奖励连续空闲时间、惩罚碎片化——一个真正 90 分钟的休息优于六个零散的 15 分钟间隙,即使场次数量相同;同时惩罚偏离偏好时段和过多步行。
  • 偶遇性:奖励刻意留白和偶尔纳入离群/探索性选择,使方案不是一台最大化塞满的兴趣机器。

最大化连续空闲时间

把空闲时间建模为块,奖励最长的连续块,把真正的休息当作目标中的一等收益,而不是剩余空间。六个不相邻、各带 15 分钟间隙的场次,比同样六场但聚在一起并留出真正休息的一天更糟——人需要连续恢复、走廊交谈和吃饭。

暴露无法打破的冲突

当两个(或多个)场次重叠、得分在 epsilon 内接近、且偏好档案无法排序时,在 unresolved_conflicts 中标记两个候选及模型无法打破平局的原因,而不是抛硬币并隐藏。当档案能打破平局时,选择并在 alternatives 中记录落选者及 why_not。

求解方法

默认(无求解器依赖):贪心种子(按时间顺序为每个时段选最佳可行项)加局部搜索——在保持可行的前提下做交换/插入/删除以改进加权目标。快速、透明,对几百场活动的议程足够好。resources/schedule.py 仅用 numpy/pandas/networkx 实现。

精确(可选):安装 pulp/ortools 且需要最优解时,可形式化为 ILP 求解。记录实际运行的方法到 method 字段。

报告权衡(Goodhart 诚实原则)

无论权重如何,方案都会牺牲权重低估的东西。在 tradeoffs_note 中说明,例如“偏向兴趣,因此第 2 天密集且休息短”或“节奏/广度加权意味着你兴趣最高的那场被放弃以换取覆盖度”。命名这种替代效应,是优化代理指标却不假装它就是目标的解药。

使用方式

工作流:

  1. 加载 events.json、affinities.json、profile.json;从配置加载房间、步行矩阵和每日时间边界。
  2. 强制纳入档案中的必参加场次;强制排除禁排/保留空闲块。
  3. 构建可行性:每个时段中不重叠、满足步行时间、可入座(容量)的场次集合。
  4. 为参会者给每个场次打分(亲和度 × 区域兴趣、深度/形式匹配)。
  5. 贪心播种一个可行方案;运行局部搜索以最大化用户加权目标。
  6. 检测顶级候选在 epsilon 内打平且档案无法排序的重叠 → unresolved_conflicts(不自动选择)。
  7. 计算 free_blocks(奖励最长连续块)和 objective_breakdown。
  8. 写出 schedule.json + schedule.md(逐日)+ conflicts.md(决策)+ rationale.md(选择、目标分解、权衡说明)。返回 schedule.json 路径。

输出契约(schedule.json)字段包括:generated_on、method、selections(含 day/start/end/event_id/room/score/why/alternatives)、free_blocks(含 purpose:break | buffer | travel | meal)、objective_breakdown(interest/breadth/pacing/serendipity/total/weights)、unresolved_conflicts(含 candidates/why_unbreakable/needs)、constraints_applied(travel_time/capacity/hard_constraints)、tradeoffs_note。

适用场景

  • 参会者面对多轨道、多房间、容量受限工作坊的会议议程,需要一份真正可执行的个人日程。
  • 需要在兴趣、主题广度、休息节奏和留白之间做明确权衡取舍的场合。
  • 需要把无法自动决定的冲突交回给人、而非被静默处理的决策场景。

限制与护栏

  1. 权重属于用户:从档案读取 objective_weights,绝不自行发明或覆盖;警惕编译进优化器的默认权重向量。
  2. 暴露冲突而非隐藏:epsilon 内打平且档案无法排序 ⇒ 写入 unresolved_conflicts,不做选择。
  3. 保护连续空闲时间:奖励最长连续空闲块,把真正休息当作一等目标项。
  4. Goodhart:在 tradeoffs_note 中说明加权牺牲了什么。
  5. 硬约束不可侵犯:优化前先过滤到可行;必参加强制纳入,禁排强制排除。
  6. 不静默截断、不重新引导、不擅自执行:记录任何候选上限;不修改档案;仅在明确指示时导出到日历。

相关技能

  • conf-preference-elicitation:提供区域、轴偏好、权重和硬约束,为本优化提供参数。
  • conf-theme-clustering:提供兴趣项和广度项所用的亲和度。
  • decision-matrix:把暴露的冲突候选结构化呈现给人类的方式。
  • expected-value:用于权衡容量有风险的工作坊(可能满员)与有保证的替代项。
  • systems-thinking-leverage:激发 tradeoffs_note 的 Goodhart/替代效应视角。

示例

示例 1:暴露的冲突。第 2 天 11:10–11:30 有两场得分 0.81 和 0.79 的演讲——一场关于 Agents,一场关于 Retrieval,都接近参会者兴趣,且档案未将 Agents 排在 Retrieval 之上。优化器不做选择,而是写入一条 unresolved_conflicts 条目,列出两者及“均在 epsilon 内;档案未对这些主题排序”,needs: your decision。

示例 2:同等兴趣下节奏胜过密集。两个可行方案在兴趣上打平。方案 A:六场演讲,整个下午间隙 15–20 分钟。方案 B:五场演讲加一个连续的 80 分钟下午块。在参会者偏节奏的权重下,方案 B 得分更高——长休息是被建模的收益而非浪费空间——tradeoffs_note 记录放弃一场较低兴趣的演讲以换取休息,这正是此人要求的取舍。