{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e5f7930c7774",
   "metadata": {},
   "source": [
    "# Chapter 21: Markets, Teams, and Institutions\n",
    "\n",
    "A team adds a shortcut between two workflow stages. Every participant sees a privately attractive route, yet their collective routing can increase delay. The missing ingredient is congestion: each choice changes the cost other participants face.\n",
    "\n",
    "This notebook solves a symmetric continuous-flow Braess construction. Two outer routes share a new shortcut route, with linear congestion and fixed delays. It calculates private equilibrium and total social travel time, then compares a toll intervention and an exact social optimum. The example is a declared institution model. It does not estimate a real market or suggest that every new workflow interface causes a paradox.\n",
    "\n",
    "**Outcome:** Compare Braess equilibrium, social optimum, tolls, and overhead.\n",
    "\n",
    "- Inspect the declared input contract\n",
    "- Predict the hand-checkable case\n",
    "- Run the shared computation\n",
    "- Change the critical assumption\n",
    "- Apply the method to the transfer data\n",
    "\n",
    "**Guided route:** Run the worked calculation, inspect its figure, change the stated assumption, and try the transfer case. Read the explanations beside each result before opening the answers.\n",
    "\n",
    "**Deeper route:** First read the mathematics and canonical equation reference. Audit the input contract, predict the changed result, then inspect the shared chapter implementation and solve the questions independently. Both routes use the same calculations and preserve the equations."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7781f3ee7dc",
   "metadata": {},
   "source": [
    "## Technical Requirements\n",
    "\n",
    "Python 3.11 or later, the complete laboratory folder, and the notebook dependencies listed in `requirements-notebooks.txt` (the launcher's **Install notebook tools** choice installs them; see START-HERE). Standard-library chapter commands also support Python 3.10. No API key, model account or network call is used by this experiment.\n",
    "\n",
    "Prior knowledge:\n",
    "\n",
    "- Python lists and dictionaries\n",
    "- The mapped chapter and its notation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8921855fc15",
   "metadata": {},
   "source": [
    "## The question and its mathematics\n",
    "\n",
    "Let total demand be D. Symmetry assigns x to each outer route and z to the shortcut, so 2x+z=D. Each congestible edge carries x+z and takes time v=(x+z)/capacity. Outer path time is v+c; shortcut time is 2v+overhead. The shortcut also pays a private toll.\n",
    "\n",
    "At an interior equilibrium, used routes have equal private cost. Solving v+c=2v+overhead+toll gives z=2 capacity(c-overhead-toll)-D, clipped to [0,D]. Boundary clipping handles unused outer or shortcut routes. Without the shortcut, outer flow is D/2 and total travel time is D[D/(2 capacity)+c].\n",
    "\n",
    "Social travel time excludes toll transfers and equals 2x(v+c)+z(2v+overhead). After substitution it is (D+z)^2/(2 capacity)+c(D-z)+overhead*z. This convex quadratic is minimized at z=capacity(c-overhead)-D, clipped to [0,D]. The price of anarchy compares equilibrium social time with that minimum, not with toll-inclusive private expense."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0134acecc887",
   "metadata": {},
   "source": [
    "## A calculation you can run\n",
    "\n",
    "Declare demand, congestion capacity, outer constant delay, shortcut overhead, and toll. Validation requires positive demand and capacity and nonnegative other quantities. The function computes symmetric equilibrium flow, path costs, total delay, optimal shortcut flow, and toll revenue.\n",
    "\n",
    "The figure varies shortcut flow from zero to total demand and plots exact social travel time. Its minimum should match the reported optimum. In the changed case add toll 0.5 without changing physical travel times. Predict how it shifts equilibrium, then compare social cost. The transfer case reduces demand, checking that a shortcut need not worsen performance under every loading condition.\n",
    "\n",
    "The next cell finds the bundle and imports the same computation used by the chapter skill. It does not change your system Python."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "42ebefc0e5c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "import sys, json\n",
    "LAB_ROOT = next((p for p in [Path.cwd(), *Path.cwd().parents] if (p / \"lab-manifest.json\").is_file()), None)\n",
    "if LAB_ROOT is None:\n",
    "    raise RuntimeError(\"Open this notebook from the complete extracted laboratory folder.\")\n",
    "sys.path.insert(0, str(LAB_ROOT / \"src\"))\n",
    "from math_ai_agents.core import analyze, report_text\n",
    "from math_ai_agents.plotting import figure_svg\n",
    "from IPython.display import SVG, display\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fffde8c0edb",
   "metadata": {},
   "source": [
    "Set the declared inputs below. These are constructed teaching values, not measurements from a production agent. Change a value only after predicting what it should change."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "6875f8982178",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chapter 21: congestion-incentives\n",
      "Can a faster-looking route make the whole workflow slower?\n",
      "Evidence: constructed teaching example\n",
      "\n",
      "Calculated quantities:\n",
      "{\n",
      "  \"without_shortcut_total_time\": 1.5,\n",
      "  \"equilibrium_shortcut_flow\": 1.0,\n",
      "  \"equilibrium_outer_flow_each\": 0.0,\n",
      "  \"equilibrium_social_time\": 2.0,\n",
      "  \"equilibrium_private_outer_time\": 2.0,\n",
      "  \"equilibrium_private_shortcut_time\": 2.0,\n",
      "  \"optimal_shortcut_flow\": 0,\n",
      "  \"optimal_social_time\": 1.5,\n",
      "  \"price_of_anarchy\": 1.333333333,\n",
      "  \"braess_worsens\": true,\n",
      "  \"toll_revenue\": 0.0\n",
      "}\n",
      "\n",
      "Interpretation:\n",
      "A new route can change private incentives and increase total delay. Tolls enter private cost; toll payments are excluded from travel-time social cost.\n",
      "\n",
      "Assumptions:\n",
      "- Symmetric continuous flow, linear congestible edges, constant outer edges.\n",
      "- All travelers choose minimum private path cost at nonatomic equilibrium.\n",
      "\n",
      "Limitations:\n",
      "- This construction does not estimate a real workflow equilibrium.\n",
      "- Discrete teams and heterogeneous incentives need additional modeling.\n",
      "\n",
      "Execution: completed locally; constructed inputs are not deployment measurements.\n"
     ]
    }
   ],
   "source": [
    "chapter = 21\n",
    "inputs = {'demand': 1,\n",
    " 'capacity': 1,\n",
    " 'constant_time': 1,\n",
    " 'shortcut_overhead': 0,\n",
    " 'shortcut_toll': 0}\n",
    "report = analyze(chapter, inputs)\n",
    "# This input was explicitly taken from the teaching fixture.\n",
    "report['evidence_kind'] = 'constructed teaching example'\n",
    "print(report_text(report))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdbe133ae5d1",
   "metadata": {},
   "source": [
    "Without the shortcut, default total time is 1(0.5+1)=1.5. With a zero-cost shortcut, equilibrium sends all demand through it, giving path time 2 and total time 2. The social optimum uses no shortcut and remains at 1.5. Price of anarchy is 2/1.5=4/3.\n",
    "\n",
    "A toll 0.5 changes the equilibrium shortcut flow to zero. Outer private time is 1.5, while an unused shortcut would also cost 1.5 including toll. Total travel time returns to 1.5. The toll affects incentives; it is not counted as destroyed travel time or an extra physical delay.\n",
    "\n",
    "The toll 0.5 sits exactly at the break-even value, so this teaching case is knife-edge. At toll 0.49 the lab returns shortcut flow 0.02 and equilibrium social time 1.5002, and at 0.51 it returns flow 0 and time 1.5. Try nearby tolls to see the threshold rather than reading 0.5 as a robust remedy.\n",
    "\n",
    "The plot below uses the calculated quantities. Read each panel's units before comparing its values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "590f57e74048",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Matplotlib is building the font cache; this may take a moment.\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" width=\"576pt\" height=\"237.6pt\" viewBox=\"0 0 576 237.6\" version=\"1.1\"><title>Calculated chapter experiment</title><desc>Labeled plot of the explicitly supplied chapter inputs. See the adjacent explanation for assumptions.</desc>\n",
       " <metadata>\n",
       "  <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n",
       "   <cc:Work>\n",
       "    <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n",
       "    <dc:format>image/svg+xml</dc:format>\n",
       "    <dc:creator>\n",
       "     <cc:Agent>\n",
       "      <dc:title>Mathematics of AI Agents Laboratory</dc:title>\n",
       "     </cc:Agent>\n",
       "    </dc:creator>\n",
       "   </cc:Work>\n",
       "  </rdf:RDF>\n",
       " </metadata>\n",
       " <defs>\n",
       "  <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n",
       " </defs>\n",
       " <g id=\"figure_1\">\n",
       "  <g id=\"patch_1\">\n",
       "   <path d=\"M 0 237.6  L 576 237.6  L 576 0  L 0 0  z \" style=\"fill: #ffffff\"/>\n",
       "  </g>\n",
       "  <g id=\"axes_1\">\n",
       "   <g id=\"patch_2\">\n",
       "    <path d=\"M 47.962344 195.477656  L 565.2 195.477656  L 565.2 60.080234  L 47.962344 60.080234  z \" style=\"fill: #ffffff\"/>\n",
       "   </g>\n",
       "   <g id=\"matplotlib.axis_1\">\n",
       "    <g id=\"xtick_1\">\n",
       "     <g id=\"line2d_1\">\n",
       "      <defs>\n",
       "       <path id=\"m1866bc0ee6\" d=\"M 0 0  L 0 3.5  \" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </defs>\n",
       "      <g>\n",
       "       <use xlink:href=\"#m1866bc0ee6\" x=\"71.473146\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_1\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"71.473146\" y=\"210.075312\" transform=\"rotate(-0 71.473146 210.075312)\">0.0</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_2\">\n",
       "     <g id=\"line2d_2\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m1866bc0ee6\" x=\"165.516357\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_2\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"165.516357\" y=\"210.075312\" transform=\"rotate(-0 165.516357 210.075312)\">0.2</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_3\">\n",
       "     <g id=\"line2d_3\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m1866bc0ee6\" x=\"259.559567\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_3\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"259.559567\" y=\"210.075312\" transform=\"rotate(-0 259.559567 210.075312)\">0.4</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_4\">\n",
       "     <g id=\"line2d_4\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m1866bc0ee6\" x=\"353.602777\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_4\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"353.602777\" y=\"210.075312\" transform=\"rotate(-0 353.602777 210.075312)\">0.6</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_5\">\n",
       "     <g id=\"line2d_5\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m1866bc0ee6\" x=\"447.645987\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_5\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"447.645987\" y=\"210.075312\" transform=\"rotate(-0 447.645987 210.075312)\">0.8</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_6\">\n",
       "     <g id=\"line2d_6\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m1866bc0ee6\" x=\"541.689197\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_6\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"541.689197\" y=\"210.075312\" transform=\"rotate(-0 541.689197 210.075312)\">1.0</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"text_7\">\n",
       "     <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"306.581172\" y=\"224.076094\" transform=\"rotate(-0 306.581172 224.076094)\">shortcut flow</text>\n",
       "    </g>\n",
       "   </g>\n",
       "   <g id=\"matplotlib.axis_2\">\n",
       "    <g id=\"ytick_1\">\n",
       "     <g id=\"line2d_7\">\n",
       "      <path d=\"M 47.962344 189.323228  L 565.2 189.323228  \" clip-path=\"url(#pca4afa0733)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_8\">\n",
       "      <defs>\n",
       "       <path id=\"m7cc2f1e8ee\" d=\"M 0 0  L -3.5 0  \" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </defs>\n",
       "      <g>\n",
       "       <use xlink:href=\"#m7cc2f1e8ee\" x=\"47.962344\" y=\"189.323228\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_8\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"193.122056\" transform=\"rotate(-0 40.962344 193.122056)\">1.5</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_2\">\n",
       "     <g id=\"line2d_9\">\n",
       "      <path d=\"M 47.962344 164.705515  L 565.2 164.705515  \" clip-path=\"url(#pca4afa0733)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_10\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m7cc2f1e8ee\" x=\"47.962344\" y=\"164.705515\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_9\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"168.504343\" transform=\"rotate(-0 40.962344 168.504343)\">1.6</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_3\">\n",
       "     <g id=\"line2d_11\">\n",
       "      <path d=\"M 47.962344 140.087802  L 565.2 140.087802  \" clip-path=\"url(#pca4afa0733)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_12\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m7cc2f1e8ee\" x=\"47.962344\" y=\"140.087802\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_10\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"143.88663\" transform=\"rotate(-0 40.962344 143.88663)\">1.7</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_4\">\n",
       "     <g id=\"line2d_13\">\n",
       "      <path d=\"M 47.962344 115.470089  L 565.2 115.470089  \" clip-path=\"url(#pca4afa0733)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_14\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m7cc2f1e8ee\" x=\"47.962344\" y=\"115.470089\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_11\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"119.268917\" transform=\"rotate(-0 40.962344 119.268917)\">1.8</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_5\">\n",
       "     <g id=\"line2d_15\">\n",
       "      <path d=\"M 47.962344 90.852376  L 565.2 90.852376  \" clip-path=\"url(#pca4afa0733)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_16\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m7cc2f1e8ee\" x=\"47.962344\" y=\"90.852376\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_12\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"94.651204\" transform=\"rotate(-0 40.962344 94.651204)\">1.9</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_6\">\n",
       "     <g id=\"line2d_17\">\n",
       "      <path d=\"M 47.962344 66.234663  L 565.2 66.234663  \" clip-path=\"url(#pca4afa0733)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_18\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m7cc2f1e8ee\" x=\"47.962344\" y=\"66.234663\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_13\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"70.033491\" transform=\"rotate(-0 40.962344 70.033491)\">2.0</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"text_14\">\n",
       "     <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"18.656875\" y=\"127.778945\" transform=\"rotate(-90 18.656875 127.778945)\">total traveler time</text>\n",
       "    </g>\n",
       "   </g>\n",
       "   <g id=\"line2d_19\">\n",
       "    <path d=\"M 71.473146 189.323228  L 76.175307 189.310919  L 80.877467 189.273993  L 85.579628 189.212448  L 90.281788 189.126286  L 94.983949 189.015507  L 99.686109 188.880109  L 104.38827 188.720094  L 109.09043 188.535461  L 113.792591 188.326211  L 118.494751 188.092342  L 123.196912 187.833856  L 127.899072 187.550753  L 132.601233 187.243031  L 137.303393 186.910692  L 142.005554 186.553735  L 146.707714 186.172161  L 151.409875 185.765968  L 156.112036 185.335158  L 160.814196 184.879731  L 165.516357 184.399685  L 170.218517 183.895022  L 174.920678 183.365741  L 179.622838 182.811843  L 184.324999 182.233327  L 189.027159 181.630193  L 193.72932 181.002441  L 198.43148 180.350072  L 203.133641 179.673084  L 207.835801 178.97148  L 212.537962 178.245257  L 217.240122 177.494417  L 221.942283 176.718959  L 226.644443 175.918883  L 231.346604 175.09419  L 236.048764 174.244879  L 240.750925 173.37095  L 245.453085 172.472403  L 250.155246 171.549239  L 254.857406 170.601457  L 259.559567 169.629058  L 264.261727 168.63204  L 268.963888 167.610405  L 273.666048 166.564152  L 278.368209 165.493282  L 283.070369 164.397794  L 287.77253 163.277688  L 292.47469 162.132964  L 297.176851 160.963623  L 301.879011 159.769663  L 306.581172 158.551087  L 311.283332 157.307892  L 315.985493 156.04008  L 320.687653 154.74765  L 325.389814 153.430602  L 330.091974 152.088937  L 334.794135 150.722654  L 339.496295 149.331753  L 344.198456 147.916235  L 348.900616 146.476098  L 353.602777 145.011344  L 358.304937 143.521973  L 363.007098 142.007983  L 367.709259 140.469376  L 372.411419 138.906152  L 377.11358 137.318309  L 381.81574 135.705849  L 386.517901 134.068771  L 391.220061 132.407075  L 395.922222 130.720762  L 400.624382 129.009831  L 405.326543 127.274282  L 410.028703 125.514116  L 414.730864 123.729332  L 419.433024 121.91993  L 424.135185 120.08591  L 428.837345 118.227273  L 433.539506 116.344018  L 438.241666 114.436145  L 442.943827 112.503654  L 447.645987 110.546546  L 452.348148 108.56482  L 457.050308 106.558477  L 461.752469 104.527515  L 466.454629 102.471936  L 471.15679 100.39174  L 475.85895 98.286925  L 480.561111 96.157493  L 485.263271 94.003443  L 489.965432 91.824775  L 494.667592 89.62149  L 499.369753 87.393587  L 504.071913 85.141066  L 508.774074 82.863928  L 513.476234 80.562172  L 518.178395 78.235798  L 522.880555 75.884806  L 527.582716 73.509197  L 532.284876 71.10897  L 536.987037 68.684125  L 541.689197 66.234663  \" clip-path=\"url(#pca4afa0733)\" style=\"fill: none; stroke: #31586b; stroke-width: 1.8; stroke-linecap: square\"/>\n",
       "   </g>\n",
       "   <g id=\"patch_3\">\n",
       "    <path d=\"M 47.962344 195.477656  L 47.962344 60.080234  \" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n",
       "   </g>\n",
       "   <g id=\"patch_4\">\n",
       "    <path d=\"M 47.962344 195.477656  L 565.2 195.477656  \" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n",
       "   </g>\n",
       "   <g id=\"text_15\">\n",
       "    <text style=\"font-size: 11px; font-family: 'DejaVu Sans'; text-anchor: start\" x=\"47.962344\" y=\"54.080234\" transform=\"rotate(-0 47.962344 54.080234)\">social travel cost</text>\n",
       "   </g>\n",
       "  </g>\n",
       "  <g id=\"text_16\">\n",
       "   <text style=\"font-size: 12px; font-family: 'DejaVu Sans'; text-anchor: start\" x=\"46.08\" y=\"13.870125\" transform=\"rotate(-0 46.08 13.870125)\">Chapter 21: congestion incentives</text>\n",
       "  </g>\n",
       " </g>\n",
       " <defs>\n",
       "  <clipPath id=\"pca4afa0733\">\n",
       "   <rect x=\"47.962344\" y=\"60.080234\" width=\"517.237656\" height=\"135.397422\"/>\n",
       "  </clipPath>\n",
       " </defs>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(SVG(figure_svg(report)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "623a8169d7e3",
   "metadata": {},
   "source": [
    "**Figure 21.L1:** Calculated chapter experiment. Each panel labels its input and output units; interpret it under the assumptions printed in the report."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69b7a9983c66",
   "metadata": {},
   "source": [
    "## Change the assumption\n",
    "\n",
    "The paradox relies on a particular network and demand regime. At low demand, the shortcut can be socially useful and privately efficient. Presenting the default construction as a law against connectivity would erase those conditions.\n",
    "\n",
    "Institutional metrics can also confuse transfers with resource costs. A toll payment changes who bears money but is excluded from this travel-time objective. A real institution may care about distributional effects or administrative overhead, which should be modeled separately. Shortcut overhead here is a real delay and therefore enters social cost.\n",
    "\n",
    "Continuous equilibrium assumes many small participants choosing minimum private cost. A small team with indivisible jobs, strategic coordination, or centralized routing may behave differently. The calculation is an exact finite model result under those assumptions, not a fitted causal claim about organizational performance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "970e70c18a40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chapter 21: congestion-incentives\n",
      "Can a faster-looking route make the whole workflow slower?\n",
      "Evidence: constructed changed-assumption example\n",
      "\n",
      "Calculated quantities:\n",
      "{\n",
      "  \"without_shortcut_total_time\": 1.5,\n",
      "  \"equilibrium_shortcut_flow\": 0,\n",
      "  \"equilibrium_outer_flow_each\": 0.5,\n",
      "  \"equilibrium_social_time\": 1.5,\n",
      "  \"equilibrium_private_outer_time\": 1.5,\n",
      "  \"equilibrium_private_shortcut_time\": 1.5,\n",
      "  \"optimal_shortcut_flow\": 0,\n",
      "  \"optimal_social_time\": 1.5,\n",
      "  \"price_of_anarchy\": 1.0,\n",
      "  \"braess_worsens\": false,\n",
      "  \"toll_revenue\": 0.0\n",
      "}\n",
      "\n",
      "Interpretation:\n",
      "A new route can change private incentives and increase total delay. Tolls enter private cost; toll payments are excluded from travel-time social cost.\n",
      "\n",
      "Assumptions:\n",
      "- Symmetric continuous flow, linear congestible edges, constant outer edges.\n",
      "- All travelers choose minimum private path cost at nonatomic equilibrium.\n",
      "\n",
      "Limitations:\n",
      "- This construction does not estimate a real workflow equilibrium.\n",
      "- Discrete teams and heterogeneous incentives need additional modeling.\n",
      "\n",
      "Execution: completed locally; constructed inputs are not deployment measurements.\n"
     ]
    },
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\" width=\"576pt\" height=\"237.6pt\" viewBox=\"0 0 576 237.6\" version=\"1.1\"><title>Calculated chapter experiment</title><desc>Labeled plot of the explicitly supplied chapter inputs. See the adjacent explanation for assumptions.</desc>\n",
       " <metadata>\n",
       "  <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n",
       "   <cc:Work>\n",
       "    <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n",
       "    <dc:format>image/svg+xml</dc:format>\n",
       "    <dc:creator>\n",
       "     <cc:Agent>\n",
       "      <dc:title>Mathematics of AI Agents Laboratory</dc:title>\n",
       "     </cc:Agent>\n",
       "    </dc:creator>\n",
       "   </cc:Work>\n",
       "  </rdf:RDF>\n",
       " </metadata>\n",
       " <defs>\n",
       "  <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n",
       " </defs>\n",
       " <g id=\"figure_1\">\n",
       "  <g id=\"patch_1\">\n",
       "   <path d=\"M 0 237.6  L 576 237.6  L 576 0  L 0 0  z \" style=\"fill: #ffffff\"/>\n",
       "  </g>\n",
       "  <g id=\"axes_1\">\n",
       "   <g id=\"patch_2\">\n",
       "    <path d=\"M 47.962344 195.477656  L 565.2 195.477656  L 565.2 60.080234  L 47.962344 60.080234  z \" style=\"fill: #ffffff\"/>\n",
       "   </g>\n",
       "   <g id=\"matplotlib.axis_1\">\n",
       "    <g id=\"xtick_1\">\n",
       "     <g id=\"line2d_1\">\n",
       "      <defs>\n",
       "       <path id=\"ma571d91d28\" d=\"M 0 0  L 0 3.5  \" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </defs>\n",
       "      <g>\n",
       "       <use xlink:href=\"#ma571d91d28\" x=\"71.473146\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_1\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"71.473146\" y=\"210.075312\" transform=\"rotate(-0 71.473146 210.075312)\">0.0</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_2\">\n",
       "     <g id=\"line2d_2\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#ma571d91d28\" x=\"165.516357\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_2\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"165.516357\" y=\"210.075312\" transform=\"rotate(-0 165.516357 210.075312)\">0.2</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_3\">\n",
       "     <g id=\"line2d_3\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#ma571d91d28\" x=\"259.559567\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_3\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"259.559567\" y=\"210.075312\" transform=\"rotate(-0 259.559567 210.075312)\">0.4</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_4\">\n",
       "     <g id=\"line2d_4\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#ma571d91d28\" x=\"353.602777\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_4\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"353.602777\" y=\"210.075312\" transform=\"rotate(-0 353.602777 210.075312)\">0.6</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_5\">\n",
       "     <g id=\"line2d_5\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#ma571d91d28\" x=\"447.645987\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_5\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"447.645987\" y=\"210.075312\" transform=\"rotate(-0 447.645987 210.075312)\">0.8</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"xtick_6\">\n",
       "     <g id=\"line2d_6\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#ma571d91d28\" x=\"541.689197\" y=\"195.477656\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_6\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"541.689197\" y=\"210.075312\" transform=\"rotate(-0 541.689197 210.075312)\">1.0</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"text_7\">\n",
       "     <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"306.581172\" y=\"224.076094\" transform=\"rotate(-0 306.581172 224.076094)\">shortcut flow</text>\n",
       "    </g>\n",
       "   </g>\n",
       "   <g id=\"matplotlib.axis_2\">\n",
       "    <g id=\"ytick_1\">\n",
       "     <g id=\"line2d_7\">\n",
       "      <path d=\"M 47.962344 189.323228  L 565.2 189.323228  \" clip-path=\"url(#p5d20eeedac)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_8\">\n",
       "      <defs>\n",
       "       <path id=\"m275d226f79\" d=\"M 0 0  L -3.5 0  \" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </defs>\n",
       "      <g>\n",
       "       <use xlink:href=\"#m275d226f79\" x=\"47.962344\" y=\"189.323228\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_8\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"193.122056\" transform=\"rotate(-0 40.962344 193.122056)\">1.5</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_2\">\n",
       "     <g id=\"line2d_9\">\n",
       "      <path d=\"M 47.962344 164.705515  L 565.2 164.705515  \" clip-path=\"url(#p5d20eeedac)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_10\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m275d226f79\" x=\"47.962344\" y=\"164.705515\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_9\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"168.504343\" transform=\"rotate(-0 40.962344 168.504343)\">1.6</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_3\">\n",
       "     <g id=\"line2d_11\">\n",
       "      <path d=\"M 47.962344 140.087802  L 565.2 140.087802  \" clip-path=\"url(#p5d20eeedac)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_12\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m275d226f79\" x=\"47.962344\" y=\"140.087802\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_10\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"143.88663\" transform=\"rotate(-0 40.962344 143.88663)\">1.7</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_4\">\n",
       "     <g id=\"line2d_13\">\n",
       "      <path d=\"M 47.962344 115.470089  L 565.2 115.470089  \" clip-path=\"url(#p5d20eeedac)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_14\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m275d226f79\" x=\"47.962344\" y=\"115.470089\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_11\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"119.268917\" transform=\"rotate(-0 40.962344 119.268917)\">1.8</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_5\">\n",
       "     <g id=\"line2d_15\">\n",
       "      <path d=\"M 47.962344 90.852376  L 565.2 90.852376  \" clip-path=\"url(#p5d20eeedac)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_16\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m275d226f79\" x=\"47.962344\" y=\"90.852376\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_12\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"94.651204\" transform=\"rotate(-0 40.962344 94.651204)\">1.9</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"ytick_6\">\n",
       "     <g id=\"line2d_17\">\n",
       "      <path d=\"M 47.962344 66.234663  L 565.2 66.234663  \" clip-path=\"url(#p5d20eeedac)\" style=\"fill: none; stroke: #d4d8da; stroke-width: 0.6; stroke-linecap: square\"/>\n",
       "     </g>\n",
       "     <g id=\"line2d_18\">\n",
       "      <g>\n",
       "       <use xlink:href=\"#m275d226f79\" x=\"47.962344\" y=\"66.234663\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n",
       "      </g>\n",
       "     </g>\n",
       "     <g id=\"text_13\">\n",
       "      <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: end\" x=\"40.962344\" y=\"70.033491\" transform=\"rotate(-0 40.962344 70.033491)\">2.0</text>\n",
       "     </g>\n",
       "    </g>\n",
       "    <g id=\"text_14\">\n",
       "     <text style=\"font-size: 10px; font-family: 'DejaVu Sans'; text-anchor: middle\" x=\"18.656875\" y=\"127.778945\" transform=\"rotate(-90 18.656875 127.778945)\">total traveler time</text>\n",
       "    </g>\n",
       "   </g>\n",
       "   <g id=\"line2d_19\">\n",
       "    <path d=\"M 71.473146 189.323228  L 76.175307 189.310919  L 80.877467 189.273993  L 85.579628 189.212448  L 90.281788 189.126286  L 94.983949 189.015507  L 99.686109 188.880109  L 104.38827 188.720094  L 109.09043 188.535461  L 113.792591 188.326211  L 118.494751 188.092342  L 123.196912 187.833856  L 127.899072 187.550753  L 132.601233 187.243031  L 137.303393 186.910692  L 142.005554 186.553735  L 146.707714 186.172161  L 151.409875 185.765968  L 156.112036 185.335158  L 160.814196 184.879731  L 165.516357 184.399685  L 170.218517 183.895022  L 174.920678 183.365741  L 179.622838 182.811843  L 184.324999 182.233327  L 189.027159 181.630193  L 193.72932 181.002441  L 198.43148 180.350072  L 203.133641 179.673084  L 207.835801 178.97148  L 212.537962 178.245257  L 217.240122 177.494417  L 221.942283 176.718959  L 226.644443 175.918883  L 231.346604 175.09419  L 236.048764 174.244879  L 240.750925 173.37095  L 245.453085 172.472403  L 250.155246 171.549239  L 254.857406 170.601457  L 259.559567 169.629058  L 264.261727 168.63204  L 268.963888 167.610405  L 273.666048 166.564152  L 278.368209 165.493282  L 283.070369 164.397794  L 287.77253 163.277688  L 292.47469 162.132964  L 297.176851 160.963623  L 301.879011 159.769663  L 306.581172 158.551087  L 311.283332 157.307892  L 315.985493 156.04008  L 320.687653 154.74765  L 325.389814 153.430602  L 330.091974 152.088937  L 334.794135 150.722654  L 339.496295 149.331753  L 344.198456 147.916235  L 348.900616 146.476098  L 353.602777 145.011344  L 358.304937 143.521973  L 363.007098 142.007983  L 367.709259 140.469376  L 372.411419 138.906152  L 377.11358 137.318309  L 381.81574 135.705849  L 386.517901 134.068771  L 391.220061 132.407075  L 395.922222 130.720762  L 400.624382 129.009831  L 405.326543 127.274282  L 410.028703 125.514116  L 414.730864 123.729332  L 419.433024 121.91993  L 424.135185 120.08591  L 428.837345 118.227273  L 433.539506 116.344018  L 438.241666 114.436145  L 442.943827 112.503654  L 447.645987 110.546546  L 452.348148 108.56482  L 457.050308 106.558477  L 461.752469 104.527515  L 466.454629 102.471936  L 471.15679 100.39174  L 475.85895 98.286925  L 480.561111 96.157493  L 485.263271 94.003443  L 489.965432 91.824775  L 494.667592 89.62149  L 499.369753 87.393587  L 504.071913 85.141066  L 508.774074 82.863928  L 513.476234 80.562172  L 518.178395 78.235798  L 522.880555 75.884806  L 527.582716 73.509197  L 532.284876 71.10897  L 536.987037 68.684125  L 541.689197 66.234663  \" clip-path=\"url(#p5d20eeedac)\" style=\"fill: none; stroke: #31586b; stroke-width: 1.8; stroke-linecap: square\"/>\n",
       "   </g>\n",
       "   <g id=\"patch_3\">\n",
       "    <path d=\"M 47.962344 195.477656  L 47.962344 60.080234  \" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n",
       "   </g>\n",
       "   <g id=\"patch_4\">\n",
       "    <path d=\"M 47.962344 195.477656  L 565.2 195.477656  \" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n",
       "   </g>\n",
       "   <g id=\"text_15\">\n",
       "    <text style=\"font-size: 11px; font-family: 'DejaVu Sans'; text-anchor: start\" x=\"47.962344\" y=\"54.080234\" transform=\"rotate(-0 47.962344 54.080234)\">social travel cost</text>\n",
       "   </g>\n",
       "  </g>\n",
       "  <g id=\"text_16\">\n",
       "   <text style=\"font-size: 12px; font-family: 'DejaVu Sans'; text-anchor: start\" x=\"46.08\" y=\"13.870125\" transform=\"rotate(-0 46.08 13.870125)\">Chapter 21: congestion incentives</text>\n",
       "  </g>\n",
       " </g>\n",
       " <defs>\n",
       "  <clipPath id=\"p5d20eeedac\">\n",
       "   <rect x=\"47.962344\" y=\"60.080234\" width=\"517.237656\" height=\"135.397422\"/>\n",
       "  </clipPath>\n",
       " </defs>\n",
       "</svg>"
      ],
      "text/plain": [
       "<IPython.core.display.SVG object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "changed_inputs = {'demand': 1,\n",
    " 'capacity': 1,\n",
    " 'constant_time': 1,\n",
    " 'shortcut_overhead': 0,\n",
    " 'shortcut_toll': 0.5}\n",
    "changed = analyze(chapter, changed_inputs)\n",
    "changed['evidence_kind'] = 'constructed changed-assumption example'\n",
    "print(report_text(changed))\n",
    "display(SVG(figure_svg(changed)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bcb325454107",
   "metadata": {},
   "source": [
    "**Figure 21.L2:** The changed-assumption result. Compare the printed quantities and the stated assumptions with the first run. A different input need not imply a causal effect in a deployed agent."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91a47d118b9d",
   "metadata": {},
   "source": [
    "## Try a new case\n",
    "\n",
    "At demand 0.5, capacity 1, and constant delay 1, equilibrium sends all flow through the shortcut. Its total time is 0.5, below the no-shortcut total 0.625. The social optimum also uses shortcut flow 0.5, so price of anarchy is 1.\n",
    "\n",
    "For local workflow analysis, identify who selects routes and which costs they internalize. Separate routing overhead from incentive charges and preserve demand units. Compare local choice with a collective objective before adding a new interface. If route delays are estimated, collect measurements under several loads rather than assuming a linear congestion law."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "dd273a9b53be",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chapter 21: congestion-incentives\n",
      "Can a faster-looking route make the whole workflow slower?\n",
      "Evidence: constructed transfer example\n",
      "\n",
      "Calculated quantities:\n",
      "{\n",
      "  \"without_shortcut_total_time\": 0.625,\n",
      "  \"equilibrium_shortcut_flow\": 0.5,\n",
      "  \"equilibrium_outer_flow_each\": 0.0,\n",
      "  \"equilibrium_social_time\": 0.5,\n",
      "  \"equilibrium_private_outer_time\": 1.5,\n",
      "  \"equilibrium_private_shortcut_time\": 1.0,\n",
      "  \"optimal_shortcut_flow\": 0.5,\n",
      "  \"optimal_social_time\": 0.5,\n",
      "  \"price_of_anarchy\": 1.0,\n",
      "  \"braess_worsens\": false,\n",
      "  \"toll_revenue\": 0.0\n",
      "}\n",
      "\n",
      "Interpretation:\n",
      "A new route can change private incentives and increase total delay. Tolls enter private cost; toll payments are excluded from travel-time social cost.\n",
      "\n",
      "Assumptions:\n",
      "- Symmetric continuous flow, linear congestible edges, constant outer edges.\n",
      "- All travelers choose minimum private path cost at nonatomic equilibrium.\n",
      "\n",
      "Limitations:\n",
      "- This construction does not estimate a real workflow equilibrium.\n",
      "- Discrete teams and heterogeneous incentives need additional modeling.\n",
      "\n",
      "Execution: completed locally; constructed inputs are not deployment measurements.\n"
     ]
    }
   ],
   "source": [
    "transfer_inputs = {'demand': 0.5,\n",
    " 'capacity': 1,\n",
    " 'constant_time': 1,\n",
    " 'shortcut_overhead': 0,\n",
    " 'shortcut_toll': 0}\n",
    "transfer = analyze(chapter, transfer_inputs)\n",
    "transfer['evidence_kind'] = 'constructed transfer example'\n",
    "print(report_text(transfer))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c513e3454cd",
   "metadata": {},
   "source": [
    "## Apply the method to your inputs\n",
    "\n",
    "The example file below has the exact input shape the method accepts. Copy it to a new file, replace its values, then point `reader_file` at your copy. Run the cell again. Supplied inputs retain their stated provenance; the program cannot establish that they are representative observations.\n",
    "\n",
    "- **demand:** Positive continuous traveler or job flow in normalized units.\n",
    "- **capacity:** Positive flow scale of each linear congestible edge.\n",
    "- **constant_time:** Nonnegative fixed delay of each outer constant edge.\n",
    "- **shortcut_overhead:** Nonnegative real delay on the shortcut.\n",
    "- **shortcut_toll:** Nonnegative private incentive charge, excluded from travel-time social cost."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "15ee3bffbd28",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chapter 21: congestion-incentives\n",
      "Can a faster-looking route make the whole workflow slower?\n",
      "Evidence: supplied local inputs; provenance not independently verified\n",
      "\n",
      "Calculated quantities:\n",
      "{\n",
      "  \"without_shortcut_total_time\": 0.625,\n",
      "  \"equilibrium_shortcut_flow\": 0.5,\n",
      "  \"equilibrium_outer_flow_each\": 0.0,\n",
      "  \"equilibrium_social_time\": 0.5,\n",
      "  \"equilibrium_private_outer_time\": 1.5,\n",
      "  \"equilibrium_private_shortcut_time\": 1.0,\n",
      "  \"optimal_shortcut_flow\": 0.5,\n",
      "  \"optimal_social_time\": 0.5,\n",
      "  \"price_of_anarchy\": 1.0,\n",
      "  \"braess_worsens\": false,\n",
      "  \"toll_revenue\": 0.0\n",
      "}\n",
      "\n",
      "Interpretation:\n",
      "A new route can change private incentives and increase total delay. Tolls enter private cost; toll payments are excluded from travel-time social cost.\n",
      "\n",
      "Assumptions:\n",
      "- Symmetric continuous flow, linear congestible edges, constant outer edges.\n",
      "- All travelers choose minimum private path cost at nonatomic equilibrium.\n",
      "\n",
      "Limitations:\n",
      "- This construction does not estimate a real workflow equilibrium.\n",
      "- Discrete teams and heterogeneous incentives need additional modeling.\n",
      "\n",
      "Execution: completed locally; constructed inputs are not deployment measurements.\n"
     ]
    }
   ],
   "source": [
    "reader_file = LAB_ROOT / 'data/examples/ch21.json'\n",
    "reader_inputs = json.loads(reader_file.read_text())\n",
    "reader_report = analyze(chapter, reader_inputs)\n",
    "print(report_text(reader_report))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93f75333e8fe",
   "metadata": {},
   "source": [
    "## Questions\n",
    "\n",
    "1. Compute default price of anarchy.\n",
    "\n",
    "2. Why exclude toll revenue from social travel time?\n",
    "\n",
    "3. Compute transfer social optimum.\n",
    "\n",
    "Answers: [separate solutions](../solutions/ch21.md). Try the calculation before opening them."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f7445d25f6f",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "Local incentives and collective outcomes can diverge. The Braess construction makes that divergence exact: a shortcut worsens default equilibrium, a toll restores efficient routing, and low-demand transfer removes the paradox. The notebook distinguishes physical overhead from private incentive charges and compares equilibrium with a convex social optimum. Its conclusions depend on the supplied network form, continuous flow, and cost law. It does not infer how a real team will respond.\n",
    "\n",
    "Limits of this experiment:\n",
    "\n",
    "- This is a local calculation under declared inputs, not an empirical claim about a deployed agent.\n",
    "- Read the returned assumptions and limitations before applying the numerical result.\n",
    "\n",
    "The assistant skill is [`maa-21-congestion-incentives`](../skills/maa-21-congestion-incentives/SKILL.md). It uses this notebook's tested computation and input contract."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9cc9f25ba898",
   "metadata": {},
   "source": [
    "## Equations from the chapter\n",
    "\n",
    "These are the unchanged display equations and their explanations from the canonical chapter. They are a reference for the experiment, not a claim that every equation is numerically implemented by this one method."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aac160861da5",
   "metadata": {},
   "source": [
    "### Equation 21.1\n",
    "\n",
    "![Equation 21.1](../assets/math/789a238d6278b03f32dc.svg)\n",
    "\n",
    "Equation (21.1) adds each edge's delay across all flow using that edge, producing the system's total time.\n",
    "\n",
    "Multiply traffic on every edge by its experienced latency, then add the products over the whole network.\n",
    "\n",
    "LaTeX source, preserved for inspection:\n",
    "\n",
    "```latex\n",
    "\\operatorname{TL}(q) \\;=\\; \\sum_{e\\in\\mathcal E} q_e\\,\\ell_e(q_e).\n",
    "\\tag{21.1}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b422832800c",
   "metadata": {},
   "source": [
    "### Equation 21.2\n",
    "\n",
    "![Equation 21.2](../assets/math/c707158415fb2c2d45b6.svg)\n",
    "\n",
    "Equation (21.2) bounds self-directed routing's total delay against best feasible routing when every edge delay is linear.\n",
    "\n",
    "Divide equilibrium delay by optimal delay; under nonnegative straight-line latency rules, ratio never exceeds four thirds.\n",
    "\n",
    "LaTeX source, preserved for inspection:\n",
    "\n",
    "```latex\n",
    "\\frac{\\operatorname{TL}(q^{\\mathrm{NE}})}{\\operatorname{TL}(q^{\\star})} \\;\\leq\\; \\frac{4}{3}\n",
    "\\qquad\\text{when every }\\ell_e(q_e)=a_e q_e+b_e\\text{ with }a_e,b_e\\geq0.\n",
    "\\tag{21.2}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d324cfd3fe9",
   "metadata": {},
   "source": [
    "### Equation 21.3\n",
    "\n",
    "![Equation 21.3](../assets/math/0d9a15c23069ca305b11.svg)\n",
    "\n",
    "Equation (21.3) converts an edge's experienced delay into a local price that includes congestion imposed on existing users.\n",
    "\n",
    "Add the direct delay to flow times its slope; for straight-line delay, double only the congestion term.\n",
    "\n",
    "LaTeX source, preserved for inspection:\n",
    "\n",
    "```latex\n",
    "\\ell^{\\mathrm{mc}}_e(q_e) \\;=\\; \\ell_e(q_e)+q_e\\ell'_e(q_e),\n",
    "\\qquad\n",
    "\\ell_e(q_e)=a_e q_e+b_e\\;\\Longrightarrow\\;\\ell^{\\mathrm{mc}}_e(q_e)=2a_e q_e+b_e.\n",
    "\\tag{21.3}\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Mathematics of AI Agents",
   "language": "python",
   "name": "maa-lab"
  },
  "lab_chapter": 21,
  "lab_execution": {
   "code_cells": 6,
   "created_utc": "2026-10-02T05:16:05.318833+00:00",
   "elapsed_seconds": 8.971499166917056,
   "method": "fresh process; new ipykernel InProcessKernelManager; cells submitted as Jupyter execute requests",
   "network_transport_tested": false,
   "python": "3.11.15",
   "source_sha256": "3852c283b08d8c766153fe9a95ac6c0662a90c2438aaa0c02cfe44bb127a7588"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
