{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "b6d1e3ec",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Lösen Sie das Problem der Marktaufteilung mit dem „ ParityQC “ Parity Twine Optimizer\"\n",
        "description: \"Erfahren Sie, wie Sie das Problem der Marktaufteilung mithilfe des Parity Twine Optimizers lösen können.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore parityqc QOBLIB marketsplit independentset */}\n",
        "\n",
        "<span id=\"solve-the-market-split-problem-with-the-parityqc-parity-twine-optimizer\" />\n",
        "\n",
        "# Lösen Sie das Problem der Marktaufteilung mit dem „ ParityQC “ Parity Twine Optimizer\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "a6f69b77",
      "metadata": {},
      "source": [
        "Geschätzte *Ausführungszeit: 10 Sekunden auf einem Nighthawk- r2 -Prozessor. (HINWEIS: Dies ist lediglich eine Schätzung. (Die Laufzeit kann variieren.)*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "21156b6f",
      "metadata": {},
      "source": [
        "<span id=\"learning-outcomes\" />\n",
        "\n",
        "## Lernziele\n",
        "\n",
        "* Rufen Sie das Marktanteils-Problem aus der [QOBLIB – Quantum Optimization Benchmarking Library](https://github.com/ZIB-AOPT/QOBLIB) ab und formatieren Sie es.\n",
        "* Richten Sie den Parity Twine Optimizer ein und nutzen Sie ihn, um einen Fall von Marktaufspaltung zu lösen.\n",
        "* Erfahren Sie, wie Sie die Optionen für den Parity Twine Optimizer auswählen und welche Ergebnisse ausgegeben werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d185259f257c1618",
      "metadata": {},
      "source": [
        "<span id=\"background\" />\n",
        "\n",
        "## Hintergrund\n",
        "\n",
        "In diesem Tutorial wird gezeigt, wie man das Problem der Marktaufteilung mit dem „ ParityQC “ von Parity Twine Optimizer löst.\n",
        "\n",
        "Das Beispielproblem stammt aus der [QOBLIB – Quantum Optimization Benchmarking Library](https://github.com/ZIB-AOPT/QOBLIB).\n",
        "\n",
        "<span id=\"market-split-problem\" />\n",
        "\n",
        "### Problem der Marktaufteilung\n",
        "\n",
        "Das Marktteilungsproblem ist ein reales, NP-schweres Problem der Ressourcenallokation und hat sich zu einem Maßstab für Quantenoptimierungsalgorithmen entwickelt.\n",
        "Dies stellt eine logistische Herausforderung mit hohem Einsatz dar: Wie lässt sich eine komplexe Landschaft aus Kunden und Produkten in überschaubare, gleich große Gebiete aufteilen?\n",
        "\n",
        "Das Ziel besteht darin, die Märkte von „ $n$ “ in zwei ausgewogene Vertriebsregionen aufzuteilen, sodass jede Region genau die Hälfte der Gesamtnachfrage nach „ $m$ “-Produkten erhält.\n",
        "Die Lösung besteht in einer spezifischen Konfiguration, die eine möglichst gleichmäßige Verteilung der Produktnachfrage gewährleistet und es einem Unternehmen ermöglicht, eine Logistik- und Personalstrategie umzusetzen, bei der beide Regionen ausgewogen bedeckt werden,\n",
        "wodurch Risiken wie lokale Produktengpässe oder Überbelegung der Lager minimiert werden.\n",
        "\n",
        "Da die Anzahl der Märkte und Produkte zunimmt, wächst die Anzahl der möglichen Kombinationen exponentiell, was es schwierig macht, mit herkömmlichen exhaustiven Suchverfahren die optimale Aufteilung zu finden.\n",
        "\n",
        "<span id=\"mathematical-formulation\" />\n",
        "\n",
        "### Mathematische Formulierung\n",
        "\n",
        "Sei $A$ eine $m \\times n$ -Matrix, die die Nachfrage nach Produkten über verschiedene Märkte hinweg darstellt, wobei $A_{ij}$ die Nachfrage nach dem Produkt $i$ im Markt $j$ ist.\n",
        "\n",
        "Es wird ein binärer Zuordnungsvektor $x = [x_1, x_2, \\dots, x_n]^T \\in \\{0, 1\\}^n$ definiert, wobei gilt:\n",
        "\n",
        "* $x_j = 1$ weist der Region A die Markt $j$ en zu.\n",
        "* $x_j = 0$ ordnet die Markt $j$ en der Region B zu.\n",
        "\n",
        "Sei $d = [d_1, d_2, \\dots, d_m]^T$ der Gesamtnachfragevektor für jedes Produkt, berechnet als $d = A \\cdot \\mathbf{1}$. Das angestrebte Absatzvolumen pro Region für das Produkt $i$ beträgt genau $\\frac{d_i}{2}$.\n",
        "\n",
        "Die Optimierungs- bzw. Machbarkeitsbedingung besagt, dass der der Region A zugewiesene Gesamtumsatz bei jedem Produkt genau der Hälfte der Gesamtnachfrage entsprechen muss:\n",
        "\n",
        "$A x = \\frac{1}{2} A \\mathbf{1} = b.$\n",
        "\n",
        "Da eine exakte Division in der Praxis selten möglich ist, wird das Problem so formuliert, dass die quadrierte Abweichung von den Nebenbedingungen (die Kostenfunktion) minimiert wird:\n",
        "\n",
        "$\\min_{x} \\left\\Vert{} A x - b \\right\\Vert{}^2 = \\sum_{i=1}^{m} \\left( \\sum_{j=1}^{n} A_{ij} x_j - b\\right)^2.$\n",
        "\n",
        "Erweitert man dies, erhält man eine Form, die einem quadratischen, uneingeschränkten binären Optimierungsproblem (QUBO) entspricht.\n",
        "\n",
        "Nach der Berechnung bestimmt der Lösungsvektor $x$, welcher Region der Markt zugeordnet wird. Dies ist die Konfiguration, mit der eine möglichst ausgewogene Verteilung der Produktnachfrage erreicht wird.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "55b94021",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## Anforderungen\n",
        "\n",
        "Bevor Sie mit dieser Anleitung beginnen, stellen Sie bitte sicher, dass folgende Komponenten installiert sind:\n",
        "\n",
        "* Qiskit Functions Catalog IBM Client (`pip install qiskit-ibm-catalog`)\n",
        "* Qiskit-Add-on „Optimization Mapper“ (`pip install qiskit_addon_opt_mapper`)\n",
        "* NumPy (`pip install numpy`)\n",
        "\n",
        "Außerdem benötigen Sie die Berechtigung, auf die Twine-Optimizer-Funktion „ ParityQC “ zuzugreifen. Um Zugang zu beantragen, füllen Sie bitte dieses [Formular](https://parityqc.com/products/parity-twine-optimizer/free-trial) aus.\n",
        "\n"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "7db2e559",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## Einrichtung\n",
        "\n",
        "(Dieser Code setzt voraus, dass Sie [Ihr Konto](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) bereits in Ihrer lokalen Umgebung gespeichert haben.)\n",
        "\n",
        "Importieren Sie zunächst alle für dieses Tutorial erforderlichen Pakete.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "bc380c46",
      "metadata": {},
      "outputs": [],
      "source": [
        "import tempfile\n",
        "\n",
        "from collections.abc import Callable\n",
        "from pathlib import Path\n",
        "\n",
        "import numpy as np\n",
        "import requests\n",
        "\n",
        "from qiskit_addon_opt_mapper import OptimizationProblem\n",
        "from qiskit_addon_opt_mapper.converters import OptimizationProblemToQubo\n",
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d59c6bf33095b413",
      "metadata": {},
      "source": [
        "Laden Sie den „Parity Twine Optimizer“ aus dem Katalog „ Qiskit Functions “ herunter:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "805c80a1180e79fe",
      "metadata": {},
      "outputs": [],
      "source": [
        "catalog = QiskitFunctionsCatalog(channel=\"ibm_quantum_platform\")\n",
        "function = catalog.load(\"parityqc/parity-twine-optimizer\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "988ee237",
      "metadata": {},
      "source": [
        "<span id=\"step-1-define-the-problem-as-an-objective-function\" />\n",
        "\n",
        "### Schritt 1: Definieren Sie das Problem als Zielfunktion\n",
        "\n",
        "Beziehen Sie wie folgt ein Beispiel für ein Marktteilungs-Problem aus der [QOBLIB – Quantum Optimization Benchmarking Library](https://github.com/ZIB-AOPT/QOBLIB).\n",
        "\n",
        "Die Funktion `load_market_split_problem` ruft ein bestimmtes Problem aus QOBLIB ab und wandelt es in ein QUBO-Problem um.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2a90bce6-1925-436f-a167-4fab3255f4a0",
      "metadata": {},
      "outputs": [],
      "source": [
        "def load_market_split_problem(instance_name: str) -> OptimizationProblem:\n",
        "    \"\"\"Load and formulate a market split optimization problem from an QOBLIB instance.\n",
        "\n",
        "    The QOBLIB library can be found here:\n",
        "    https://github.com/ZIB-AOPT/QOBLIB.\n",
        "\n",
        "    Args:\n",
        "        instance_name: Name of the market split instance to load as specified by the .dat file\n",
        "            in the QOBLIB repo.\n",
        "\n",
        "    Returns:\n",
        "        The output OptimizationProblem containing the loaded market split problem.\n",
        "    \"\"\"\n",
        "\n",
        "    problem_matrix, problem_vector = fetch_and_parse(\n",
        "        instance_name, \"01-marketsplit\", parse_marketsplit_dat\n",
        "    )\n",
        "\n",
        "    # Create optimization problem\n",
        "    optimization_problem = OptimizationProblem(instance_name)\n",
        "\n",
        "    # Add binary variables (one for each market)\n",
        "    optimization_problem.binary_var_list(problem_matrix.shape[1])\n",
        "\n",
        "    # Add equality constraints (one for each product)\n",
        "    for idx, rhs in enumerate(problem_vector):\n",
        "        optimization_problem.linear_constraint(\n",
        "            problem_matrix[idx, :], sense=\"==\", rhs=rhs\n",
        "        )\n",
        "\n",
        "    # Convert to QUBO with penalty parameter\n",
        "    return OptimizationProblemToQubo(penalty=1).convert(optimization_problem)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "becd6460-8eb9-4796-8a21-60d6edc56cd1",
      "metadata": {},
      "source": [
        "Die Funktion `load_market_split_problem` benötigt die folgenden Parser-Funktionen, um die Daten zum Marktaufteilungsproblem aus QOBLIB abzurufen und zu verarbeiten.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c07d1d1b-3dc1-4fd8-b7cd-b7898e974eee",
      "metadata": {},
      "outputs": [],
      "source": [
        "def fetch_and_parse(instance_name: str, problem: str, parse_func: Callable):\n",
        "    \"\"\"Generic function to fetch and parse data from QOBLIB repository.\n",
        "\n",
        "    Args:\n",
        "        instance_name: Name of the instance to fetch.\n",
        "        problem: Category of the problem (e.g., '01-marketsplit', '07-independentset').\n",
        "        parse_func: Function used to parse the downloaded file\n",
        "            (e.g., parse_marketsplit_dat, parse_gph_file).\n",
        "\n",
        "    Returns:\n",
        "        Result of `parse_func` - either (np.ndarray, np.ndarray) for marketsplit\n",
        "        or nx.Graph for MIS.\n",
        "    \"\"\"\n",
        "    base_url = (\n",
        "        \"https://raw.githubusercontent.com/ZIB-AOPT/QOBLIB/refs/heads/main/\"\n",
        "    )\n",
        "    url = (\n",
        "        base_url\n",
        "        + problem\n",
        "        + \"/instances/\"\n",
        "        + instance_name\n",
        "        + (\".dat\" if problem == \"01-marketsplit\" else \".gph\")\n",
        "    )\n",
        "\n",
        "    try:\n",
        "        response = requests.get(url, timeout=30)\n",
        "        response.raise_for_status()\n",
        "\n",
        "        with tempfile.NamedTemporaryFile(\n",
        "            mode=\"w\",\n",
        "            suffix=\".dat\" if problem == \"01-marketsplit\" else \".gph\",\n",
        "            delete=False,\n",
        "            encoding=\"utf-8\",\n",
        "        ) as temp_file:\n",
        "            temp_file.write(response.text)\n",
        "            temp_file_path = temp_file.name\n",
        "\n",
        "        try:\n",
        "            return parse_func(temp_file_path)\n",
        "        finally:\n",
        "            Path(temp_file_path).unlink(missing_ok=True)\n",
        "\n",
        "    except requests.RequestException as e:\n",
        "        print(f\"Error fetching data from repository: {e}\")\n",
        "    except (ValueError, OSError) as e:\n",
        "        print(f\"Error processing data: {e}\")\n",
        "        return None\n",
        "\n",
        "\n",
        "def parse_marketsplit_dat(filename: str) -> tuple[np.ndarray, np.ndarray]:\n",
        "    \"\"\"Parse a market split problem from a .dat file format.\n",
        "\n",
        "    Args:\n",
        "        filename: Path to the .dat file.\n",
        "\n",
        "    Returns:\n",
        "        Tuple of (A, b) where:\n",
        "            - A: (m, n) array of coefficients.\n",
        "            - b: (m,) array of target values.\n",
        "\n",
        "    Raises:\n",
        "        ValueError: If file format is invalid or file is empty.\n",
        "    \"\"\"\n",
        "    with Path(filename).open(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",
        "    try:\n",
        "        m, n = map(int, lines[0].split())\n",
        "    except (ValueError, IndexError) as e:\n",
        "        raise ValueError(\n",
        "            \"Invalid file format: first line must contain 'm n' integers\"\n",
        "        ) from e\n",
        "\n",
        "    if len(lines) < m + 1:\n",
        "        raise ValueError(\n",
        "            f\"File contains {len(lines)} lines but expected {m + 1} lines\"\n",
        "        )\n",
        "\n",
        "    # Next m lines: each row of A followed by corresponding element of b\n",
        "    mat_a = []\n",
        "    vec_b = []\n",
        "\n",
        "    for i in range(1, m + 1):\n",
        "        try:\n",
        "            values = list(map(int, lines[i].split()))\n",
        "        except ValueError as e:\n",
        "            raise ValueError(f\"Invalid integer values in line {i + 1}\") from e\n",
        "\n",
        "        if len(values) != n + 1:\n",
        "            raise ValueError(\n",
        "                f\"Line {i + 1} contains {len(values)} values but expected {n + 1}\"\n",
        "            )\n",
        "\n",
        "        mat_a.append(values[:-1])  # First n values: product sales per market\n",
        "        vec_b.append(values[-1])  # Last value: target sales for this product\n",
        "\n",
        "    return np.array(mat_a), np.array(vec_b)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9811ef6c-717e-4033-963d-3fd85790be23",
      "metadata": {},
      "source": [
        "Sobald definiert ist, `load_marketsplit_problem` kann damit eine bestimmte Probleminstanz aus der Bibliothek geladen werden:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "287f6c52-9b2a-46b7-994d-7005bd4ab1c6",
      "metadata": {},
      "outputs": [],
      "source": [
        "ms_instance = \"ms_04_050_001\"\n",
        "\n",
        "ms_problem = load_market_split_problem(ms_instance)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ac6f36e3",
      "metadata": {},
      "source": [
        "<span id=\"step-2-convert-to-json-format\" />\n",
        "\n",
        "### Schritt 2: In das JSON-Format konvertieren\n",
        "\n",
        "Im ersten Schritt haben Sie die QUBO-Form des Problems ermittelt.  Wandeln Sie es nun für die Optimierungsfunktion in das JSON-Format um:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "fe1169b1-50a0-4edb-9db5-7c0d99ce9a68",
      "metadata": {},
      "outputs": [],
      "source": [
        "def optimization_problem_to_json(\n",
        "    problem: OptimizationProblem,\n",
        ") -> dict[str, float]:\n",
        "    \"\"\"\n",
        "    Converts an unconstrained quadratic OptimizationProblem in terms of binary or spin variables\n",
        "    to the JSON input format of the Parity Twine Qiskit Function.\n",
        "\n",
        "    Args:\n",
        "        problem: The optimization problem to convert to JSON.\n",
        "\n",
        "    Returns:\n",
        "        The JSON input format of the given problem.\n",
        "    \"\"\"\n",
        "    ising, constant = problem.to_ising()\n",
        "    output = {\"()\": float(constant)}\n",
        "    for op, coefficient in zip(ising.paulis, ising.coeffs, strict=True):\n",
        "        # Invert the label strings because Qiskit has opposite convention\n",
        "        qubits = tuple(\n",
        "            num\n",
        "            for num, pauli in enumerate(op.to_label()[::-1])\n",
        "            if pauli == \"Z\"\n",
        "        )\n",
        "        output[str(qubits)] = float(coefficient)\n",
        "    return output"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9e374de6-384a-497e-bcf1-c8617c1945ec",
      "metadata": {},
      "source": [
        "Die QUBO-Instanz des Marktaufteilungsproblems wird nun wie folgt in das JSON-Format konvertiert:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "4885df90-4d15-4bc7-8130-ec1d9ece7670",
      "metadata": {},
      "outputs": [],
      "source": [
        "json_ms_problem = optimization_problem_to_json(ms_problem)"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "b4d480b3",
      "metadata": {},
      "source": [
        "<span id=\"step-3-solve-the-problem-using-the-parity-twine-optimizer\" />\n",
        "\n",
        "### Schritt 3: Lösen Sie das Problem mit dem „Parity Twine Optimizer“\n",
        "\n",
        "Nachdem Sie nun das Marktteilungsproblem formuliert und in die richtige Form gebracht haben, können Sie mithilfe des Twine Optimizers und eines ausgewählten Backends unter IBM® eine Lösung finden.\n",
        "\n",
        "Um die Funktion auszuführen, wählen Sie ein geeignetes Backend-Gerät aus; zum Beispiel `ibm_phoenix`.\n",
        "\n",
        "Sie können verwenden, `options` um (optional) zusätzliche Kontrolle über die Übermittlung zu erhalten:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a3eaff0a-9c54-4ffc-b6b2-5d43c49e6a07",
      "metadata": {},
      "outputs": [],
      "source": [
        "options = {\n",
        "    \"shots\": 100000,\n",
        "    \"postprocessing_level\": 1,\n",
        "    \"transpile_only\": False,\n",
        "    \"job_tags\": [\"market_split\"],\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "864629a2-34fe-473b-b9f1-277e0a99752d",
      "metadata": {},
      "source": [
        "wobei eine ganze Zahl ist `shots` , die die Anzahl der Schaltkreisaufrufe angibt, `postprocessing_level` bestimmt, ob das Ergebnis einer Nachbearbeitung unterzogen wird,\n",
        "`transpile_only`gibt an, ob das Problem lediglich in einen Schaltkreis transpiliert (und nicht gelöst) wird, und `job_tags` ist die Kennung, mit der der Auftrag auf IBM Quantum® Platform identifiziert wird.\n",
        "\n",
        "Führen Sie den Optimierer aus:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2c4a5ce3de728746",
      "metadata": {},
      "outputs": [],
      "source": [
        "function_job = function.run(\n",
        "    problem=json_ms_problem,\n",
        "    variable_type=\"spin\",\n",
        "    backend_name=\"ibm_phoenix\",\n",
        "    options=options,\n",
        ")\n",
        "print(f\"Job ID: {function_job.job_id}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e8e66a1efeef3757",
      "metadata": {},
      "source": [
        "Überprüfen Sie den Auftragsstatus:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "be7bbe053da38198",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Monitor the job status\n",
        "function_job.status()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fe4ea9784df0bcbb",
      "metadata": {},
      "source": [
        "Ergebnisse abrufen:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "9af5dddb30694451",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Retrieve the job result if the status is DONE\n",
        "result = function_job.result()\n",
        "\n",
        "result"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8b888ac0-c0eb-4849-be0d-4bf331707df5",
      "metadata": {},
      "source": [
        "Das Ergebnis hat folgende Form:\n",
        "\n",
        "```\n",
        "{\n",
        "    'solution': {'0': 1, '1': -1, '10': 1, ... },\n",
        "    'objective_value':  1.0,\n",
        "    'solution_bitstring': '010000011101111011001001110010',\n",
        "    'metadata': {\n",
        "        'circuit_metrics': {\n",
        "            'depth': 309,\n",
        "            'gate_count': 3880,\n",
        "            'two_qubit_gate_depth': 116,\n",
        "            'two_qubit_gate_count': 899,\n",
        "            'num_qubits': 30,\n",
        "            'operations': {'sx': 1244, 'rz': 1227, 'cz': 899, 'delay': 473, 'measure': 30, 'x': 7},\n",
        "        },\n",
        "        'solver_info': {\n",
        "            'variable_mapping': {'0': 0, '1': 1, '10': 2, ... },\n",
        "            'bitstring_distributions': {\n",
        "                'before_postprocessing': {'011101110010110111001110011000': 1, ...},\n",
        "                'after_postprocessing': {'011011110000110101001111011000': 1, ...}\n",
        "            },\n",
        "            'best_parameters': {\n",
        "                'beta': [-0.18054534155552715],\n",
        "                'gamma': [1.4141236348317905]\n",
        "            }\n",
        "        },\n",
        "        'resource_usage': {\n",
        "            'RUNNING: MAPPING': {'CPU_TIME': 172.936},\n",
        "            'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 0.272},\n",
        "            'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 7.798},\n",
        "            'RUNNING: EXECUTING_QPU': {'QPU_TIME': 30.0},\n",
        "            'RUNNING: POST_PROCESSING': {'CPU_TIME': 31.613},\n",
        "        },\n",
        "    }\n",
        "}\n",
        "```\n",
        "\n",
        "wobei das Wörterbuch `solution` den in der Aufgabe definierten Qubits entspricht und deren optimierte Spinwerte angibt.\n",
        "`metadata` liefert Informationen zur Transpilierung (Anzahl der Zwei-Qubit-Gatter/Tiefe, verwendete Gatter, aktive Qubits) sowie zu verschiedenen Laufzeiten.\n",
        "\n",
        "Im Zusammenhang mit dem Marktaufteilungsproblem stellt die Lösungsbitstring einen binären Zuordnungsvektor dar, der dazu dient, Märkte in zwei separate Bereiche aufzuteilen. Der Wert 1 ordnet diesen\n",
        "bestimmten Markt der Region A zu, während der Wert 0 ihn der Region B zuordnet. Bei der optimalen Lösung sorgt die Kombination für eine ausgewogene Aufteilung, d. h., beide Regionen erhalten genau die Hälfte der gesamten Unternehmensnachfrage\n",
        "für jedes Produkt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2cb5785c",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Beantragen Sie den Zugriff auf die Funktion, indem Sie dieses [Formular](https://parityqc.com/products/parity-twine-optimizer/free-trial) ausfüllen.\n",
        "  * Rufen Sie die [API-Referenz](/docs/api/functions/parity-twine-optimizer) für diese Qiskit-Funktion auf.\n",
        "  * Lies die [Anleitung](/docs/guides/parity-twine-optimizer).\n",
        "  * Probieren Sie das [Tutorial](/docs/tutorials/parity-twine-optimizer-sk) zur Anwendung des „Parity Twine Optimizer“ auf das Sherrington-Kirkpatrick-Modell aus.\n",
        "  * Lesen Sie den Preprint [„Connectivity-aware Synthesis of Quantum Algorithms“ von Drier et al. (2025)](https://arxiv.org/abs/2501.14020) unter ArXiv.\n",
        "</Admonition>\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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}