원클릭으로
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 を増やす