Skip to content

要件定義: 日本の学校の実態調査に基づく規模・制約要件を追加 - #1

Merged
ykwyuta merged 5 commits into
masterfrom
claude/project-status-investigation-p55j7c
Sep 2, 2026
Merged

ykwyuta merged 5 commits into
masterfrom
claude/project-status-investigation-p55j7c

Conversation

@ykwyuta

@ykwyuta ykwyuta commented Sep 2, 2026

Copy link
Copy Markdown
Owner

小学校から高校までの実態を一次資料(文部科学省)で調査し、Webアプリの
確定要件として docs/requirements.md にまとめた。

  • 標準授業時数から週コマ数を導出(小4以上・中29コマ、高30コマ)。
    週30枠に対しほぼ完全充填となるため、全制約のソフト制約化が必須要件。
  • 学級編制・学校規模からサポート規模を1〜36学級に確定。
  • 校種ごとの編成実態(小: 学級担任制+専科、中: 教科担任制と週持ちコマ数、
    高: 選択科目の同時展開)を制約要件に落とし込み、割当の単位を
    「学級」ではなく「講座」とするデータモデルを規定。
  • benchmarks/solver_benchmark.py で実態規模の求解時間を実測。小・中は
    1〜2秒で安定する一方、高校は0.3〜25秒とばらつき規模と相関しないため、
    求解の非同期ジョブ化を要件に追加(前回の不要判断を撤回)。

Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01DHGVNyssktZ69PWwmY1LCA

小学校から高校までの実態を一次資料(文部科学省)で調査し、Webアプリの
確定要件として docs/requirements.md にまとめた。

- 標準授業時数から週コマ数を導出(小4以上・中29コマ、高30コマ)。
  週30枠に対しほぼ完全充填となるため、全制約のソフト制約化が必須要件。
- 学級編制・学校規模からサポート規模を1〜36学級に確定。
- 校種ごとの編成実態(小: 学級担任制+専科、中: 教科担任制と週持ちコマ数、
  高: 選択科目の同時展開)を制約要件に落とし込み、割当の単位を
  「学級」ではなく「講座」とするデータモデルを規定。
- benchmarks/solver_benchmark.py で実態規模の求解時間を実測。小・中は
  1〜2秒で安定する一方、高校は0.3〜25秒とばらつき規模と相関しないため、
  求解の非同期ジョブ化を要件に追加(前回の不要判断を撤回)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHGVNyssktZ69PWwmY1LCA
時間割自動編成のバックエンドを実装した。制約は constraints.py に1度だけ定義し、
「LPへの追加(apply)」と「既存割当の検査(check)」の両方を同じクラスが持つ構造に
することで、自動提案と手編集の検証がズレないようにしている。

- ドメイン: 割当の単位を学級×教科ではなく Course(講座)とし、高校の選択科目の
  並列開講と特別支援学級の交流及び共同学習を同じ仕組みで表現できるようにした
- 教育課程マスタ: 学校教育法施行規則の標準授業時数を持ち、週コマ数を最大剰余法で
  導出する。導出結果は小1=25、小4〜6=29、中=29、高=30で施行規則の総授業時数と一致
- ソルバー: ハード制約をすべて「空解で充足可能」な形にしたためモデルは常に実行可能で、
  不足は必ず未充足コマ数として定量化される
- 求解API: ジョブID+ポーリングの非同期方式。相対ギャップ2%・時間制限30秒で打ち切る

実測(生成データ): 小学校19学級 5.3秒、中学校13学級 4.2秒、高校15学級 19.8秒。
いずれも未充足0コマ・ハード違反0。

実装中に判明して直した点:
- 特別教室の保有数を固定値にすると大規模校で原理的に配置不能になるため、需要から算出
- 同時展開制約を緩めると、それに依存する H1(学級の重複)が実質ソフト化してしまう
- 交流及び共同学習を別講座+同時展開で表現すると教室を二重に消費してしまう
- 同じ講座を同じコマに二重配置すると固定の矛盾検査をすり抜ける

置いた仮定はすべて docs/assumptions.md に A-01〜A-29 として記録した。
バックエンドテスト50件すべて通過。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHGVNyssktZ69PWwmY1LCA
React + TypeScript + @dnd-kit で、時間割をドラッグ&ドロップで微調整できる画面を
実装した。クラス別/教員別の切替、違反のハイライト、コマの固定、未配置トレイ、
undo/redo、CSV出力、求解の進捗表示とキャンセルを備える。

- 自動提案はジョブID+1秒ポーリングで待ち、完了したら新しい版として表示する
- 手編集のたびにサーバの検証エンジンが違反を返し、ハード違反は赤・ソフトは黄で表示
- 「固定を保って再提案」で、鍵をかけたコマを動かさずに残りを組み直せる
- 割当の一括置換APIを undo/redo に使い、操作ごとの逆操作を定義せずに済ませている

Playwright の E2E は、バックエンドとフロントエンドを自動起動して
提案 → 編集 → 違反検出 → 固定 → 再提案 → 出力 の一連を通す。

実装中に見つけて直した点:
- 学校を選んでから時間割が届くまでの一瞬だけセットアップ画面が表示され、
  入力中に画面が入れ替わって操作が失われるレースがあった

2019年の強化学習の実験(env/, keras*.py, chainer0001.py)と線形計画法の
ノートブックは archive/ へ移し、経緯を archive/README.md に残した。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHGVNyssktZ69PWwmY1LCA
ドラッグのヘルパーが、ドラッグ元の座標を取得したあとにドロップ先を
スクロールしていたため、押下位置がずれて要素の外を掴んでいた。
必要なスクロールを先に済ませてから両方の位置を読むように直し、
画面外を掴もうとした場合は明示的に失敗させるようにした。

あわせてE2Eのビューポートを縦1400pxにし、時間割グリッドと未配置トレイが
スクロールなしで同時に収まるようにした。

E2E 11件、バックエンド50件、フロントエンドの型チェックとビルドすべて通過。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHGVNyssktZ69PWwmY1LCA
各ディレクトリの .gitignore に加えて、生成物(SQLite、pytestキャッシュ、
Playwrightの実行結果)をリポジトリ全体で無視する。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHGVNyssktZ69PWwmY1LCA
@ykwyuta
ykwyuta merged commit c637e76 into master Sep 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants