بنقرة واحدة
opt-baseline
実行可能性(feasibility)を確認する。問題の複雑度に応じて一発解きor段階的解法を選ぶ
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
実行可能性(feasibility)を確認する。問題の複雑度に応じて一発解きor段階的解法を選ぶ
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
受け取ったデータから最適化問題の構造を把握し、仮説を立てる。最も重要なスキル。
最適化モデルの運用設計。自動化・監視・フォールバックを定義する
ボトルネックに合わせた改善策を設計・実行・検証する
最適化結果を非技術者にも伝わる改善提案書にまとめる
追加データの依頼書を生成する。何がなぜ必要かを非技術者向けに説明
| name | opt-baseline |
| description | 実行可能性(feasibility)を確認する。問題の複雑度に応じて一発解きor段階的解法を選ぶ |
| user_invocable | true |
/opt-baseline [data_path] で実行。
役割: この問題が解けるか?どこが壁か?を特定する。
品質の最適化は opt-improve に任せる。baseline は feasibility に集中する。
run_in_background=true で 複数 Phase を同時投入し、最初に infeasible になる Phase の検出を高速化する(warm start を使う場合のみ直列)FEASIBLE フラグを信じない。verify_hard_constraints() を別関数で書き、active / pending を分けて報告time_limit=300s 等は run_in_background=true で投げ、その間に reports/baseline_report.md の骨格作成と QA チェックリスト整備を並行詳細は reference/opus47_collaboration.md。
assess で判定された complexity に応じて戦略を切り替える:
complexity: simple
→ 一発解き(random + greedy + solver の3手法)
→ shift_scheduling のような小規模問題
complexity: medium
→ まず一発解き
→ infeasible なら段階的解法にフォールバック
complexity: complex
→ 段階的解法(必須)
→ 制約を1つずつ追加して、どこで壁にぶつかるか特定
ランダム: 下限の確認(「何もしないとこれだけ悪い」) 貪欲法: 常識的な解(最近傍法、優先順位ソート等) ソルバー: 性能の上限(CP-SAT、time_limit=30秒)
ランダム 貪欲法 ソルバー
feasible? x(50違反) x(5違反) o(0違反)
違反内訳 HC1:30 ... HC3:5 -
→ ボトルネック制約を特定
目的: 全HCを一度に満たそうとするのではなく、1つずつ追加して壁を特定する。
Phase 0: 変数定義のみ、制約なし
→ 必ず feasible。「上限値」の確認
Phase 1: HC1 追加
→ まだ feasible のはず(充足条件のみ)
Phase 2: +HC2
→ infeasible になったら → HC1+HC2 が両立不可
Phase 3: +HC3
→ ...
...
Phase N: 全HC
→ ここまで feasible なら成功
→ どこかで infeasible になったら、そこが壁
各 Phase は active HCs(その Phase でモデルに入れている制約)と newly added(今回追加した制約)の 2 つを明示する。 独立検証器は全 HC をチェックするが、結果を active / pending の 2 つに分けて報告する:
これで出力が明確になる:
active OK ✓, pending=59 → 「今は HC1-5 を満たしている。HC6-12 は未評価」と読めるactive VIOL ✗ → 「想定した制約を満たしていない」→ バグ調査さらに 前 Phase からの差分 (Δ) を pending に付けると、制約追加の影響が見える:
pending=59 (Δ -10) → 直近の制約追加で他の違反も副次的に 10 減ったpending=198 (Δ +90) → 制約を追加したら他の違反が増えた (ソルバーが別方向に最適化した。正常)各 Phase のレポート項目:
重要: 制約を追加する順番は意図的に設計する。
推奨順序:
1. 需要充足系(HC1: 各シフトの必要人数)
→ まず「需要が満たせるか」を確認
2. 供給上限系(HC2: 最大勤務時間、最大積載量)
→ 需要 vs 供給のギャップが見える
3. 可用性系(HC3: 利用不可日、時間枠)
→ さらに供給が絞られる
4. 適合性系(HC4: スキル、ライセンス)
→ どの組合せが許されるか
5. 連鎖系(HC5: 休息時間、連続勤務)
→ 時間的制約
6. 特殊系(ペア、優先、優先順位)
→ 最後に入れる
この順序だと「どのレイヤーで壁にぶつかったか」が明確になる:
- Phase 2 で infeasible → 需給バランスの問題(人員不足)
- Phase 3 で infeasible → 可用性の問題(不可日が多すぎる)
- Phase 4 で infeasible → スキル分布の問題
- Phase 5 で infeasible → 休息制約が厳しすぎる
- Phase 6 で infeasible → ペア制約が矛盾
# Each phase: (name, active HCs, newly_added at this phase)
PHASES = [
("phase0_vars_only", set(), set()),
("phase1_hc1", {"HC1"}, {"HC1"}),
("phase2_add_hc2", {"HC1", "HC2"}, {"HC2"}),
("phase3_add_hc3", {"HC1", "HC2", "HC3"}, {"HC3"}),
# ... etc.
]
def staged_baseline(data):
results = []
first_infeasible = None
for name, active_hcs, newly_added in PHASES:
model = build_model_with(active_hcs, data)
solver = cp_model.CpSolver()
status = solver.Solve(model)
feasible = status in (OPTIMAL, FEASIBLE)
if feasible:
# Run independent verifier on ALL HCs
all_viol = verify_all_hcs(solver, model, data)
# Split into active (should be 0) and pending (ok if > 0)
active_viol = {hc: v for hc, v in all_viol.items()
if hc in active_hcs and v > 0}
pending_viol = {hc: v for hc, v in all_viol.items()
if hc not in active_hcs and v > 0}
results.append({
"phase": name,
"active_hcs": sorted(active_hcs),
"newly_added": sorted(newly_added),
"feasible": feasible,
"active_hc_violations": active_viol,
"active_hc_ok": sum(active_viol.values()) == 0,
"pending_hc_violations": pending_viol,
"pending_hc_total": sum(pending_viol.values()),
"stats": result.stats,
})
if not result.feasible and first_infeasible is None:
first_infeasible = name
return results, first_infeasible
infeasible を検出したら、「どの制約が組合せで壁を作っているか」を数値で特定すること。 レポートに以下を必ず書く:
データから該当リソースを数える — 制約を満たす候補の数 vs 需要の数
例: HC7 (skill) + HC8 (bilingual) の場合
- en + reception の両方を持つ作業者 = 4 名 (データから計数)
- bilingual_required + reception 指定のシフト = 4 シフト、各 5 名必要
- → 5 必要 vs プール 4 → 鳩の巣原理による不可能性
鳩の巣原理 or 需給ギャップの形で示す
必要人数 N > 候補プール P → 不可能
または
総需要 D h > 総供給 S h → 構造的不足 (D-S) h
無実の制約を明示する — 段階化で分かったこと
Phase 5 で壁 → HC9-12 (休息・ペア) は無実(容疑から外す)
原因が分かったら、どうすれば解決できるかを複数案で提示すること。 提案は opt-improve や opt-report で検証するので、ここでは候補リストを出す。
A. 入力を変える(データ側の修正)
B. 仕様を変える(HC の緩和)
C. 運用で回避(プロセス変更)
各選択肢に:
重要: 「解けません」で終わらない。必ず対案を複数出す。これが不可能性の証明を「価値ある提言」に変える。
バージョンフォルダ内に以下を保存する:
reports/baseline_report.md(ベースライン結果・ボトルネック分析・次のステップ)scripts/baseline.py(一発解きの場合)または scripts/staged_baseline.py(段階化の場合)results/baseline_results.json## ベースライン結果(一発解き)
| 手法 | Feasible | 違反数 | スコア |
|------|----------|--------|--------|
| ランダム | ... | ... | ... |
| 貪欲法 | ... | ... | ... |
| ソルバー | ... | ... | ... |
## ボトルネック分析
- 最もきつい制約: [XX](違反の80%を占める)
- 改善余地: [大/中/小]
## 次のステップ
→ /opt-improve でボトルネックに対策
## ベースライン結果(段階的解法)
### 読み方
各 Phase でソルバーに渡す制約を段階的に増やす。独立検証器は全 HC をチェックするが、結果を 2 つに分けて報告:
- **active**: その Phase で**すでに強制している** HC。ソルバーが正しければ違反ゼロになるはず → ゼロでなければ実装バグ
- **pending**: まだモデルに入れていない HC。違反があっても OK (後の Phase で解消する対象)
### Phase 表
| Phase | 追加 | ソルバー | 割当 | active HC | pending 違反 (Δ) | 時間 |
|-------|------|:---:|-----:|:---:|---|---:|
| 0 | - | OPTIMAL | 0 | ✓ (なし) | N | 0.1s |
| 1 | HC1 | OPTIMAL | 48 | ✓ | M (Δ ±X) | 0.2s |
| 2 | HC2 | **INFEASIBLE** | - | - | - | 0.3s |
- **active OK ✓**: Phase が強制する制約は全て満たしている
- **pending=N**: 未追加の HC に違反が N 件残る (後の Phase で解消予定)
- **Δ**: 前 Phase からの pending 変化。増えていても問題ない (制約追加の副作用)
### 壁にぶつかった Phase: **Phase 2 (+HC2)**
### 根本原因分析
**なぜ infeasible なのか、数値で示す:**
- データから候補/需要を計数:
- 総需要: 48 人・シフト × 8h = **384 時間/週**
- 総供給上限(全員フル稼働): 10人 × max_hours 合計 = **368 時間/週**
- ギャップ: 需要 384 > 供給 368 → **16時間(= 2シフト)不足**
- → **構造的な人手不足。アルゴリズム改善では解決不可能**
**無実の制約:**
- HC3 以降は未評価。HC2 の時点で壁に到達しているので、HC3-5 の影響は「あったとしても追加で悪化する方向」と言える
### 解決策の選択肢
| 案 | 内容 | コスト | 導入難易度 |
|---|---|---|---|
| A. 入力変更 | パート1名追加 (週24h以上) | 人件費 | 採用次第 |
| B. 仕様変更 | 夜勤必要人数を2→1に緩和 | 0円 | 要安全検討 |
| C. 運用変更 | 一部シフトを統合・削減 | 0円 | 要業務再設計 |
→ **推奨**: 案 A(恒久対策) + 採用まで案 B で暫定運用
### ボトルネック制約: HC2 + HC1 の組合せ
## 次のステップ
→ /opt-improve で以下を検討:
1. 何人追加すれば feasible になるか(不可能性の定量化)
2. HC2 を緩和した場合のスコア
3. 需要(HC1)を削減した場合のスコア
.opt_state.yaml の assess セクションassess.complexity を参照して戦略を決定.opt_state.yaml の baseline セクションstrategy: single_shot | staged)reference/state_schema.md を参照症状: 制約なしで解こうとしているのに feasible にならない
原因と対策:
├── 変数定義にバグ(domain が不正、依存関係の欠落)
├── データの整合性(空の集合、参照先なし)
└── ソルバーのバグ → モデルを print して確認
症状: 各 Phase が遅い
対策:
├── time_limit を Phase ごとに調整(Phase 1-2 は短く、最終 Phase は長く)
├── Phase N-1 の解を warm start として Phase N に渡す
├── infeasible 検知を早める(solver.parameters.enumerate_all_solutions = False)
└── 並列実行: 全 Phase を独立に並列で走らせる(依存がないので可能)
推奨: assess の hard_constraints の順序に従う
or 「需要→供給→可用性→適合→連鎖→特殊」の一般順序を使う
or 制約の種類を以下で判定:
├── 「各XXに必ずN個」→ 需要充足
├── 「XXの合計が上限以下」→ 供給上限
├── 「XXはこの日に使えない」→ 可用性
├── 「XXはこのスキルが必要」→ 適合性
├── 「XXの後にYYは禁止」→ 連鎖
└── 「XXとYYは同時」→ ペア/特殊
対策:
├── 企業プロキシ → pip install --proxy http://proxy:port ortools
├── Python バージョン(3.8-3.12 対応)
└── 代替: PuLP + HiGHS
対策:
├── time_limit 延長(30s → 120s → 300s)
├── 問題分解(AM/PM分割、クラスタ分割)
├── 変数削減(明らかな割当を先に固定)
└── num_workers を増やす