{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "score_search-0",
   "metadata": {},
   "source": [
    "# Score-based search (XGES / hill climbing / Tabu search / exact search / GIES)\n",
    "\n",
    "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Abel-ai-lab/andrey/blob/main/examples/score_search.ipynb)\n",
    "\n",
    "XGES, hill climbing, and Tabu search look for the graph with the best BIC score. XGES searches\n",
    "over equivalence classes, as GES does, with deletions first. Hill climbing adds, removes, or\n",
    "reverses one edge of a DAG at a time and stops when no move improves the score; Tabu search keeps\n",
    "going past that point and returns the best DAG it visits. All three return a CPDAG and suit\n",
    "linear-Gaussian data. Exact search finds the best-scoring DAG on a few variables, and GIES also\n",
    "learns from interventions."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-1",
   "metadata": {},
   "source": [
    "## Start\n",
    "\n",
    "Choose a CPU runtime and run this cell first. In Colab it installs `andrey-core==0.9.0` from PyPI;\n",
    "local kernels use the installed environment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "score_search-2",
   "metadata": {
    "tags": [
     "colab-setup"
    ]
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "\n",
    "IN_COLAB = \"google.colab\" in sys.modules\n",
    "\n",
    "if IN_COLAB:\n",
    "    os.environ[\"ANDREY_DEVICE\"] = \"cpu\"\n",
    "    !pip install --quiet \"andrey-core[viz]==0.9.0\" pandas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "score_search-3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from IPython.display import display\n",
    "\n",
    "import andrey\n",
    "import andrey.metrics as metrics\n",
    "import andrey.viz\n",
    "from andrey.data import benchmarks"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-4",
   "metadata": {},
   "source": [
    "## Data\n",
    "\n",
    "`linear_gauss_er` draws an Erdos-Renyi graph with linear mechanisms and Gaussian noise: here 10\n",
    "variables and 2,000 samples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "score_search-5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2000 observations, 10 variables, seed 7\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 464 332\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"464\" height=\"332\" fill=\"#fafbfc\"/><line x1=\"312.82\" y1=\"44.82\" x2=\"242.84\" y2=\"91.09\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.16,39.30 310.06,40.65 315.57,48.99\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"144.93\" y1=\"163.00\" x2=\"409.13\" y2=\"134.59\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.07,133.52 408.60,129.62 409.67,139.56\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"113.24\" y1=\"177.70\" x2=\"42.60\" y2=\"227.83\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.40,171.91 110.35,173.62 116.14,181.78\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"112.82\" y1=\"151.70\" x2=\"42.84\" y2=\"105.43\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.16,157.22 115.57,147.53 110.06,155.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"409.32\" y1=\"128.29\" x2=\"244.82\" y2=\"100.43\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.18,129.96 410.16,123.36 408.49,133.22\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"410.18\" y1=\"124.86\" x2=\"144.33\" y2=\"36.24\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.67,128.02 411.76,120.11 408.60,129.60\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"410.11\" y1=\"139.19\" x2=\"344.37\" y2=\"160.40\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.63,136.12 408.58,134.43 411.65,143.95\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"139.66\" y1=\"224.85\" x2=\"218.45\" y2=\"116.84\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"224.34,108.76 214.41,113.89 222.49,119.79\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"142.92\" y1=\"242.40\" x2=\"212.67\" y2=\"287.40\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"221.08,292.82 215.38,283.20 209.96,291.60\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"109.00\" y1=\"235.35\" x2=\"45.00\" y2=\"235.35\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,235.35 109.00,230.35 109.00,240.35\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"212.82\" y1=\"85.57\" x2=\"142.84\" y2=\"39.30\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"221.16,91.09 215.57,81.40 210.06,89.74\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"242.84\" y1=\"105.43\" x2=\"312.82\" y2=\"151.70\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.16,157.22 315.57,147.53 310.06,155.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"209.00\" y1=\"98.26\" x2=\"45.00\" y2=\"98.26\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,98.26 209.00,93.26 209.00,103.26\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"112.82\" y1=\"44.82\" x2=\"42.84\" y2=\"91.09\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.16,39.30 110.06,40.65 115.57,48.99\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"210.11\" y1=\"292.81\" x2=\"44.37\" y2=\"239.35\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.63,295.88 211.65,288.05 208.58,297.57\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"332.00\" cy=\"32.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"32.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"132.00\" cy=\"164.39\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"164.39\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"432.00\" cy=\"132.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"432.00\" y=\"132.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"132.00\" cy=\"235.35\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"235.35\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"232.00\" cy=\"98.26\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"98.26\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"132.00\" cy=\"32.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"32.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"232.00\" cy=\"299.87\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"299.87\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"32.00\" cy=\"235.35\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"235.35\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"332.00\" cy=\"164.39\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"164.39\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"32.00\" cy=\"98.26\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"98.26\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>"
      ],
      "text/plain": [
       "'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 464 332\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"464\" height=\"332\" fill=\"#fafbfc\"/><line x1=\"312.82\" y1=\"44.82\" x2=\"242.84\" y2=\"91.09\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.16,39.30 310.06,40.65 315.57,48.99\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"144.93\" y1=\"163.00\" x2=\"409.13\" y2=\"134.59\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.07,133.52 408.60,129.62 409.67,139.56\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"113.24\" y1=\"177.70\" x2=\"42.60\" y2=\"227.83\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.40,171.91 110.35,173.62 116.14,181.78\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"112.82\" y1=\"151.70\" x2=\"42.84\" y2=\"105.43\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.16,157.22 115.57,147.53 110.06,155.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"409.32\" y1=\"128.29\" x2=\"244.82\" y2=\"100.43\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.18,129.96 410.16,123.36 408.49,133.22\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"410.18\" y1=\"124.86\" x2=\"144.33\" y2=\"36.24\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.67,128.02 411.76,120.11 408.60,129.60\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"410.11\" y1=\"139.19\" x2=\"344.37\" y2=\"160.40\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.63,136.12 408.58,134.43 411.65,143.95\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"139.66\" y1=\"224.85\" x2=\"218.45\" y2=\"116.84\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"224.34,108.76 214.41,113.89 222.49,119.79\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"142.92\" y1=\"242.40\" x2=\"212.67\" y2=\"287.40\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"221.08,292.82 215.38,283.20 209.96,291.60\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"109.00\" y1=\"235.35\" x2=\"45.00\" y2=\"235.35\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,235.35 109.00,230.35 109.00,240.35\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"212.82\" y1=\"85.57\" x2=\"142.84\" y2=\"39.30\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"221.16,91.09 215.57,81.40 210.06,89.74\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"242.84\" y1=\"105.43\" x2=\"312.82\" y2=\"151.70\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.16,157.22 315.57,147.53 310.06,155.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"209.00\" y1=\"98.26\" x2=\"45.00\" y2=\"98.26\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,98.26 209.00,93.26 209.00,103.26\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"112.82\" y1=\"44.82\" x2=\"42.84\" y2=\"91.09\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.16,39.30 110.06,40.65 115.57,48.99\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"210.11\" y1=\"292.81\" x2=\"44.37\" y2=\"239.35\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.63,295.88 211.65,288.05 208.58,297.57\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"332.00\" cy=\"32.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"32.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"132.00\" cy=\"164.39\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"164.39\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"432.00\" cy=\"132.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"432.00\" y=\"132.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"132.00\" cy=\"235.35\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"235.35\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"232.00\" cy=\"98.26\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"98.26\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"132.00\" cy=\"32.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"32.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"232.00\" cy=\"299.87\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"299.87\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"32.00\" cy=\"235.35\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"235.35\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"332.00\" cy=\"164.39\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"164.39\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"32.00\" cy=\"98.26\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"98.26\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>'"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "seed = 7\n",
    "dataset = benchmarks.scm(\"linear_gauss_er\", d=10).sample(n=2000, seed=seed, scale=\"standardize\")\n",
    "X, truth = dataset.data, dataset.observed_graph\n",
    "print(f\"{X.shape[0]} observations, {X.shape[1]} variables, seed {seed}\")\n",
    "display(andrey.viz.draw(truth))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-6",
   "metadata": {},
   "source": [
    "## Fit XGES, hill climbing, and Tabu search\n",
    "\n",
    "`metadata[\"score\"]` is the BIC score of the returned graph, which each search minimizes. A larger\n",
    "`lambda_value` weighs the BIC penalty more and gives a sparser graph. With\n",
    "`extended_search=False`, XGES skips its extended search for a faster fit, and `tabu_length` sets\n",
    "how many recently visited DAGs Tabu search may not return to."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "score_search-7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "XGES: cpdag, score -22406.2\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 364 279\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"364\" height=\"279\" fill=\"#fafbfc\"/><line x1=\"209.35\" y1=\"242.74\" x2=\"144.80\" y2=\"231.29\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.20,244.49 210.23,237.82 208.48,247.67\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"240.90\" y1=\"43.33\" x2=\"316.25\" y2=\"123.55\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"323.10,130.83 319.90,120.12 312.61,126.97\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"209.00\" y1=\"33.85\" x2=\"145.00\" y2=\"33.85\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,33.85 209.00,28.85 209.00,38.85\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"214.31\" y1=\"48.55\" x2=\"42.00\" y2=\"191.68\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"222.00,42.16 211.11,44.70 217.50,52.39\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 313.70 154.24 Q 242.54 208.43 144.78 226.64\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.66,148.18 310.67,150.27 316.73,158.22\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"132.62\" x2=\"244.25\" y2=\"109.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,135.96 312.00,127.90 308.65,137.33\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"148.00\" x2=\"244.25\" y2=\"171.45\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,144.66 308.65,143.29 312.00,152.71\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"40.09\" y1=\"113.38\" x2=\"117.69\" y2=\"211.01\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"123.91,218.84 121.60,207.90 113.77,214.12\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"103.31\" x2=\"209.00\" y2=\"104.63\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,104.72 209.04,99.63 208.96,109.63\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"42.68\" y1=\"95.80\" x2=\"113.10\" y2=\"46.96\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.32,41.26 110.25,42.85 115.95,51.07\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"140.15\" y1=\"218.89\" x2=\"217.58\" y2=\"122.73\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"223.85,114.95 213.68,119.60 221.47,125.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"143.48\" y1=\"222.91\" x2=\"211.70\" y2=\"186.60\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"220.52,181.90 209.35,182.19 214.05,191.01\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"109.91\" y1=\"222.61\" x2=\"44.48\" y2=\"203.61\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.52,225.39 111.31,217.80 108.52,227.41\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"32.45\" x2=\"109.00\" y2=\"33.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,33.64 109.08,28.48 108.92,38.48\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"232.00\" cy=\"246.76\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"246.76\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"232.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"332.00\" cy=\"140.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"140.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"103.21\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"103.21\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"132.00\" cy=\"229.02\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"229.02\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"232.00\" cy=\"104.82\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"104.82\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"32.00\" cy=\"32.24\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"32.24\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"132.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"232.00\" cy=\"175.79\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"175.79\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"32.00\" cy=\"199.99\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"199.99\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>"
      ],
      "text/plain": [
       "'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 364 279\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"364\" height=\"279\" fill=\"#fafbfc\"/><line x1=\"209.35\" y1=\"242.74\" x2=\"144.80\" y2=\"231.29\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.20,244.49 210.23,237.82 208.48,247.67\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"240.90\" y1=\"43.33\" x2=\"316.25\" y2=\"123.55\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"323.10,130.83 319.90,120.12 312.61,126.97\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"209.00\" y1=\"33.85\" x2=\"145.00\" y2=\"33.85\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,33.85 209.00,28.85 209.00,38.85\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"214.31\" y1=\"48.55\" x2=\"42.00\" y2=\"191.68\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"222.00,42.16 211.11,44.70 217.50,52.39\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 313.70 154.24 Q 242.54 208.43 144.78 226.64\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.66,148.18 310.67,150.27 316.73,158.22\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"132.62\" x2=\"244.25\" y2=\"109.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,135.96 312.00,127.90 308.65,137.33\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"148.00\" x2=\"244.25\" y2=\"171.45\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,144.66 308.65,143.29 312.00,152.71\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"40.09\" y1=\"113.38\" x2=\"117.69\" y2=\"211.01\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"123.91,218.84 121.60,207.90 113.77,214.12\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"103.31\" x2=\"209.00\" y2=\"104.63\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,104.72 209.04,99.63 208.96,109.63\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"42.68\" y1=\"95.80\" x2=\"113.10\" y2=\"46.96\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.32,41.26 110.25,42.85 115.95,51.07\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"140.15\" y1=\"218.89\" x2=\"217.58\" y2=\"122.73\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"223.85,114.95 213.68,119.60 221.47,125.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"143.48\" y1=\"222.91\" x2=\"211.70\" y2=\"186.60\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"220.52,181.90 209.35,182.19 214.05,191.01\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"109.91\" y1=\"222.61\" x2=\"44.48\" y2=\"203.61\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.52,225.39 111.31,217.80 108.52,227.41\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"32.45\" x2=\"109.00\" y2=\"33.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,33.64 109.08,28.48 108.92,38.48\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"232.00\" cy=\"246.76\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"246.76\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"232.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"332.00\" cy=\"140.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"140.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"103.21\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"103.21\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"132.00\" cy=\"229.02\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"229.02\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"232.00\" cy=\"104.82\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"104.82\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"32.00\" cy=\"32.24\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"32.24\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"132.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"232.00\" cy=\"175.79\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"175.79\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"32.00\" cy=\"199.99\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"199.99\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>'"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hill climbing: cpdag, score -22356.9\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 764 375\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"764\" height=\"375\" fill=\"#fafbfc\"/><line x1=\"709.00\" y1=\"154.44\" x2=\"645.00\" y2=\"154.44\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"719.00,154.44 709.00,149.44 709.00,159.44\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"336.75\" y1=\"100.41\" x2=\"423.60\" y2=\"321.73\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"427.25,331.04 428.25,319.91 418.94,323.56\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"344.70\" y1=\"91.10\" x2=\"609.54\" y2=\"149.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.30,151.64 610.62,144.60 608.46,154.37\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"309.00\" y1=\"88.31\" x2=\"245.00\" y2=\"88.31\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.00,88.31 309.00,83.31 309.00,93.31\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"344.34\" y1=\"92.39\" x2=\"510.16\" y2=\"147.22\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.66,150.35 511.73,142.47 508.59,151.96\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"319.88\" y1=\"107.85\" x2=\"238.85\" y2=\"238.55\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"325.15,99.36 315.63,105.22 324.13,110.49\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 412.50 330.95 Q 216.03 208.02 41.39 40.84\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"420.98,336.25 415.15,326.71 409.85,335.18\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"441.46\" y1=\"334.22\" x2=\"615.27\" y2=\"170.22\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"622.54,163.36 611.84,166.58 618.70,173.86\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"410.04\" y1=\"336.30\" x2=\"144.41\" y2=\"253.47\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.59,339.28 411.53,331.52 408.55,341.07\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"438.09\" y1=\"331.66\" x2=\"525.91\" y2=\"165.92\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"411.17\" y1=\"333.40\" x2=\"243.78\" y2=\"255.10\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"420.22,337.64 413.28,328.87 409.05,337.93\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 44.99 32.29 Q 342.41 42.20 610.55 146.12\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.88,149.74 612.36,141.46 608.75,150.79\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"42.84\" y1=\"39.03\" x2=\"121.16\" y2=\"90.81\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"44.51\" y1=\"35.39\" x2=\"219.49\" y2=\"84.78\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><path d=\"M 43.76 37.39 Q 269.62 143.65 509.02 153.49\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.01,153.90 509.22,148.50 508.81,158.49\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"609.00\" y1=\"154.44\" x2=\"545.00\" y2=\"154.44\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.00,154.44 609.00,149.44 609.00,159.44\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"609.62\" y1=\"159.76\" x2=\"244.65\" y2=\"246.59\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.35,157.44 608.47,154.89 610.78,164.62\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"144.65\" y1=\"246.59\" x2=\"509.62\" y2=\"159.76\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.35,157.44 508.47,154.89 510.78,164.62\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"145.00\" y1=\"249.60\" x2=\"219.00\" y2=\"249.60\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"144.94\" y1=\"96.73\" x2=\"219.06\" y2=\"89.56\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"510.08\" y1=\"161.39\" x2=\"244.39\" y2=\"245.67\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.61,158.37 508.56,156.62 511.59,166.16\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"732.00\" cy=\"154.44\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"732.00\" y=\"154.44\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"332.00\" cy=\"88.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"88.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"432.00\" cy=\"343.15\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"432.00\" y=\"343.15\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"31.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"31.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"632.00\" cy=\"154.44\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"632.00\" y=\"154.44\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"132.00\" cy=\"249.60\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"249.60\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"132.00\" cy=\"97.98\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"97.98\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"232.00\" cy=\"88.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"88.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"532.00\" cy=\"154.44\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"532.00\" y=\"154.44\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"232.00\" cy=\"249.60\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"249.60\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>"
      ],
      "text/plain": [
       "'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 764 375\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"764\" height=\"375\" fill=\"#fafbfc\"/><line x1=\"709.00\" y1=\"154.44\" x2=\"645.00\" y2=\"154.44\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"719.00,154.44 709.00,149.44 709.00,159.44\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"336.75\" y1=\"100.41\" x2=\"423.60\" y2=\"321.73\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"427.25,331.04 428.25,319.91 418.94,323.56\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"344.70\" y1=\"91.10\" x2=\"609.54\" y2=\"149.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.30,151.64 610.62,144.60 608.46,154.37\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"309.00\" y1=\"88.31\" x2=\"245.00\" y2=\"88.31\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.00,88.31 309.00,83.31 309.00,93.31\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"344.34\" y1=\"92.39\" x2=\"510.16\" y2=\"147.22\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.66,150.35 511.73,142.47 508.59,151.96\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"319.88\" y1=\"107.85\" x2=\"238.85\" y2=\"238.55\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"325.15,99.36 315.63,105.22 324.13,110.49\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 412.50 330.95 Q 216.03 208.02 41.39 40.84\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"420.98,336.25 415.15,326.71 409.85,335.18\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"441.46\" y1=\"334.22\" x2=\"615.27\" y2=\"170.22\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"622.54,163.36 611.84,166.58 618.70,173.86\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"410.04\" y1=\"336.30\" x2=\"144.41\" y2=\"253.47\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.59,339.28 411.53,331.52 408.55,341.07\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"438.09\" y1=\"331.66\" x2=\"525.91\" y2=\"165.92\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"411.17\" y1=\"333.40\" x2=\"243.78\" y2=\"255.10\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"420.22,337.64 413.28,328.87 409.05,337.93\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 44.99 32.29 Q 342.41 42.20 610.55 146.12\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.88,149.74 612.36,141.46 608.75,150.79\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"42.84\" y1=\"39.03\" x2=\"121.16\" y2=\"90.81\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"44.51\" y1=\"35.39\" x2=\"219.49\" y2=\"84.78\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><path d=\"M 43.76 37.39 Q 269.62 143.65 509.02 153.49\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.01,153.90 509.22,148.50 508.81,158.49\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"609.00\" y1=\"154.44\" x2=\"545.00\" y2=\"154.44\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.00,154.44 609.00,149.44 609.00,159.44\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"609.62\" y1=\"159.76\" x2=\"244.65\" y2=\"246.59\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"619.35,157.44 608.47,154.89 610.78,164.62\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"144.65\" y1=\"246.59\" x2=\"509.62\" y2=\"159.76\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.35,157.44 508.47,154.89 510.78,164.62\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"145.00\" y1=\"249.60\" x2=\"219.00\" y2=\"249.60\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"144.94\" y1=\"96.73\" x2=\"219.06\" y2=\"89.56\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"510.08\" y1=\"161.39\" x2=\"244.39\" y2=\"245.67\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.61,158.37 508.56,156.62 511.59,166.16\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"732.00\" cy=\"154.44\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"732.00\" y=\"154.44\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"332.00\" cy=\"88.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"88.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"432.00\" cy=\"343.15\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"432.00\" y=\"343.15\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"31.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"31.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"632.00\" cy=\"154.44\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"632.00\" y=\"154.44\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"132.00\" cy=\"249.60\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"249.60\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"132.00\" cy=\"97.98\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"97.98\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"232.00\" cy=\"88.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"88.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"532.00\" cy=\"154.44\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"532.00\" y=\"154.44\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"232.00\" cy=\"249.60\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"249.60\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>'"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tabu search: cpdag, score -22368.4\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 564 456\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"564\" height=\"456\" fill=\"#fafbfc\"/><line x1=\"509.00\" y1=\"288.48\" x2=\"445.00\" y2=\"288.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.00,288.48 509.00,283.48 509.00,293.48\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"238.05\" y1=\"175.79\" x2=\"321.30\" y2=\"334.26\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"325.95,343.11 325.73,331.93 316.88,336.58\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"243.04\" y1=\"171.14\" x2=\"412.46\" y2=\"276.35\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"420.96,281.62 415.10,272.10 409.82,280.59\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"218.13\" y1=\"145.94\" x2=\"139.84\" y2=\"42.40\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"224.16,153.92 222.12,142.92 214.14,148.96\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"218.13\" y1=\"182.63\" x2=\"139.84\" y2=\"286.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"224.16,174.66 214.14,179.62 222.12,185.65\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"312.53\" y1=\"342.37\" x2=\"43.00\" y2=\"172.82\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.00,347.69 315.19,338.14 309.87,346.60\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"342.84\" y1=\"347.45\" x2=\"412.82\" y2=\"301.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"421.16,295.65 410.06,297.00 415.57,305.34\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"309.59\" y1=\"359.80\" x2=\"44.67\" y2=\"421.04\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.33,357.55 308.46,354.93 310.72,364.67\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"312.67\" y1=\"367.09\" x2=\"242.92\" y2=\"412.09\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.08,361.66 309.96,362.88 315.38,371.29\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"309.91\" y1=\"348.20\" x2=\"144.48\" y2=\"300.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.52,350.99 311.31,343.40 308.52,353.01\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"44.43\" y1=\"169.71\" x2=\"410.01\" y2=\"281.74\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.57,284.67 411.47,276.96 408.54,286.52\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"39.78\" y1=\"155.48\" x2=\"118.24\" y2=\"50.45\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"124.22,42.44 114.23,47.46 122.24,53.45\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 42.23 173.92 Q 162.61 268.34 222.38 398.24\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"226.57,407.32 226.93,396.15 217.84,400.33\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 409.79 294.46 Q 310.67 321.16 240.14 409.00\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.45,291.86 408.49,289.63 411.09,299.29\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"409.01\" y1=\"289.10\" x2=\"145.00\" y2=\"296.20\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.00,288.83 408.87,284.10 409.14,294.10\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"423.66\" x2=\"209.01\" y2=\"419.69\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,419.45 208.89,414.69 209.13,424.69\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"40.03\" y1=\"413.74\" x2=\"123.97\" y2=\"306.77\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"45.00\" y1=\"32.03\" x2=\"109.00\" y2=\"32.03\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,32.03 109.00,27.03 109.00,37.03\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"217.46\" y1=\"401.31\" x2=\"140.22\" y2=\"306.62\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"223.78,409.06 221.34,398.15 213.59,404.47\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"532.00\" cy=\"288.48\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"532.00\" y=\"288.48\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"232.00\" cy=\"164.29\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"164.29\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"332.00\" cy=\"354.62\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"354.62\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"165.90\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"165.90\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"432.00\" cy=\"288.48\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"432.00\" y=\"288.48\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"32.00\" cy=\"423.97\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"423.97\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"32.00\" cy=\"32.03\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"32.03\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"132.00\" cy=\"32.03\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"32.03\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"232.00\" cy=\"419.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"419.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"132.00\" cy=\"296.54\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"296.54\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>"
      ],
      "text/plain": [
       "'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 564 456\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"564\" height=\"456\" fill=\"#fafbfc\"/><line x1=\"509.00\" y1=\"288.48\" x2=\"445.00\" y2=\"288.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"519.00,288.48 509.00,283.48 509.00,293.48\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"238.05\" y1=\"175.79\" x2=\"321.30\" y2=\"334.26\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"325.95,343.11 325.73,331.93 316.88,336.58\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"243.04\" y1=\"171.14\" x2=\"412.46\" y2=\"276.35\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"420.96,281.62 415.10,272.10 409.82,280.59\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"218.13\" y1=\"145.94\" x2=\"139.84\" y2=\"42.40\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"224.16,153.92 222.12,142.92 214.14,148.96\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"218.13\" y1=\"182.63\" x2=\"139.84\" y2=\"286.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"224.16,174.66 214.14,179.62 222.12,185.65\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"312.53\" y1=\"342.37\" x2=\"43.00\" y2=\"172.82\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.00,347.69 315.19,338.14 309.87,346.60\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"342.84\" y1=\"347.45\" x2=\"412.82\" y2=\"301.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"421.16,295.65 410.06,297.00 415.57,305.34\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"309.59\" y1=\"359.80\" x2=\"44.67\" y2=\"421.04\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.33,357.55 308.46,354.93 310.72,364.67\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"312.67\" y1=\"367.09\" x2=\"242.92\" y2=\"412.09\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.08,361.66 309.96,362.88 315.38,371.29\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"309.91\" y1=\"348.20\" x2=\"144.48\" y2=\"300.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.52,350.99 311.31,343.40 308.52,353.01\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"44.43\" y1=\"169.71\" x2=\"410.01\" y2=\"281.74\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.57,284.67 411.47,276.96 408.54,286.52\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"39.78\" y1=\"155.48\" x2=\"118.24\" y2=\"50.45\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"124.22,42.44 114.23,47.46 122.24,53.45\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 42.23 173.92 Q 162.61 268.34 222.38 398.24\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"226.57,407.32 226.93,396.15 217.84,400.33\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 409.79 294.46 Q 310.67 321.16 240.14 409.00\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.45,291.86 408.49,289.63 411.09,299.29\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"409.01\" y1=\"289.10\" x2=\"145.00\" y2=\"296.20\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"419.00,288.83 408.87,284.10 409.14,294.10\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"423.66\" x2=\"209.01\" y2=\"419.69\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,419.45 208.89,414.69 209.13,424.69\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"40.03\" y1=\"413.74\" x2=\"123.97\" y2=\"306.77\" stroke=\"#e0982b\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><line x1=\"45.00\" y1=\"32.03\" x2=\"109.00\" y2=\"32.03\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,32.03 109.00,27.03 109.00,37.03\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"217.46\" y1=\"401.31\" x2=\"140.22\" y2=\"306.62\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"223.78,409.06 221.34,398.15 213.59,404.47\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"532.00\" cy=\"288.48\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"532.00\" y=\"288.48\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"232.00\" cy=\"164.29\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"164.29\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"332.00\" cy=\"354.62\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"354.62\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"165.90\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"165.90\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"432.00\" cy=\"288.48\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"432.00\" y=\"288.48\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"32.00\" cy=\"423.97\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"423.97\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"32.00\" cy=\"32.03\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"32.03\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"132.00\" cy=\"32.03\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"32.03\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"232.00\" cy=\"419.13\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"419.13\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"132.00\" cy=\"296.54\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"296.54\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>'"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "results = {\n",
    "    \"XGES\": andrey.xges(X),\n",
    "    \"Hill climbing\": andrey.hc(X),\n",
    "    \"Tabu search\": andrey.tabu(X),\n",
    "}\n",
    "for name, result in results.items():\n",
    "    print(f\"{name}: {result.structure.kind}, score {result.metadata['score']:.1f}\")\n",
    "    display(andrey.viz.draw(result.structure))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-8",
   "metadata": {},
   "source": [
    "## Compare with GES over ten datasets\n",
    "\n",
    "Structural Hamming distance (SHD) counts errors against the truth's CPDAG; lower is better. The\n",
    "empty graph's SHD is the number of true edges, so an estimate at or above it has not improved on\n",
    "returning no edges. One dataset can favor any method, so the table covers ten seeds and their\n",
    "median."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "score_search-9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>seed</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "      <th>median</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Empty graph</th>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15</td>\n",
       "      <td>15.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>GES</th>\n",
       "      <td>21</td>\n",
       "      <td>10</td>\n",
       "      <td>0</td>\n",
       "      <td>10</td>\n",
       "      <td>17</td>\n",
       "      <td>7</td>\n",
       "      <td>11</td>\n",
       "      <td>17</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>10.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>XGES</th>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>0</td>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Hill climbing</th>\n",
       "      <td>28</td>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>8</td>\n",
       "      <td>25</td>\n",
       "      <td>16</td>\n",
       "      <td>22</td>\n",
       "      <td>11</td>\n",
       "      <td>4</td>\n",
       "      <td>13</td>\n",
       "      <td>12.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Tabu search</th>\n",
       "      <td>6</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>20</td>\n",
       "      <td>9</td>\n",
       "      <td>16</td>\n",
       "      <td>12</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>3.5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "seed            0   1   2   3   4   5   6   7   8   9  median\n",
       "Empty graph    15  15  15  15  15  15  15  15  15  15    15.0\n",
       "GES            21  10   0  10  17   7  11  17   0   0    10.0\n",
       "XGES            0   8   0   9   1   0   1   6   0   0     0.5\n",
       "Hill climbing  28   6   0   8  25  16  22  11   4  13    12.0\n",
       "Tabu search     6   0   0   1  20   9  16  12   0   0     3.5"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "methods = {\n",
    "    \"GES\": lambda X: andrey.ges(X),\n",
    "    \"XGES\": lambda X: andrey.xges(X),\n",
    "    \"Hill climbing\": lambda X: andrey.hc(X),\n",
    "    \"Tabu search\": lambda X: andrey.tabu(X),\n",
    "}\n",
    "rows = {}\n",
    "for s in range(10):\n",
    "    draw = benchmarks.scm(\"linear_gauss_er\", d=10).sample(n=2000, seed=s, scale=\"standardize\")\n",
    "    d = draw.observed_graph.n_nodes\n",
    "    empty = andrey.GraphStructure.from_numpy(np.zeros((d, d), dtype=np.uint8), kind=\"cpdag\")\n",
    "    rows[s] = {\"Empty graph\": metrics.score(empty, draw.observed_graph)[\"shd\"]}\n",
    "    for name, fit in methods.items():\n",
    "        rows[s][name] = metrics.score(fit(draw.data), draw.observed_graph)[\"shd\"]\n",
    "shd = pd.DataFrame(rows)\n",
    "shd.columns.name = \"seed\"\n",
    "shd[\"median\"] = shd.median(axis=1)\n",
    "shd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-10",
   "metadata": {},
   "source": [
    "Tabu search starts with hill climbing's moves, so its score is never worse than hill\n",
    "climbing's on the same data. The [0.3.0 release card](https://andrey.abel.ai/docs/benchmarks/0.3.0.html)\n",
    "compares XGES with the xges package and the other two with bnlearn, on larger graphs with ten rows\n",
    "per variable."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-11",
   "metadata": {},
   "source": [
    "## Exact search\n",
    "\n",
    "`exact_search` scores every parent set of every variable and returns a DAG with the best BIC\n",
    "score. Its run time at least doubles with each added variable, so keep it to about 20 variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "score_search-12",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Exact search: dag\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 364 279\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"364\" height=\"279\" fill=\"#fafbfc\"/><line x1=\"209.35\" y1=\"242.74\" x2=\"144.80\" y2=\"231.29\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.20,244.49 210.23,237.82 208.48,247.67\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"240.90\" y1=\"43.33\" x2=\"316.25\" y2=\"123.55\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"323.10,130.83 319.90,120.12 312.61,126.97\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"209.00\" y1=\"33.85\" x2=\"145.00\" y2=\"33.85\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,33.85 209.00,28.85 209.00,38.85\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"214.31\" y1=\"48.55\" x2=\"42.00\" y2=\"191.68\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"222.00,42.16 211.11,44.70 217.50,52.39\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 313.70 154.24 Q 242.54 208.43 144.78 226.64\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.66,148.18 310.67,150.27 316.73,158.22\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"132.62\" x2=\"244.25\" y2=\"109.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,135.96 312.00,127.90 308.65,137.33\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"148.00\" x2=\"244.25\" y2=\"171.45\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,144.66 308.65,143.29 312.00,152.71\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"40.09\" y1=\"113.38\" x2=\"117.69\" y2=\"211.01\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"123.91,218.84 121.60,207.90 113.77,214.12\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"103.31\" x2=\"209.00\" y2=\"104.63\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,104.72 209.04,99.63 208.96,109.63\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"42.68\" y1=\"95.80\" x2=\"113.10\" y2=\"46.96\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.32,41.26 110.25,42.85 115.95,51.07\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"140.15\" y1=\"218.89\" x2=\"217.58\" y2=\"122.73\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"223.85,114.95 213.68,119.60 221.47,125.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"143.48\" y1=\"222.91\" x2=\"211.70\" y2=\"186.60\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"220.52,181.90 209.35,182.19 214.05,191.01\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"109.91\" y1=\"222.61\" x2=\"44.48\" y2=\"203.61\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.52,225.39 111.31,217.80 108.52,227.41\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"32.45\" x2=\"109.00\" y2=\"33.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,33.64 109.08,28.48 108.92,38.48\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"232.00\" cy=\"246.76\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"246.76\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"232.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"332.00\" cy=\"140.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"140.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"103.21\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"103.21\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"132.00\" cy=\"229.02\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"229.02\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"232.00\" cy=\"104.82\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"104.82\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"32.00\" cy=\"32.24\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"32.24\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"132.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"232.00\" cy=\"175.79\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"175.79\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"32.00\" cy=\"199.99\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"199.99\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>"
      ],
      "text/plain": [
       "'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 364 279\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"364\" height=\"279\" fill=\"#fafbfc\"/><line x1=\"209.35\" y1=\"242.74\" x2=\"144.80\" y2=\"231.29\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.20,244.49 210.23,237.82 208.48,247.67\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"240.90\" y1=\"43.33\" x2=\"316.25\" y2=\"123.55\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"323.10,130.83 319.90,120.12 312.61,126.97\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"209.00\" y1=\"33.85\" x2=\"145.00\" y2=\"33.85\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,33.85 209.00,28.85 209.00,38.85\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"214.31\" y1=\"48.55\" x2=\"42.00\" y2=\"191.68\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"222.00,42.16 211.11,44.70 217.50,52.39\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><path d=\"M 313.70 154.24 Q 242.54 208.43 144.78 226.64\" fill=\"none\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"321.66,148.18 310.67,150.27 316.73,158.22\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"132.62\" x2=\"244.25\" y2=\"109.17\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,135.96 312.00,127.90 308.65,137.33\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"310.32\" y1=\"148.00\" x2=\"244.25\" y2=\"171.45\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"319.75,144.66 308.65,143.29 312.00,152.71\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"40.09\" y1=\"113.38\" x2=\"117.69\" y2=\"211.01\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"123.91,218.84 121.60,207.90 113.77,214.12\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"103.31\" x2=\"209.00\" y2=\"104.63\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"219.00,104.72 209.04,99.63 208.96,109.63\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"42.68\" y1=\"95.80\" x2=\"113.10\" y2=\"46.96\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"121.32,41.26 110.25,42.85 115.95,51.07\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"140.15\" y1=\"218.89\" x2=\"217.58\" y2=\"122.73\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"223.85,114.95 213.68,119.60 221.47,125.87\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"143.48\" y1=\"222.91\" x2=\"211.70\" y2=\"186.60\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"220.52,181.90 209.35,182.19 214.05,191.01\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"109.91\" y1=\"222.61\" x2=\"44.48\" y2=\"203.61\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.52,225.39 111.31,217.80 108.52,227.41\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"45.00\" y1=\"32.45\" x2=\"109.00\" y2=\"33.48\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"119.00,33.64 109.08,28.48 108.92,38.48\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"232.00\" cy=\"246.76\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"246.76\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">0</text><circle cx=\"232.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">1</text><circle cx=\"332.00\" cy=\"140.31\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"332.00\" y=\"140.31\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">2</text><circle cx=\"32.00\" cy=\"103.21\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"103.21\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">3</text><circle cx=\"132.00\" cy=\"229.02\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"229.02\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">4</text><circle cx=\"232.00\" cy=\"104.82\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"104.82\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">5</text><circle cx=\"32.00\" cy=\"32.24\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"32.24\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">6</text><circle cx=\"132.00\" cy=\"33.85\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"132.00\" y=\"33.85\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">7</text><circle cx=\"232.00\" cy=\"175.79\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"232.00\" y=\"175.79\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">8</text><circle cx=\"32.00\" cy=\"199.99\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"32.00\" y=\"199.99\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">9</text></svg>'"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "exact = andrey.exact_search(X)\n",
    "print(\"Exact search:\", exact.structure.kind)\n",
    "display(andrey.viz.draw(exact.structure))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-13",
   "metadata": {},
   "source": [
    "## Interventions: GIES\n",
    "\n",
    "`gies` also takes the rows' interventions: `True` where a row's value of a variable was set from\n",
    "outside. A chain from observational data stays undirected; here the last 1,000 rows set `x1`, which\n",
    "orients both of its edges. The columns come in an order drawn from the seed, and the interventions\n",
    "follow them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "score_search-14",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('x1', 'x2', 'directed'), ('x0', 'x1', 'directed')]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 360 240\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"360\" height=\"240\" fill=\"#fafbfc\"/><line x1=\"193.00\" y1=\"120.00\" x2=\"257.00\" y2=\"120.00\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"267.00,120.00 257.00,115.00 257.00,125.00\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"157.00\" y1=\"120.00\" x2=\"93.00\" y2=\"120.00\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"167.00,120.00 157.00,115.00 157.00,125.00\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"180.00\" cy=\"120.00\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"180.00\" y=\"120.00\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">x1</text><circle cx=\"280.00\" cy=\"120.00\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"280.00\" y=\"120.00\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">x2</text><circle cx=\"80.00\" cy=\"120.00\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"80.00\" y=\"120.00\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">x0</text></svg>"
      ],
      "text/plain": [
       "'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 360 240\" width=\"100%\" font-family=\"Inter, system-ui, sans-serif\"><rect width=\"360\" height=\"240\" fill=\"#fafbfc\"/><line x1=\"193.00\" y1=\"120.00\" x2=\"257.00\" y2=\"120.00\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"267.00,120.00 257.00,115.00 257.00,125.00\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><line x1=\"157.00\" y1=\"120.00\" x2=\"93.00\" y2=\"120.00\" stroke=\"#3a4658\" stroke-width=\"2.0\" stroke-linecap=\"round\"/><polygon points=\"167.00,120.00 157.00,115.00 157.00,125.00\" fill=\"#3a4658\" stroke-linejoin=\"round\"/><circle cx=\"180.00\" cy=\"120.00\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"180.00\" y=\"120.00\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">x1</text><circle cx=\"280.00\" cy=\"120.00\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"280.00\" y=\"120.00\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">x2</text><circle cx=\"80.00\" cy=\"120.00\" r=\"13.00\" fill=\"#ffffff\" stroke=\"#182233\" stroke-width=\"1.8\"/><text x=\"80.00\" y=\"120.00\" text-anchor=\"middle\" font-size=\"11\" font-weight=\"600\" fill=\"#182233\" dominant-baseline=\"central\">x0</text></svg>'"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "CHAIN = [(\"x0\", \"x1\"), (\"x1\", \"x2\")]  # the true edges, cause first\n",
    "\n",
    "\n",
    "def sample_intervened(\n",
    "    seed: int, n: int = 3000, shuffle: bool = True\n",
    ") -> tuple[pd.DataFrame, np.ndarray]:\n",
    "    \"\"\"Draw n rows of the chain, the last 1,000 setting x1 from outside, and the interventions.\"\"\"\n",
    "    rng = np.random.default_rng(seed)\n",
    "    x0 = rng.standard_normal(n)\n",
    "    x1 = 0.8 * x0 + rng.standard_normal(n)\n",
    "    x1[n - 1000 :] = rng.standard_normal(1000)  # the last 1,000 rows set x1 from outside\n",
    "    x2 = 0.8 * x1 + rng.standard_normal(n)\n",
    "    frame = pd.DataFrame({\"x0\": x0, \"x1\": x1, \"x2\": x2})\n",
    "    frame = frame[rng.permutation(frame.columns)] if shuffle else frame\n",
    "    intervened = np.zeros((n, 3), dtype=bool)\n",
    "    intervened[n - 1000 :, frame.columns.get_loc(\"x1\")] = True\n",
    "    return frame, intervened\n",
    "\n",
    "\n",
    "gies_out = andrey.gies(*sample_intervened(seed=1))\n",
    "print(gies_out.structure.oriented_edges())\n",
    "display(andrey.viz.draw(gies_out.structure))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "score_search-15",
   "metadata": {},
   "source": [
    "## Use another dataset\n",
    "\n",
    "Change `seed`, or the `d` and `n` passed to `benchmarks.scm` and `sample`, and rerun."
   ]
  }
 ],
 "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.14.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
