{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "title",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"キプ・クオンタムの「イスカイ量子最適化器」で市場分割問題を解決\"\n",
        "description: \"IBM Quantum ハードウェア上で、bf-DCQOアルゴリズムを搭載したIskay Quantum Optimizerを用いて、市場分割問題の解決方法を学びましょう\"\n",
        "---\n",
        "\n",
        "<span id=\"solve-the-market-split-problem-with-kipu-quantums-iskay-quantum-optimizer\" />\n",
        "\n",
        "# キプ・クオンタムの「イスカイ量子最適化器」で市場分割問題を解決\n",
        "\n",
        "{/* cspell:ignore adiabaticity, HUBO, bitflip, metaheuristic, fontweight, fontsize, QOBLIB, Zuse, Kochenberger, Tramontani, Weninger, edgecolor, nonumber */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "note",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\" title=\"注\">\n",
        "  Qiskit Functions は、 IBM Quantum® Premium Plan、Flexプラン、 On-Prem （ IBM Quantum Platform API経由）プランのユーザーだけが利用できる実験的な機能です。 これらはプレビューリリースであり、変更される可能性がある。\n",
        "</Admonition>\n",
        "\n",
        "*使用時間の見積もり：Heron r2 プロセッサーで20秒。 (注：これはあくまでも目安です。 ランタイムは異なるかもしれない)。*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "background",
      "metadata": {},
      "source": [
        "<span id=\"background\" />\n",
        "\n",
        "## 背景\n",
        "\n",
        "このチュートリアルでは、 [Kipu QuantumのIskay量子オプティマイザ](/docs/guides/kipu-optimization) [\\[1\\]](#references) を使用して、Market Split問題を解く方法を説明します。 市場分割問題は、正確な需要目標を達成するために、市場をバランスのとれた販売地域に分割しなければならないという、現実世界の資源配分の課題を表している。\n",
        "\n",
        "<span id=\"the-market-split-challenge\" />\n",
        "\n",
        "### 市場の分断という課題\n",
        "\n",
        "市場分割問題は、資源配分において、一見単純なようでいて計算量の多い難問である。 $n$ の異なる市場で $m$ の製品が販売されており、各市場が特定の製品バンドル（行列 $A$ の列で表される）を購入している企業を考える。ビジネスの目的は、これらの市場を2つのバランスのとれた販売地域に分割し、それぞれの地域がすべての製品の総需要のちょうど半分を受け取るようにすることである。\n",
        "\n",
        "**数学的定式化：**\n",
        "\n",
        "二値代入ベクトル $x$ を求める：\n",
        "\n",
        "* $x_j = 1$ $j$ をリージョンAに割り当てる\n",
        "* $x_j = 0$ $j$ をリージョンBに割り当てる\n",
        "* 制約条件 $Ax = b$ を満たさなければならない。 $b$ は目標売上高（通常、製品ごとの総需要の半分）を表す\n",
        "\n",
        "**コスト関数：**\n",
        "\n",
        "この問題を解くには、制約違反の2乗を最小化する：\n",
        "\n",
        "$C(x) = ||Ax - b||^2 = \\sum_{i=1}^{m} \\left(\\sum_{j=1}^{n} A_{ij}x_j - b_i\\right)^2$\n",
        "\n",
        "ここで、それぞれ以下のとおりです。\n",
        "\n",
        "* $A_{ij}$ $i$。 $j$\n",
        "* $x_j \\in \\{0,1\\}$ は市場のバイナリ割り当てである。 $j$\n",
        "* $b_i$ は、各地域における製品 $i$ の目標売上高である\n",
        "* すべての制約が満たされたとき、コストは正確にゼロになる\n",
        "\n",
        "合計の各項は、特定の商品の目標売上高からの偏差の二乗を表している。 このコスト関数を展開すると、こうなる：\n",
        "\n",
        "$C(x) = x^T A^T A x - 2b^T A x + b^T b$\n",
        "\n",
        "$b^T b$ は定数なので、 $C(x)$ を最小化することは、2次関数 $x^T A^T A x - 2b^T A x$ を最小化することと等価であり、これはまさにQUBO（2次制約なし2値最適化）問題である。\n",
        "\n",
        "**計算の複雑さ：**\n",
        "\n",
        "この問題は、ビジネス上のわかりやすい解釈にもかかわらず、顕著な計算難度を示す：\n",
        "\n",
        "* **小規模な失敗** ：従来の混合整数計画ソルバは、1時間のタイムアウトの下で、わずか7個の製品しかないインスタンスで失敗する [\\[4\\]](#references)\n",
        "* **指数関数的成長** ：解空間は指数関数的に増大し ( $2^n$ 可能な割り当て)、総当り的なアプローチは実行不可能になる\n",
        "\n",
        "この深刻な計算障壁は、領土計画や資源配分への実用的な関連性と相まって、市場分割問題を量子最適化アルゴリズムの理想的なベンチマークにしている [\\[4\\]](#references)。\n",
        "\n",
        "<span id=\"what-makes-iskays-approach-unique\" />\n",
        "\n",
        "### イスケイのアプローチの独自性とは何ですか？\n",
        "\n",
        "イスカイ・オプティマイザーは、 **bf-DCQO（bias-field digitized counterdiabatic quantum optimization）** アルゴリズム [\\[1\\]](#references) を採用しており、量子最適化において大きな進歩を遂げている：\n",
        "\n",
        "**回路効率** ：bf-DCQOアルゴリズムは顕著なゲート削減を達成する [\\[1\\]：](#references)\n",
        "\n",
        "* デジタル量子アニーリング（DQA）より最大 **10倍少ないエンタングルゲート数**\n",
        "* かなり浅い回路が可能になる：\n",
        "  * 量子実行時のエラー蓄積が少ない\n",
        "  * 現在の量子ハードウェアでより大きな問題に取り組む能力\n",
        "  * エラー軽減技術は不要\n",
        "\n",
        "**非変数設計** ：約100回の反復を必要とする変分アルゴリズムとは異なり、bf-DCQOは通常**約10回の反復しか**必要としない [\\[1\\]](#references)。 これは次のような方法で達成される：\n",
        "\n",
        "* 測定された状態分布からのインテリジェントなバイアス磁場計算\n",
        "* 前回の解に近いエネルギー状態から各反復を開始する\n",
        "* 古典的な後処理と局所探索の統合\n",
        "\n",
        "**対断熱プロトコル** ：このアルゴリズムには、短い進化時間中に不要な量子励起を抑制する対断熱項が組み込まれており、急激な遷移があっても系を基底状態付近に保つことができる [\\[1\\]](#references)。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "requirements",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## 要件\n",
        "\n",
        "このチュートリアルを始める前に、以下のものがインストールされていることを確認してください：\n",
        "\n",
        "* Qiskit IBM ランタイム (`pip install qiskit-ibm-runtime`)\n",
        "* Qiskit Functions (`pip install qiskit-ibm-catalog`)\n",
        "* NumPy (`pip install numpy`)\n",
        "* リクエスト (`pip install requests`)\n",
        "* Opt Mapper Qiskit アドオン (`pip install qiskit-addon-opt-mapper`)\n",
        "\n",
        "また、 Qiskit Functions Catalog から[イスカイ・クォンタム・オプティマイザー機能に](/functions?id=kipu-quantum-iskay-quantum-optimizer)アクセスする必要がある。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "setup",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## セットアップ\n",
        "\n",
        "まず、このチュートリアルに必要なパッケージをすべてインポートする。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "imports",
      "metadata": {},
      "outputs": [],
      "source": [
        "import os\n",
        "import tempfile\n",
        "import time\n",
        "from typing import Tuple, Optional\n",
        "\n",
        "import numpy as np\n",
        "import requests\n",
        "\n",
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "\n",
        "from qiskit_addon_opt_mapper import OptimizationProblem\n",
        "from qiskit_addon_opt_mapper.converters import OptimizationProblemToQubo\n",
        "\n",
        "print(\"All required libraries imported successfully\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "credentials",
      "metadata": {},
      "source": [
        "<span id=\"configure-ibm-quantum-credentials\" />\n",
        "\n",
        "### IBM Quantum の認証情報を設定する\n",
        "\n",
        "あなたの [IBM Quantum® Platform](/) クレデンシャル 必要なもの\n",
        "\n",
        "* **APIトークン** ：44文字のAPIキー IBM Quantum Platform\n",
        "* **インスタンスCRN** : IBM Cloud® インスタンス識別子\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "creds",
      "metadata": {},
      "outputs": [],
      "source": [
        "token = \"<YOUR_API_KEY>\"\n",
        "instance = \"<YOUR_INSTANCE_CRN>\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step1",
      "metadata": {},
      "source": [
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "## ステップ1：古典的な入力を量子問題にマッピングする\n",
        "\n",
        "古典的な問題を量子的な表現に置き換えることから始める。 このステップには以下が含まれる：\n",
        "\n",
        "1. イスカイ量子オプティマイザーへの接続\n",
        "2. 市場分割問題の読み込みと定式化\n",
        "3. この問題を解くbf-DCQOアルゴリズムの理解\n",
        "\n",
        "<span id=\"connect-to-iskay-quantum-optimizer\" />\n",
        "\n",
        "### Iskay Quantum Optimizer に接続する\n",
        "\n",
        "まず、 Qiskit Functions Catalog に接続し、イスカイ・クォンタム・オプティマイザーをロードする。 Iskay OptimizerはKipu Quantum社が提供する量子関数で、量子ハードウェア上で最適化問題を解くためのbf-DCQOアルゴリズムを実装している。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "load_solver",
      "metadata": {},
      "outputs": [],
      "source": [
        "catalog = QiskitFunctionsCatalog(token=token, instance=instance)\n",
        "iskay_solver = catalog.load(\"kipu-quantum/iskay-quantum-optimizer\")\n",
        "\n",
        "print(\"Iskay optimizer loaded successfully\")\n",
        "print(\"Ready to solve optimization problems using bf-DCQO algorithm\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step2",
      "metadata": {},
      "source": [
        "<span id=\"load-and-formulate-the-problem\" />\n",
        "\n",
        "### 問題をロードし、定式化する\n",
        "\n",
        "<span id=\"understand-the-problem-data-format\" />\n",
        "\n",
        "#### 問題データの形式を理解する\n",
        "\n",
        "QOBLIB（Quantum Optimization Benchmarking Library） [\\[2\\]](#references) の問題インスタンスは、単純なテキスト形式で格納されている。 ターゲット・インスタンス `ms_03_200_177.dat` の実際の中身を見てみよう：\n",
        "\n",
        "```text\n",
        "3 20\n",
        "60   92  161   53   97    2   75   81    6  139  132   45  108  112  181   93  152  200  164   51 1002\n",
        "176  196   41  143    2   88    0   79   10   71   75  148   82  135   34  187   33  155   58   46  879\n",
        "68   68  179  173  127  163   48   49   99   78   44   52  173  131   73  198   84  109  180   95 1040\n",
        "```\n",
        "\n",
        "**フォーマット構成：**\n",
        "\n",
        "* **一行目：** `3 20`\n",
        "  * `3` ＝積の数（制約／行列の行数 $A$ ）\n",
        "  * `20` = 市場の数（行列の変数/列） $A$\n",
        "\n",
        "* **次の3行：** 係数行列 $A$、ターゲット・ベクトル $b$\n",
        "  * 各行には21個の数字があり、最初の20個が行係数、最後がターゲットである\n",
        "  * 2行目 `60 92 161 ... 51 | 1002`\n",
        "    * 最初の20の数字：20の市場それぞれで製品1がどれだけ売れているか\n",
        "    * 最後の数字（1002）：ある地域における製品1の販売目標\n",
        "  * 3行目 `176 196 41 ... 46 | 879`\n",
        "    * 製品2の市場別・目標別売上高 (879)\n",
        "  * 4行目 `68 68 179 ... 95 | 1040`\n",
        "    * 市場別・ターゲット別売上高(1040)\n",
        "\n",
        "**ビジネス通訳：**\n",
        "\n",
        "* 市場0の販売：製品1が60ユニット、製品2が176ユニット、製品3が68ユニット\n",
        "* 市場1の販売：製品1が92ユニット、製品2が196ユニット、製品3が68ユニット\n",
        "* そして、20の市場すべてについて......。\n",
        "* **目標** ：この20の市場を2つの地域に分割し、それぞれの地域に製品1を1002ユニット、製品2を879ユニット、製品3を1040ユニット供給する\n",
        "\n",
        "<span id=\"qubo-transformation\" />\n",
        "\n",
        "#### QUBO変換\n",
        "\n",
        "<span id=\"from-constraints-to-qubo-the-mathematical-transformation\" />\n",
        "\n",
        "## 制約からQUBOへ：数学的変換\n",
        "\n",
        "量子最適化の威力は、制約のある問題を制約のない2次形式に変換することにある [\\[4\\]](#references)。 市場分割問題では、等式制約を次のように変換する\n",
        "\n",
        "$Ax = b$\n",
        "\n",
        "ここで、 $x ∈ \\{0,1\\}^n$、制約違反にペナルティを課すことでQUBOに変換する。\n",
        "\n",
        "**ペナルティ法：** $Ax = b$ を正確に保持する必要があるので、二乗違反を最小化する： $f(x) = ||Ax - b||^2$\n",
        "\n",
        "これは、すべての制約が満たされたときに正確にゼロに等しくなる。 代数的に展開する： $f(x) = (Ax - b)^T(Ax - b) = x^T A^T A x - 2b^T A x + b^T b$\n",
        "\n",
        "**QUBOの目的：** $b^T b$ は一定なので、最適化は次のようになる： $\\text{minimize} \\quad Q(x) = x^T(A^T A)x - 2(A^T b)^T x$\n",
        "\n",
        "**重要な洞察：** この変換は厳密であり、近似ではない。 等式制約は、補助変数やペナルティ・パラメータを必要とせず、自然に2次形式に2乗されるため、この定式化は数学的にエレガントであり、量子ソルバーにとって計算効率が高い [\\[4\\]](#references)。 `OptimizationProblem` クラスを使って制約問題を定義し、 `OptimizationProblemToQubo`、両方とも **qiskit\\_addon\\_opt\\_mapper** パッケージのものを使ってQUBO形式に変換します。 これにより、ペナルティに基づく変換が自動的に処理される。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "functions_intro",
      "metadata": {},
      "source": [
        "<span id=\"implement-data-loading-and-qubo-conversion-functions\" />\n",
        "\n",
        "### データ読み込みおよびQUBO変換機能を実装する\n",
        "\n",
        "ここで3つの効用関数を定義する：\n",
        "\n",
        "1. `parse_marketsplit_dat()` - `.dat` ファイル形式を解析し、マトリックス $A$ を抽出する。 $b$\n",
        "2. `fetch_marketsplit_data()` - QOBLIBリポジトリから問題のインスタンスを直接ダウンロードする\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "functions",
      "metadata": {},
      "outputs": [],
      "source": [
        "def parse_marketsplit_dat(filename: str) -> Tuple[np.ndarray, np.ndarray]:\n",
        "    \"\"\"\n",
        "    Parse a market split problem from a .dat file format.\n",
        "\n",
        "    Parameters\n",
        "    ----------\n",
        "    filename : str\n",
        "        Path to the .dat file containing the market split problem data.\n",
        "\n",
        "    Returns\n",
        "    -------\n",
        "    A : np.ndarray\n",
        "        Coefficient matrix of shape (m, n) where m is the number of products\n",
        "        and n is the number of markets.\n",
        "    b : np.ndarray\n",
        "        Target vector of shape (m,) containing the target sales per product.\n",
        "    \"\"\"\n",
        "    with open(filename, \"r\", encoding=\"utf-8\") as f:\n",
        "        lines = [\n",
        "            line.strip()\n",
        "            for line in f\n",
        "            if line.strip() and not line.startswith(\"#\")\n",
        "        ]\n",
        "\n",
        "    if not lines:\n",
        "        raise ValueError(\"Empty or invalid .dat file\")\n",
        "\n",
        "    # First line: m n (number of products and markets)\n",
        "    m, n = map(int, lines[0].split())\n",
        "\n",
        "    # Next m lines: each row of A followed by corresponding element of b\n",
        "    A, b = [], []\n",
        "    for i in range(1, m + 1):\n",
        "        values = list(map(int, lines[i].split()))\n",
        "        A.append(values[:-1])  # First n values: product sales per market\n",
        "        b.append(values[-1])  # Last value: target sales for this product\n",
        "\n",
        "    return np.array(A, dtype=np.int32), np.array(b, dtype=np.int32)\n",
        "\n",
        "\n",
        "def fetch_marketsplit_data(\n",
        "    instance_name: str = \"ms_03_200_177.dat\",\n",
        ") -> Tuple[Optional[np.ndarray], Optional[np.ndarray]]:\n",
        "    \"\"\"\n",
        "    Fetch market split data directly from the QOBLIB repository.\n",
        "\n",
        "    Parameters\n",
        "    ----------\n",
        "    instance_name : str\n",
        "        Name of the .dat file to fetch (default: \"ms_03_200_177.dat\").\n",
        "\n",
        "    Returns\n",
        "    -------\n",
        "    A : np.ndarray or None\n",
        "        Coefficient matrix if successful, None if failed.\n",
        "    b : np.ndarray or None\n",
        "        Target vector if successful, None if failed.\n",
        "    \"\"\"\n",
        "    url = f\"https://git.zib.de/qopt/qoblib-quantum-optimization-benchmarking-library/-/raw/main/01-marketsplit/instances/{instance_name}\"\n",
        "\n",
        "    try:\n",
        "        response = requests.get(url, timeout=30)\n",
        "        response.raise_for_status()\n",
        "\n",
        "        with tempfile.NamedTemporaryFile(\n",
        "            mode=\"w\", suffix=\".dat\", delete=False, encoding=\"utf-8\"\n",
        "        ) as f:\n",
        "            f.write(response.text)\n",
        "            temp_path = f.name\n",
        "\n",
        "        try:\n",
        "            return parse_marketsplit_dat(temp_path)\n",
        "        finally:\n",
        "            os.unlink(temp_path)\n",
        "    except Exception as e:\n",
        "        print(f\"Error: {e}\")\n",
        "        return None, None"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "load_intro",
      "metadata": {},
      "source": [
        "<span id=\"load-the-problem-instance\" />\n",
        "\n",
        "### 問題インスタンスを読み込む\n",
        "\n",
        "ここで、QOBLIB \\[2] から特定の問題インスタンス `ms_03_200_177.dat` をロードします。 このインスタンスには\n",
        "\n",
        "* 3製品（制約条件）\n",
        "* 20市場（バイナリー決定変数）\n",
        "* 100万以上の市場割り当てが可能 ( $2^{20} = 1,048,576$ )\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "load",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Load the problem instance\n",
        "instance_name = \"ms_03_200_177.dat\"\n",
        "A, b = fetch_marketsplit_data(instance_name=instance_name)\n",
        "\n",
        "if A is not None:\n",
        "    print(\"Successfully loaded problem instance from QOBLIB\")\n",
        "    print(\"\\nProblem Instance Analysis:\")\n",
        "    print(\"=\" * 50)\n",
        "    print(f\"Coefficient Matrix A: {A.shape[0]} × {A.shape[1]}\")\n",
        "    print(f\"   → {A.shape[0]} products (constraints)\")\n",
        "    print(f\"   → {A.shape[1]} markets (decision variables)\")\n",
        "    print(f\"Target Vector b: {b}\")\n",
        "    print(\"   → Target sales per product for each region\")\n",
        "    print(\n",
        "        f\"Solution Space: \"\n",
        "        f\"2^{A.shape[1]} = {2**A.shape[1]:,} possible assignments\"\n",
        "    )"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "convert_intro",
      "metadata": {},
      "source": [
        "<span id=\"convert-to-qubo-format\" />\n",
        "\n",
        "### QUBO形式に変換する\n",
        "\n",
        "ここで制約付き最適化問題をQUBO形式に変換する：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "convert",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Create optimization problem\n",
        "ms = OptimizationProblem(instance_name.replace(\".dat\", \"\"))\n",
        "\n",
        "# Add binary variables (one for each market)\n",
        "ms.binary_var_list(A.shape[1])\n",
        "\n",
        "# Add equality constraints (one for each product)\n",
        "for idx, rhs in enumerate(b):\n",
        "    ms.linear_constraint(A[idx, :], sense=\"==\", rhs=rhs)\n",
        "\n",
        "# Convert to QUBO with penalty parameter\n",
        "qubo = OptimizationProblemToQubo(penalty=1).convert(ms)\n",
        "\n",
        "print(\"QUBO Conversion Complete:\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Number of variables: {qubo.get_num_vars()}\")\n",
        "print(f\"Constant term: {qubo.objective.constant}\")\n",
        "print(f\"Linear terms: {len(qubo.objective.linear.to_dict())}\")\n",
        "print(f\"Quadratic terms: {len(qubo.objective.quadratic.to_dict())}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1d307072",
      "metadata": {},
      "source": [
        "<span id=\"convert-qubo-to-iskay-format\" />\n",
        "\n",
        "### QUBOをIskay形式に変換する\n",
        "\n",
        "ここで、QUBOオブジェクトをKipu Quantumのイスカイ・オプティマイザーが必要とする辞書形式に変換する必要がある。\n",
        "\n",
        "`problem` と `problem_type` の引数は、以下の形式の最適化問題を表す\n",
        "\n",
        "$$\n",
        "\\begin{align}\n",
        "\\min_{(x_1, x_2, \\ldots, x_n) \\in D} C(x_1, x_2, \\ldots, x_n) \\nonumber\n",
        "\\end{align}\n",
        "$$\n",
        "\n",
        "ここで\n",
        "\n",
        "$$\n",
        "C(x_1, ... , x_n) = a + \\sum_{i} b_i x_i + \\sum_{i, j} c_{i, j} x_i x_j + ... + \\sum_{k_1, ..., k_m} g_{k_1, ..., k_m} x_{k_1} ... x_{k_m}\n",
        "$$\n",
        "\n",
        "* `problem_type = \"binary\"` を選択することで、コスト関数が `binary` 形式であることを指定します。これは $D = \\{0,  1\\}^{n}$ のように、コスト関数が QUBO/HUBO 形式で書かれていることを意味します。\n",
        "* 一方、 `problem_type = \"spin\"` を選ぶと、コスト関数はイジング定式化で記述される。 $D = \\{-1, 1\\}^{n}$。\n",
        "\n",
        "問題の係数は、次のように辞書にエンコードする必要がある：\n",
        "\n",
        "$$\n",
        "\\begin{align} \\nonumber\n",
        "&\\texttt{\\{} \\\\ \\nonumber\n",
        "&\\texttt{\"()\"}&: \\quad &a, \\\\ \\nonumber\n",
        "&\\texttt{\"(i,)\"}&: \\quad &b_i, \\\\ \\nonumber\n",
        "&\\texttt{\"(i, j)\"}&: \\quad &c_{i, j}, \\quad (i \\neq j) \\\\ \\nonumber\n",
        "&\\quad  \\vdots \\\\ \\nonumber\n",
        "&\\texttt{\"(} k_1, ..., k_m  \\texttt{)\"}&: \\quad &g_{k_1, ..., k_m}, \\quad (k_1 \\neq k_2 \\neq \\dots \\neq k_m) \\\\ \\nonumber\n",
        "&\\texttt{\\}}\n",
        "\\end{align}\n",
        "$$\n",
        "\n",
        "辞書のキーは、繰り返しのない整数の有効なタプルを含む文字列でなければならないことに注意。 二進法の問題では、私たちは次のことを知っている：\n",
        "\n",
        "$$\n",
        "x_i^2 = x_i\n",
        "$$\n",
        "\n",
        "を $i=j$ （ $x_i \\in \\{0,1\\}$ は $x_i \\cdot x_i = x_i$ を意味するので）。つまり、QUBOの定式化において、線形寄与 $b_i x_i$ と対角2次寄与 $c_{i,i} x_i^2$ の両方がある場合、これらの項は1つの線形係数にまとめなければならない：\n",
        "\n",
        "**変数 $x_i$ の線形係数の合計** ： $b_i + c_{i,i}$\n",
        "\n",
        "これは、次のことを意味します：\n",
        "\n",
        "* `\"(i, )\"` のような線形項は、元の線形係数＋対角2次係数を含む\n",
        "* `\"(i, i)\"` のような対角線上の2次用語は、最終的な**辞書に載っては**ならない\n",
        "* `\"(i, j)\"` $i \\neq j$ のような非対角二次項のみを別の項目として含める\n",
        "\n",
        "**例**もしあなたのQUBOが $3x_1 + 2x_1^2 + 4x_1 x_2$、イスケイの辞書にはこう書かれているはずだ：\n",
        "\n",
        "* `\"(0, )\"`: `5.0` ( $3 + 2 = 5$ を組み合わせる)\n",
        "* `\"(0, 1)\"`: `4.0` (非対角項)\n",
        "\n",
        "`\"(0, )\"`: `3.0` と `\"(0, 0)\"`: `2.0` のエントリーは**別々ではない。**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "57eda6fd",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Convert QUBO to Iskay dictionary format:\n",
        "\n",
        "# Create empty Iskay input dictionary\n",
        "iskay_input_problem = {}\n",
        "\n",
        "# Convert QUBO to Iskay dictionary format\n",
        "iskay_input_problem = {\"()\": qubo.objective.constant}\n",
        "\n",
        "for i in range(qubo.get_num_vars()):\n",
        "    for j in range(i, qubo.get_num_vars()):\n",
        "        if i == j:\n",
        "            # Add linear term (including diagonal quadratic contribution)\n",
        "            iskay_input_problem[f\"({i}, )\"] = float(\n",
        "                qubo.objective.linear.to_dict().get(i)\n",
        "            ) + float(qubo.objective.quadratic.to_dict().get((i, i)))\n",
        "        else:\n",
        "            # Add off-diagonal quadratic term\n",
        "            iskay_input_problem[f\"({i}, {j})\"] = float(\n",
        "                qubo.objective.quadratic.to_dict().get((i, j))\n",
        "            )\n",
        "\n",
        "# Display Iskay dictionary summary\n",
        "print(\"Iskay Dictionary Format:\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Total coefficients: {len(iskay_input_problem)}\")\n",
        "print(f\"  • Constant term: {iskay_input_problem['()']}\")\n",
        "print(\n",
        "    f\"  • Linear terms: \"\n",
        "    f\"{sum(1 for k in iskay_input_problem.keys() if k != '()' and ', )' in k)}\"\n",
        ")\n",
        "print(\n",
        "    f\"  • Quadratic terms: \"\n",
        "    f\"{sum(1 for k in iskay_input_problem.keys() if k != '()' and ', )' not in k)}\"\n",
        ")\n",
        "print(\"\\nSample coefficients:\")\n",
        "\n",
        "# Get first 10 and last 5 items properly\n",
        "items = list(iskay_input_problem.items())\n",
        "first_10 = list(enumerate(items[:10]))\n",
        "last_5 = list(enumerate(items[-5:], start=len(items) - 5))\n",
        "\n",
        "for i, (key, value) in first_10 + last_5:\n",
        "    coeff_type = (\n",
        "        \"constant\"\n",
        "        if key == \"()\"\n",
        "        else \"linear\"\n",
        "        if \", )\" in key\n",
        "        else \"quadratic\"\n",
        "    )\n",
        "    print(f\"  {key}: {value} ({coeff_type})\")\n",
        "print(\"  ...\")\n",
        "print(\"\\n✓ Problem ready for Iskay optimizer!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step3",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-bf-dcqo-algorithm\" />\n",
        "\n",
        "### bf-DCQOアルゴリズムを理解する\n",
        "\n",
        "最適化を実行する前に、イスカイを動かす高度な量子アルゴリズムを理解しよう： **bf-DCQO（bias-field digitized counterdiabatic quantum optimization）** [\\[1\\]](#references)。\n",
        "\n",
        "<span id=\"what-is-bf-dcqo\" />\n",
        "\n",
        "#### bf-DCQOとは何ですか？\n",
        "\n",
        "bf-DCQOは量子系の時間発展に基づいており、問題の解は最終的な量子ハミルトニアンの**基底状態** （最低エネルギー状態）に符号化される [\\[1\\]](#references)。 このアルゴリズムは、量子最適化における基本的な課題に取り組んでいる：\n",
        "\n",
        "**課題** ：従来の断熱量子コンピューティングでは、断熱定理に従って基底状態を維持するために、非常にゆっくりとした進化が必要だった。 このため、問題の複雑さが増すにつれて量子回路はますます深くなり、ゲート演算の回数が増え、累積エラーも増えていく。\n",
        "\n",
        "**解決策** ：bf-DCQOは対断熱プロトコルを使用し、基底状態の忠実度を維持しながら迅速な進化を可能にし、回路の深さを劇的に減少させる。\n",
        "\n",
        "<span id=\"mathematical-framework\" />\n",
        "\n",
        "#### 数学的枠組み\n",
        "\n",
        "このアルゴリズムは、以下の形式のコスト関数を最小化する：\n",
        "\n",
        "$\\min_{(x_1,x_2,...,x_n) \\in D} C(x_1,x_2,...,x_n)$\n",
        "\n",
        "ここで、 $D = \\{0,1\\}^n$ はバイナリ変数とする：\n",
        "\n",
        "$C(x) = a + \\sum_i b_i x_i + \\sum_{i,j} c_{ij} x_i x_j + ... + \\sum g_{k_1,...,k_m} x_{k_1}...x_{k_m}$\n",
        "\n",
        "市場分割問題では、コスト関数は次のようになる：\n",
        "\n",
        "$C(x) = ||Ax - b||^2 = x^T A^T A x - 2 b^T A x + b^T b$\n",
        "\n",
        "<span id=\"the-role-of-counterdiabatic-terms\" />\n",
        "\n",
        "#### 抗糖尿病項目の役割\n",
        "\n",
        "**対断熱項は**、時間依存ハミルトニアンに導入される追加項であり、量子発展中の不要な励起を抑制する。 それがなぜ重要なのかを説明しよう：\n",
        "\n",
        "断熱的量子最適化では、時間依存のハミルトニアンに従って系を進化させる：\n",
        "\n",
        "$H(t) = \\left(1 - \\frac{t}{T}\\right) H_{\\text{initial}} + \\frac{t}{T} H_{\\text{problem}}$\n",
        "\n",
        "ここで、 $H_{\\text{problem}}$ は最適化問題を符号化している。 急速な進化の間に基底状態を維持するために、対断熱項を加える：\n",
        "\n",
        "$H_{\\text{CD}}(t) = H(t) + H_{\\text{counter}}(t)$\n",
        "\n",
        "これらの対断熱項は次のような働きをする：\n",
        "\n",
        "1. **不要な遷移を抑制する** ：高速進化中に量子状態が励起状態にジャンプするのを防ぐ\n",
        "2. **より短い進化時間を可能にする** ：断熱性に違反することなく、より速く最終状態に到達できる\n",
        "3. **回路の深さを減らす** ：より短い進化は、より少ないゲートとより少ないエラーにつながる\n",
        "\n",
        "bf-DCQOは、デジタル量子アニーリング [\\[1\\]](#references) よりも最大 **10倍少ないエンタングルゲートを**使用するため、今日のノイズの多い量子ハードウェアに実用的である。\n",
        "\n",
        "<span id=\"bias-field-iterative-optimization\" />\n",
        "\n",
        "#### バイアス場反復最適化\n",
        "\n",
        "何度も反復して回路パラメータを最適化する変分アルゴリズムとは異なり、bf-DCQOは**バイアス・フィールド・ガイド・アプローチを**採用しており、約10回の反復で収束する \\[1] ：\n",
        "\n",
        "**反復プロセス：**\n",
        "\n",
        "1. **最初の量子進化**対断熱進化プロトコルを実装した量子回路から始める\n",
        "\n",
        "2. **測定** ：量子状態を測定し、ビット列の確率分布を得る\n",
        "\n",
        "3. **バイアス場の計算** ：測定の統計量を分析し、各量子ビットに最適なバイアス磁場 $h_i$ を計算する： $h_i = \\text{f}(\\text{measurement statistics}, \\text{previous solutions})$\n",
        "\n",
        "4. **次の反復** ：バイアスフィールドは次の反復のためにハミルトニアンを修正する： $H_{\\text{next}} = H_{\\text{problem}} + \\sum_i h_i \\sigma_i^z$\n",
        "\n",
        "   これにより、以前に見つかった良い解の近くから始めることができ、効果的に \"量子局所探索 \"を行うことができる\n",
        "\n",
        "5. **収束** ：解の質が安定するか、最大反復回数に達するまで繰り返す\n",
        "\n",
        "**主な利点**パラメータ空間をやみくもに探索しなければならない変分法とは異なり、各反復は、以前の測定からの情報を取り入れることによって、最適解に向けた意味のある進歩を提供する。\n",
        "\n",
        "<span id=\"integrated-classical-post-processing\" />\n",
        "\n",
        "#### 統合された古典的な後処理\n",
        "\n",
        "量子最適化が収束した後、イスキーは古典的な**局所探索の**後処理を行う：\n",
        "\n",
        "* **ビットフリップ探索** ：最良の測定解のビットを系統的またはランダムに反転させる\n",
        "* **エネルギー評価** ： $C(x)$ を計算する\n",
        "* **貪欲な選択** ：コスト関数を下げる改善を受け入れる\n",
        "* **複数のパス** ：複数のパスを実行する（ `postprocessing_level` で制御）\n",
        "\n",
        "このハイブリッド・アプローチは、ハードウェアの不完全性や読み出しエラーによるビット・フリップ・エラーを補正し、ノイズの多い量子デバイスでも高品質のソリューションを保証する。\n",
        "\n",
        "<span id=\"why-bf-dcqo-excels-on-current-hardware\" />\n",
        "\n",
        "#### なぜbf-DCQOが現行ハードウェアで優れているのか\n",
        "\n",
        "bf-DCQOアルゴリズムは、今日のノイズの多い中間量子（NISQ）デバイス [\\[1\\]](#references) で優れた性能を発揮するように特別に設計されている：\n",
        "\n",
        "1. **エラーの回復力** ：ゲート数が少ない（10分の1）ため、エラーの蓄積が劇的に少ない\n",
        "2. **エラー緩和が不要** ：アルゴリズム固有の効率性により、高価なエラー緩和技術が不要になる [\\[1\\]](#references)\n",
        "3. **スケーラビリティ** ：最大156量子ビット(156個の2進変数)の問題を直接量子ビットマッピングで扱うことができる [\\[1\\]](#references)\n",
        "4. **実証済みの性能** ：ベンチマーク MaxCut およびHUBOインスタンスで100%の近似比を達成 [\\[1\\]。](#references)\n",
        "\n",
        "では、この強力なアルゴリズムを、マーケット・スプリット問題で実際に使ってみよう！\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step4",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-problem-for-quantum-hardware-execution\" />\n",
        "\n",
        "## ステップ2：量子ハードウェア実行に向けた問題の最適化\n",
        "\n",
        "bf-DCQOアルゴリズムは自動的に回路の最適化を行い、ターゲットとなるバックエンドのために特別に設計された対断熱項を持つ浅い量子回路を作成する。\n",
        "\n",
        "<span id=\"configure-the-optimization\" />\n",
        "\n",
        "### 最適化を設定する\n",
        "\n",
        "Iskay Optimizerは、最適化問題を効果的に解くために、いくつかの重要なパラメータを必要とします。 量子最適化プロセスにおける各パラメーターとその役割について見てみよう：\n",
        "\n",
        "<span id=\"required-parameters\" />\n",
        "\n",
        "#### 必須パラメーター\n",
        "\n",
        "| パラメーター      | タイプ                | 説明                                              | 例                                           |\n",
        "| ----------- | ------------------ | ----------------------------------------------- | ------------------------------------------- |\n",
        "| **問題**      | `Dict[str, float]` | 文字列キー形式のQUBO係数                                  | `{\"()\": -21.0, \"(0,4)\": 0.5, \"(0,1)\": 0.5}` |\n",
        "| **問題タイプ**   | `str`              | フォーマット指定：QUBOの場合は `\"binary\"` 、イジングの場合は `\"spin\"` | `\"binary\"`                                  |\n",
        "| **バックエンド名** | `str`              | ターゲット量子デバイス                                     | `\"ibm_fez\"`                                 |\n",
        "\n",
        "<span id=\"essential-concepts\" />\n",
        "\n",
        "#### 基本概念\n",
        "\n",
        "* **問題の形式** ：変数がバイナリ（0/1）であり、市場の割り当てを表すため、 `\"binary\"` 。\n",
        "* **バックエンドの選択** ：ニーズとコンピュート・リソース・インスタンスに基づいて、利用可能なQPU（例えば、 `\"ibm_fez\"` ）から選択します。\n",
        "* **QUBO構造** ：私たちの問題辞書には、数学的変換の正確な係数が含まれています。\n",
        "\n",
        "<span id=\"advanced-options-optional\" />\n",
        "\n",
        "#### 詳細設定（任意）\n",
        "\n",
        "イスカイはオプションのパラメーターで微調整ができる。 デフォルトはほとんどの問題に対してうまく機能するが、特定の要件に合わせて動作をカスタマイズすることもできる：\n",
        "\n",
        "| パラメーター               | タイプ         | デフォルト | 説明                                    |\n",
        "| -------------------- | ----------- | ----- | ------------------------------------- |\n",
        "| **ショット**             | `int`       | 10000 | 反復ごとの量子計測（高いほど正確）                     |\n",
        "| **num\\_iterations**  | `int`       | 10    | アルゴリズムの反復（反復回数を増やすことで解の質を向上させることができる） |\n",
        "| **使用セッション**          | `bool`      | はい    | IBM セッションを利用し、待ち時間を短縮                 |\n",
        "| **seed\\_transpiler** | `int`       | なし    | 再現可能な量子回路コンパイルのためのセット                 |\n",
        "| **direct\\_qubit**    | `bool`      | いいえ   | 仮想量子ビットを物理量子ビットに直接マッピングする             |\n",
        "| **job\\_tags**        | `List[str]` | なし    | ジョブ追跡用カスタムタグ                          |\n",
        "| **前処理レベル**           | `int`       | 0     | 問題の前処理強度（0～3）-下記詳細参照                  |\n",
        "| **後処理レベル**           | `int`       | 2     | 解の絞り込みレベル（0～2） - 詳細は以下を参照             |\n",
        "| **翻訳レベル**            | `int`       | 0     | トランスパイラ最適化試験（0～5）-下記詳細を参照             |\n",
        "| **トランスパイル・オンリー**     | `bool`      | いいえ   | 完全な実行を行わずに回路の最適化を分析                   |\n",
        "\n",
        "**前処理レベル（0～3）** ：ハードウェアのコヒーレンス時間に収まらないような大きな問題には特に重要。 より高い前処理レベルは、問題の転置における近似によって、より浅い回路深度を達成する：\n",
        "\n",
        "* **レベル0** ：正確で長いサーキット\n",
        "* **レベル1** ：精度と近似度のバランスが良く、最低10パーセンタイルの角度のゲートだけを切り取る\n",
        "* **レベル2** ：最低20パーセンタイルの角度を持つゲートをカットし、 `approximation_degree=0.95`\n",
        "* **レベル3** ：最大近似レベル。最低30パーセンタイルのゲートをカットし、 `approximation_degree=0.90`\n",
        "\n",
        "**Transpilation Levels (0-5)：** 量子回路コンパイルのための高度なトランスパイラ最適化トライアルを制御します。 これは古典的なオーバーヘッドの増加につながる可能性があり、場合によっては回路の深さは変わらないかもしれない。 デフォルト値 `2` は、一般的に回路が最小になり、比較的高速になる。\n",
        "\n",
        "* **レベル0** ：分解されたDCQO回路の最適化（レイアウト、配線、スケジューリング）\n",
        "* **レベル1** : `PauliEvolutionGate` の最適化、そして分解されたDCQO回路( max\\_trials=10 )\n",
        "* **レベル2** : `PauliEvolutionGate` の最適化、そして分解されたDCQO回路( max\\_trials=15 )\n",
        "* **レベル3** : `PauliEvolutionGate` の最適化、そして分解されたDCQO回路( max\\_trials=20 )\n",
        "* **レベル4** : `PauliEvolutionGate` の最適化、そして分解されたDCQO回路( max\\_trials=25 )\n",
        "* **レベル5** : `PauliEvolutionGate` の最適化、そして分解されたDCQO回路( max\\_trials=50 )\n",
        "\n",
        "**後処理レベル(0-2)：** 局所探索の貪欲なパスの回数を変えてビット反転エラーを補正する、古典的な最適化の度合いを制御する：\n",
        "\n",
        "* **レベル0** ：1パス\n",
        "* **レベル1** ：2パス\n",
        "* **レベル2** ：3パス\n",
        "\n",
        "**トランスパイル専用モード** ：完全な量子アルゴリズム実行を行わずに回路の最適化を解析したいユーザー向けに用意されました。\n",
        "\n",
        "<span id=\"custom-configuration-example\" />\n",
        "\n",
        "#### カスタム設定例\n",
        "\n",
        "以下は、さまざまな設定でイスカイを設定する方法だ：\n",
        "\n",
        "```python\n",
        "custom_options = {\n",
        "    # Higher shot count for better statistics\n",
        "    \"shots\": 15_000,\n",
        "\n",
        "    # More iterations for solution refinement\n",
        "    \"num_iterations\": 12,\n",
        "\n",
        "    # Light preprocessing for problem simplification\n",
        "    \"preprocessing_level\": 1,\n",
        "\n",
        "    # Maximum postprocessing for solution quality\n",
        "    \"postprocessing_level\": 2,\n",
        "\n",
        "    # Using higher transpilation level for circuit optimization\n",
        "    \"transpilation_level\": 3,\n",
        "\n",
        "    # Fixed seed for reproducible results\n",
        "    \"seed_transpiler\": 42,\n",
        "\n",
        "    # Custom tracking tags\n",
        "    \"job_tags\": [\"market_split\"]\n",
        "}\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "86e2b10d",
      "metadata": {},
      "source": [
        "このチュートリアルでは、ほとんどのデフォルトパラメータを維持し、バイアスフィールドの反復回数だけを変更します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "config",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Specify the target backend\n",
        "backend_name = \"ibm_fez\"\n",
        "\n",
        "# Set the number of bias-field iterations and set a tag to identify the jobs\n",
        "options = {\n",
        "    \"num_iterations\": 3,  # Change number of bias-field iterations\n",
        "    \"job_tags\": [\"market_split_example\"],  # Tag to identify jobs\n",
        "}\n",
        "\n",
        "# Configure Iskay optimizer\n",
        "iskay_input = {\n",
        "    \"problem\": iskay_input_problem,\n",
        "    \"problem_type\": \"binary\",\n",
        "    \"backend_name\": backend_name,\n",
        "    \"options\": options,\n",
        "}\n",
        "\n",
        "print(\"Iskay Optimizer Configuration:\")\n",
        "print(\"=\" * 40)\n",
        "print(f\"  Backend: {backend_name}\")\n",
        "print(f\"  Problem: {len(iskay_input['problem'])} terms\")\n",
        "print(\"  Algorithm: bf-DCQO\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "submit_intro",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-qiskit-primitives\" />\n",
        "\n",
        "## ステップ3: `Qiskit primitives`を使用して実行する\n",
        "\n",
        "IBM Quantum。 bf-DCQOアルゴリズムはそうする：\n",
        "\n",
        "1. 対断熱項を持つ浅い量子回路の構築\n",
        "2. バイアスフィールド最適化で約10回の反復を行う\n",
        "3. ローカルサーチによる古典的な後処理の実行\n",
        "4. 最適な市場割り当てを返す\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "run",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Submit the optimization job\n",
        "print(\"Submitting optimization job to Kipu Quantum...\")\n",
        "print(\n",
        "    f\"Problem size: {A.shape[1]} variables, {len(iskay_input['problem'])} terms\"\n",
        ")\n",
        "print(\n",
        "    \"Algorithm: bf-DCQO (bias-field digitized counterdiabatic quantum optimization)\"\n",
        ")\n",
        "\n",
        "job = iskay_solver.run(**iskay_input)\n",
        "\n",
        "print(\"\\nJob successfully submitted!\")\n",
        "print(f\"Job ID: {job.job_id}\")\n",
        "print(\"Optimization in progress...\")\n",
        "print(\n",
        "    f\"The bf-DCQO algorithm will efficiently explore \"\n",
        "    f\"{2**A.shape[1]:,} possible assignments\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "status_intro",
      "metadata": {},
      "source": [
        "<span id=\"monitor-job-status\" />\n",
        "\n",
        "### ジョブの状態を監視する\n",
        "\n",
        "最適化ジョブの現在のステータスを確認できます。 表示されることがある状況は、次の通りです。\n",
        "\n",
        "* `QUEUED`:ジョブはキューで待機中\n",
        "* `RUNNING`:ジョブは量子ハードウェア上で実行中\n",
        "* `DONE`:ジョブが正常に完了\n",
        "* `CANCELED`:仕事がキャンセルされた\n",
        "* `ERROR`:ジョブでエラーが発生しました\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "status",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Check job status\n",
        "print(f\"Job status: {job.status()}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "wait_intro",
      "metadata": {},
      "source": [
        "<span id=\"wait-for-completion\" />\n",
        "\n",
        "### 完了するまでお待ちください\n",
        "\n",
        "このセルはジョブが完了するまでブロックされる。 最適化プロセスには以下が含まれる：\n",
        "\n",
        "* キュー時間（量子ハードウェアアクセス待ち）\n",
        "* 実行時間（約10回の反復によるbf-DCQOアルゴリズムの実行）\n",
        "* 後処理時間（古典的局所探索）\n",
        "\n",
        "典型的な完了時間は、待ち行列の状況にもよるが、数分から数十分である。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "wait",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Wait for job completion\n",
        "while True:\n",
        "    status = job.status()\n",
        "    print(\n",
        "        f\"Waiting for job {job.job_id} to complete... (status: {status})\",\n",
        "        end=\"\\r\",\n",
        "        flush=True,\n",
        "    )\n",
        "    if status in [\"DONE\", \"CANCELED\", \"ERROR\"]:\n",
        "        print(\n",
        "            f\"\\nJob {job.job_id} completed with status: {status}\" + \" \" * 20\n",
        "        )\n",
        "        break\n",
        "    time.sleep(30)\n",
        "\n",
        "# Retrieve the optimization results\n",
        "result = job.result()\n",
        "print(\"\\nOptimization complete!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "step5",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-and-return-result-in-desired-classical-format\" />\n",
        "\n",
        "## ステップ4：後処理を行い、結果を希望の古典形式で返す\n",
        "\n",
        "次に、量子の実行結果を後処理する。 こちらには以下の内容が含まれます：\n",
        "\n",
        "* ソリューション構造の分析\n",
        "* 制約充足の検証\n",
        "* 古典的アプローチに対するベンチマーク\n",
        "\n",
        "<span id=\"analyze-results\" />\n",
        "\n",
        "### 結果を分析する\n",
        "\n",
        "<span id=\"understand-the-result-structure\" />\n",
        "\n",
        "#### 結果構造を理解する\n",
        "\n",
        "イスカイは、以下を含む包括的な結果辞書を返す：\n",
        "\n",
        "* **`solution`**:変数のインデックスを最適値（0または1）にマッピングする辞書\n",
        "* **`solution_info`**:詳細情報\n",
        "  * `bitstring`:バイナリ文字列としての最適な割り当て\n",
        "  * `cost`:目的関数の値（制約を完全に満たすためには0でなければならない）\n",
        "  * `mapping`:ビット列の位置と問題変数の対応\n",
        "  * `seed_transpiler`:再現性のために使用されるシード\n",
        "* **`prob_type`**:解答がバイナリ形式かスピン形式か\n",
        "\n",
        "量子オプティマイザが返す解を調べてみよう。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "results",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Display the optimization results\n",
        "print(\"Optimization Results\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Problem Type: {result['prob_type']}\")\n",
        "print(\"\\nSolution Info:\")\n",
        "print(f\"  Bitstring: {result['solution_info']['bitstring']}\")\n",
        "print(f\"  Cost: {result['solution_info']['cost']}\")\n",
        "print(\"\\nSolution (first 10 variables):\")\n",
        "for i, (var, val) in enumerate(list(result[\"solution\"].items())[:10]):\n",
        "    print(f\"  {var}: {val}\")\n",
        "print(\"  ...\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "validation_intro",
      "metadata": {},
      "source": [
        "<span id=\"solution-validation\" />\n",
        "\n",
        "#### ソリューションの有効化\n",
        "\n",
        "次に、量子解がマーケット・スプリット制約を満たすかどうかを検証する。 検証プロセスはチェックする：\n",
        "\n",
        "**制約違反とは何か？**\n",
        "\n",
        "* 各商品 $i$、地域Aでの実際の売上を計算する： $(Ax)_i$\n",
        "* 目標売上高と比較する $b_i$\n",
        "* **違反は**絶対的な違いだ： $|(Ax)_i - b_i|$\n",
        "* **実行可能な解は**、すべての製品について違反がゼロである\n",
        "\n",
        "**期待すること**\n",
        "\n",
        "* **理想的なケース**違反の合計 = 0 (すべての制約が完全に満たされる)\n",
        "  * 地域Aは、製品1をちょうど1002ユニット、製品2を879ユニット、製品3を1040ユニット入手する\n",
        "  * B地域は残りのユニットを獲得する（それぞれ1002、879、1040）\n",
        "* **良いケース**違反の合計が小さい（最適解に近い）\n",
        "* **悪いケース** ：大きな違反は、ソリューションがビジネス要件を満たしていないことを示している\n",
        "\n",
        "検証関数が計算する：\n",
        "\n",
        "1. 各地域における製品別販売実績\n",
        "2. 各製品の制約違反\n",
        "3. 地域間の市場分布\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "validate",
      "metadata": {},
      "outputs": [],
      "source": [
        "def validate_solution(A, b, solution):\n",
        "    \"\"\"Validate market split solution.\"\"\"\n",
        "    x = np.array(solution)\n",
        "    region_a = A @ x\n",
        "    region_b = A @ (1 - x)\n",
        "    violations = np.abs(region_a - b)\n",
        "\n",
        "    return {\n",
        "        \"target\": b,\n",
        "        \"region_a\": region_a,\n",
        "        \"region_b\": region_b,\n",
        "        \"violations\": violations,\n",
        "        \"total_violation\": np.sum(violations),\n",
        "        \"is_feasible\": np.sum(violations) == 0,\n",
        "        \"region_a_markets\": int(np.sum(x)),\n",
        "        \"region_b_markets\": len(x) - int(np.sum(x)),\n",
        "    }\n",
        "\n",
        "\n",
        "# Convert bitstring to list of integers and validate\n",
        "optimal_assignment = [\n",
        "    int(bit) for bit in result[\"solution_info\"][\"bitstring\"]\n",
        "]\n",
        "validation = validate_solution(A, b, optimal_assignment)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "validation_results_intro",
      "metadata": {},
      "source": [
        "<span id=\"interpret-the-validation-results\" />\n",
        "\n",
        "#### 検証結果を解釈する\n",
        "\n",
        "検証結果は、量子オプティマイザーが実行可能な解を見つけたかどうかを示す。 以下、検証してみよう：\n",
        "\n",
        "**実現可能性のチェック**\n",
        "\n",
        "* **`is_feasible = True`** 解がすべての制約を完全に満たすことを意味する（違反の合計 = 0）\n",
        "* **`is_feasible = False`** いくつかの制約に違反していることを意味する\n",
        "\n",
        "**販売分析：**\n",
        "\n",
        "* 各商品の目標売上と実績売上を比較\n",
        "* 完璧なソリューションのために両地域の全製品について、実績＝目標\n",
        "* その差は、望ましい市場分割にどれだけ近づいているかを示している\n",
        "\n",
        "**市場分布：**\n",
        "\n",
        "* 各地域にいくつの市場が割り当てられているかを示す\n",
        "* 市場数が同数である必要はなく、販売目標が達成されていればよい\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "display_validation",
      "metadata": {},
      "outputs": [],
      "source": [
        "print(\"Solution Validation\")\n",
        "print(\"=\" * 50)\n",
        "print(f\"Feasible solution: {validation['is_feasible']}\")\n",
        "print(f\"Total constraint violation: {validation['total_violation']}\")\n",
        "\n",
        "print(\"\\nSales Analysis (Target vs Actual):\")\n",
        "for i, (target, actual_a, actual_b) in enumerate(\n",
        "    zip(validation[\"target\"], validation[\"region_a\"], validation[\"region_b\"])\n",
        "):\n",
        "    violation_a = abs(actual_a - target)\n",
        "    violation_b = abs(actual_b - target)\n",
        "    print(f\"  Product {i+1}:\")\n",
        "    print(f\"    Target: {target}\")\n",
        "    print(f\"    Region A: {actual_a} (violation: {violation_a})\")\n",
        "    print(f\"    Region B: {actual_b} (violation: {violation_b})\")\n",
        "\n",
        "print(\"\\nMarket Distribution:\")\n",
        "print(f\"  Region A: {validation['region_a_markets']} markets\")\n",
        "print(f\"  Region B: {validation['region_b_markets']} markets\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "interpretation",
      "metadata": {},
      "source": [
        "<span id=\"solution-quality-assessment\" />\n",
        "\n",
        "#### ソリューション品質評価\n",
        "\n",
        "上記の検証結果に基づいて、量子ソリューションの品質を評価することができる：\n",
        "\n",
        "\\*\\* `is_feasible = True` （違反合計＝0）の場合：\\*\\*\n",
        "\n",
        "* 量子オプティマイザーは最適解の発見に成功した\n",
        "* すべてのビジネス上の制約が完全に満たされている\n",
        "* これは、古典的なソルバーが苦戦する問題で量子の優位性を示している [\\[4\\]。](#references)\n",
        "\n",
        "\\*\\* `is_feasible = False` （違反合計＞0）の場合：\\*\\*\n",
        "\n",
        "* 解決策は最適に近いが完璧ではない\n",
        "* 小さな違反は、実際には容認されるかもしれない\n",
        "* オプティマイザのパラメーターの調整を検討する：\n",
        "  * `num_iterations` を増やして最適化パスを増やす\n",
        "  * よりクラシカルな洗練のために `postprocessing_level`\n",
        "  * より良い測定統計のために `shots` を増やす\n",
        "\n",
        "**コスト関数の解釈：**\n",
        "\n",
        "* `solution_info` からの `cost` の値は等しい。 $||Ax - b||^2$\n",
        "* コスト＝0は完全な制約充足を示す\n",
        "* コスト値が高いほど、制約違反が大きいことを示す\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "conclusion",
      "metadata": {},
      "source": [
        "<span id=\"conclusion\" />\n",
        "\n",
        "## おわりに\n",
        "\n",
        "<span id=\"what-we-accomplished\" />\n",
        "\n",
        "### 私たちが成し遂げたこと\n",
        "\n",
        "このチュートリアルで、我々は成功した：\n",
        "\n",
        "1. **実際の最適化問題をロード** ：QOBLIBベンチマークライブラリから難易度の高いMarket Splitインスタンスを取得 \\[2]\n",
        "2. **QUBO形式に変換** ：制約付き問題を無制約二次定式化に変換 \\[3]\n",
        "3. **高度な量子アルゴリズムを活用** ：Kipu Quantumのbf-DCQOアルゴリズム（対断熱項付き）を使用 \\[1]\n",
        "4. **最適解を得る** ：すべての制約条件を満たす実現可能な解を見つける\n",
        "\n",
        "<span id=\"key-takeaways\" />\n",
        "\n",
        "### 主なポイント\n",
        "\n",
        "**アルゴリズムの革新** bf-DCQOアルゴリズムは重要な進歩である [\\[1\\]：](#references)\n",
        "\n",
        "* デジタル量子アニーリングより **10倍少ないゲート数**\n",
        "* 変分法の場合の約100回の反復ではなく、 **約10回の反復**\n",
        "* 回路効率による**エラーの回復力を内蔵**\n",
        "\n",
        "**対断熱項** ：基底状態の忠実性を維持しながら、急速な量子発展を可能にし、今日のノイズの多いハードウェア上で量子最適化を実用化する [\\[1\\]](#references)。\n",
        "\n",
        "**バイアス・フィールド・ガイダンス** ：反復バイアスフィールド・アプローチは、各反復が以前に見つかった良い解の近くから始まることを可能にし、量子強化局所探索の一形態を提供する [\\[1\\]](#references)。\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "### 次のステップ\n",
        "\n",
        "理解を深め、さらに探求するために：\n",
        "\n",
        "1. **さまざまなインスタンスを試す**様々なサイズのQOBLIBインスタンスを試す\n",
        "2. **パラメーターを調整する** ： `num_iterations`, `preprocessing_level` を調整する、 `postprocessing_level`\n",
        "3. **従来のものと比較** : 従来の最適化ソルバーと比較したベンチマーク\n",
        "4. **さまざまな戦略を試す** ：より良いエンコーディングを見つけるか、（可能であれば）HUBOとして定式化してみる\n",
        "5. **あなたの領域に適用する** QUBO/HUBOの定式化テクニックをご自身の最適化問題に適用する\n",
        "\n",
        "<span id=\"references\" />\n",
        "\n",
        "### 参照\n",
        "\n",
        "\\[1] IBM Quantum. \"[キプ量子最適化](/docs/guides/kipu-optimization) \" *IBM Quantum ドキュメンテーション*\n",
        "\n",
        "\\[2] QOBLIB - 量子最適化ベンチマークライブラリ。 ズース・インスティテュート・ベルリン（ZIB）。 [https://git.zib.de/qopt/qoblib-quantum-optimization-benchmarking-library](https://git.zib.de/qopt/qoblib-quantum-optimization-benchmarking-library)\n",
        "\n",
        "\\[3] グラバー、F、 Kochenberger, G., & Du, Y. (2019). \"量子ブリッジ分析I：QUBOモデルの定式化と利用に関するチュートリアル\" *4OR: A Quarterly Journal of Operations Research*, 17(4), 335-371.\n",
        "\n",
        "\\[4] ロディ、A、 Tramontani, A., & Weninger, K. (2023). 「難解な十種競技難解な組合せ問題のベンチマーク\" *INFORMS Journal on Computing*.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    },
    "hours": 1,
    "qpuSeconds": 20
  },
  "nbformat": 4,
  "nbformat_minor": 5
}