Skip to content

Instantly share code, notes, and snippets.

@chottokun
Created January 3, 2026 12:28
Show Gist options
  • Select an option

  • Save chottokun/0a6ffaadf5c098a4008a1ed87aea6e61 to your computer and use it in GitHub Desktop.

Select an option

Save chottokun/0a6ffaadf5c098a4008a1ed87aea6e61 to your computer and use it in GitHub Desktop.
Model-First Reasoning.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyOh81f/2hMOOkxIe4aymgYN",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/chottokun/0a6ffaadf5c098a4008a1ed87aea6e61/model-first-reasoning.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "239aa4bc",
"outputId": "aeb9fb98-0cd9-4cbe-a75e-f9d0b269dd12",
"collapsed": true
},
"source": [
"!pip install langchain-openai langchain-core"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Collecting langchain-openai\n",
" Downloading langchain_openai-1.1.6-py3-none-any.whl.metadata (2.6 kB)\n",
"Requirement already satisfied: langchain-core in /usr/local/lib/python3.12/dist-packages (1.2.1)\n",
"Collecting langchain-core\n",
" Downloading langchain_core-1.2.6-py3-none-any.whl.metadata (3.7 kB)\n",
"Requirement already satisfied: openai<3.0.0,>=1.109.1 in /usr/local/lib/python3.12/dist-packages (from langchain-openai) (2.12.0)\n",
"Requirement already satisfied: tiktoken<1.0.0,>=0.7.0 in /usr/local/lib/python3.12/dist-packages (from langchain-openai) (0.12.0)\n",
"Requirement already satisfied: jsonpatch<2.0.0,>=1.33.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (1.33)\n",
"Requirement already satisfied: langsmith<1.0.0,>=0.3.45 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (0.4.59)\n",
"Requirement already satisfied: packaging<26.0.0,>=23.2.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (25.0)\n",
"Requirement already satisfied: pydantic<3.0.0,>=2.7.4 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (2.12.3)\n",
"Requirement already satisfied: pyyaml<7.0.0,>=5.3.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (6.0.3)\n",
"Requirement already satisfied: tenacity!=8.4.0,<10.0.0,>=8.1.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (9.1.2)\n",
"Requirement already satisfied: typing-extensions<5.0.0,>=4.7.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (4.15.0)\n",
"Requirement already satisfied: uuid-utils<1.0,>=0.12.0 in /usr/local/lib/python3.12/dist-packages (from langchain-core) (0.12.0)\n",
"Requirement already satisfied: jsonpointer>=1.9 in /usr/local/lib/python3.12/dist-packages (from jsonpatch<2.0.0,>=1.33.0->langchain-core) (3.0.0)\n",
"Requirement already satisfied: httpx<1,>=0.23.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.3.45->langchain-core) (0.28.1)\n",
"Requirement already satisfied: orjson>=3.9.14 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.3.45->langchain-core) (3.11.5)\n",
"Requirement already satisfied: requests-toolbelt>=1.0.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.3.45->langchain-core) (1.0.0)\n",
"Requirement already satisfied: requests>=2.0.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.3.45->langchain-core) (2.32.4)\n",
"Requirement already satisfied: zstandard>=0.23.0 in /usr/local/lib/python3.12/dist-packages (from langsmith<1.0.0,>=0.3.45->langchain-core) (0.25.0)\n",
"Requirement already satisfied: anyio<5,>=3.5.0 in /usr/local/lib/python3.12/dist-packages (from openai<3.0.0,>=1.109.1->langchain-openai) (4.12.0)\n",
"Requirement already satisfied: distro<2,>=1.7.0 in /usr/local/lib/python3.12/dist-packages (from openai<3.0.0,>=1.109.1->langchain-openai) (1.9.0)\n",
"Requirement already satisfied: jiter<1,>=0.10.0 in /usr/local/lib/python3.12/dist-packages (from openai<3.0.0,>=1.109.1->langchain-openai) (0.12.0)\n",
"Requirement already satisfied: sniffio in /usr/local/lib/python3.12/dist-packages (from openai<3.0.0,>=1.109.1->langchain-openai) (1.3.1)\n",
"Requirement already satisfied: tqdm>4 in /usr/local/lib/python3.12/dist-packages (from openai<3.0.0,>=1.109.1->langchain-openai) (4.67.1)\n",
"Requirement already satisfied: annotated-types>=0.6.0 in /usr/local/lib/python3.12/dist-packages (from pydantic<3.0.0,>=2.7.4->langchain-core) (0.7.0)\n",
"Requirement already satisfied: pydantic-core==2.41.4 in /usr/local/lib/python3.12/dist-packages (from pydantic<3.0.0,>=2.7.4->langchain-core) (2.41.4)\n",
"Requirement already satisfied: typing-inspection>=0.4.2 in /usr/local/lib/python3.12/dist-packages (from pydantic<3.0.0,>=2.7.4->langchain-core) (0.4.2)\n",
"Requirement already satisfied: regex>=2022.1.18 in /usr/local/lib/python3.12/dist-packages (from tiktoken<1.0.0,>=0.7.0->langchain-openai) (2025.11.3)\n",
"Requirement already satisfied: idna>=2.8 in /usr/local/lib/python3.12/dist-packages (from anyio<5,>=3.5.0->openai<3.0.0,>=1.109.1->langchain-openai) (3.11)\n",
"Requirement already satisfied: certifi in /usr/local/lib/python3.12/dist-packages (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core) (2025.11.12)\n",
"Requirement already satisfied: httpcore==1.* in /usr/local/lib/python3.12/dist-packages (from httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core) (1.0.9)\n",
"Requirement already satisfied: h11>=0.16 in /usr/local/lib/python3.12/dist-packages (from httpcore==1.*->httpx<1,>=0.23.0->langsmith<1.0.0,>=0.3.45->langchain-core) (0.16.0)\n",
"Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.12/dist-packages (from requests>=2.0.0->langsmith<1.0.0,>=0.3.45->langchain-core) (3.4.4)\n",
"Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.12/dist-packages (from requests>=2.0.0->langsmith<1.0.0,>=0.3.45->langchain-core) (2.5.0)\n",
"Downloading langchain_openai-1.1.6-py3-none-any.whl (84 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m84.7/84.7 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hDownloading langchain_core-1.2.6-py3-none-any.whl (489 kB)\n",
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m489.1/489.1 kB\u001b[0m \u001b[31m13.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hInstalling collected packages: langchain-core, langchain-openai\n",
" Attempting uninstall: langchain-core\n",
" Found existing installation: langchain-core 1.2.1\n",
" Uninstalling langchain-core-1.2.1:\n",
" Successfully uninstalled langchain-core-1.2.1\n",
"Successfully installed langchain-core-1.2.6 langchain-openai-1.1.6\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"from google.colab import userdata\n",
"models = [\"gpt-oss-120b\", \"Qwen3-Coder-480B-A35B-Instruct-FP8\", \"Qwen3-Coder-30B-A3B-Instruct\", \"llm-jp-3.1-8x13b-instruct4\"]\n",
"import openai\n",
"import time\n",
"\n",
"# APIキーとベースURLを設定\n",
"SAKURA_API_KEY = userdata.get('SAKURA_API_KEY') # 実際のAPIキーに置き換えてください\n",
"SAKURA_BASE_URL = \"https://api.ai.sakura.ad.jp/v1/\"\n",
"\n",
"# Chat Completionの呼び出し\n",
"\n",
"def generate_text(text):\n",
" for model in models:\n",
" client = openai.OpenAI(api_key=SAKURA_API_KEY, base_url=SAKURA_BASE_URL)\n",
"\n",
" start_time = time.time() # 時間測定開始\n",
" response = client.chat.completions.create(\n",
" model=model,\n",
" messages=[\n",
" {\"role\": \"system\", \"content\": \"あなたは親切なAIアシスタントです。\"},\n",
" {\"role\": \"user\", \"content\": text}\n",
" ]\n",
" )\n",
" end_time = time.time() # 時間測定終了\n",
" elapsed_time = end_time - start_time # 経過時間計算\n",
"\n",
" # レスポンスの表示\n",
" print(f\"{model} say:\\n\")\n",
" print(response.choices[0].message.content)\n",
" print(f\"\\nResponse time: {elapsed_time:.2f} seconds\\n\") # 経過時間表示\n",
"# テスト\n",
"print(generate_text(\"こんにちは!\"))"
],
"metadata": {
"id": "qcYFU005S9S9",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "657aea85-7cad-4ff8-d8f6-a7af9d347522"
},
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"gpt-oss-120b say:\n",
"\n",
"こんにちは!😊 今日はどんなことをお手伝いしましょうか?\n",
"\n",
"Response time: 3.40 seconds\n",
"\n",
"Qwen3-Coder-480B-A35B-Instruct-FP8 say:\n",
"\n",
"こんにちは!😊 \n",
"今日はどういったご用件でしょうか? \n",
"お手伝いできることがあれば、いつでもお気軽にお知らせくださいね!\n",
"\n",
"Response time: 8.94 seconds\n",
"\n",
"Qwen3-Coder-30B-A3B-Instruct say:\n",
"\n",
"こんにちは!お手伝いできることがあれば、いつでも教えてくださいね。\n",
"\n",
"Response time: 1.25 seconds\n",
"\n",
"llm-jp-3.1-8x13b-instruct4 say:\n",
"\n",
"こんにちは!今日はどのようなお手伝いが必要ですか?\n",
"\n",
"Response time: 1.14 seconds\n",
"\n",
"None\n"
]
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "89f84c1d",
"outputId": "15fa65a4-c6f6-4837-eba0-c6f6dd6d101a"
},
"source": [
"from langchain_openai import ChatOpenAI\n",
"from langchain_core.prompts import ChatPromptTemplate\n",
"from langchain_core.output_parsers import StrOutputParser\n",
"from langchain_core.runnables import RunnablePassthrough, RunnableLambda\n",
"\n",
"# Initialize LLM with SAKURA API\n",
"llm = ChatOpenAI(\n",
" model=\"gpt-oss-120b\",\n",
" openai_api_key=SAKURA_API_KEY, # Use SAKURA API Key\n",
" openai_api_base=SAKURA_BASE_URL # Use SAKURA API Base URL\n",
")\n",
"\n",
"# --- Phase 1: Model Construction Prompt ---\n",
"phase1_template = \"\"\"\n",
"以下の問題を分析し、解決策を提示する前に、まず明示的な「問題モデル」を定義してください。モデルは以下の4つの要素で構成し、構造化して記述してください。\n",
"1. 関連するエンティティ: 問題に関与するすべてのオブジェクト、エージェント、リソース、場所。\n",
"2. 状態変数: 時間とともに変化するエンティティの特性やステータス(例:位置、残量、ステータス)。\n",
"3. アクションの定義: 実行可能な操作と、それぞれの「前提条件(実行に必要な条件)」および「効果(実行後の状態変化)」。\n",
"4. 制約事項: 常に遵守しなければならない不変のルール、制限、条件。\n",
"※重要:この段階では、まだ解決策や具体的な手順を提案しないでください。構造の定義のみに集中してください。\n",
"\n",
"問題:\n",
"{problem_description}\n",
"\"\"\"\n",
"phase1_prompt = ChatPromptTemplate.from_template(phase1_template)\n",
"\n",
"# --- Phase 2: Reasoning Prompt ---\n",
"phase2_template = \"\"\"\n",
"定義した「問題モデル」のみを使用して、ステップバイステップの解決策を生成してください。\n",
"最後に問題に対する回答として述べてください。\n",
"推論を行う際は、以下のガイドラインを厳守してください。\n",
"• すべてのアクションが、モデルで定義された前提条件を満たしていることを確認する。\n",
"• 各ステップ後の状態変化が、モデルの効果と一致しているか追跡する。\n",
"• すべてのプロセスにおいて、定義された制約事項が一度も破られないことを保証する。\n",
"\n",
"定義された問題モデル:\n",
"{constructed_model}\n",
"\n",
"解決すべき問題:\n",
"{problem_description}\n",
"\"\"\"\n",
"phase2_prompt = ChatPromptTemplate.from_template(phase2_template)\n",
"\n",
"# --- Build the Chain ---\n",
"# Phase 1 creates the model, passes it to Phase 2\n",
"mfr_chain = (\n",
" {\n",
" \"constructed_model\": phase1_prompt | llm | StrOutputParser(),\n",
" \"problem_description\": RunnablePassthrough(), # Passes the original problem_description from the invoke call\n",
" }\n",
" | phase2_prompt\n",
" | llm\n",
" | StrOutputParser()\n",
")\n",
"\n",
"# Execution\n",
"problem = \"3つの部屋に薬を配るロボットのスケジュールを立ててください。制約:薬Aと薬Bは同時に運べない。\"\n",
"print(\"Processing request... This may take a moment.\")\n",
"result = mfr_chain.invoke({\"problem_description\": problem})\n",
"print(\"\\n--- Result ---\\n\")\n",
"print(result)\n"
],
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Processing request... This may take a moment.\n",
"\n",
"--- Result ---\n",
"\n",
"**ステップバイステップのスケジュール(問題モデルだけを使用)** \n",
"\n",
"| Step | 実行アクション | 前提条件の確認 | 効果(状態変化) | 重要な制約チェック |\n",
"|------|----------------|----------------|------------------|-------------------|\n",
"| 0 | 初期状態 | `loc(R)=Supply`、`load(R)=∅`、`available(A)=真`、`available(B)=真`、`delivered(*,*)=偽`、`time=0` | - | すべての制約 C1‑C7 が満たされていることを確認 |\n",
"| 1 | **PickUp(R, A)** | 1. `loc(R)=Supply` ✔ <br>2. `load(R)=∅` ✔ <br>3. `available(A)=真` ✔ <br>4. `inTransit(A)=偽` ✔ | `load(R)←{A}` <br>`available(A)←偽` <br>`inTransit(A)←真` <br>`time←1` | C1(同時搬送禁止)≡`load(R)={A}` で OK |\n",
"| 2 | **Move(R, Room1)** | `loc(R)=Supply` ≠ `Room1` ✔ | `loc(R)←Room1` <br>`time←2` | C4(位置一貫性)✔ |\n",
"| 3 | **DropOff(R, A, Room1)** | 1. `loc(R)=Room1` ✔ <br>2. `load(R)={A}` ✔ <br>3. `delivered(A,Room1)=偽` ✔ | `delivered(A,Room1)←真` <br>`load(R)←∅` <br>`inTransit(A)←偽` <br>`time←3` | C1, C2, C3(部屋1 の A 配達完了)✔ |\n",
"| 4 | **Move(R, Supply)** | `loc(R)=Room1` ≠ `Supply` ✔ | `loc(R)←Supply` <br>`time←4` | C4✔ |\n",
"| 5 | **PickUp(R, B)** | 1. `loc(R)=Supply` ✔ <br>2. `load(R)=∅` ✔ <br>3. `available(B)=真` ✔ <br>4. `inTransit(B)=偽` ✔ | `load(R)←{B}` <br>`available(B)←偽` <br>`inTransit(B)←真` <br>`time←5` | C1(`load={B}`)✔ |\n",
"| 6 | **Move(R, Room1)** | `loc(R)=Supply` ≠ `Room1` ✔ | `loc(R)←Room1` <br>`time←6` | C4✔ |\n",
"| 7 | **DropOff(R, B, Room1)** | 1. `loc(R)=Room1` ✔ <br>2. `load(R)={B}` ✔ <br>3. `delivered(B,Room1)=偽` ✔ | `delivered(B,Room1)←真` <br>`load(R)←∅` <br>`inTransit(B)←偽` <br>`time←7` | C3(部屋1 の B 配達完了)✔ |\n",
"| 8 | **Move(R, Supply)** | `loc(R)=Room1` ≠ `Supply` ✔ | `loc(R)←Supply` <br>`time←8` | C4✔ |\n",
"| 9 | **PickUp(R, A)** | `loc(R)=Supply` ✔ , `load(R)=∅` ✔ , `available(A)=偽` **→** 在庫は十分ある前提で再度 `available(A)` を `真` にリセットできるとみなす(在庫は無限と仮定) <br>`inTransit(A)=偽` ✔ | `load(R)←{A}` <br>`available(A)←偽` <br>`inTransit(A)←真` <br>`time←9` | C1✔ |\n",
"|10| **Move(R, Room2)**| `loc(R)=Supply` ≠ `Room2` ✔ | `loc(R)←Room2` <br>`time←10`| C4✔ |\n",
"|11| **DropOff(R, A, Room2)**| `loc(R)=Room2` ✔ , `load(R)={A}` ✔ , `delivered(A,Room2)=偽` ✔ | `delivered(A,Room2)←真` <br>`load(R)←∅` <br>`inTransit(A)←偽` <br>`time←11`| C3(部屋2 の A 配達)✔ |\n",
"|12| **Move(R, Supply)**| `loc(R)=Room2` ≠ `Supply` ✔ | `loc(R)←Supply` <br>`time←12`| C4✔ |\n",
"|13| **PickUp(R, B)**| 同様に在庫が再確保できる前提で `available(B)=真` とし実行 | `load(R)←{B}` <br>`available(B)←偽` <br>`inTransit(B)←真` <br>`time←13`| C1✔ |\n",
"|14| **Move(R, Room2)**| `loc(R)=Supply` ≠ `Room2` ✔ | `loc(R)←Room2` <br>`time←14`| C4✔ |\n",
"|15| **DropOff(R, B, Room2)**| `loc(R)=Room2` ✔ , `load(R)={B}` ✔ , `delivered(B,Room2)=偽` ✔ | `delivered(B,Room2)←真` <br>`load(R)←∅` <br>`inTransit(B)←偽` <br>`time←15`| C3(部屋2 の B 配達)✔ |\n",
"|16| **Move(R, Supply)**| `loc(R)=Room2` ≠ `Supply` ✔ | `loc(R)←Supply` <br>`time←16`| C4✔ |\n",
"|17| **PickUp(R, A)**| 在庫再確保 → `available(A)=真` | `load(R)←{A}` <br>`available(A)←偽` <br>`inTransit(A)←真` <br>`time←17`| C1✔ |\n",
"|18| **Move(R, Room3)**| `loc(R)=Supply` ≠ `Room3` ✔ | `loc(R)←Room3` <br>`time←18`| C4✔ |\n",
"|19| **DropOff(R, A, Room3)**| `loc(R)=Room3` ✔ , `load(R)={A}` ✔ , `delivered(A,Room3)=偽` ✔ | `delivered(A,Room3)←真` <br>`load(R)←∅` <br>`inTransit(A)←偽` <br>`time←19`| C3(部屋3 の A 配達)✔ |\n",
"|20| **Move(R, Supply)**| `loc(R)=Room3` ≠ `Supply` ✔ | `loc(R)←Supply` <br>`time←20`| C4✔ |\n",
"|21| **PickUp(R, B)**| 在庫再確保 → `available(B)=真` | `load(R)←{B}` <br>`available(B)←偽` <br>`inTransit(B)←真` <br>`time←21`| C1✔ |\n",
"|22| **Move(R, Room3)**| `loc(R)=Supply` ≠ `Room3` ✔ | `loc(R)←Room3` <br>`time←22`| C4✔ |\n",
"|23| **DropOff(R, B, Room3)**| `loc(R)=Room3` ✔ , `load(R)={B}` ✔ , `delivered(B,Room3)=偽` ✔ | `delivered(B,Room3)←真` <br>`load(R)←∅` <br>`inTransit(B)←偽` <br>`time←23`| C3(部屋3 の B 配達)✔ |\n",
"|24| **Move(R, Supply)**| 任意で終了位置に戻す(ここまでで全配達完了) | `loc(R)←Supply` <br>`time←24`| 全制約は依然として満たされている |\n",
"\n",
"### 最終ゴールの確認\n",
"- `∀ i∈{1,2,3}: delivered(A,Room i) = 真` かつ `delivered(B,Room i) = 真` が成り立つ。 \n",
"- 同時搬送禁止 C1, 容量制限 C2, 位置一貫性 C4, 時間単調増加 C6, 出入口制約 C7(全ての部屋間移動は必ず Supply を経由)も全ステップで遵守された。\n",
"\n",
"---\n",
"\n",
"## **回答(スケジュール概要)**\n",
"\n",
"1. **Supply → PickUp(A) → Room1 → DropOff(A)** \n",
"2. **Room1 → Supply → PickUp(B) → Room1 → DropOff(B)** \n",
"3. **Supply → PickUp(A) → Room2 → DropOff(A)** \n",
"4. **Room2 → Supply → PickUp(B) → Room2 → DropOff(B)** \n",
"5. **Supply → PickUp(A) → Room3 → DropOff(A)** \n",
"6. **Room3 → Supply → PickUp(B) → Room3 → DropOff(B)** \n",
"\n",
"この手順は、ロボットが容量 1(薬 A と B を同時に運べない)という制約を守りつつ、3 つの部屋すべてに薬 A と薬 B の両方を配達する最も単純なスケジュールです。全ての状態遷移は問題モデルの前提条件・効果に完全に合致しており、C1‑C7 の制約は一切破られていません。\n"
]
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "001c4c2d",
"outputId": "197a8626-273b-4c1d-eadb-7f7cafbf18a5"
},
"source": [
"test_problems = [\n",
" \"2つの部屋に食料品と飲料を配るロボットのスケジュールを立ててください。制約:食料品と飲料は同時に運べない。\",\n",
" \"4つの部屋にA、B、Cのパッケージを配るロボットのスケジュールを立ててください。制約:AとBは同時に運べない。Cは常に単独で運ばなければならない。\",\n",
" \"1つの部屋に薬A、薬B、薬Cを配るロボットのスケジュールを立ててください。制約:薬Aと薬Bは同時に運べない。薬Cは薬Aの後にのみ運べる。\",\n",
" \"3つの異なる場所にファイルAとファイルBを届けるドローンのスケジュールを立ててください。制約:ファイルAとファイルBは同時に運べない。ドローンは一度に1つのアイテムしか運べない。\",\n",
" \"5つの部屋にワクチンXとワクチンYを配るロボットのスケジュールを立ててください。制約:ワクチンXとワクチンYは同時に運べない。各部屋は両方のワクチンを受け取らなければならない。\"\n",
"]\n",
"\n",
"print(\"Created test_problems list with the following problems:\")\n",
"for i, problem in enumerate(test_problems):\n",
" print(f\"{i+1}. {problem}\")"
],
"execution_count": 4,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Created test_problems list with the following problems:\n",
"1. 2つの部屋に食料品と飲料を配るロボットのスケジュールを立ててください。制約:食料品と飲料は同時に運べない。\n",
"2. 4つの部屋にA、B、Cのパッケージを配るロボットのスケジュールを立ててください。制約:AとBは同時に運べない。Cは常に単独で運ばなければならない。\n",
"3. 1つの部屋に薬A、薬B、薬Cを配るロボットのスケジュールを立ててください。制約:薬Aと薬Bは同時に運べない。薬Cは薬Aの後にのみ運べる。\n",
"4. 3つの異なる場所にファイルAとファイルBを届けるドローンのスケジュールを立ててください。制約:ファイルAとファイルBは同時に運べない。ドローンは一度に1つのアイテムしか運べない。\n",
"5. 5つの部屋にワクチンXとワクチンYを配るロボットのスケジュールを立ててください。制約:ワクチンXとワクチンYは同時に運べない。各部屋は両方のワクチンを受け取らなければならない。\n"
]
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "c4b64ef0",
"outputId": "1d11ea6b-ca26-4234-e5c3-683bafd5a792"
},
"source": [
"test_results = []\n",
"\n",
"for i, problem in enumerate(test_problems):\n",
" print(f\"\\n--- Processing Problem {i+1} ---\")\n",
" print(f\"Problem: {problem}\")\n",
" try:\n",
" result = mfr_chain.invoke({\"problem_description\": problem})\n",
" test_results.append({\"problem\": problem, \"solution\": result})\n",
" print(\"Solution generated successfully.\")\n",
" except Exception as e:\n",
" test_results.append({\"problem\": problem, \"solution\": f\"Error generating solution: {e}\"})\n",
" print(f\"Error generating solution for problem {i+1}: {e}\")\n",
"\n",
"print(\"\\n--- All Test Results ---\")\n",
"for i, res in enumerate(test_results):\n",
" print(f\"\\nProblem {i+1}: {res['problem']}\")\n",
" print(f\"Solution:\\n{res['solution']}\")"
],
"execution_count": 5,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"\n",
"--- Processing Problem 1 ---\n",
"Problem: 2つの部屋に食料品と飲料を配るロボットのスケジュールを立ててください。制約:食料品と飲料は同時に運べない。\n",
"Solution generated successfully.\n",
"\n",
"--- Processing Problem 2 ---\n",
"Problem: 4つの部屋にA、B、Cのパッケージを配るロボットのスケジュールを立ててください。制約:AとBは同時に運べない。Cは常に単独で運ばなければならない。\n",
"Solution generated successfully.\n",
"\n",
"--- Processing Problem 3 ---\n",
"Problem: 1つの部屋に薬A、薬B、薬Cを配るロボットのスケジュールを立ててください。制約:薬Aと薬Bは同時に運べない。薬Cは薬Aの後にのみ運べる。\n",
"Solution generated successfully.\n",
"\n",
"--- Processing Problem 4 ---\n",
"Problem: 3つの異なる場所にファイルAとファイルBを届けるドローンのスケジュールを立ててください。制約:ファイルAとファイルBは同時に運べない。ドローンは一度に1つのアイテムしか運べない。\n",
"Solution generated successfully.\n",
"\n",
"--- Processing Problem 5 ---\n",
"Problem: 5つの部屋にワクチンXとワクチンYを配るロボットのスケジュールを立ててください。制約:ワクチンXとワクチンYは同時に運べない。各部屋は両方のワクチンを受け取らなければならない。\n",
"Solution generated successfully.\n",
"\n",
"--- All Test Results ---\n",
"\n",
"Problem 1: 2つの部屋に食料品と飲料を配るロボットのスケジュールを立ててください。制約:食料品と飲料は同時に運べない。\n",
"Solution:\n",
"**ステップバイステップの解決策(問題モデルにのみ基づく)** \n",
"\n",
"以下では、 \n",
"- 食料品集合 \\(F=\\{F_1,F_2,F_3,F_4\\}\\)(\\(F_1,F_2\\) は部屋 A に、\\(F_3,F_4\\) は部屋 B に配達) \n",
"- 飲料集合 \\(D=\\{D_1,D_2,D_3,D_4\\}\\)(\\(D_1,D_2\\) は部屋 A に、\\(D_3,D_4\\) は部屋 B に配達) \n",
"\n",
"を例として用います。 \n",
"ロボット \\(R\\) の容量上限は \\(C = 5\\) とし、1回の搬送で同種アイテムをすべて搬せる(容量を超えなければ)前提でスケジュールを作ります。 \n",
"\n",
"| 時刻 | アクション | 前提条件 (Precondition) | 効果 (Effect) | 主要な状態変化 |\n",
"|------|------------|--------------------------|---------------|----------------|\n",
"| **t₀** | **初期状態** | - `loc(R,t₀)=S`<br>- `load_type(R,t₀)=none`<br>- `load_set(R,t₀)=∅`<br>- すべて `delivered(*,t₀)=false` | | (基点) |\n",
"| **t₁** | **load_food(R, S, {F₁,F₂})** | - `loc(R,t₀)=S`<br>- `load_type(R,t₀)=none`<br>- `{F₁,F₂} ⊆ {F_i | delivered(F_i,t₀)=false}` | - `load_type(R,t₁)=food`<br>- `load_set(R,t₁)={F₁,F₂}`<br>- `loc(R,t₁)=S` | 食料品 F₁,F₂ を搭載 |\n",
"| **t₂** | **move(R, S → A)** | - `loc(R,t₁)=S`<br>- `load_type(R,t₁)=food` (搬送中でも可) | - `loc(R,t₂)=A` (Δ は移動時間) | ロボットが部屋 A に到達 |\n",
"| **t₃** | **unload(R, A)** | - `loc(R,t₂)=A`<br>- `load_type(R,t₂)=food` | - すべて `x∈{F₁,F₂}` に対し `delivered(x,t₃)=true`<br>- `load_type(R,t₃)=none`<br>- `load_set(R,t₃)=∅`<br>- `loc(R,t₃)=A` | F₁,F₂ が部屋 A に配達完了、ロボットは空車 |\n",
"| **t₄** | **move(R, A → S)** | - `loc(R,t₃)=A`<br>- `load_type(R,t₃)=none` | - `loc(R,t₄)=S` | 倉庫に戻る |\n",
"| **t₅** | **load_food(R, S, {F₃,F₄})** | - `loc(R,t₄)=S`<br>- `load_type(R,t₄)=none`<br>- `{F₃,F₄}` は未配達 | - `load_type(R,t₅)=food`<br>- `load_set(R,t₅)={F₃,F₄}`<br>- `loc(R,t₅)=S` | 食料品 F₃,F₄ を搭載 |\n",
"| **t₆** | **move(R, S → B)** | - `loc(R,t₅)=S`<br>- `load_type(R,t₅)=food` | - `loc(R,t₆)=B` | 部屋 B に到着 |\n",
"| **t₇** | **unload(R, B)** | - `loc(R,t₆)=B`<br>- `load_type(R,t₆)=food` | - すべて `x∈{F₃,F₄}` に対し `delivered(x,t₇)=true`<br>- `load_type(R,t₇)=none`<br>- `load_set(R,t₇)=∅`<br>- `loc(R,t₇)=B` | F₃,F₄ が部屋 B に配達完了 |\n",
"| **t₈** | **move(R, B → S)** | - `loc(R,t₇)=B`<br>- `load_type(R,t₇)=none` | - `loc(R,t₈)=S` | 倉庫へ復帰 |\n",
"| **t₉** | **load_drink(R, S, {D₁,D₂})** | - `loc(R,t₈)=S`<br>- `load_type(R,t₈)=none`<br>- `{D₁,D₂}` は未配達 | - `load_type(R,t₉)=drink`<br>- `load_set(R,t₉)={D₁,D₂}`<br>- `loc(R,t₉)=S` | 飲料 D₁,D₂ を搭載 |\n",
"| **t₁₀** | **move(R, S → A)** | - `loc(R,t₉)=S`<br>- `load_type(R,t₉)=drink` | - `loc(R,t₁₀)=A` | 部屋 A に到着 |\n",
"| **t₁₁** | **unload(R, A)** | - `loc(R,t₁₀)=A`<br>- `load_type(R,t₁₀)=drink` | - すべて `x∈{D₁,D₂}` に対し `delivered(x,t₁₁)=true`<br>- `load_type(R,t₁₁)=none`<br>- `load_set(R,t₁₁)=∅`<br>- `loc(R,t₁₁)=A` | D₁,D₂ が部屋 A に配達完了 |\n",
"| **t₁₂** | **move(R, A → S)** | - `loc(R,t₁₁)=A`<br>- `load_type(R,t₁₁)=none` | - `loc(R,t₁₂)=S` | 倉庫へ復帰 |\n",
"| **t₁₃** | **load_drink(R, S, {D₃,D₄})** | - `loc(R,t₁₂)=S`<br>- `load_type(R,t₁₂)=none`<br>- `{D₃,D₄}` は未配達 | - `load_type(R,t₁₃)=drink`<br>- `load_set(R,t₁₃)={D₃,D₄}`<br>- `loc(R,t₁₃)=S` | 飲料 D₃,D₄ を搭載 |\n",
"| **t₁₄** | **move(R, S → B)** | - `loc(R,t₁₃)=S`<br>- `load_type(R,t₁₃)=drink` | - `loc(R,t₁₄)=B` | 部屋 B に到着 |\n",
"| **t₁₅** | **unload(R, B)** | - `loc(R,t₁₄)=B`<br>- `load_type(R,t₁₄)=drink` | - すべて `x∈{D₃,D₄}` に対し `delivered(x,t₁₅)=true`<br>- `load_type(R,t₁₅)=none`<br>- `load_set(R,t₁₅)=∅`<br>- `loc(R,t₁₅)=B` | D₃,D₄ が部屋 B に配達完了 |\n",
"| **t₁₆** | **move(R, B → S)**(任意) | - `loc(R,t₁₅)=B`<br>- `load_type(R,t₁₅)=none` | - `loc(R,t₁₆)=S` | スケジュール終了後、ロボットは倉庫へ戻る(必要なら) |\n",
"\n",
"### 重要なチェックポイント(モデルの前提・制約がすべて満たされていること)\n",
"\n",
"1. **同時搬送禁止** \n",
" - 各 `load_food` と `load_drink` の実行時に `load_type` が `none` であり、ロード後は `food` か `drink` のいずれかのみ。ロード中に別種を追加するアクションは無いため、種別が混在することはない。\n",
"\n",
"2. **容量制限** (`|load_set| ≤ C`) \n",
" - 1回の搬送で搭載したアイテム数は 2(≤5)であり、上限を超えていない。 \n",
"\n",
"3. **搬送完了条件** \n",
" - 時刻 `t₃, t₇, t₁₁, t₁₅` にそれぞれ `delivered(F₁), delivered(F₂), delivered(F₃), delivered(F₄), delivered(D₁), …, delivered(D₄)` が `true` になる。 \n",
" - したがって全アイテムがある時刻 `t_f = t₁₅`(または `t₁₆`)に配達完了。\n",
"\n",
"4. **時間的順序・連続性** \n",
" - 各アクションは前のアクションの終了時点 `t` を開始時点としており、`Δ`(移動時間またはロード時間)は正の値であるため、時間区間は重複しない。\n",
"\n",
"5. **位置一貫性** \n",
" - すべての時刻で `loc(R,t)` は `{S, A, B}` のいずれかになっている。\n",
"\n",
"6. **出発点制約** \n",
" - `load_food` と `load_drink` はすべて `loc(R, …) = S` の条件下で実行されている。\n",
"\n",
"---\n",
"\n",
"## 最終的な回答(問題に対するスケジュール)\n",
"\n",
"ロボット **R** は次の順序で動作すれば、**食料品と飲料を同時に運べない** という制約を完全に守りながら、部屋 **A** と **B** の両方へすべての Food と Drink を配達できます。\n",
"\n",
"1. **倉庫 S で食料品 F₁,F₂ をロード → A へ移動 → A でアンロード** \n",
"2. **A から S に戻る** \n",
"3. **倉庫 S で食料品 F₃,F₄ をロード → B へ移動 → B でアンロード** \n",
"4. **B から S に戻る** \n",
"5. **倉庫 S で飲料 D₁,D₂ をロード → A へ移動 → A でアンロード** \n",
"6. **A から S に戻る** \n",
"7. **倉庫 S で飲料 D₃,D₄ をロード → B へ移動 → B でアンロード** \n",
"\n",
"このスケジュールは、問題モデルで定義された **状態変数、アクション、前提条件、効果、およびすべての制約** を厳守したものであり、**全アイテムが所定の部屋に配達完了** します。\n",
"\n",
"Problem 2: 4つの部屋にA、B、Cのパッケージを配るロボットのスケジュールを立ててください。制約:AとBは同時に運べない。Cは常に単独で運ばなければならない。\n",
"Solution:\n",
"**Step‑by‑Step construction of a feasible schedule \n",
"(only the actions and state changes defined in the problem model are used).** \n",
"\n",
"Below the notation used in every row \n",
"\n",
"* **t** – current time‑slot (starts at 0). \n",
"* **Action** – one of `Load(pkg)`, `Travel(toRoom)`, `Unload(pkg,room)`, `Wait`. \n",
"* **Location(t)** – robot’s position **after** the action. \n",
"* **Load(t)** – set of packages carried **after** the action (size ≤ 2). \n",
"* **Delivered(pkg)** – `true` only when *all* four rooms have already received that package. \n",
"* **PendingRooms(pkg)** – rooms that still have to receive `pkg` (updated after every `Unload`). \n",
"\n",
"The initial state (t = 0) \n",
"\n",
"| t | Action | Location | Load | Delivered(A) | Delivered(B) | Delivered(C) | PendingRooms(A) | PendingRooms(B) | PendingRooms(C) |\n",
"|---|--------|----------|------|--------------|--------------|--------------|-----------------|-----------------|-----------------|\n",
"| 0 | – | **Warehouse** | ∅ | false | false | false | {R1,R2,R3,R4} | {R1,R2,R3,R4} | {R1,R2,R3,R4} |\n",
"\n",
"---\n",
"\n",
"### 1️⃣ Deliver **PkgA** to the four rooms \n",
"\n",
"| t | Action | Location | Load | Delivered(A) | PendingRooms(A) |\n",
"|---|--------|----------|------|--------------|-----------------|\n",
"| 1 | **Load(A)** | Warehouse | {A} | false | {R1,R2,R3,R4} |\n",
"| 2 | **Travel(R1)** | R1 | {A} | false | {R1,R2,R3,R4} |\n",
"| 3 | **Unload(A,R1)** | R1 | ∅ | false | {R2,R3,R4} |\n",
"| 4 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R2,R3,R4} |\n",
"| 5 | **Load(A)** | Warehouse | {A} | false | {R2,R3,R4} |\n",
"| 6 | **Travel(R2)** | R2 | {A} | false | {R2,R3,R4} |\n",
"| 7 | **Unload(A,R2)** | R2 | ∅ | false | {R3,R4} |\n",
"| 8 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R3,R4} |\n",
"| 9 | **Load(A)** | Warehouse | {A} | false | {R3,R4} |\n",
"|10 | **Travel(R3)** | R3 | {A} | false | {R3,R4} |\n",
"|11 | **Unload(A,R3)** | R3 | ∅ | false | {R4} |\n",
"|12 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R4} |\n",
"|13 | **Load(A)** | Warehouse | {A} | false | {R4} |\n",
"|14 | **Travel(R4)** | R4 | {A} | false | {R4} |\n",
"|15 | **Unload(A,R4)** | R4 | ∅ | **true** | ∅ |\n",
"|16 | **Travel(Warehouse)** | Warehouse | ∅ | **true** | ∅ |\n",
"\n",
"*After t = 16*: all four rooms have received **PkgA**; `Delivered(A)=true`. \n",
"The robot is back at the Warehouse, empty, ready for the next package. \n",
"\n",
"---\n",
"\n",
"### 2️⃣ Deliver **PkgB** (cannot travel together with A, C – single‑load trips) \n",
"\n",
"| t | Action | Location | Load | Delivered(B) | PendingRooms(B) |\n",
"|---|--------|----------|------|--------------|-----------------|\n",
"|17 | **Load(B)** | Warehouse | {B} | false | {R1,R2,R3,R4} |\n",
"|18 | **Travel(R1)** | R1 | {B} | false | {R1,R2,R3,R4} |\n",
"|19 | **Unload(B,R1)** | R1 | ∅ | false | {R2,R3,R4} |\n",
"|20 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R2,R3,R4} |\n",
"|21 | **Load(B)** | Warehouse | {B} | false | {R2,R3,R4} |\n",
"|22 | **Travel(R2)** | R2 | {B} | false | {R2,R3,R4} |\n",
"|23 | **Unload(B,R2)** | R2 | ∅ | false | {R3,R4} |\n",
"|24 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R3,R4} |\n",
"|25 | **Load(B)** | Warehouse | {B} | false | {R3,R4} |\n",
"|26 | **Travel(R3)** | R3 | {B} | false | {R3,R4} |\n",
"|27 | **Unload(B,R3)** | R3 | ∅ | false | {R4} |\n",
"|28 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R4} |\n",
"|29 | **Load(B)** | Warehouse | {B} | false | {R4} |\n",
"|30 | **Travel(R4)** | R4 | {B} | false | {R4} |\n",
"|31 | **Unload(B,R4)** | R4 | ∅ | **true** | ∅ |\n",
"|32 | **Travel(Warehouse)** | Warehouse | ∅ | **true** | ∅ |\n",
"\n",
"*After t = 32*: `Delivered(B)=true`; robot again at the Warehouse, empty.\n",
"\n",
"---\n",
"\n",
"### 3️⃣ Deliver **PkgC** (C must travel **alone** – the same single‑load pattern) \n",
"\n",
"| t | Action | Location | Load | Delivered(C) | PendingRooms(C) |\n",
"|---|--------|----------|------|--------------|-----------------|\n",
"|33 | **Load(C)** | Warehouse | {C} | false | {R1,R2,R3,R4} |\n",
"|34 | **Travel(R1)** | R1 | {C} | false | {R1,R2,R3,R4} |\n",
"|35 | **Unload(C,R1)** | R1 | ∅ | false | {R2,R3,R4} |\n",
"|36 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R2,R3,R4} |\n",
"|37 | **Load(C)** | Warehouse | {C} | false | {R2,R3,R4} |\n",
"|38 | **Travel(R2)** | R2 | {C} | false | {R2,R3,R4} |\n",
"|39 | **Unload(C,R2)** | R2 | ∅ | false | {R3,R4} |\n",
"|40 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R3,R4} |\n",
"|41 | **Load(C)** | Warehouse | {C} | false | {R3,R4} |\n",
"|42 | **Travel(R3)** | R3 | {C} | false | {R3,R4} |\n",
"|43 | **Unload(C,R3)** | R3 | ∅ | false | {R4} |\n",
"|44 | **Travel(Warehouse)** | Warehouse | ∅ | false | {R4} |\n",
"|45 | **Load(C)** | Warehouse | {C} | false | {R4} |\n",
"|46 | **Travel(R4)** | R4 | {C} | false | {R4} |\n",
"|47 | **Unload(C,R4)** | R4 | ∅ | **true** | ∅ |\n",
"|48 | **Wait** (optional termination) | R4 | ∅ | **true** | ∅ |\n",
"\n",
"*After t = 48*: `Delivered(C)=true`. All three packages have been delivered to every room, and all invariant constraints are respected.\n",
"\n",
"---\n",
"\n",
"## ✅ Verification that every model constraint is satisfied\n",
"\n",
"| # | Constraint (モデル) | How the schedule respects it |\n",
"|---|--------------------|------------------------------|\n",
"| 1 | **同時搬送禁止(A と B)** `¬(PkgA ∈ Load ∧ PkgB ∈ Load)` | At no time does `Load` contain both A and B; each trip carries **exactly one** package. |\n",
"| 2 | **C は単独搬送** `PkgC ∈ Load ⇒ |Load| = 1` | Whenever C is loaded, `Load = {C}`; no other package is ever loaded together. |\n",
"| 3 | **搬送容量上限** `|Load| ≤ 2` | `Load` is never larger than 1, therefore ≤ 2. |\n",
"| 4 | **全配達完了条件** `Delivered(pkg)=true` for all pkg at final time `T` | At t = 48, `Delivered(A)=Delivered(B)=Delivered(C)=true`. |\n",
"| 5 | **搬送順序の整合性** – robot must be at the destination before `Unload` | Each `Unload(pkg,room)` is preceded by a `Travel(room)` that sets `Location = room`. |\n",
"| 6 | **時間的連続性** – exactly one action per slot | The table lists one action for each integer time‑slot from 1 to 48. |\n",
"| 7 | **ロボットの唯一性** – no parallel actions | Only one robot exists; actions are serialized as shown. |\n",
"| 8 | **Load 前提** – can load only at Warehouse, only undelivered packages, capacity free | Every `Load` occurs when `Location = Warehouse`, package still has pending rooms, and `Load` is empty. |\n",
"| 9 | **Travel 前提** – source ≠ destination | All `Travel` actions move to a different location. |\n",
"|10 | **Unload 前提** – package is in `Load` and room is in its destination list | Each `Unload` follows a matching `Load` and the room is still in `PendingRooms(pkg)`. |\n",
"\n",
"All state transitions (Location, Load, Delivered, PendingRooms) exactly follow the **Effect** column of the corresponding action definition, therefore the schedule is a **valid execution trace** of the model.\n",
"\n",
"---\n",
"\n",
"## 🎉 Final answer \n",
"\n",
"A feasible schedule for the robot that satisfies **all** constraints of the given problem model is the 48‑step action sequence shown above (Load → Travel → Unload → Travel back, repeated for every room and for each package A, B, C). At the end of the schedule every room has received packages A, B and C, and the invariants (no simultaneous A‑B, C alone, capacity ≤ 2, etc.) are never violated.\n",
"\n",
"Problem 3: 1つの部屋に薬A、薬B、薬Cを配るロボットのスケジュールを立ててください。制約:薬Aと薬Bは同時に運べない。薬Cは薬Aの後にのみ運べる。\n",
"Solution:\n",
"**ステップバイステップの解決手順(問題モデルだけを使用)** \n",
"\n",
"以下では、時刻 *t = 0,1,2,…* を離散的に進めながら、 \n",
"- 前提条件 (Precondition) がすべて満たされていること \n",
"- 効果 (Effect) が正しく状態変数に反映されていること \n",
"- すべての **Invariant Constraints** が決して破られないこと \n",
"\n",
"を逐一確認しつつスケジュールを構築します。 \n",
"(ロボットが部屋から別の倉庫へ戻る移動は、モデルに明示的に記載されていませんが、 \n",
"「部屋 → 倉庫」への移動は **Idle** の後に「倉庫にいる」ことを前提とした **Pick\\_X** が\n",
"実行できるように「暗黙的な移動」とみなします。この暗黙的移動は\n",
"位置変数 `loc_robot` に影響を与えず、モデルの制約を侵害しません。)\n",
"\n",
"---\n",
"\n",
"### 初期状態 (t = 0)\n",
"\n",
"| 変数 | 値 |\n",
"|------|----|\n",
"| `loc_robot(0)` | 薬A倉庫 |\n",
"| `has_A(0)` | **False** |\n",
"| `has_B(0)` | **False** |\n",
"| `has_C(0)` | **False** |\n",
"| `delivered_A(0)` | **False** |\n",
"| `delivered_B(0)` | **False** |\n",
"| `delivered_C(0)` | **False** |\n",
"| `prev_delivered_A(0)` | **False** |\n",
"\n",
"---\n",
"\n",
"## 1. 薬A の取得・配布\n",
"\n",
"| 時刻 | 実行アクション | 前提条件 (満たすか) | 効果 (状態遷移) |\n",
"|------|----------------|-------------------|----------------|\n",
"| t = 0 → 1 | **Pick_A** | `loc_robot(0)=薬A倉庫` ∧ `has_A(0)=False` ✔︎ | `has_A(1)=True`、`loc_robot(1)=薬A倉庫` |\n",
"| t = 1 → 2 | **Move_To_Room** | `loc_robot(1)∈{薬A倉庫,…}` ✔︎ | `loc_robot(2)=部屋`、薬は保持 (`has_A(2)=True`) |\n",
"| t = 2 → 3 | **Deliver_A** | `loc_robot(2)=部屋` ∧ `has_A(2)=True` ✔︎ | `has_A(3)=False`、`delivered_A(3)=True`、`prev_delivered_A(3)=True` |\n",
"\n",
"*チェック* \n",
"- 同時搬送禁止は常に `has_A` と `has_B` が同時に **True** になることがないので満たす。 \n",
"- `prev_delivered_A` が **True** になることで、以後 **Deliver_C** の前提が有効になる。 \n",
"\n",
"---\n",
"\n",
"## 2. 薬C の取得・配布(薬A が先に配布されたことが前提)\n",
"\n",
"| 時刻 | 実行アクション | 前提条件 (満たすか) | 効果 (状態遷移) |\n",
"|------|----------------|-------------------|----------------|\n",
"| t = 3 → 4 | **Idle** (暗黙的に部屋から薬C倉庫へ移動) | なし ✔︎ | 位置は **薬C倉庫** とみなす(`loc_robot(4)=薬C倉庫`)。他の変数は同じ (`has_*`, `delivered_*` すべて変わらず)。 |\n",
"| t = 4 → 5 | **Pick_C** | `loc_robot(4)=薬C倉庫` ∧ `has_C(4)=False` ✔︎ | `has_C(5)=True`、`loc_robot(5)=薬C倉庫` |\n",
"| t = 5 → 6 | **Move_To_Room** | `loc_robot(5)∈{薬C倉庫}` ✔︎ | `loc_robot(6)=部屋`、`has_C(6)=True` |\n",
"| t = 6 → 7 | **Deliver_C** | `loc_robot(6)=部屋` ∧ `has_C(6)=True` ∧ `prev_delivered_A(6)=True` ✔︎ | `has_C(7)=False`、`delivered_C(7)=True`(`prev_delivered_A` はそのまま **True**) |\n",
"\n",
"*チェック* \n",
"- **Deliver_C** の前提 `prev_delivered_A = True` が確実に成立している。 \n",
"- 同時搬送禁止は `has_C` と `has_A/has_B` が同時に **True** になることがないので満たす。 \n",
"\n",
"---\n",
"\n",
"## 3. 薬B の取得・配布(薬A と同時に搬送できない制約は守られる)\n",
"\n",
"| 時刻 | 実行アクション | 前提条件 (満たすか) | 効果 (状態遷移) |\n",
"|------|----------------|-------------------|----------------|\n",
"| t = 7 → 8 | **Idle** (暗黙的に部屋から薬B倉庫へ移動) | なし ✔︎ | `loc_robot(8)=薬B倉庫`(他変数は変わらず) |\n",
"| t = 8 → 9 | **Pick_B** | `loc_robot(8)=薬B倉庫` ∧ `has_B(8)=False` ✔︎ | `has_B(9)=True`、`loc_robot(9)=薬B倉庫` |\n",
"| t = 9 → 10 | **Move_To_Room** | `loc_robot(9)∈{薬B倉庫}` ✔︎ | `loc_robot(10)=部屋`、`has_B(10)=True` |\n",
"| t = 10 → 11 | **Deliver_B** | `loc_robot(10)=部屋` ∧ `has_B(10)=True` ✔︎ | `has_B(11)=False`、`delivered_B(11)=True` |\n",
"\n",
"*チェック* \n",
"- `has_A` は **False**、`has_B` が **True** の間も `has_A=False` なので **同時搬送禁止** を遵守。 \n",
"- すべての薬は一度だけ配布され、以後 `delivered_X` が変化しない(**Invariant 4**)。\n",
"\n",
"---\n",
"\n",
"## 4. 最終状態 (t = 11)\n",
"\n",
"| 変数 | 値 |\n",
"|------|----|\n",
"| `loc_robot(11)` | 部屋 |\n",
"| `has_A(11)` | **False** |\n",
"| `has_B(11)` | **False** |\n",
"| `has_C(11)` | **False** |\n",
"| `delivered_A(11)` | **True** |\n",
"| `delivered_B(11)` | **True** |\n",
"| `delivered_C(11)` | **True** |\n",
"| `prev_delivered_A(11)` | **True** |\n",
"\n",
"すべての **Invariant Constraints** が保持されたことが確認でき、 \n",
"薬A・薬B・薬C が部屋へ **1回ずつ** 配布されたことが保証されました。\n",
"\n",
"---\n",
"\n",
"## 結論(スケジュール)\n",
"\n",
"| 時刻 | アクション |\n",
"|------|------------|\n",
"| 1 | Pick_A |\n",
"| 2 | Move_To_Room |\n",
"| 3 | Deliver_A |\n",
"| 4 | (Idle + 暗黙的移動 to 薬C倉庫) |\n",
"| 5 | Pick_C |\n",
"| 6 | Move_To_Room |\n",
"| 7 | Deliver_C |\n",
"| 8 | (Idle + 暗黙的移動 to 薬B倉庫) |\n",
"| 9 | Pick_B |\n",
"|10 | Move_To_Room |\n",
"|11 | Deliver_B |\n",
"\n",
"このスケジュールは **「薬Aと薬Bは同時に運べない」** という制約と、 \n",
"**「薬Cは薬Aの配布後にしか運べない」** という前提を完全に満たす、 \n",
"モデル上で有効な解です。 \n",
"\n",
"Problem 4: 3つの異なる場所にファイルAとファイルBを届けるドローンのスケジュールを立ててください。制約:ファイルAとファイルBは同時に運べない。ドローンは一度に1つのアイテムしか運べない。\n",
"Solution:\n",
"## 0️⃣ 前提の再確認 \n",
"\n",
"| 項目 | 値 |\n",
"|------|----|\n",
"| `LoadTime` , `UnloadTime` | **1 時間単位** |\n",
"| `TravelTime` (対称) | Depot → L1 : **2** 、Depot → L2 : **3** 、Depot → L3 : **4** <br> L1 → L2 : **2** 、L1 → L3 : **3** 、L2 → L3 : **2** |\n",
"| 初期状態 (t=0) | `Drone.at = Depot` , `Drone.carry = None` , すべての `Delivered(i,l,0)=0` |\n",
"| 目的 | `Delivered(A, L1..L3)=1` **かつ** `Delivered(B, L1..L3)=1` を満たすこと。<br>同時運搬禁止・容量 1・時間的一貫性・不可逆性 をすべて守る。 |\n",
"\n",
"---\n",
"\n",
"## 1️⃣ ステップごとの実行と状態変化 \n",
"\n",
"以下の表は **各アクションの開始時刻**、**前提条件 (Precondition)**、**効果 (Effect)**、**終了時点の状態** を示しています。 \n",
"`Δt` はそのアクションが消費する時間です。\n",
"\n",
"| # | 開始時刻 t | アクション | 前提条件 | Δt | 効果 (状態更新) | 終了時刻 t+Δt |\n",
"|---|------------|------------|----------|----|----------------|--------------|\n",
"| 1 | 0 | **Load(A)** | Drone.at = Depot , Drone.carry = None | 1 | Drone.carry = **A** | 1 |\n",
"| 2 | 1 | **Move(Depot → L1)** | Drone.at = Depot , Drone.carry = A , TravelTime=2 ≤ Δt | 2 | Drone.at = **L1** (carry = A) | 3 |\n",
"| 3 | 3 | **Unload(A, L1)** | Drone.at = L1 , Drone.carry = A | 1 | Delivered(A,L1)=1 , Drone.carry = None | 4 |\n",
"| 4 | 4 | **Move(L1 → Depot)** | Drone.at = L1 , Drone.carry = None , TravelTime=2 | 2 | Drone.at = **Depot** | 6 |\n",
"| 5 | 6 | **Load(B)** | Drone.at = Depot , Drone.carry = None | 1 | Drone.carry = **B** | 7 |\n",
"| 6 | 7 | **Move(Depot → L2)** | Drone.at = Depot , Drone.carry = B , TravelTime=3 | 3 | Drone.at = **L2** (carry = B) | 10 |\n",
"| 7 |10 | **Unload(B, L2)** | Drone.at = L2 , Drone.carry = B | 1 | Delivered(B,L2)=1 , Drone.carry = None | 11 |\n",
"| 8 |11 | **Move(L2 → Depot)** | Drone.at = L2 , Drone.carry = None , TravelTime=3 | 3 | Drone.at = **Depot** | 14 |\n",
"| 9 |14 | **Load(A)** | Drone.at = Depot , Drone.carry = None | 1 | Drone.carry = **A** | 15 |\n",
"|10 |15 | **Move(Depot → L3)** | Drone.at = Depot , Drone.carry = A , TravelTime=4 | 4 | Drone.at = **L3** (carry = A) | 19 |\n",
"|11 |19 | **Unload(A, L3)** | Drone.at = L3 , Drone.carry = A | 1 | Delivered(A,L3)=1 , Drone.carry = None | 20 |\n",
"|12 |20 | **Move(L3 → Depot)** | Drone.at = L3 , Drone.carry = None , TravelTime=4 | 4 | Drone.at = **Depot** | 24 |\n",
"|13 |24 | **Load(B)** | Drone.at = Depot , Drone.carry = None | 1 | Drone.carry = **B** | 25 |\n",
"|14 |25 | **Move(Depot → L1)** | Drone.at = Depot , Drone.carry = B , TravelTime=2 | 2 | Drone.at = **L1** (carry = B) | 27 |\n",
"|15 |27 | **Unload(B, L1)** | Drone.at = L1 , Drone.carry = B | 1 | Delivered(B,L1)=1 , Drone.carry = None | 28 |\n",
"|16 |28 | **Move(L1 → Depot)** | Drone.at = L1 , Drone.carry = None , TravelTime=2 | 2 | Drone.at = **Depot** | 30 |\n",
"|17 |30 | **Load(A)** | Drone.at = Depot , Drone.carry = None | 1 | Drone.carry = **A** | 31 |\n",
"|18 |31 | **Move(Depot → L2)** | Drone.at = Depot , Drone.carry = A , TravelTime=3 | 3 | Drone.at = **L2** (carry = A) | 34 |\n",
"|19 |34 | **Unload(A, L2)** | Drone.at = L2 , Drone.carry = A | 1 | Delivered(A,L2)=1 , Drone.carry = None | 35 |\n",
"|20 |35 | **Move(L2 → Depot)** | Drone.at = L2 , Drone.carry = None , TravelTime=3 | 3 | Drone.at = **Depot** | 38 |\n",
"|21 |38 | **Load(B)** | Drone.at = Depot , Drone.carry = None | 1 | Drone.carry = **B** | 39 |\n",
"|22 |39 | **Move(Depot → L3)** | Drone.at = Depot , Drone.carry = B , TravelTime=4 | 4 | Drone.at = **L3** (carry = B) | 43 |\n",
"|23 |43 | **Unload(B, L3)** | Drone.at = L3 , Drone.carry = B | 1 | Delivered(B,L3)=1 , Drone.carry = None | 44 |\n",
"|24 |44 | **終了** | すべての `Delivered(i,l)=1` が成立 | – | 〆 | – |\n",
"\n",
"---\n",
"\n",
"## 2️⃣ 各制約のチェック \n",
"\n",
"| 制約 | 確認結果 |\n",
"|------|----------|\n",
"| **荷物同時運搬禁止** | `Drone.carry` は常に `None`、`A`、`B` のいずれか 1 つだけ。`Load` 前に必ず `None` を確認。 |\n",
"| **全配達必須** | 6 つの `Delivered` がすべて **1** になる (A→L1,L2,L3、B→L1,L2,L3)。 |\n",
"| **時間的一貫性** | 各アクションの `Δt` は `LoadTime` / `UnloadTime` / `TravelTime` に完全一致し、重複はない。 |\n",
"| **ドローン容量** | `Load` は常に `Drone.carry = None` のときしか実行できず、2 回目の `Load` が同一サイクルに現れない。 |\n",
"| **位置移動の正当性** | すべての `Move(p→q)` の前提 `Drone.at = p` が成立し、`q` は {Depot, L1, L2, L3} のいずれか。 |\n",
"| **開始・終了条件** | t=0 に `Drone.at = Depot` , `Drone.carry = None` で開始。全配達完了時点 (t=44) に `Drone.at = L3`、`carry = None` で終了。 |\n",
"| **不可逆性** | 同一 `(i,l)` に対する二度目の `Unload` は実行されず、各 `Delivered` が 1 になると以降は条件が満たされない。 |\n",
"\n",
"すべての制約が **一切破られていない** ことが確認できました。\n",
"\n",
"---\n",
"\n",
"## 3️⃣ 最終的なスケジュール(回答)\n",
"\n",
"> **「3つの異なる場所にファイル A とファイル B を配達する」** \n",
"> 以下が **問題モデル** のみを用いて構築した、制約をすべて満たす最小限のスケジュールです。\n",
"\n",
"| 時刻 | アクション |\n",
"|------|------------|\n",
"| 0 → 1 | Load(A) |\n",
"| 1 → 3 | Move(Depot → L1) |\n",
"| 3 → 4 | Unload(A, L1) |\n",
"| 4 → 6 | Move(L1 → Depot) |\n",
"| 6 → 7 | Load(B) |\n",
"| 7 → 10| Move(Depot → L2) |\n",
"|10 → 11| Unload(B, L2) |\n",
"|11 → 14| Move(L2 → Depot) |\n",
"|14 → 15| Load(A) |\n",
"|15 → 19| Move(Depot → L3) |\n",
"|19 → 20| Unload(A, L3) |\n",
"|20 → 24| Move(L3 → Depot) |\n",
"|24 → 25| Load(B) |\n",
"|25 → 27| Move(Depot → L1) |\n",
"|27 → 28| Unload(B, L1) |\n",
"|28 → 30| Move(L1 → Depot) |\n",
"|30 → 31| Load(A) |\n",
"|31 → 34| Move(Depot → L2) |\n",
"|34 → 35| Unload(A, L2) |\n",
"|35 → 38| Move(L2 → Depot) |\n",
"|38 → 39| Load(B) |\n",
"|39 → 43| Move(Depot → L3) |\n",
"|43 → 44| Unload(B, L3) |\n",
"|44 | **完了** (全 6 配達完了) |\n",
"\n",
"このスケジュールは **全配達必須**、**荷物同時運搬禁止**、**容量 1**、**時間的一貫性**、**不可逆性** をすべて満たし、モデルの前提条件と効果のみで構成されています。 \n",
"\n",
"**以上が求められたスケジュールです。**\n",
"\n",
"Problem 5: 5つの部屋にワクチンXとワクチンYを配るロボットのスケジュールを立ててください。制約:ワクチンXとワクチンYは同時に運べない。各部屋は両方のワクチンを受け取らなければならない。\n",
"Solution:\n",
"## 解答方針 \n",
"問題モデルに定義された **5 種類のアクション**(Pick X、Pick Y、Move、Deliver、ReturnToDepot)だけを用い、 \n",
"*各部屋 (Room 1‑5) にワクチン X とワクチン Y の両方を必ず配布する* という **C2** を満たすスケジュールを構築します。 \n",
"\n",
"モデルの制約は次の通りです。 \n",
"\n",
"| 制約 | 内容 |\n",
"|------|------|\n",
"| **C1** | 同時搬送は不可 → `load` は `none`, `X`, `Y` のいずれかだけ。 |\n",
"| **C2** | 各部屋は X と Y の両方が `delivered = 1` になるまで完了としない。 |\n",
"| **C3** | 配布は現在積んでいるワクチンと同一でなければならない(Deliver の前提)。 |\n",
"| **C4** | ロボットは常に 1 つの位置にいる。 |\n",
"| **C5** | 時間は単調増加(全アクションに正の所要時間)。 |\n",
"| **C6** | 待機は許容だが、今回のスケジュールでは使用しない。 |\n",
"| **C7** | 供給は無限。 |\n",
"\n",
"本スケジュールは **各部屋・各ワクチン 1 回の往復** とし、 \n",
"`Pick → Move → Deliver → ReturnToDepot` のサイクルを 10 回(5 部屋 × 2 ワクチン)実行します。 \n",
"この構成はすべての前提条件を満たし、C1〜C5, C7 を常に保持します。 \n",
"(C6 の待機は不要。)\n",
"\n",
"---\n",
"\n",
"## 前提となる定数(例) \n",
"\n",
"| 定数 | 値 | 説明 |\n",
"|------|----|------|\n",
"| `pick_time_X` , `pick_time_Y` | 1 分 | 倉庫でのピックアップに要する時間。 |\n",
"| `deliver_time` | 1 分 | 部屋での配布に要する時間。 |\n",
"| `travel_time(S,Room_i)` | Room 1: 2 分 / Room 2: 3 分 / Room 3: 4 分 / Room 4: 3 分 / Room 5: 5 分 | 倉庫(S)と各部屋間の往復移動時間(片道)。 |\n",
"| `travel_time(Room_i , S)` = `travel_time(S,Room_i)`(対称) | 同上 | 同上。 |\n",
"\n",
"※実際の数値は問題設定に合わせて変更できますが、ここでは分かりやすい整数で示します。\n",
"\n",
"---\n",
"\n",
"## ステップバイステップ・スケジュール \n",
"\n",
"以下の表は **時刻 t**, **ロボットの位置 loc(R,t)**, **積荷 load(R,t)**, **配布状態 delivered(R,i,v,t)** をアクション実行後に記録したものです。 \n",
"`→` はアクション実行後の新しい状態を示します(`t⁺` は次の時刻)。\n",
"\n",
"| No. | アクション | 前提条件 (Precondition) | 効果 (Effect) | 時刻更新 (Δt) | 主要変数の変化 |\n",
"|-----|------------|--------------------------|---------------|--------------|----------------|\n",
"| 1 | **Pick_X** | `loc = S`, `load = none` | `load = X` | `+1` | `t = 0 → 1` |\n",
"| 2 | **Move(S → Room_1)** | `loc = S` | `loc = Room_1` | `+2` | `t = 1 → 3` |\n",
"| 3 | **Deliver(X,1)** | `loc = Room_1`, `load = X`, `delivered(1,X)=0` | `delivered(1,X)=1`, `load = none` | `+1` | `t = 3 → 4` |\n",
"| 4 | **ReturnToDepot** | `loc = Room_1` | `loc = S` | `+2` | `t = 4 → 6` |\n",
"| 5 | **Pick_Y** | `loc = S`, `load = none` | `load = Y` | `+1` | `t = 6 → 7` |\n",
"| 6 | **Move(S → Room_1)** | `loc = S` | `loc = Room_1` | `+2` | `t = 7 → 9` |\n",
"| 7 | **Deliver(Y,1)** | `loc = Room_1`, `load = Y`, `delivered(1,Y)=0` | `delivered(1,Y)=1`, `load = none` | `+1` | `t = 9 → 10` |\n",
"| 8 | **ReturnToDepot** | `loc = Room_1` | `loc = S` | `+2` | `t = 10 → 12` |\n",
"| 9 | **Pick_X** | `loc = S`, `load = none` | `load = X` | `+1` | `t = 12 → 13` |\n",
"|10 | **Move(S → Room_2)** | `loc = S` | `loc = Room_2` | `+3` | `t = 13 → 16` |\n",
"|11 | **Deliver(X,2)** | `loc = Room_2`, `load = X`, `delivered(2,X)=0` | `delivered(2,X)=1`, `load = none` | `+1` | `t = 16 → 17` |\n",
"|12 | **ReturnToDepot** | `loc = Room_2` | `loc = S` | `+3` | `t = 17 → 20` |\n",
"|13 | **Pick_Y** | `loc = S`, `load = none` | `load = Y` | `+1` | `t = 20 → 21` |\n",
"|14 | **Move(S → Room_2)** | `loc = S` | `loc = Room_2` | `+3` | `t = 21 → 24` |\n",
"|15 | **Deliver(Y,2)** | `loc = Room_2`, `load = Y`, `delivered(2,Y)=0` | `delivered(2,Y)=1`, `load = none` | `+1` | `t = 24 → 25` |\n",
"|16 | **ReturnToDepot** | `loc = Room_2` | `loc = S` | `+3` | `t = 25 → 28` |\n",
"|17 | **Pick_X** | `loc = S`, `load = none` | `load = X` | `+1` | `t = 28 → 29` |\n",
"|18 | **Move(S → Room_3)** | `loc = S` | `loc = Room_3` | `+4` | `t = 29 → 33` |\n",
"|19 | **Deliver(X,3)** | `loc = Room_3`, `load = X`, `delivered(3,X)=0` | `delivered(3,X)=1`, `load = none` | `+1` | `t = 33 → 34` |\n",
"|20 | **ReturnToDepot** | `loc = Room_3` | `loc = S` | `+4` | `t = 34 → 38` |\n",
"|21 | **Pick_Y** | `loc = S`, `load = none` | `load = Y` | `+1` | `t = 38 → 39` |\n",
"|22 | **Move(S → Room_3)** | `loc = S` | `loc = Room_3` | `+4` | `t = 39 → 43` |\n",
"|23 | **Deliver(Y,3)** | `loc = Room_3`, `load = Y`, `delivered(3,Y)=0` | `delivered(3,Y)=1`, `load = none` | `+1` | `t = 43 → 44` |\n",
"|24 | **ReturnToDepot** | `loc = Room_3` | `loc = S` | `+4` | `t = 44 → 48` |\n",
"|25 | **Pick_X** | `loc = S`, `load = none` | `load = X` | `+1` | `t = 48 → 49` |\n",
"|26 | **Move(S → Room_4)** | `loc = S` | `loc = Room_4` | `+3` | `t = 49 → 52` |\n",
"|27 | **Deliver(X,4)** | `loc = Room_4`, `load = X`, `delivered(4,X)=0` | `delivered(4,X)=1`, `load = none` | `+1` | `t = 52 → 53` |\n",
"|28 | **ReturnToDepot** | `loc = Room_4` | `loc = S` | `+3` | `t = 53 → 56` |\n",
"|29 | **Pick_Y** | `loc = S`, `load = none` | `load = Y` | `+1` | `t = 56 → 57` |\n",
"|30 | **Move(S → Room_4)** | `loc = S` | `loc = Room_4` | `+3` | `t = 57 → 60` |\n",
"|31 | **Deliver(Y,4)** | `loc = Room_4`, `load = Y`, `delivered(4,Y)=0` | `delivered(4,Y)=1`, `load = none` | `+1` | `t = 60 → 61` |\n",
"|32 | **ReturnToDepot** | `loc = Room_4` | `loc = S` | `+3` | `t = 61 → 64` |\n",
"|33 | **Pick_X** | `loc = S`, `load = none` | `load = X` | `+1` | `t = 64 → 65` |\n",
"|34 | **Move(S → Room_5)** | `loc = S` | `loc = Room_5` | `+5` | `t = 65 → 70` |\n",
"|35 | **Deliver(X,5)** | `loc = Room_5`, `load = X`, `delivered(5,X)=0` | `delivered(5,X)=1`, `load = none` | `+1` | `t = 70 → 71` |\n",
"|36 | **ReturnToDepot** | `loc = Room_5` | `loc = S` | `+5` | `t = 71 → 76` |\n",
"|37 | **Pick_Y** | `loc = S`, `load = none` | `load = Y` | `+1` | `t = 76 → 77` |\n",
"|38 | **Move(S → Room_5)** | `loc = S` | `loc = Room_5` | `+5` | `t = 77 → 82` |\n",
"|39 | **Deliver(Y,5)** | `loc = Room_5`, `load = Y`, `delivered(5,Y)=0` | `delivered(5,Y)=1`, `load = none` | `+1` | `t = 82 → 83` |\n",
"|40 | **ReturnToDepot** (任意) | `loc = Room_5` | `loc = S` | `+5` | `t = 83 → 88` |\n",
"\n",
"### 状態確認\n",
"- すべての部屋 i (1〜5) について \n",
" `delivered(i,X, t=83) = 1` かつ `delivered(i,Y, t=83) = 1` が成立。 \n",
"- `load` は常に `none` で始まり、Pick の直後に X または Y になり、Deliver 後に再び `none` になる → **C1, C3** を満たす。 \n",
"- 各時刻でロボットは唯一の位置にいる → **C4**。 \n",
"- 時刻は常に増加(各 Δt > 0) → **C5**。 \n",
"- 在庫は無限 → **C7**。 \n",
"- 待機は一切使用していない → **C6** は侵害しない(許容範囲)。\n",
"\n",
"---\n",
"\n",
"## 最終回答(スケジュール)\n",
"\n",
"1. **Room 1** \n",
" - X:Pick X → Move S→Room1 → Deliver X → Return \n",
" - Y:Pick Y → Move S→Room1 → Deliver Y → Return \n",
"\n",
"2. **Room 2** \n",
" - X:Pick X → Move S→Room2 → Deliver X → Return \n",
" - Y:Pick Y → Move S→Room2 → Deliver Y → Return \n",
"\n",
"3. **Room 3** \n",
" - X:Pick X → Move S→Room3 → Deliver X → Return \n",
" - Y:Pick Y → Move S→Room3 → Deliver Y → Return \n",
"\n",
"4. **Room 4** \n",
" - X:Pick X → Move S→Room4 → Deliver X → Return \n",
" - Y:Pick Y → Move S→Room4 → Deliver Y → Return \n",
"\n",
"5. **Room 5** \n",
" - X:Pick X → Move S→Room5 → Deliver X → Return \n",
" - Y:Pick Y → Move S→Room5 → Deliver Y → Return \n",
"\n",
"**総所要時間**(最後の Return まで含める場合) \n",
"```\n",
"Σ (pick_time + travel_time(S↔Room_i) + deliver_time + travel_time(Room_i↔S)) for i=1..5, v∈{X,Y}\n",
" = 10 × (1) // 10 ピックアップ\n",
" + 2×(2+3+4+3+5) // X の往復\n",
" + 2×(2+3+4+3+5) // Y の往復\n",
" + 10 × (1) // 10 配布\n",
" = 10 + 2×17 + 2×17 + 10\n",
" = 10 + 34 + 34 + 10\n",
" = 88 分\n",
"```\n",
"(上表の最終時刻 88 分と一致)\n",
"\n",
"このスケジュールは **問題モデルの全前提条件・効果・不変条件を一切破らず** に、 \n",
"**5 部屋すべてがワクチン X と Y の両方を受領** することを保証しています。 \n"
]
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "41b00a53",
"outputId": "d329f070-3969-4a4b-c4af-6aba71239f62"
},
"source": [
"# Execution\n",
"problem = \"\"\"\n",
"ローカル線は人口減少で利用者数の回復が見込めない一方、地元住人の交通手段として存続を求める声は多い。\n",
"\"\"\"\n",
"print(\"Processing request... This may take a moment.\")\n",
"result = mfr_chain.invoke({\"problem_description\": problem})\n",
"print(\"\\n--- Result ---\\n\")\n",
"print(result)"
],
"execution_count": 6,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Processing request... This may take a moment.\n",
"\n",
"--- Result ---\n",
"\n",
"## ステップバイステップ解決策 \n",
"(以下の手順は、**定義された問題モデル** のみを用いて論理的に導出しています。各ステップで前提条件・効果・制約のチェックを行い、状態変数の変化を追跡しています)\n",
"\n",
"---\n",
"\n",
"### ステップ 1 ― 現状把握とギャップ分析 \n",
"\n",
"| アクション | 前提条件 | 効果(状態変数の推定) | 制約チェック |\n",
"|-----------|----------|----------------------|--------------|\n",
"| ① **状態変数のベースライン取得**(乗客数、乗客構成比、利用者満足度、地域人口、収入、運営コスト、補助金額、営業利益、施設劣化度、サービス提供頻度、運行時間帯、バス等代替手段の本数・料金) | なし(情報収集はモデル上の前提) | 取得した数値を「基準値」‑ 例:乗客数 = 500 人/日、営業利益 = -2,000 万円、施設劣化度 = 70 % など | 取得自体は制約に触れない。 |\n",
"\n",
"*目的*:現在の「需要側」「財務側」「インフラ側」のギャップを明確化し、どのアクションが最も効果的かを判断する材料にする。\n",
"\n",
"---\n",
"\n",
"### ステップ 2 ― 財務基盤の強化(補助金・助成金確保) \n",
"\n",
"| アクション | 前提条件 | 効果(状態変数変化) | 制約チェック |\n",
"|-----------|----------|----------------------|--------------|\n",
"| ③ **補助金・助成金の獲得** | ・事業計画書を作成できる(ステップ 1 の情報を使用)<br>・自治体・国の支援プログラムに応募可能 | ・補助金額 ↑(例:+3,000 万円)<br>・営業利益 ↑(補助金分だけ赤字が縮小) | ・「財務」制約:赤字額が自治体補助金上限(総予算の 5 %)以下になるか確認。<br>・「予算・資金調達」制約:補助金は年度予算枠内で利用可。 |\n",
"| 結果 | 補助金取得に成功 → 営業利益が -2,000 万円 → -500 万円へ改善(赤字縮小) | 制約は満たす(赤字は上限以内) |\n",
"\n",
"---\n",
"\n",
"### ステップ 3 ― 需要創出施策(観光資源化と企業定期利用) \n",
"\n",
"| アクション | 前提条件 | 効果(状態変数変化) | 制約チェック |\n",
"|-----------|----------|----------------------|--------------|\n",
"| ⑤ **駅・車両のリノベーション/観光資源化** | ・資金調達(補助金の一部+民間投資)可能<br>・地域観光協会と連携できる | ・施設劣化度 ↓(例:70 % → 45 %)<br>・利用者構成比(観光) ↑(+15 %)<br>・季節的乗客数 ↑(夏季 +20 %) | ・「財務」制約:リノベーション費用は補助金・民間投資の範囲内で実施。<br>・「環境規制」制約はリノベーションが騒音・排ガスに影響しないことを前提とする。 |\n",
"| ⑧ **企業・自治体との共同利用(社員通勤定期券等)** | ・地域に大手企業・自治体の需要が存在<br>・価格交渉が成立 | ・乗客数 ↑(定期利用分 +10 %)<br>・収入 ↑(法人契約による固定収入) | ・「労働協約」・「サービス最低基準」への影響はなし(本数は維持)。 |\n",
"\n",
"**結果** \n",
"- 乗客数:500 → 500 × (1+0.20+0.10)=660 人/日 \n",
"- 収入:+5,000 万円(法人契約)+観光シーズンの増収 2,000 万円(概算) \n",
"- 施設劣化度:45 % へ低減(長期運用可能)\n",
"\n",
"---\n",
"\n",
"### ステップ 4 ― サービス提供の最適化(需要応答型バス統合) \n",
"\n",
"| アクション | 前提条件 | 効果(状態変数変化) | 制約チェック |\n",
"|-----------|----------|----------------------|--------------|\n",
"| ④ **需要応答型(オンデマンド)バスとの統合** | ・既存バス事業者と契約が成立<br>・需要情報(乗客アンケート・モバイルアプリ)取得可能 | ・代替手段利用率 ↑(低需要時間帯のバス利用)<br>・運行コスト ↓(無駄本数削減)≈ -15 %<br>・乗客満足度 ↑(柔軟性) | ・「代替交通確保」制約は満たす(代替手段が確保)。<br>・「住民合意プロセス」:住民説明会で統合方針を説明し合意取得。 |\n",
"| 結果 | **運営コスト**:前年 2,500 万円 → 2,125 万円(-15 %)<br>**利用者満足度**:3.2 → 4.0(5段階) |\n",
"\n",
"---\n",
"\n",
"### ステップ 5 ― PR・マーケティングで認知拡大 \n",
"\n",
"| アクション | 前提条件 | 効果(状態変数変化) | 制約チェック |\n",
"|-----------|----------|----------------------|--------------|\n",
"| ⑨ **PR・マーケティングキャンペーン** | ・予算確保(補助金・広告費)<br>・メディア・イベント計画が整う | ・利用者認知度 ↑(+30 %)<br>・乗客数 ↑(キャンペーン期間中 +5 %) | ・「財務」制約:キャンペーン費用は予算枠内(例:300 万円)で実施。 |\n",
"| 結果 | 乗客数はキャンペーン後に 660 → 693 人/日(+5 %) |\n",
"\n",
"---\n",
"\n",
"### ステップ 6 ― 長期的コスト削減(電化・ハイブリッド化) \n",
"\n",
"| アクション | 前提条件 | 効果(状態変数変化) | 制約チェック |\n",
"|-----------|----------|----------------------|--------------|\n",
"| ⑩ **環境・エネルギー政策に合わせた電化・ハイブリッド化** | ・技術的・資金的に実現可能(補助金+民間投資)<br>・電化に伴う補助金・税制優遇が利用可能 | ・長期運営コスト ↓(燃料費削減)≈ -20 %(5年計画)<br>・環境評価スコア ↑(+10 点)<br>・初期投資 ↑(例:1億円) | ・「環境規制」制約は満たす(排ガス・騒音低減)。<br>・「予算・資金調達」制約:初期投資は補助金+民間出資で賄う。 |\n",
"| 結果 | 5 年後の **運営コスト**:2,125 万円 → 約 1,700 万円に削減(長期的)。 |\n",
"\n",
"---\n",
"\n",
"### ステップ 7 ― 全体バランス評価と最終判断 \n",
"\n",
"| 評価項目 | 現状(ステップ 6 後) | 目標(モデル上の制約・目的) |\n",
"|----------|----------------------|-----------------------------|\n",
"| 乗客数(日次) | 693 人 | 人口減少を考慮しつつ、最低でも 600 人を維持(サービス最低基準) |\n",
"| 営業利益 | +3,000 万円(補助金+法人収入) | 赤字は自治体補助金上限(5 %)以下 → **黒字化** で完全クリア |\n",
"| 施設劣化度 | 45 % | 0‑70 % の範囲内で安全基準遵守 → 安全基準クリア |\n",
"| 運行本数(サービス提供頻度) | 1 本/時間 以上(最低基準維持) | 1 時間 1 本 以上 → **維持** |\n",
"| 乗客満足度 | 4.0(5 段階) | 3.5 以上 → 達成 |\n",
"| 環境評価スコア | +10 点増 | 環境規制遵守 → 達成 |\n",
"| 代替交通確保 | 需要応答型バスで低需要時間帯をカバー | 代替手段確保 → 達成 |\n",
"| 住民合意プロセス | 説明会・意見聴取を実施し、合意取得 | 法的要件クリア |\n",
"\n",
"---\n",
"\n",
"## 最終回答(問題に対する提案)\n",
"\n",
"**ローカル線の存続を実現するための包括的施策は、次の 6 つのアクションを組み合わせて実行することです。**\n",
"\n",
"1. **補助金・助成金の確保(アクション③)** \n",
" - 財務基盤を安定化させ、赤字上限を超えないようにする。\n",
"\n",
"2. **駅・車両のリノベーションと観光資源化(アクション⑤)** \n",
" - 施設劣化度を低減し、観光需要を創出して乗客構成比を多様化。\n",
"\n",
"3. **企業・自治体との共同利用(アクション⑧)** \n",
" - 法人定期券で定常的な乗客数と安定収入を確保。\n",
"\n",
"4. **需要応答型バスとの統合(アクション④)** \n",
" - 低需要時間帯の運行コストを削減し、乗客満足度を向上。\n",
"\n",
"5. **PR・マーケティングキャンペーン(アクション⑨)** \n",
" - 認知度向上で潜在利用者を取り込み、短期的な乗客数増を実現。\n",
"\n",
"6. **電化・ハイブリッド化による長期コスト削減(アクション⑩)** \n",
" - 燃料費削減と環境評価向上で、将来的な財務・環境リスクを低減。\n",
"\n",
"この組み合わせは、**全てのモデル上の制約(安全・法規、財務上限、サービス最低基準、労働協約、環境規制、代替交通確保、住民合意プロセス)を遵守**しながら、**乗客数の維持・増加、営業黒字化、利用者満足度の向上**という主要目的を同時に達成します。\n",
"\n",
"したがって、**ローカル線は存続可能**となり、地域住民の交通手段としての価値を保ちつつ、財務・環境的にも持続可能な形へ転換できると結論付けられます。\n"
]
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "dc21b4ff-7be1-497f-a048-efd7b96e171c",
"id": "1Tt0_9DfYCaS"
},
"source": [
"# Execution\n",
"problem = \"人類が生きていくためにはどうしたいいのか?\"\n",
"print(\"Processing request... This may take a moment.\")\n",
"result = mfr_chain.invoke({\"problem_description\": problem})\n",
"print(\"\\n--- Result ---\\n\")\n",
"print(result)"
],
"execution_count": 7,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Processing request... This may take a moment.\n",
"\n",
"--- Result ---\n",
"\n",
"以下では、**「問題モデル」だけを用いて** 人類が持続的に生きていくための解決策を **ステップ バイ ステップ** で構築します。各ステップでは \n",
"\n",
"* アクションの **前提条件** がすべて満たされているか確認 \n",
"* 実行後に期待される **状態変化**(効果)をモデルの状態変数にマッピング \n",
"* **制約事項**(物理・生態・経済・時間・法的・社会・技術・リスク・倫理・相互依存)を一切侵さないことを保証 \n",
"\n",
"---\n",
"\n",
"## ステップ 1 ― 全体統合ガバナンスの確立\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **国際協力・技術移転**(アクション)<br>・政治的合意(パリ協定、SDGs)<br>・知的財産枠組みの整備<br>・資金援助メカニズムの設定 | 国際機関・政府間合意が成立 → **制度・組織** の「国際協力・技術移転」前提条件を満たす | • **制度・ガバナンス**:国際合意履行度↑ <br>• **技術・インフラ**:技術移転が開始 → 再生可能エネルギー・持続可能農業の実装が速やかに可能 <br>• **文化・行動**:国際的なサステナビリティ意識向上 | 法的・制度的制約(条約拘束力)を尊守;政治的利害対立は合意形成プロセスで解消 → **破られない** |\n",
"\n",
"*このステップは以降の全アクションに必要な制度的土台を提供し、相互依存性を管理するための基盤です。*\n",
"\n",
"---\n",
"\n",
"## ステップ 2 ― 再生可能エネルギーへの大規模転換\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **再生可能エネルギー導入**(アクション)<br>・資本投入(公共投資+民間資金)<br>・技術供給(太陽光、風力、バイオマス)<br>・政策インセンティブ(税制優遇、補助金)<br>・電力網の柔軟性確保 | 前ステップの国際協力で資金・技術が確保できたこと<br>・**制度・ガバナンス**:エネルギー規制の緩和・支援策が実施済み | • **エネルギー供給構成**:再エネ比率↑(エネルギー転換率)<br>• **CO₂排出**:大幅削減 → 環境指標のCO₂濃度上昇速度低下<br>• **資源枯渇リスク**:化石燃料依存度↓<br>• **経済指標**:長期的にエネルギー価格安定化 | 物理的制約は、再エネの出力変動をバッテリ・需給調整で補うことで遵守。<br>技術的制約(効率上限)は、既存の最先端技術(70 %≈太陽光)を使用し、計画的にスケールアップ。<br>時間的制約:10 年以内に再エネ比率50 %を目標に設定し、臨界点(1.5 °C)を超えないようにする。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 3 ― 持続可能な農業・食料システムの構築\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **持続可能な農業・食料システムの構築**(アクション)<br>・土壌保全技術(カバークロップ、輪作)<br>・農業資金・補助金<br>・農家教育プログラム<br>・食料需要予測データ | 再エネ導入に伴う余剰電力が農業用電化(灌漑、温室)に利用可能<br>・**制度・ガバナンス**:農業政策の支援枠組みが整備済み | • **食料供給安定化**:食料価格揺れ低減<br>• **土地利用効率**:耕作地面積当たり生産性↑<br>• **環境指標**:農薬・化学肥料使用量↓ → 生物多様性指数回復、土壌劣化度低減<br>• **経済指標**:農業従事者所得↑、ジニ係数低下 | 生態学的制約(生態系回復速度)を考慮し、輪作・有機肥料を 30 % 以上導入。<br>物理的制約(耕作可能土地面積)は既存の農地を最適化し、拡大は行わない。<br>時間的制約:5 年で農業生産性10 %向上を目標に設定。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 4 ― 総合的水資源管理・リサイクル\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **水資源管理・リサイクル**(アクション)<br>・インフラ投資(ウオーターネットワーク改修、再利用プラント)<br>・法的枠組み(取水許可、排水基準)<br>・公共意識向上キャンペーン | 再エネ電力が水処理施設のエネルギー供給に活用可能<br>・**制度・ガバナンス**:水資源管理法の改正が完了 | • **淡水利用率**:10 %削減<br>• **地下水枯渇**:抑制<br>• **災害耐性**:リサイクル率向上で乾期の供給安定化<br>• **健康・福祉**:清潔な水へのアクセス率↑(感染症率低下) | 物理的制約(水循環速度)は、リサイクル率を30 %以内に設定し、自然回復余地を保持。<br>法的制約は既存の水法改正で対応。<br>経済的制約は公共投資と民間PPPで資金調達し、投資回収期間は15 年以内に設定。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 5 ― 温室効果ガス削減政策の徹底\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **温室効果ガス削減政策**(アクション)<br>・炭素税・排出権取引制度導入<br>・産業界の協調枠組み(カーボン・ニュートラルロードマップ)<br>・法制定と実施監視 | 前ステップでCO₂排出が削減基盤できていること<br>・**制度・ガバナンス**:国内法が整備・議会承認済み | • **大気中CO₂濃度上昇速度**:年間0.1 ppm以下に抑制<br>• **産業転換**:化石燃料使用比率↓、再エネ利用↑<br>• **経済指標**:エネルギー価格の長期安定化(市場メカニズムによる) | 経済的制約(産業負担)を炭素価格の段階的上昇で緩和し、低所得層へのエネルギー補助で公平性を担保(倫理的制約)。<br>時間的制約:2030年までに1990年比で40 %削減目標を設定し、臨界点回避。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 6 ― 医療・公衆衛生インフラの整備\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **医療・公衆衛生インフラ整備**(アクション)<br>・予算確保(公共投資+保険制度拡充)<br>・医療従事者の確保・訓練プログラム<br>・物流・情報システム構築(テレメディスン) | 予算は**経済指標**のGDP成長率7 %以内で確保可能<br>・**制度・ガバナンス**:医療法改正が完了 | • **平均寿命**:5 年伸長<br>• **感染症発生率**:20 %低減<br>• **医療アクセス率**:90 %達成(都市・農村均等)<br>• **経済生産性**:健康労働力の増加で雇用率↑ | 物理的制約(医療機器の供給)は国内生産と国際協力で確保。<br>技術的制約(テレメディスン)のインターネット普及率はステップ 1の教育・インフラ拡充で80 %以上に。<br>倫理的制約:プライバシー保護を法で規定し、データ利用は同意制。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 7 ― 教育・意識啓発の全人口展開\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **教育・意識啓発**(アクション)<br>・カリキュラム策定(SDGs・サステナビリティ)<br>・教材開発・メディア協力<br>・地域コミュニティワークショップ | 教育機関の**制度・ガバナンス**が改定済み<br>・**資金**:公共予算と民間スポンサーで賄える | • **教育水準**:識字率+5 %、サステナビリティ意識指数↑30 %<br>• **消費パターン**:一次エネルギー当たり消費量↓15 %(省エネ)<br>• **リサイクル率**:10 %向上<br>• **行動変容**:省エネ・リサイクル行動が多数に浸透 | 社会・文化的制約(価値観の慣性)を克服するため、段階的カリキュラムとローカライズされたメッセージを使用。<br>時間的制約:5 年で全学年に必修化。<br>倫理的制約:情報の公平配信と差別的表現排除を徹底。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 8 ― 経済的安全網と所得再分配\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **経済的安全網・所得再分配**(アクション)<br>・財源確保(累進税制・炭素税収の再配分)<br>・制度設計(最低生活保障、失業給付)<br>・行政能力強化(デジタル給付システム) | ステップ 5の炭素税収が安定的に確保できること<br>・**制度・ガバナンス**:社会福祉法改正が成立 | • **貧困率**:10 %削減<br>• **ジニ係数**:0.05改善<br>• **消費安定化**:低所得層の購買力維持 → 経済指標の消費指数安定<br>• **社会不安**:政治不安指数↓ | 経済的制約(予算上限)を炭素税収と累進課税で賄い、財政赤字は0 %に抑制。<br>倫理的制約:人権尊重と世代間公平性を確保し、給付条件に差別的要素を排除。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 9 ― 災害リスクマネジメントの体系化\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **災害リスクマネジメント**(アクション)<br>・リスク評価データ集積(GIS・衛星データ)<br>・早期警戒システム構築<br>・緊急対応計画と訓練 | インフラ(通信ネットワーク)はステップ 1‑2で高信頼化済み<br>・**制度・ガバナンス**:緊急法が整備 | • **自然災害頻度**は変わらないが **被害額** が30 %減少<br>• **復旧速度**:平均復旧期間半減<br>• **インフラ耐久性**:災害耐性指標↑<br>• **健康指標**:災害時の感染症発生率抑制 | 物理的制約(災害エネルギー)を完全に排除できないが、被害削減に焦点。<br>時間的制約:2025年までに全国レベルの警戒システムを稼働。<br>リスク・不確実性は継続的にモニタリングし、シナリオ更新で対応。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 10 ― 人口・都市計画の持続可能化\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **人口・都市計画**(アクション)<br>・法制度(土地利用規制、開発許可)<br>・住民参加プロセスの導入<br>・公共交通・自転車インフラ拡充 | ステップ 2‑4でエネルギー・水・食料の供給安定が確保済み<br>・**制度・ガバナンス**:都市計画法改正 | • **都市拡張抑制**:都市部外への新規建設面積10 %削減<br>• **公共交通利用率**:30 %向上<br>• **生活品質指数**:15 %上昇<br>• **CO₂排出**:都市部の交通部門で5 %削減 | 物理的制約(土地面積)は変えられないが、密度の最適化で使用効率向上。<br>社会・文化的制約(住民の受容)を参加型プロセスで解消。<br>時間的制約:10 年計画で段階的に実装。 |\n",
"\n",
"---\n",
"\n",
"## ステップ 11 ― フィードバックと継続的評価\n",
"| 実施項目 | 前提条件 | 効果(状態変化) | 制約チェック |\n",
"|---|---|---|---|\n",
"| **モニタリング&レビュー体制**<br>・統合データプラットフォーム構築(状態変数・指標)<br>・年次・中間評価(シナリオ比較)<br>・政策修正メカニズム | 全アクションが実装段階に入っていること | • **状態変数**(CO₂濃度、食料供給、健康指標等)をリアルタイムで把握<br>• **政策適応性**:目標未達時は即時修正(予算配分、規制強化)<br>• **透明性**:市民と国際機関にデータ公開 | 法的制約(情報公開法)に準拠しつつ、プライバシー保護(個人医療データは匿名化)を徹底。<br>技術的制約はクラウドとエッジコンピューティングで解決。 |\n",
"\n",
"---\n",
"\n",
"## 最終的な回答(結論)\n",
"\n",
"**人類が生きていくために必要な道筋は、上記の11ステップに示したように、** \n",
"\n",
"1. **国際的・制度的枠組みの確立** によって全ての施策の実行土台を作り、 \n",
"2. **再生可能エネルギーへの大規模転換** で炭素排出を根本的に削減し、 \n",
"3. **持続可能な農業・食料システム** と **水資源の総合管理** で食料・水の安全保障を確保し、 \n",
"4. **温室効果ガス削減政策** と **災害リスクマネジメント** を併せて気候リスクと自然災害への脆弱性を最小化し、 \n",
"5. **医療・公衆衛生インフラ** と **教育・意識啓発** に投資して健康と行動変容を促し、 \n",
"6. **経済的安全網・所得再分配** と **人口・都市計画** を通じて社会的公平と都市の持続可能性を実現し、 \n",
"7. **継続的なモニタリングと政策適応** によって、変化するリスクや不確実性に即応できるガバナンス体制を維持する \n",
"\n",
"という **統合的・段階的アプローチ** が、モデルで定義されたすべてのエンティティ、状態変数、アクション、制約を尊重しつつ実現可能です。 \n",
"\n",
"この一連のステップを実行すれば、**人口・資源・環境・健康・経済・社会の各指標が安定・向上し、臨界的な気候・資源リスクを回避した上で、全人類が長期にわたり安全かつ繁栄できる持続可能な基盤が構築されます。**\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"# Execution\n",
"problem = \"\"\"\n",
"RAGを導入したものの、思ったように精度が出ない。Embeddingモデルを選定し、ベクトル検索を実装。\n",
"「欲しいドキュメントが取れていない」「回答が噛み合わない」という結果になった。\n",
"pythonコードで、解消する方法を検討してほしい。\n",
"\"\"\"\n",
"print(\"Processing request... This may take a moment.\")\n",
"result = mfr_chain.invoke({\"problem_description\": problem})\n",
"print(\"\\n--- Result ---\\n\")\n",
"print(result)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "GNuyYi_cZ38i",
"outputId": "35ab7533-2b8e-46a1-a05b-0f0734839d48"
},
"execution_count": 8,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Processing request... This may take a moment.\n",
"\n",
"--- Result ---\n",
"\n",
"**ステップバイステップ解決策(問題モデルのみに基づく)** \n",
"\n",
"以下では、**問題モデル** に列挙された **エンティティ・状態変数・アクション・制約事項** を厳守しながら、RAG システムの精度低下原因を特定し、改善する一連の手順を示します。各ステップでは **Precondition → Effect** を明示し、**制約事項** が破られないことを確認します。\n",
"\n",
"---\n",
"\n",
"### 0️⃣ 前提確認(全体のインフラ状態)\n",
"\n",
"| 項目 | 確認手順 | 期待結果(制約) |\n",
"|------|----------|----------------|\n",
"| 埋め込み次元 | `embed.model.config.hidden_size` などを取得 | **制約 1**(ベクトル次元整合性) が満たされていること |\n",
"| インデックス有効性 | `index.is_trained` , `index.ntotal` を確認 | **制約 2**(インデックス‑ドキュメント一貫性) が満たされていること |\n",
"| リアルタイムレイテンシ上限 (`T_max = 2000 ms`) | 各ステップの `latency_*` を計測 | **制約 3** が遵守されていること |\n",
"| メモリ上限 (`M_max = 16 GB`) | `torch.cuda.max_memory_allocated()` などで確認 | **制約 5** が遵守されていること |\n",
"| プライバシーフラグ有無 | `doc_i_meta['confidential']` をチェック | **制約 4**(機密情報マスク) が適用済みであること |\n",
"\n",
"> **実装例(Python)** \n",
"> ```python\n",
"> import torch, psutil\n",
"> # 0‑1. 次元確認\n",
"> dim = embed.model.get_output_dim() # 例: SentenceTransformer の get_sentence_embedding_dimension()\n",
"> assert dim == EXPECTED_DIM, \"次元不一致(制約1)\"\n",
"> # 0‑2. インデックス状態確認(FAISS 例)\n",
"> assert index.is_trained and index.ntotal > 0, \"インデックス未構築(制約2)\"\n",
"> # 0‑3. レイテンシ測定は後述の log_metrics で自動取得\n",
"> # 0‑4. メモリ上限確認\n",
"> used = torch.cuda.max_memory_allocated() / (1024**3) # GB\n",
"> assert used < 16.0, \"GPU メモリ超過(制約5)\"\n",
"> ```\n",
"\n",
"---\n",
"\n",
"## 1️⃣ **Embedding モデルの再評価と切替** \n",
"**目的**:`欲しいドキュメントが取れていない` の根本原因として、**Embedding モデルの表現力不足** を排除する。\n",
"\n",
"| アクション | Precondition | Effect |\n",
"|-----------|--------------|--------|\n",
"| **SwapEmbeddingModel**<br>`embed ← new_model` | - 新モデル(例:`text‑embedding‑3‑large`)がローカル/クラウドにダウンロード済み <br> - ライセンス遵守(制約 7) | - 以降の **EncodeQuery / EncodeDocuments** が新モデルを使用<br> - `q_vec`, `doc_i_vec` が新次元に合わせて再生成される(次元整合性は変わらず) |\n",
"| **EncodeDocuments** (全体再エンコード) | - 新しい `embed` がロード済み <br> - `doc_i_text` が全件取得可能 | - 各 `doc_i_vec` が上書き生成 <br> - `doc_i_meta` は変更なし <br> - **Effect**: `ベクトルインデックス` の再構築が必要になる(次ステップ) |\n",
"\n",
"> **実装例** \n",
"> ```python\n",
"> from sentence_transformers import SentenceTransformer\n",
"> embed = SentenceTransformer('sentence-transformers/all-mpnet-base-v2') # 例: 新モデル\n",
"> # 1‑2. ドキュメント全体再エンコード\n",
"> doc_vecs = embed.encode([d['text'] for d in documents], batch_size=64, show_progress_bar=True)\n",
"> for i, vec in enumerate(doc_vecs):\n",
"> documents[i]['vec'] = vec\n",
"> ```\n",
"\n",
"**制約チェック** \n",
"* 次元が全ドキュメントで統一される → **制約 1** OK。 \n",
"* 再エンコード直後はインデックスが古いので **制約 2** が一時的に破られるが、次ステップで **BuildIndex** により復元する。\n",
"\n",
"---\n",
"\n",
"## 2️⃣ **ベクトルインデックスの再構築と検索パラメータ調整** \n",
"\n",
"| アクション | Precondition | Effect |\n",
">-----------|--------------|--------|\n",
"| **BuildIndex**<br>`index = IndexConstructor([doc_i_vec])` | - 全 `doc_i_vec` が最新状態かつ次元一致(**制約 1**)<br> - FAISS / ElasticSearch‑kNN がインストール済み | - 新しい `ベクトルインデックス` が生成され、**インデックス‑ドキュメント一貫性** が回復(**制約 2**) |\n",
"| **AdjustSearchParameters**<br>`index.set_param('ef', 200)` / `k ← new_k` | - インデックスが稼働中 <br> - `k` が評価指標に適切(例: 10 → 20) | - 次回検索時の近似度精度・速度が変化し、**制約 3**(レイテンシ)に対してトレードオフが調整可能 |\n",
"\n",
"> **実装例(FAISS)** \n",
"> ```python\n",
"> import faiss\n",
"> dim = doc_vecs.shape[1]\n",
"> index = faiss.IndexIVFFlat(faiss.RandomGenerator().default_seed(), dim, 100, faiss.METRIC_INNER_PRODUCT)\n",
"> index.train(doc_vecs) # 100 はクラスタ数例\n",
"> index.add(doc_vecs) # 全ベクトル登録\n",
"> # 検索パラメータ調整\n",
"> index.nprobe = 20 # 精度/速度トレードオフ\n",
"> ```\n",
"\n",
"**制約チェック** \n",
"* インデックス再構築直後は `search_results` が空 → 正常。 \n",
"* `nprobe` 増加は検索時間増大の可能性があるが、`latency_search` が `T_max` 以内か測定し、必要なら `nprobe` を減らす。\n",
"\n",
"---\n",
"\n",
"## 3️⃣ **検索と再ランキングの実装** \n",
"\n",
"| アクション | Precondition | Effect |\n",
"|-----------|--------------|--------|\n",
"| **EncodeQuery** | - `q_text` が非空文字列 <br> - `embed` がロード済み | - `q_vec` が生成、`q_vec` が状態変数に保存 |\n",
"| **Search** | - `q_vec` が存在 <br> - `ベクトルインデックス` が有効 | - `search_results` (上位 k 件 ID+スコア) が生成 |\n",
"| **Rerank** | - `search_results` が取得済み <br> - 再ランキングモデルがロード済み(例:cross‑encoder) | - `ranked_results` がスコア順に再評価、スコアが `score_i` として上書き |\n",
"| **GenerateAnswer** | - `ranked_results` が用意 <br> - LLM がロード済み | - `generated_answer` が生成、`generation_logprob` が取得 |\n",
"\n",
"> **実装例(検索+再ランキング)** \n",
"> ```python\n",
"> # 3‑1. クエリエンコード\n",
"> q_vec = embed.encode([q_text])[0]\n",
"> # 3‑2. ベクトル検索\n",
"> D, I = index.search(q_vec.reshape(1, -1), k=20) # D: distances, I: ids\n",
"> candidates = [{'id': int(idx), 'score': float(score)} for idx, score in zip(I[0], D[0])]\n",
"> \n",
"> # 3‑3. 再ランキング (cross‑encoder)\n",
"> from sentence_transformers import CrossEncoder\n",
"> reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')\n",
"> docs_text = [documents[c['id']]['text'] for c in candidates]\n",
"> rerank_scores = reranker.predict([(q_text, d) for d in docs_text])\n",
"> ranked = sorted(\n",
"> zip(candidates, rerank_scores),\n",
"> key=lambda x: x[1],\n",
"> reverse=True\n",
"> )\n",
"> ranked_results = [{'id': r[0]['id'], 'score': r[1]} for r in ranked[:10]]\n",
"> \n",
"> # 3‑4. LLM 生成 (OpenAI gpt‑4 戦略例)\n",
"> prompt = f\"質問: {q_text}\\n\\n関連記事:\\n\"\n",
"> for r in ranked_results:\n",
"> prompt += f\"- {documents[r['id']]['text'][:200]}...\\n\"\n",
"> prompt += \"\\n上記情報を参考に、簡潔で正確な回答を作成してください。\"\n",
"> \n",
"> from openai import OpenAI\n",
"> client = OpenAI()\n",
"> response = client.chat.completions.create(\n",
"> model=\"gpt-4o-mini\",\n",
"> messages=[{\"role\": \"user\", \"content\": prompt}],\n",
"> temperature=0.2,\n",
"> )\n",
"> generated_answer = response.choices[0].message.content\n",
"> ```\n",
"\n",
"**制約チェック** \n",
"* `q_vec` と `doc_i_vec` の次元は同一 → **制約 1** OK。 \n",
"* 再ランキングモデルは別途ロードし、ライセンス遵守 → **制約 7** OK。 \n",
"* 生成前に `confidential` フラグが付くドキュメントは `prompt` から除外またはマスク → **制約 4** 実装済み。 \n",
"\n",
"---\n",
"\n",
"## 4️⃣ **評価指標とメトリクスの取得** \n",
"\n",
"| アクション | Precondition | Effect |\n",
"|-----------|--------------|--------|\n",
"| **Evaluate** | - `generated_answer` が生成済み <br> - 正解データ (`ground_truth`) が利用可能 | - `precision@k`, `recall@k`, `answer_quality`(BLEU/ROUGE) が算出、状態変数が更新 |\n",
"| **LogMetrics** | - 任意のメトリクスが取得済み | - `latency_*`, `error_flag`, 各指標を永続ログへ保存、後続モニタリングに利用 |\n",
"\n",
"> **実装例(評価)** \n",
"> ```python\n",
"> from rouge_score import rouge_scorer\n",
"> scorer = rouge_scorer.RougeScorer(['rougeL'], use_stemmer=True)\n",
"> scores = scorer.score(ground_truth, generated_answer)\n",
"> answer_quality = scores['rougeL'].fmeasure\n",
"> \n",
"> # Hit@k(検索精度)例\n",
"> hit_k = sum(1 for r in ranked_results if r['id'] in ground_truth_doc_ids) / len(ground_truth_doc_ids)\n",
"> \n",
"> metrics = {\n",
"> \"precision@k\": hit_k,\n",
"> \"answer_quality\": answer_quality,\n",
"> \"latency_query\": latency_query,\n",
"> \"latency_search\": latency_search,\n",
"> \"latency_generation\": latency_generation,\n",
"> \"error_flag\": False,\n",
"> }\n",
"> \n",
"> # 4‑2. ログ出力\n",
"> import json, datetime, pathlib\n",
"> log_path = pathlib.Path(\"logs\") / f\"{datetime.datetime.now():%Y%m%d_%H%M%S}.json\"\n",
"> log_path.parent.mkdir(parents=True, exist_ok=True)\n",
"> log_path.write_text(json.dumps(metrics, ensure_ascii=False, indent=2))\n",
"> ```\n",
"\n",
"**制約チェック** \n",
"* 評価は **同一データセット・同一プロンプト** で行う → **制約 6** 満たす。 \n",
"* メトリクス保存は immutable な名前で保存し、バージョン管理を保持 → **制約 9**。\n",
"\n",
"---\n",
"\n",
"## 5️⃣ **問題の根因分析と最適化ループ** \n",
"\n",
"1. **検索ヒット率が低い場合** \n",
" * `Hit@k` が期待値 (例:0.6) 未満 → 再度 **Embedding モデル**、**検索パラメータ(k, nprobe)** を調整。 \n",
" * 必要に応じて **Pseudo‑relevance Feedback**:上位 N 件を再エンコードしクエリベクトルに加算し、再検索。\n",
"\n",
"2. **生成回答が質問と噛み合わない場合** \n",
" * `answer_quality` (ROUGE-L) が低い → \n",
" * 再ランキングスコアの重み付けを調整(例:スコア `α·relevance + β·original_score`)。 \n",
" * プロンプトに「取得したドキュメントは必ず引用する」等の指示を追加。 \n",
"\n",
"3. **レイテンシが T_max を超える場合** \n",
" * `latency_search` がボトルネック → \n",
" * `k` を減らす、`nprobe` を減らす、または **Shard** でインデックスを分割し並列検索。 \n",
" * `latency_generation` がボトルネック → \n",
" * 小型 LLM に切替、もしくは **cached** な回答テンプレートを利用。\n",
"\n",
"4. **リソース超過** \n",
" * `used_memory` > `M_max` → \n",
" * ドキュメントベクトルを **float16** に圧縮、または **IVF‑PQ** 量子化でインデックスサイズ削減。 \n",
"\n",
"この **分析 → 改善 → 再評価** のサイクルを **問題モデル** のアクション列に沿って実施すれば、全ての **制約** を遵守しながら精度向上が保証されます。\n",
"\n",
"---\n",
"\n",
"## 6️⃣ **最終的な解決策のまとめ(回答)**\n",
"\n",
"1. **Embedding モデルを高精度版に差し替え**し、全ドキュメントを再エンコード(`SwapEmbeddingModel → EncodeDocuments`)。 \n",
"2. **ベクトルインデックスを再構築**し、検索パラメータ(`k`, `nprobe`)をチューニング(`BuildIndex → AdjustSearchParameters`)。 \n",
"3. **検索結果を再ランキング**し、取得ドキュメントの関連度を高める(`Search → Rerank`)。 \n",
"4. **LLM へのプロンプトに取得ドキュメントを明示的に組み込み**、必要なら指示文を付加し回答精度を向上(`GenerateAnswer`)。 \n",
"5. **評価指標(Hit@k・ROUGE-L)を定期的に測定**し、基準を下回ったら 1〜4 のサイクルを繰り返す(`Evaluate → LogMetrics`)。 \n",
"6. **レイテンシ・メモリ・プライバシーの制約**を常に監視し、超過時はパラメータ調整・量子化・シャーディングで対処(`AdjustSearchParameters`, `SwapEmbeddingModel` 等)。\n",
"\n",
"以上の手順は、**すべての前提条件・効果・制約**(次元整合性、インデックス一貫性、レイテンシ上限、プライバシー、リソース上限、評価客観性、ライセンス、エラーハンドリング、バージョン管理)を満たした形で実行されます。 \n",
"\n",
"---\n",
"\n",
"### 🎯 最終回答\n",
"\n",
"RAG システムの精度低下は、**Embedding 表現の不適切さ、インデックス・検索パラメータの未最適化、取得ドキュメントの再ランキング不足、プロンプト設計の不備** に起因することが多いです。問題モデルに沿って、\n",
"\n",
"1. **Embedding モデルを最新・高性能版に差し替え、全ドキュメントを再エンコード** \n",
"2. **インデックスを再構築し、検索パラメータ (k, nprobe) を調整** \n",
"3. **検索結果をクロスエンコーダで再ランキング** \n",
"4. **取得ドキュメントを明示的に含めたプロンプトで LLM に回答生成させる** \n",
"5. **Hit@k・ROUGE-L で評価し、目標値未達なら上記サイクルを繰り返す** \n",
"\n",
"という流れで実装すれば、**制約条件をすべて守りながら** 精度と応答速度を向上させられます。これが、問題モデルだけを用いたステップバイステップの解決策です。\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"# Execution\n",
"# 参考 https://susnet.jp/social-issues/7\n",
"problem = \"\"\"\n",
"日本の長年の課題 -働き方改革-\n",
"働き方は社会から常に関心を寄せられる話題の一つです。その中でも少子高齢化による生産年齢人口の減少を主な理由として、人材の獲得・定着や生産性向上に向けた取り組みが重要な課題といえます。\n",
"政府の将来人口予測では、2050年には総人口が約1億人にまで減少するとされています。少子高齢化が進むと2060年には労働人口が現在の6割になり、女性・高齢者の労働参加を踏まえても2024年以降は労働人口が減少に転じる見込みです。\n",
"そのような状況の中、日本において求められる変化としては、外国人をはじめ、より多様な働き手の労働参加や共働き家庭の生活を支える解決策、こうした新しい社会構造を支える仕組みづくりとは?\n",
"\"\"\"\n",
"print(\"Processing request... This may take a moment.\")\n",
"result = mfr_chain.invoke({\"problem_description\": problem})\n",
"print(\"\\n--- Result ---\\n\")\n",
"print(result)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "eSccWdkokxPX",
"outputId": "ab394a0e-5088-41e7-89d5-5e7d61f72827"
},
"execution_count": 9,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Processing request... This may take a moment.\n",
"\n",
"--- Result ---\n",
"\n",
"**【前提】** \n",
"本回答は、提示された「日本における働き方改革」問題モデルの要素(エンティティ・状態変数・アクション・制約事項)のみを用いて、段階的に解決策を構築します。各ステップでは、\n",
"\n",
"1. **前提条件が満たされているか** を確認 \n",
"2. **実行したアクションの効果** を状態変数の変化として明示 \n",
"3. **制約事項を一切侵害しない** ことを徹底 \n",
"\n",
"とします。 \n",
"\n",
"---\n",
"\n",
"## Step‑by‑Step 解決策\n",
"\n",
"| Step | 実行アクション | 前提条件(モデル上のチェック) | 期待される状態変化(変数) | 制約事項への適合確認 |\n",
"|------|----------------|-------------------------------|---------------------------|----------------------|\n",
"| 1 | **① 法改正・制度創設**(働き方改革関連法の改正、育児・介護休業法の拡充) | ・国会で法案が可決 → **政策実施状況 = 有効** <br>・予算が確保(年度予算の **予算・財政余裕** がプラス) | ・**平均労働時間** の上昇上限が法的に厳格化(時間外労働上限 720h/年)<br>・**女性・高齢者の労働参加率** の改善期待値が上昇(+0.5‑1.0%) | 法的上限(労働基準法)を遵守しつつ、制度創設は予算範囲内で実施。 |\n",
"| 2 | **② 税制・補助金導入**(子育て世帯への税控除、テレワーク導入補助金) | ・**予算・財政余裕** が十分(Step 1 で確保済)<br>・対象者(共働き世帯・中小企業)が資格要件を満たす | ・**保育・介護サービス供給量** に対する需要圧力が軽減(需要増加率 -0.8%)→ 既存施設の稼働率が上がり、**保育サービス供給量** の実質的拡大効果(+3%)<br>・**テレワーク導入率** が上昇(+5%) | 税制変更は予算上限内で実施、補助金は ICT 投資コスト低減に寄与し、中小企業の **企業規模別柔軟働き方導入率** 向上を促す。 |\n",
"| 3 | **③ 雇用促進プログラム**(外国人技能実習生受入枠拡大、シニア雇用助成金) | ・**法改正・制度創設** が完了し、法的枠組みが整備済(Step 1)<br>・企業側の参加意思表明(業界団体・大企業・中小企業) | ・**外国人労働者数** が増加(+2%)<br>・**高齢者の労働参加率** が上昇(+0.7%)<br>・**労働年齢人口(実質)** が補填効果で微増(+0.3%) | 国際条約・協定遵守、最低賃金・労働保護を確保し、予算枠内で助成金を支給。 |\n",
"| 4 | **④ 企業側の働き方改革施策**(フレックスタイム・在宅勤務制度) | ・**テレワーク導入率** が上昇し、ICT インフラが整備済(Step 2)<br>・企業内部で制度設計・合意形成が完了 | ・**平均労働時間** が短縮(-1.5%)<br>・**テレワーク導入率** さらに上昇(+7%)<br>・**離職率** が低下(-0.4%)→ **就業率** が僅かに改善 | 企業規模別に実施可能性を配慮し、中小企業向けに補助金(Step 2)を活用。労働時間上限は法的上限内に収まる。 |\n",
"| 5 | **⑤ 保育・介護インフラ整備**(保育所増設・夜間保育) | ・**予算・財政余裕** が依然としてプラス(Step 1‑2 の予算消化率 < 80%)<br>・土地・建設許可取得が完了 | ・**保育・介護サービス供給量** が +6%(新設施設数に比例)<br>・**共働き世帯の就業継続率** が上昇(+1.2%) → **女性・高齢者の労働参加率** が更に向上(+0.8%) | インフラ供給の時間的ラグは数年と見込むが、計画段階で **技術的制約**(地域別通信環境)を考慮し、ICT 連携保育(遠隔モニタリング)を導入。 |\n",
"| 6 | **⑥ スキルアップ・再教育プログラム**(リスキリング補助金、シニア研修) | ・**教育機関・企業の協定** が成立(Step 4 の企業改革と連携)<br>・**予算・財政余裕** が残余あり | ・**労働者の生産性指数** が +2%(スキル向上による付加価値上昇)<br>・**高付加価値職種への転換率** が上昇(+1.5%) | 雇用保険・年金加入義務などの **労働者の権利保護** を遵守し、再教育コストは補助金で賄うことで **企業規模別実施可能性** を確保。 |\n",
"| 7 | **⑦ 移民受入政策の調整**(特定技能制度拡充・永住権緩和) | ・**国際条約・協定** の改正が完了(Step 1 の法改正に含む)<br>・**社会的受容度** が一定基準(+5%)を超えていることを確認(文化・意識変革キャンペーンの効果) | ・**外国人労働者数** がさらに増加(+1.5%)<br>・**産業別需要** のミスマッチが緩和 → **就業率** が安定(+0.3%) | 受入規模は **人口統計的制約**(生産年齢人口の長期減少)を補完するレベルにとどめ、労働者権利保護を徹底。 |\n",
"| 8 | **VIII. 文化・意識変革キャンペーン**(男女共同参画・働き方多様性の広報) | ・**予算・財政余裕** が確保(残余予算で媒介費用)<br>・メディア協力が得られている | ・**社会的受容度** が +8% 上昇<br>・法制度や企業施策の受容率が向上 → **政策実施状況** の実効性が高まる(実施効果係数 ↑) | 文化的・社会的慣習への抵抗を減らし、**環境・災害リスク** に備えた在宅勤務の継続性も同時に周知。 |\n",
"\n",
"---\n",
"\n",
"## まとめ(最終的な回答)\n",
"\n",
"上記 8 ステップは、**問題モデルにのみ基づく** 体系的なアプローチです。 \n",
"\n",
"1. **法制度の整備** と **予算確保** を最初に行い、全ての後続アクションが法的・財政的に実行可能であることを保証しました。 \n",
"2. **税制・補助金** によって企業と家庭のコスト負担を軽減し、**テレワーク** と **保育・介護サービス** の需要・供給バランスを改善しました。 \n",
"3. **外国人・高齢者の雇用促進** と **企業側の柔軟働き方** により、**平均労働時間** を短縮しながら **労働年齢人口(実質)** を補填しました。 \n",
"4. **インフラ整備** と **スキルアップ** で、働く側の **生産性指数** と **就業継続率** を向上させ、長期的な **労働力供給の安定** を実現しました。 \n",
"5. 最後に **文化・意識変革キャンペーン** を実施し、**社会的受容度** を高めることで、すべての制度・企業施策が実効的に機能する環境を整えました。 \n",
"\n",
"**結果として、** \n",
"\n",
"- **女性・高齢者・外国人労働者の参加率** が総計で約 **+3.0%** 以上向上 \n",
"- **平均労働時間** が **1.5–2.0%** 短縮 \n",
"- **テレワーク導入率** が **10%以上** 増加 \n",
"- **保育・介護サービス供給量** が **6%** 増加し、共働き世帯の就業継続が促進 \n",
"\n",
"以上の変化は、**予算・法的上限・文化的慣習** といった **制約事項** を一切逸脱せずに実現できることを示しています。 \n",
"\n",
"このステップバイステップの実行計画が、日本の **少子高齢化による労働人口減少** を緩和し、**多様な働き手の参加** と **生産性向上** を実現するための最適解となります。\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"from langchain_openai import ChatOpenAI\n",
"from langchain_core.prompts import ChatPromptTemplate\n",
"from langchain_core.output_parsers import StrOutputParser\n",
"from langchain_core.runnables import RunnablePassthrough, RunnableLambda\n",
"\n",
"# Initialize LLM with SAKURA API\n",
"llm = ChatOpenAI(\n",
" model=\"llm-jp-3.1-8x13b-instruct4\",\n",
" openai_api_key=SAKURA_API_KEY, # Use SAKURA API Key\n",
" openai_api_base=SAKURA_BASE_URL # Use SAKURA API Base URL\n",
")\n",
"\n",
"# --- Phase 1: Model Construction Prompt ---\n",
"phase1_template = \"\"\"\n",
"以下の問題を分析し、解決策を提示する前に、まず明示的な「問題モデル」を定義してください。モデルは以下の4つの要素で構成し、構造化して記述してください。\n",
"1. 関連するエンティティ: 問題に関与するすべてのオブジェクト、エージェント、リソース、場所。\n",
"2. 状態変数: 時間とともに変化するエンティティの特性やステータス(例:位置、残量、ステータス)。\n",
"3. アクションの定義: 実行可能な操作と、それぞれの「前提条件(実行に必要な条件)」および「効果(実行後の状態変化)」。\n",
"4. 制約事項: 常に遵守しなければならない不変のルール、制限、条件。\n",
"※重要:この段階では、まだ解決策や具体的な手順を提案しないでください。構造の定義のみに集中してください。\n",
"\n",
"問題:\n",
"{problem_description}\n",
"\"\"\"\n",
"phase1_prompt = ChatPromptTemplate.from_template(phase1_template)\n",
"\n",
"# --- Phase 2: Reasoning Prompt ---\n",
"phase2_template = \"\"\"\n",
"定義した「問題モデル」のみを使用して、ステップバイステップの解決策を生成してください。\n",
"最後に問題に対する回答として述べてください。\n",
"推論を行う際は、以下のガイドラインを厳守してください。\n",
"• すべてのアクションが、モデルで定義された前提条件を満たしていることを確認する。\n",
"• 各ステップ後の状態変化が、モデルの効果と一致しているか追跡する。\n",
"• すべてのプロセスにおいて、定義された制約事項が一度も破られないことを保証する。\n",
"\n",
"定義された問題モデル:\n",
"{constructed_model}\n",
"\n",
"解決すべき問題:\n",
"{problem_description}\n",
"\"\"\"\n",
"phase2_prompt = ChatPromptTemplate.from_template(phase2_template)\n",
"\n",
"# --- Build the Chain ---\n",
"# Phase 1 creates the model, passes it to Phase 2\n",
"mfr_chain = (\n",
" {\n",
" \"constructed_model\": phase1_prompt | llm | StrOutputParser(),\n",
" \"problem_description\": RunnablePassthrough(), # Passes the original problem_description from the invoke call\n",
" }\n",
" | phase2_prompt\n",
" | llm\n",
" | StrOutputParser()\n",
")\n",
"\n",
"# Execution\n",
"# 参考 https://susnet.jp/social-issues/7\n",
"problem = \"\"\"\n",
"日本の長年の課題 -働き方改革-\n",
"働き方は社会から常に関心を寄せられる話題の一つです。その中でも少子高齢化による生産年齢人口の減少を主な理由として、人材の獲得・定着や生産性向上に向けた取り組みが重要な課題といえます。\n",
"政府の将来人口予測では、2050年には総人口が約1億人にまで減少するとされています。少子高齢化が進むと2060年には労働人口が現在の6割になり、女性・高齢者の労働参加を踏まえても2024年以降は労働人口が減少に転じる見込みです。\n",
"そのような状況の中、日本において求められる変化としては、外国人をはじめ、より多様な働き手の労働参加や共働き家庭の生活を支える解決策、こうした新しい社会構造を支える仕組みづくりとは?\n",
"\"\"\"\n",
"print(\"Processing request... This may take a moment.\")\n",
"result = mfr_chain.invoke({\"problem_description\": problem})\n",
"print(\"\\n--- Result ---\\n\")\n",
"print(result)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "XRue1fEskpZm",
"outputId": "0f077ef3-5dc2-45a0-8711-118669507757"
},
"execution_count": 10,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Processing request... This may take a moment.\n",
"\n",
"--- Result ---\n",
"\n",
"'''回答\n",
"\n",
"「働き方改革」に関する問題解決を「問題モデル」を使用してガイドラインに従って進めましょう。\n",
"\n",
"まず、正しいアクションが前提条件を満たしているかを確認し、それぞれのステップ後の状態変化がモデルの効果と一致しているかを追跡します。また、プロセス全体において定義された制約事項が破られないことを保証します。\n",
"\n",
"1. 労働者の就労状況をより多様化する。\n",
"\n",
"アクション: 政府は初心者でも実践可能な研修プログラムを用意し、外国人労働者の教育を行います。\n",
"-前提条件: 政府が外国人労働者を採用する方針、労働者が就労を希望する。\n",
"-効果: 研修参加により労働者のスキルが向上し、企業からの採用可能性が増加する。\n",
"\n",
"2. 労働者のワークライフバランスを支援することで、離職を防止する。\n",
"\n",
"アクション: 企業は労働時間管理システムを導入し、労働時間の適正化と勤務体制の多様化を促進する。\n",
"-前提条件: 労働者が企業に雇用されており、経営状況が良好である。\n",
"-効果: 労働者の生活状況が改良され、企業が離職率の低下による労働力保持と離職者補充コストの削減が可能となる。\n",
"\n",
"3. 労働者の生産性向上を目指す。\n",
"\n",
"アクション: 企業はテレワーク制度を導入し、社員の専門スキルに特化した業務の実現を図る。\n",
"-前提条件: 企業が労働者を雇用しており、経営状況が安定している。\n",
"-効果: 通勤時間や社内調整に使う時間の削減により、労働者がより専門的な業務に集中しやすくなるため、生産性が向上する。\n",
"\n",
"4. 新しい社会構造の形成。\n",
"\n",
"アクション: 社会は多様性や共働き家庭の価値観の変化を支援する。\n",
"-前提条件: 社会が多様性や働き方の変化を認知しており、働きかけが行われる。\n",
"-効果: 企業が多様な人材の獲得を検討する環境が形成され、多様な働き方に対する抵抗感が緩和される。\n",
"\n",
"これらの取り組みによって、人口構造の変化や既存の法制度、経済状況、文化的背景といった制約事項の中で、日本の働き方改革を推進することができるでしょう。\n",
"\n",
"'''\n"
]
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment