<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>The Nightly Build</title>
  <link rel="self" type="application/atom+xml" href="https://ryansaxe.github.io/the-nightly-build/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/"/>
  <id>tag:ryansaxe.github.io,2026:the-nightly-build/feed.xml</id>
  <author><name>The Nightly Build</name></author>
  <updated>2026-11-04T07:38:22Z</updated>
  <entry>
    <title>Muon&#x27;s fine-tuning lead runs out after a similar token count at every size tested</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/muon-fine-tuning-crossover.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/muon-fine-tuning-crossover</id>
    <updated>2026-11-04T06:54:11Z</updated>
    <summary>Across a CMU preprint&#x27;s 30M-to-600M models, AdamW pretraining takes the lead between 2.4 and 19.2 billion tokens, and production models pretrained with Muon have seen trillions.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Feature&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;Muon&#x27;s fine-tuning lead runs out after a similar token count at every size tested&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;Across a CMU preprint&#x27;s 30M-to-600M models, AdamW pretraining takes the lead between 2.4 and 19.2 billion tokens, and production models pretrained with Muon have seen trillions.&lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;5 min read&lt;/span&gt;&lt;span&gt;2026-11-04&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section data-nb-section=&quot;orientation&quot; id=&quot;orientation&quot;&gt;
        &lt;h2&gt;Muon pretrains better and still loses the fine-tuning trade&lt;/h2&gt;
        &lt;p&gt;
          In a CMU preprint covering about 600 pretraining runs from 30M to
          600M parameters,
          &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/the-paper/muon-optimizer.html&quot;&gt;Muon&lt;/a&gt; reaches lower
          pretraining loss than AdamW in every cell. Past a crossover budget,
          though, the AdamW-pretrained model learns a fine-tuning task with
          less forgetting.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          The authors report that crossover as a token-to-parameter ratio that
          falls as models grow. Counted in tokens, all 20 of their crossovers
          sit between 2.4 and 19.2 billion. Every Muon-pretrained production
          model with published counts has seen about 300 times as many or
          more, at sizes the paper never ran.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;where-adamws-frontier-pulls-ahead&quot; id=&quot;where-adamws-frontier-pulls-ahead&quot;&gt;
        &lt;h2&gt;Where AdamW&#x27;s frontier pulls ahead&lt;/h2&gt;
        &lt;p&gt;
          The paper fine-tunes each optimizer&#x27;s lowest-pretraining-loss 60M
          model on StackMathQA across a sweep of learning rates. Each run gives
          a fine-tuning loss and a forgetting loss on held-out DCLM text, and
          the lower-left hull of those points is the
          frontier.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
          &lt;img
            src=&quot;muon-fine-tuning-crossover/figure-1.png&quot;
            alt=&quot;Four panels of fine-tuning loss against forgetting for 60M models fine-tuned on StackMathQA, at 2.4B, 9.6B, 19.2B and 38.4B pretraining tokens. At 2.4B the Muon curve lies below and left of the AdamW curve; in the other three panels the AdamW curve lies below and left of Muon&#x27;s.&quot;
          /&gt;
          &lt;figcaption&gt;
            Fig. 1 · Learning–forgetting frontiers of the lowest-loss 60M base
            models on StackMathQA, in nats. Lower-left is better. Preprint
            Figure 1.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          At 2.4 billion pretraining tokens Muon&#x27;s curve sits below AdamW&#x27;s
          along its whole length. By 9.6 billion the curves have swapped. The
          crossover is the smallest budget on the paper&#x27;s doubling grid where
          AdamW&#x27;s frontier wins, here 4.8 billion tokens, or 80 per parameter.
          Muon-pretrained models are fine-tuned with both optimizers and the
          runs pooled, so the fine-tuning optimizer does not handicap
          them.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          The authors explain the reversal with a margin-to-spread ratio: the
          correct logit&#x27;s mean lead over the wrong ones, divided by the wrong
          logits&#x27; spread. The larger it is, the more wrong answers stay below
          the right one when fine-tuning perturbs the outputs, and AdamW&#x27;s
          overtakes Muon&#x27;s as the budget grows. Their theorem compares Muon
          with gradient descent, not AdamW, and covers the budget reversal but
          not the fall with size.&lt;sup class=&quot;nb-cite&quot;
            &gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup
          &gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;twenty-crossovers-inside-one-token-band&quot; id=&quot;twenty-crossovers-inside-one-token-band&quot;&gt;
        &lt;h2&gt;Twenty crossovers inside one token band&lt;/h2&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
          &lt;div style=&quot;display: flex; flex-wrap: wrap; gap: 1rem&quot;&gt;
          &lt;svg viewBox=&quot;0 0 400 300&quot; role=&quot;img&quot; aria-label=&quot;Crossover tokens per parameter against model size, log-log, for four fine-tuning sets. Values fall from 80 to 640 at 30M to 5 to 20 at 600M, inside a diagonal band of constant token count from 2.4 to 19.2 billion.&quot; style=&quot;flex: 1 1 18rem; min-width: 0; height: auto&quot;&gt;
          &lt;text x=&quot;56&quot; y=&quot;16&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 13.5px; font-weight: 600&quot;&gt;Tokens per parameter&lt;/text&gt;
          &lt;line x1=&quot;52&quot; y1=&quot;36&quot; x2=&quot;72&quot; y2=&quot;36&quot; style=&quot;stroke: var(--chart-1); stroke-width: 1.8&quot;/&gt;
          &lt;circle cx=&quot;62&quot; cy=&quot;36&quot; r=&quot;3.6&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;text x=&quot;77&quot; y=&quot;40&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 12px&quot;&gt;Alpaca&lt;/text&gt;
          &lt;line x1=&quot;124&quot; y1=&quot;36&quot; x2=&quot;144&quot; y2=&quot;36&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.8; stroke-dasharray: 5 3&quot;/&gt;
          &lt;rect x=&quot;130.9&quot; y=&quot;32.9&quot; width=&quot;6.1&quot; height=&quot;6.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;text x=&quot;149&quot; y=&quot;40&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 12px&quot;&gt;GSM8K&lt;/text&gt;
          &lt;line x1=&quot;198&quot; y1=&quot;36&quot; x2=&quot;218&quot; y2=&quot;36&quot; style=&quot;stroke: var(--chart-3); stroke-width: 1.8; stroke-dasharray: 1.5 2.5&quot;/&gt;
          &lt;polygon points=&quot;208,31.1 212.9,36 208,40.9 203.1,36&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;text x=&quot;223&quot; y=&quot;40&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 12px&quot;&gt;MusicPile&lt;/text&gt;
          &lt;line x1=&quot;288&quot; y1=&quot;36&quot; x2=&quot;308&quot; y2=&quot;36&quot; style=&quot;stroke: var(--chart-4); stroke-width: 1.8; stroke-dasharray: 7 3 1.5 3&quot;/&gt;
          &lt;polygon points=&quot;298,31.3 302.7,39.5 293.3,39.5&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;text x=&quot;313&quot; y=&quot;40&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 12px&quot;&gt;StackMathQA&lt;/text&gt;
          &lt;clipPath id=&quot;clip-fig2-tpr&quot;&gt;&lt;rect x=&quot;56&quot; y=&quot;54&quot; width=&quot;332&quot; height=&quot;196&quot;/&gt;&lt;/clipPath&gt;
          &lt;polygon points=&quot;56,132 388,254.7 388,180.8 56,58.2&quot; clip-path=&quot;url(#clip-fig2-tpr)&quot; style=&quot;fill: var(--ink-soft); fill-opacity: 0.13&quot;/&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;238.3&quot; x2=&quot;388&quot; y2=&quot;238.3&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;242.3&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;5&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;213.7&quot; x2=&quot;388&quot; y2=&quot;213.7&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;217.7&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;10&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;189.1&quot; x2=&quot;388&quot; y2=&quot;189.1&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;193.1&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;20&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;164.5&quot; x2=&quot;388&quot; y2=&quot;164.5&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;168.5&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;40&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;139.9&quot; x2=&quot;388&quot; y2=&quot;139.9&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;143.9&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;80&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;115.3&quot; x2=&quot;388&quot; y2=&quot;115.3&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;119.3&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;160&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;90.7&quot; x2=&quot;388&quot; y2=&quot;90.7&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;94.7&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;320&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;66.1&quot; x2=&quot;388&quot; y2=&quot;66.1&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;70.1&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;640&lt;/text&gt;
          &lt;line x1=&quot;77.4&quot; y1=&quot;54&quot; x2=&quot;77.4&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;77.4&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;30M&lt;/text&gt;
          &lt;line x1=&quot;144&quot; y1=&quot;54&quot; x2=&quot;144&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;144&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;60M&lt;/text&gt;
          &lt;line x1=&quot;193.1&quot; y1=&quot;54&quot; x2=&quot;193.1&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;193.1&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;100M&lt;/text&gt;
          &lt;line x1=&quot;298.7&quot; y1=&quot;54&quot; x2=&quot;298.7&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;298.7&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;300M&lt;/text&gt;
          &lt;line x1=&quot;365.3&quot; y1=&quot;54&quot; x2=&quot;365.3&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;365.3&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;600M&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;250&quot; x2=&quot;388&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.6; stroke-width: 0.8&quot;/&gt;
          &lt;text x=&quot;222.0&quot; y=&quot;286&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 12px&quot;&gt;Parameters&lt;/text&gt;
          &lt;polyline points=&quot;67.3,115.3 133.9,139.9 183,139.9 288.6,164.5 355.2,189.1&quot; style=&quot;fill: none; stroke: var(--chart-1); stroke-width: 1.8&quot;/&gt;
          &lt;circle cx=&quot;67.3&quot; cy=&quot;115.3&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;133.9&quot; cy=&quot;139.9&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;183&quot; cy=&quot;139.9&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;288.6&quot; cy=&quot;164.5&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;355.2&quot; cy=&quot;189.1&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;polyline points=&quot;74,139.9 140.6,139.9 189.7,164.5 295.3,213.7 361.9,238.3&quot; style=&quot;fill: none; stroke: var(--chart-2); stroke-width: 1.8; stroke-dasharray: 5 3&quot;/&gt;
          &lt;rect x=&quot;70.4&quot; y=&quot;136.3&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;137&quot; y=&quot;136.3&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;186.1&quot; y=&quot;161&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;291.7&quot; y=&quot;210.2&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;358.3&quot; y=&quot;234.8&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;polyline points=&quot;80.7,66.1 147.3,139.9 196.4,139.9 302,164.5 368.6,213.7&quot; style=&quot;fill: none; stroke: var(--chart-3); stroke-width: 1.8; stroke-dasharray: 1.5 2.5&quot;/&gt;
          &lt;polygon points=&quot;80.7,60.4 86.4,66.1 80.7,71.8 75.1,66.1&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;147.3,134.2 153,139.9 147.3,145.6 141.7,139.9&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;196.4,134.2 202.1,139.9 196.4,145.6 190.8,139.9&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;302,158.9 307.7,164.5 302,170.2 296.3,164.5&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;368.6,208.1 374.3,213.7 368.6,219.4 362.9,213.7&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polyline points=&quot;87.5,90.7 154.1,139.9 203.2,164.5 308.7,189.1 375.3,213.7&quot; style=&quot;fill: none; stroke: var(--chart-4); stroke-width: 1.8; stroke-dasharray: 7 3 1.5 3&quot;/&gt;
          &lt;polygon points=&quot;87.5,85.2 92.9,94.8 82,94.8&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;154.1,134.5 159.5,144 148.6,144&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;203.2,159.1 208.6,168.6 197.7,168.6&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;308.7,183.7 314.2,193.2 303.3,193.2&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;375.3,208.3 380.8,217.8 369.9,217.8&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;circle cx=&quot;361.9&quot; cy=&quot;238.3&quot; r=&quot;9&quot; style=&quot;fill: none; stroke: var(--ink); stroke-width: 1.2&quot;/&gt;
          &lt;/svg&gt;
          &lt;svg viewBox=&quot;0 0 400 300&quot; role=&quot;img&quot; aria-label=&quot;The same 20 crossovers converted to billions of tokens against model size, log-log. Every point lies in a flat band from 2.4 to 19.2 billion tokens.&quot; style=&quot;flex: 1 1 18rem; min-width: 0; height: auto&quot;&gt;
          &lt;text x=&quot;56&quot; y=&quot;16&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 13.5px; font-weight: 600&quot;&gt;Billions of tokens&lt;/text&gt;
          &lt;clipPath id=&quot;clip-fig2-tokens&quot;&gt;&lt;rect x=&quot;56&quot; y=&quot;54&quot; width=&quot;332&quot; height=&quot;196&quot;/&gt;&lt;/clipPath&gt;
          &lt;polygon points=&quot;56,225.6 388,225.6 388,78.2 56,78.2&quot; clip-path=&quot;url(#clip-fig2-tokens)&quot; style=&quot;fill: var(--ink-soft); fill-opacity: 0.13&quot;/&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;225.6&quot; x2=&quot;388&quot; y2=&quot;225.6&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;229.6&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;2.4B&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;176.4&quot; x2=&quot;388&quot; y2=&quot;176.4&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;180.4&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;4.8B&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;127.3&quot; x2=&quot;388&quot; y2=&quot;127.3&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;131.3&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;9.6B&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;78.2&quot; x2=&quot;388&quot; y2=&quot;78.2&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;51&quot; y=&quot;82.2&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;19.2B&lt;/text&gt;
          &lt;line x1=&quot;77.4&quot; y1=&quot;54&quot; x2=&quot;77.4&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;77.4&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;30M&lt;/text&gt;
          &lt;line x1=&quot;144&quot; y1=&quot;54&quot; x2=&quot;144&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;144&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;60M&lt;/text&gt;
          &lt;line x1=&quot;193.1&quot; y1=&quot;54&quot; x2=&quot;193.1&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;193.1&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;100M&lt;/text&gt;
          &lt;line x1=&quot;298.7&quot; y1=&quot;54&quot; x2=&quot;298.7&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;298.7&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;300M&lt;/text&gt;
          &lt;line x1=&quot;365.3&quot; y1=&quot;54&quot; x2=&quot;365.3&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;365.3&quot; y=&quot;266&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;600M&lt;/text&gt;
          &lt;line x1=&quot;56&quot; y1=&quot;250&quot; x2=&quot;388&quot; y2=&quot;250&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.6; stroke-width: 0.8&quot;/&gt;
          &lt;text x=&quot;222.0&quot; y=&quot;286&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 12px&quot;&gt;Parameters&lt;/text&gt;
          &lt;text x=&quot;384&quot; y=&quot;73.2&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;2.4B–19.2B tokens&lt;/text&gt;
          &lt;polyline points=&quot;67.3,176.4 133.9,176.4 183,140.2 288.6,111.5 355.2,111.5&quot; style=&quot;fill: none; stroke: var(--chart-1); stroke-width: 1.8&quot;/&gt;
          &lt;circle cx=&quot;67.3&quot; cy=&quot;176.4&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;133.9&quot; cy=&quot;176.4&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;183&quot; cy=&quot;140.2&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;288.6&quot; cy=&quot;111.5&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;355.2&quot; cy=&quot;111.5&quot; r=&quot;4.2&quot; style=&quot;fill: var(--chart-1); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/circle&gt;
          &lt;polyline points=&quot;74,225.6 140.6,176.4 189.7,189.3 295.3,209.7 361.9,209.7&quot; style=&quot;fill: none; stroke: var(--chart-2); stroke-width: 1.8; stroke-dasharray: 5 3&quot;/&gt;
          &lt;rect x=&quot;70.4&quot; y=&quot;222&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;137&quot; y=&quot;172.9&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;186.1&quot; y=&quot;185.8&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;291.7&quot; y=&quot;206.2&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;rect x=&quot;358.3&quot; y=&quot;206.2&quot; width=&quot;7.1&quot; height=&quot;7.1&quot; style=&quot;fill: var(--chart-2); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/rect&gt;
          &lt;polyline points=&quot;80.7,78.2 147.3,176.4 196.4,140.2 302,111.5 368.6,160.6&quot; style=&quot;fill: none; stroke: var(--chart-3); stroke-width: 1.8; stroke-dasharray: 1.5 2.5&quot;/&gt;
          &lt;polygon points=&quot;80.7,72.5 86.4,78.2 80.7,83.8 75.1,78.2&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;147.3,170.8 153,176.4 147.3,182.1 141.7,176.4&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;196.4,134.5 202.1,140.2 196.4,145.9 190.8,140.2&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;302,105.8 307.7,111.5 302,117.1 296.3,111.5&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;368.6,154.9 374.3,160.6 368.6,166.3 362.9,160.6&quot; style=&quot;fill: var(--chart-3); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polyline points=&quot;87.5,127.3 154.1,176.4 203.2,189.3 308.7,160.6 375.3,160.6&quot; style=&quot;fill: none; stroke: var(--chart-4); stroke-width: 1.8; stroke-dasharray: 7 3 1.5 3&quot;/&gt;
          &lt;polygon points=&quot;87.5,121.8 92.9,131.4 82,131.4&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;154.1,171 159.5,180.5 148.6,180.5&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;203.2,183.9 208.6,193.4 197.7,193.4&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;308.7,155.2 314.2,164.7 303.3,164.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;375.3,155.2 380.8,164.7 369.9,164.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;circle cx=&quot;361.9&quot; cy=&quot;209.7&quot; r=&quot;9&quot; style=&quot;fill: none; stroke: var(--ink); stroke-width: 1.2&quot;/&gt;
          &lt;/svg&gt;
          &lt;/div&gt;
          &lt;figcaption&gt;
            Fig. 2 · The preprint&#x27;s Table 2 crossovers, per parameter and in
            tokens, on log scales. Points are offset sideways. The ringed
            600M GSM8K value is the smallest budget run, so the true crossover
            is at or below it.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          StackMathQA&#x27;s crossover is 320 tokens per parameter at 30M and 10 at
          600M.&lt;sup class=&quot;nb-cite&quot;
            &gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup
          &gt;
          In tokens those are 9.6 and 6.0 billion. A least-squares fit of log
          crossover ratio against log size over all 20 cells has a slope of
          −0.97, and a crossover fixed in tokens would give exactly −1. The
          paper does not make this observation.
        &lt;/p&gt;
        &lt;p&gt;
          The fit is not tight. From 30M to 600M the ratio falls 8-fold on
          Alpaca and 64-fold on MusicPile, and Alpaca&#x27;s token crossover rises
          from 4.8 to 12 billion. Each value is a point on a doubling grid,
          from one base model per optimizer, with no seeds or error
          bars.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          Across the 20 cells the ratios vary 128-fold and the token counts
          8-fold.
        &lt;/p&gt;
        &lt;p&gt;
          At the Chinchilla-optimal 20 tokens per parameter, a 600M model has
          seen 12 billion tokens and is at or past its crossover on all four
          sets.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;production-models-on-either-parameter-count&quot; id=&quot;production-models-on-either-parameter-count&quot;&gt;
        &lt;h2&gt;Production models, on either parameter count&lt;/h2&gt;
        &lt;p&gt;
          Kimi K2, a mixture-of-experts model, was pretrained on 15.5 trillion
          tokens: 475 per active parameter and 15 per total parameter.&lt;sup class=&quot;nb-cite&quot;
            &gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup
          &gt;
        &lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
          &lt;svg viewBox=&quot;0 0 400 325&quot; role=&quot;img&quot; aria-label=&quot;Dot plot. Rows: the paper&#x27;s measured crossovers at 30M to 300M and at 600M, then eight Muon-pretrained production models. Left: tokens per parameter on a log scale; each model spans from its total-parameter ratio to its active-parameter ratio, from 15 for Kimi K2&#x27;s total up to 10,000 for Trinity Nano&#x27;s active count, while the 600M crossovers sit at 5 to 20. Right: pretraining tokens on a log scale; crossovers sit between 2.4 and 19.2 billion and every production model between 5.7 and 28.5 trillion.&quot; style=&quot;display: block; width: 100%; max-width: 34rem; margin: 0 auto; height: auto&quot;&gt;
          &lt;text x=&quot;172.0&quot; y=&quot;16&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 12.5px; font-weight: 600&quot;&gt;Tokens per parameter&lt;/text&gt;
          &lt;text x=&quot;323.0&quot; y=&quot;16&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 12.5px; font-weight: 600&quot;&gt;Pretraining tokens&lt;/text&gt;
          &lt;polygon points=&quot;10,31.1 14.9,39.7 5.1,39.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;text x=&quot;18&quot; y=&quot;40&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;Measured crossover&lt;/text&gt;
          &lt;circle cx=&quot;150&quot; cy=&quot;36&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;/&gt;
          &lt;text x=&quot;158&quot; y=&quot;40&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;Active params&lt;/text&gt;
          &lt;circle cx=&quot;256&quot; cy=&quot;36&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;text x=&quot;264&quot; y=&quot;40&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11.5px&quot;&gt;Total params&lt;/text&gt;
          &lt;line x1=&quot;109.8&quot; y1=&quot;54&quot; x2=&quot;109.8&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;109.8&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;5&lt;/text&gt;
          &lt;line x1=&quot;132.1&quot; y1=&quot;54&quot; x2=&quot;132.1&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;132.1&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;20&lt;/text&gt;
          &lt;line x1=&quot;158.1&quot; y1=&quot;54&quot; x2=&quot;158.1&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;158.1&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;100&lt;/text&gt;
          &lt;line x1=&quot;188.1&quot; y1=&quot;54&quot; x2=&quot;188.1&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;188.1&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;640&lt;/text&gt;
          &lt;line x1=&quot;232.4&quot; y1=&quot;54&quot; x2=&quot;232.4&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;232.4&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;10k&lt;/text&gt;
          &lt;line x1=&quot;281.4&quot; y1=&quot;54&quot; x2=&quot;281.4&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;281.4&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;10B&lt;/text&gt;
          &lt;line x1=&quot;311.1&quot; y1=&quot;54&quot; x2=&quot;311.1&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;311.1&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;100B&lt;/text&gt;
          &lt;line x1=&quot;340.8&quot; y1=&quot;54&quot; x2=&quot;340.8&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;340.8&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;1T&lt;/text&gt;
          &lt;line x1=&quot;370.6&quot; y1=&quot;54&quot; x2=&quot;370.6&quot; y2=&quot;303&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;370.6&quot; y=&quot;318&quot; text-anchor=&quot;middle&quot; style=&quot;fill: var(--ink-soft); font-family: var(--sans); font-size: 11px&quot;&gt;10T&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;66&quot; x2=&quot;240&quot; y2=&quot;66&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;66&quot; x2=&quot;390&quot; y2=&quot;66&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;70&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Paper, 30M–300M&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;91&quot; x2=&quot;240&quot; y2=&quot;91&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;91&quot; x2=&quot;390&quot; y2=&quot;91&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;95&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Paper, 600M&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;116&quot; x2=&quot;240&quot; y2=&quot;116&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;116&quot; x2=&quot;390&quot; y2=&quot;116&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;120&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Moonlight&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;141&quot; x2=&quot;240&quot; y2=&quot;141&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;141&quot; x2=&quot;390&quot; y2=&quot;141&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;145&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Kimi Linear&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;166&quot; x2=&quot;240&quot; y2=&quot;166&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;166&quot; x2=&quot;390&quot; y2=&quot;166&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;170&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Trinity Nano&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;191&quot; x2=&quot;240&quot; y2=&quot;191&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;191&quot; x2=&quot;390&quot; y2=&quot;191&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;195&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Trinity Mini&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;216&quot; x2=&quot;240&quot; y2=&quot;216&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;216&quot; x2=&quot;390&quot; y2=&quot;216&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;220&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Kimi K2&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;241&quot; x2=&quot;240&quot; y2=&quot;241&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;241&quot; x2=&quot;390&quot; y2=&quot;241&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;245&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;Trinity Large&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;266&quot; x2=&quot;240&quot; y2=&quot;266&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;266&quot; x2=&quot;390&quot; y2=&quot;266&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;270&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;GLM-4.5&lt;/text&gt;
          &lt;line x1=&quot;104&quot; y1=&quot;291&quot; x2=&quot;240&quot; y2=&quot;291&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;line x1=&quot;256&quot; y1=&quot;291&quot; x2=&quot;390&quot; y2=&quot;291&quot; style=&quot;stroke: var(--ink-soft); stroke-opacity: 0.22; stroke-width: 0.6&quot;/&gt;
          &lt;text x=&quot;96&quot; y=&quot;295&quot; text-anchor=&quot;end&quot; style=&quot;fill: var(--ink); font-family: var(--sans); font-size: 11px&quot;&gt;GLM-5&lt;/text&gt;
          &lt;polygon points=&quot;165.7,61.1 170.6,69.7 160.7,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;271.9,61.1 276.8,69.7 267,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;154.5,61.1 159.4,69.7 149.6,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;263,61.1 267.9,69.7 258,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;188.1,61.1 193,69.7 183.1,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;289.8,61.1 294.7,69.7 284.9,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;176.9,61.1 181.8,69.7 171.9,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;280.9,61.1 285.8,69.7 275.9,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;278.5,61.1 283.4,69.7 273.6,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;143.3,61.1 148.3,69.7 138.4,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;269.6,61.1 274.5,69.7 264.6,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;283.7,61.1 288.7,69.7 278.8,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;120.9,61.1 125.9,69.7 116,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;265.8,61.1 270.8,69.7 260.9,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;132.1,61.1 137.1,69.7 127.2,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;274.8,61.1 279.7,69.7 269.9,69.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;132.1,86.1 137.1,94.7 127.2,94.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;283.7,86.1 288.7,94.7 278.8,94.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;109.8,86.1 114.7,94.7 104.8,94.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;265.8,86.1 270.8,94.7 260.9,94.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;120.9,86.1 125.9,94.7 116,94.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;polygon points=&quot;274.8,86.1 279.7,94.7 269.9,94.7&quot; style=&quot;fill: var(--chart-4); stroke: var(--panel); stroke-width: 0.8&quot;&gt;&lt;/polygon&gt;
          &lt;line x1=&quot;179.3&quot; y1=&quot;116&quot; x2=&quot;210.3&quot; y2=&quot;116&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;210.3&quot; cy=&quot;116&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;179.3&quot; cy=&quot;116&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;363.3&quot; cy=&quot;116&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;line x1=&quot;160.9&quot; y1=&quot;141&quot; x2=&quot;205.6&quot; y2=&quot;141&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;205.6&quot; cy=&quot;141&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;160.9&quot; cy=&quot;141&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;363.3&quot; cy=&quot;141&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;line x1=&quot;203.5&quot; y1=&quot;166&quot; x2=&quot;232.4&quot; y2=&quot;166&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;232.4&quot; cy=&quot;166&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;203.5&quot; cy=&quot;166&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;370.6&quot; cy=&quot;166&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;line x1=&quot;179.8&quot; y1=&quot;191&quot; x2=&quot;214.7&quot; y2=&quot;191&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;214.7&quot; cy=&quot;191&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;179.8&quot; cy=&quot;191&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;370.6&quot; cy=&quot;191&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;line x1=&quot;127.4&quot; y1=&quot;216&quot; x2=&quot;183.3&quot; y2=&quot;216&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;183.3&quot; cy=&quot;216&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;127.4&quot; cy=&quot;216&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;376.2&quot; cy=&quot;216&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;line x1=&quot;144.3&quot; y1=&quot;241&quot; x2=&quot;199.6&quot; y2=&quot;241&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;199.6&quot; cy=&quot;241&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;144.3&quot; cy=&quot;241&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;377.4&quot; cy=&quot;241&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;line x1=&quot;151.1&quot; y1=&quot;266&quot; x2=&quot;189.9&quot; y2=&quot;266&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;189.9&quot; cy=&quot;266&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;151.1&quot; cy=&quot;266&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;381.3&quot; cy=&quot;266&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;line x1=&quot;142.6&quot; y1=&quot;291&quot; x2=&quot;189.8&quot; y2=&quot;291&quot; style=&quot;stroke: var(--chart-2); stroke-width: 1.6&quot;/&gt;
          &lt;circle cx=&quot;189.8&quot; cy=&quot;291&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;142.6&quot; cy=&quot;291&quot; r=&quot;3.6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-2); stroke-width: 1.6&quot;&gt;&lt;/circle&gt;
          &lt;circle cx=&quot;384.1&quot; cy=&quot;291&quot; r=&quot;4&quot; style=&quot;fill: var(--chart-2)&quot;&gt;&lt;/circle&gt;
          &lt;/svg&gt;
          &lt;figcaption&gt;
            Fig. 3 · Measured crossovers&lt;sup class=&quot;nb-cite&quot;
              &gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup
            &gt;
            against published counts for Moonlight,&lt;sup class=&quot;nb-cite&quot;
              &gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup
            &gt;
            Kimi Linear,&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;
            Trinity,&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
            Kimi K2,&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
            GLM-4.5&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;
            and GLM-5,&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;
            on log scales. Ratios are our computation.
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          On the ratio scale, K2&#x27;s total-parameter ratio falls below the 600M
          Alpaca crossover of 20, the only placement the convention changes.
          On the token scale the convention drops out. Every model sits
          between 5.7 and 28.5 trillion tokens, about 300 to 1,500 times the
          largest measured crossover.
        &lt;/p&gt;
        &lt;p&gt;
          None of these placements is tested. The production models are
          mixture-of-experts, with up to 67 times the active parameters
          of the paper&#x27;s largest dense model. The preprint names Kimi K2 and
          GLM-4.5 as Muon-pretrained but says of scale only that the falling crossover “suggests that the problem
          persists as we scale.”&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;moonlights-twin-runs-point-the-other-way&quot; id=&quot;moonlights-twin-runs-point-the-other-way&quot;&gt;
        &lt;h2&gt;Moonlight&#x27;s twin runs point the other way&lt;/h2&gt;
        &lt;p&gt;
          Moonshot AI&#x27;s report on Moonlight has the one matched comparison at
          production scale. Moonlight-A “follows the same training settings as
          Moonlight, except that it uses the AdamW optimizer.” Both
          1.2-trillion-token checkpoints were fine-tuned with each
          optimizer.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;table class=&quot;nb-table&quot;&gt;
          &lt;caption&gt;
            Moonlight (2.24B active, 15.29B total) after SFT, from Table 6 of
            its report.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
          &lt;/caption&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th class=&quot;txt&quot;&gt;Pretrain / SFT&lt;/th&gt;
              &lt;th&gt;MMLU&lt;/th&gt;
              &lt;th&gt;HumanEval&lt;/th&gt;
              &lt;th&gt;MBPP&lt;/th&gt;
              &lt;th&gt;GSM8K&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;Muon / Muon&lt;/td&gt;
              &lt;td&gt;55.7&lt;/td&gt;
              &lt;td&gt;57.3&lt;/td&gt;
              &lt;td&gt;55.6&lt;/td&gt;
              &lt;td&gt;68.0&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;AdamW / Muon&lt;/td&gt;
              &lt;td&gt;55.3&lt;/td&gt;
              &lt;td&gt;53.7&lt;/td&gt;
              &lt;td&gt;55.5&lt;/td&gt;
              &lt;td&gt;62.1&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;Muon / AdamW&lt;/td&gt;
              &lt;td&gt;50.2&lt;/td&gt;
              &lt;td&gt;52.4&lt;/td&gt;
              &lt;td&gt;55.2&lt;/td&gt;
              &lt;td&gt;64.9&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;AdamW / AdamW&lt;/td&gt;
              &lt;td&gt;52.0&lt;/td&gt;
              &lt;td&gt;53.1&lt;/td&gt;
              &lt;td&gt;55.2&lt;/td&gt;
              &lt;td&gt;64.6&lt;/td&gt;
            &lt;/tr&gt;
          &lt;/tbody&gt;
        &lt;/table&gt;
        &lt;p&gt;
          Paired the way the preprint pairs them, AdamW with AdamW and Muon
          with its best, the Muon pipeline wins all four benchmarks at 62
          times the top of the token band. With AdamW fine-tuning on both, the result splits. The
          test has one run per arm and measures no forgetting. Its checkpoints
          also predate cooldown, and Wen and colleagues found that optimizer
          rankings at intermediate checkpoints can flip once the learning rate
          decays.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          The preprint, a single version-1 release, sweeps only the peak
          learning rate and fixes weight decay at 0.1 for both optimizers. Its
          authors hypothesize that the falling crossover comes partly from
          Muon&#x27;s shrinking pretraining advantage,&lt;sup class=&quot;nb-cite&quot;
            &gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup
          &gt;
          which a second paper from Wen&#x27;s group observes “when using standard
          constant decoupled weight decay,” the preprint&#x27;s setting.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s9&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          For dense models from 30M to 600M, AdamW pretraining gives the
          better learning–forgetting trade by 19.2 billion tokens at every
          size. Production models sit trillions of tokens further on, where
          the one matched test favored Muon without measuring forgetting.
          Until someone
          measures held-out pretraining loss after fine-tuning a matched pair
          that large, the reversal is a finding about models under a billion
          parameters.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Sections 1, 3.2 and 4; Figure 1 (p. 2); Table 2 (p. 32); Appendices A.3, C.1–C.5&quot;
              href=&quot;https://arxiv.org/abs/2611.03633&quot;
              &gt;Li et al., Carnegie Mellon · Pretraining Data Scale Reverses the Muon-AdamW Fine-Tuning Gap, arXiv 2611.03633v1&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Table 2 (p. 6); Sections 2.5 and 3.1 (p. 9)&quot;
              href=&quot;https://arxiv.org/abs/2507.20534&quot;
              &gt;Moonshot AI · Kimi K2: Open Agentic Intelligence, arXiv 2507.20534&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s3&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Section 3.3 (p. 7); Table 6 (p. 10)&quot;
              href=&quot;https://arxiv.org/abs/2502.16982&quot;
              &gt;Moonshot AI · Muon is Scalable for LLM Training, arXiv 2502.16982&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s4&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Abstract; Section 5.4.1 (p. 10)&quot;
              href=&quot;https://arxiv.org/abs/2510.26692&quot;
              &gt;Moonshot AI · Kimi Linear: An Expressive, Efficient Attention Architecture, arXiv 2510.26692&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s5&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Abstract (p. 1); Section 3.4.2 (p. 12)&quot;
              href=&quot;https://arxiv.org/abs/2602.17004&quot;
              &gt;Arcee AI · Arcee Trinity Large Technical Report, arXiv 2602.17004&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s6&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Abstract; Section 2.4 (p. 5)&quot;
              href=&quot;https://arxiv.org/abs/2508.06471&quot;
              &gt;Zhipu AI and Tsinghua University · GLM-4.5: Agentic, Reasoning, and Coding (ARC) Foundation Models, arXiv 2508.06471&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s7&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Section 2 (p. 4); Appendix A (p. 36)&quot;
              href=&quot;https://arxiv.org/abs/2602.15763&quot;
              &gt;Zhipu AI · GLM-5: from Vibe Coding to Agentic Engineering, arXiv 2602.15763&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s8&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Abstract (p. 1)&quot;
              href=&quot;https://arxiv.org/abs/2509.02046&quot;
              &gt;Wen et al., Stanford · Fantastic Pretraining Optimizers and Where to Find Them, arXiv 2509.02046v3&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s9&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              data-nb-locator=&quot;Abstract (p. 1)&quot;
              href=&quot;https://arxiv.org/abs/2606.16899&quot;
              &gt;Wen et al. · Fantastic Pretraining Optimizers and Where to Find Them II: Hyperball Optimization, arXiv 2606.16899v2&lt;/a
            &gt;
          &lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="feature"/>
  </entry>
  <entry>
    <title>ε-greedy control settles for the best policy that keeps exploring</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/reinforcement-learning/epsilon-greedy-exploration.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/reinforcement-learning/epsilon-greedy-exploration</id>
    <updated>2026-11-04T07:38:04Z</updated>
    <summary>Monte Carlo control with ordinary starts needs a policy that sometimes moves at random, and the price of those moves grows with ε, first in value and then in the learned arrows.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Reinforcement Learning&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;ε-greedy control settles for the best policy that keeps exploring&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;Monte Carlo control with ordinary starts needs a policy that sometimes moves at random, and the price of those moves grows with ε, first in value and then in the learned arrows.&lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;17 min read&lt;/span&gt;&lt;span&gt;2026-11-04&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section class=&quot;nb-bookend&quot; data-nb-section=&quot;why&quot; id=&quot;why&quot;&gt;
        &lt;p class=&quot;nb-bookend-name&quot;&gt;Why this matters&lt;/p&gt;
        &lt;div class=&quot;nb-bookend-rule&quot;&gt;&lt;/div&gt;
        &lt;p&gt;Monte Carlo control with exploring starts can reach the optimal policy because each episode can open with any move in any cell, which an environment cannot always offer. With ordinary starts, where each episode opens with the policy&#x27;s own move, control never leaves the hand-drawn policy, since a greedy policy collects returns only for the moves it takes. The fix gives every move in every cell a probability of at least ε divided by the number of moves. A policy with that floor is ε-soft, and the ε-soft policy closest to greedy is called ε-greedy. You can then prove that an ε-greedy step never makes such a policy worse. You can also find the one policy where the step can stop, by changing the grid&#x27;s transitions, and the smallest ε at which its arrows stop being optimal.&lt;/p&gt;
        &lt;div class=&quot;nb-bookend-band&quot;&gt;
          &lt;span class=&quot;nb-bookend-label&quot;&gt;Background&lt;/span&gt;
          &lt;span class=&quot;nb-bookend-note&quot;&gt;optional reading&lt;/span&gt;
        &lt;/div&gt;
        &lt;dl class=&quot;nb-bookend-reading&quot;&gt;
          &lt;dt&gt;01&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/action-values-from-samples.html&quot;&gt;Action values let an agent improve its policy from episodes alone&lt;/a&gt;: averaging returns per (cell, move) pair, the greedy step over those averages, exploring starts, and &lt;code&gt;mc_control.py&lt;/code&gt;, which the code below imports.&lt;/dd&gt;
          &lt;dt&gt;02&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;Two improvements find the best policy&lt;/a&gt;: the policy improvement theorem, the Bellman optimality equation and value iteration, all used below, with &lt;code&gt;control.py&lt;/code&gt;.&lt;/dd&gt;
          &lt;dt&gt;03&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/learning-values-from-samples.html&quot;&gt;An agent can learn what each state is worth without knowing the rules&lt;/a&gt;: first-visit Monte Carlo and &lt;code&gt;estimators.py&lt;/code&gt;, which does the averaging.&lt;/dd&gt;
          &lt;dt&gt;04&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/environments-and-the-rl-problem.html&quot;&gt;The value of a state is an average you can solve for&lt;/a&gt;: the slippery grid, the hand-drawn policy and &lt;code&gt;gridworld.py&lt;/code&gt;.&lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;orientation&quot; id=&quot;orientation&quot;&gt;
        &lt;h2&gt;Forty-two moves with no returns&lt;/h2&gt;
        &lt;p&gt;We run &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/action-values-from-samples.html&quot;&gt;Monte Carlo control&lt;/a&gt; from the &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/environments-and-the-rl-problem.html&quot;&gt;hand-drawn policy&lt;/a&gt; with ordinary starts, where each episode begins in a random cell with the policy&#x27;s own move. In 20 runs of 10,000 episodes, none reaches the optimal policy. Fig.&amp;nbsp;1 shows run 0 at the end. Each cell is four triangles, one per move, shaded by the average return after that move.&lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
&lt;div style=&quot;display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center&quot;&gt;&lt;svg viewBox=&quot;0 0 220 234&quot; role=&quot;img&quot; aria-label=&quot;Run 0 of greedy Monte Carlo control with ordinary starts after 10,000 episodes. In every cell only the triangle of the policy&#x27;s own move is shaded; the other 42 triangles are blank because those moves have no returns. The arrows are still the hand-drawn policy, which aims up at cells 13 and 14, where the optimal moves are right.&quot; style=&quot;flex: 1 1 13rem; min-width: 0; max-width: 20rem; height: auto&quot;&gt;&lt;text x=&quot;110.0&quot; y=&quot;16&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12.5px;fill:var(--ink);font-weight:600&quot;&gt;greedy, 10,000 episodes&lt;/text&gt;&lt;polygon points=&quot;35.0,51.0 10,26 60,26&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 60,26 60,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.377;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 60,76 10,76&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 10,76 10,26&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;51.0&quot; x2=&quot;48.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;52.5,51.0 48.0,54.6 48.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 60,26 110,26&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 110,26 110,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.610;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 110,76 60,76&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 60,76 60,26&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;51.0&quot; x2=&quot;98.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;102.5,51.0 98.0,54.6 98.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 110,26 160,26&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 160,26 160,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 160,76 110,76&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 110,76 110,26&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;51.0&quot; x2=&quot;148.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,51.0 148.0,54.6 148.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;162&quot; y=&quot;28&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;55.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;&lt;polygon points=&quot;35.0,101.0 10,76 60,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.214;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 60,76 60,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 60,126 10,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 10,126 10,76&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;105.0&quot; x2=&quot;35.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,83.5 38.6,88.0 31.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 60,76 110,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.186;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 110,76 110,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 110,126 60,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 60,126 60,76&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;105.0&quot; x2=&quot;85.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,83.5 88.6,88.0 81.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;112&quot; y=&quot;78&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;105.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;&lt;polygon points=&quot;185.0,101.0 160,76 210,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 210,76 210,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 210,126 160,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 160,126 160,76&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;105.0&quot; x2=&quot;185.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,83.5 188.6,88.0 181.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 10,126 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.206;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 60,126 60,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 60,176 10,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 10,176 10,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;155.0&quot; x2=&quot;35.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,133.5 38.6,138.0 31.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 60,126 110,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.256;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 110,126 110,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 110,176 60,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 60,176 60,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;155.0&quot; x2=&quot;85.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,133.5 88.6,138.0 81.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 110,126 160,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 160,126 160,176&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.157;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 160,176 110,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 110,176 110,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;151.0&quot; x2=&quot;148.0&quot; y2=&quot;151.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,151.0 148.0,154.6 148.0,147.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 160,126 210,126&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.636;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 210,126 210,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 210,176 160,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 160,176 160,126&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;155.0&quot; x2=&quot;185.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,133.5 188.6,138.0 181.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 10,176 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.362;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 60,176 60,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 60,226 10,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 10,226 10,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;205.0&quot; x2=&quot;35.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,183.5 38.6,188.0 31.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 60,176 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.347;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 110,176 110,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 110,226 60,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 60,226 60,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;205.0&quot; x2=&quot;85.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,183.5 88.6,188.0 81.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;62.5&quot; y=&quot;178.5&quot; width=&quot;45&quot; height=&quot;45&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 110,176 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.248;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 160,176 160,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 160,226 110,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 110,226 110,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;135.0&quot; y1=&quot;205.0&quot; x2=&quot;135.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;135.0,183.5 138.6,188.0 131.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;112.5&quot; y=&quot;178.5&quot; width=&quot;45&quot; height=&quot;45&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 160,176 210,176&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.405;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 210,176 210,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 210,226 160,226&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 160,226 160,176&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;205.0&quot; x2=&quot;185.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,183.5 188.6,188.0 181.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;/svg&gt;&lt;/div&gt;&lt;svg viewBox=&quot;0 0 470.2 30&quot; role=&quot;img&quot; aria-label=&quot;Legend: green shading for values above 0, red below, deepest at 6 or more either way; a blank triangle has no returns; an amber square marks an arrow not optimal.&quot; style=&quot;display: block; width: 100%; max-width: 36.7rem; margin: 0.4rem auto 0; height: auto&quot;&gt;&lt;rect x=&quot;8&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;27&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;−6 or less&lt;/text&gt;&lt;rect x=&quot;105.0&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.140;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;124.0&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;0&lt;/text&gt;&lt;rect x=&quot;144.4&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;163.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;+6 or more&lt;/text&gt;&lt;polygon points=&quot;241.4,23 255.4,23 248.4,9&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;260.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;no returns&lt;/text&gt;&lt;rect x=&quot;338.4&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:2.4&quot;/&gt;&lt;text x=&quot;357.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;arrow not optimal&lt;/text&gt;&lt;/svg&gt;
          &lt;figcaption&gt;Fig.&amp;nbsp;1 · Run 0 of greedy Monte Carlo control with ordinary starts, after 10,000 episodes. Arrows show the policy, amber squares mark arrows that are not optimal, and a blank triangle is a move with no returns. From &lt;code&gt;exploration.py&lt;/code&gt;.&lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;Only 14 of the 56 (cell, move) pairs have any returns, one in each cell. At cell 14, up has 976 returns and the other three moves have none. Right is the move that &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;policy iteration&lt;/a&gt; switched cell 14 to in its first round, and the agent has never tried it there.&lt;/p&gt;
        &lt;p&gt;The greedy step cannot supply the missing returns. It would switch cell 14 to right only if right&#x27;s average beat up&#x27;s. Right has no average yet, so &lt;code&gt;greedy&lt;/code&gt; in &lt;code&gt;mc_control.py&lt;/code&gt; skips it. The agent would have to take right to give it returns, and the agent takes only the policy&#x27;s move. Each episode adds returns to the same 14 pairs, so after 10,000 greedy steps the policy is still the hand-drawn one. Sutton and Barto state the general case: with no returns to average, the estimates of the other moves &amp;ldquo;will not improve with experience&amp;rdquo;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.2, p. 96&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
        &lt;p&gt;So the agent has to take every move in every cell now and then, whatever its averages say. Exploring starts arranged that from outside the agent, by choosing each episode&#x27;s first move. A policy that sometimes moves at random can arrange it instead.&lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;floor&quot; id=&quot;floor&quot;&gt;
        &lt;h2&gt;A floor of ε/4 on every move&lt;/h2&gt;
        &lt;p&gt;An ε-greedy policy usually makes the greedy move, the one with the largest average. With a small probability ε it instead picks one of the moves uniformly at random, the greedy move included.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 2.2, pp. 27-28&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; In a cell whose greedy move is &lt;span class=&quot;nb-math-in&quot;&gt;a^*&lt;/span&gt;, each move gets the following probability.&lt;/p&gt;
        &lt;figure class=&quot;nb-math&quot;&gt;
          &lt;div class=&quot;nb-math-eq&quot;&gt;\pi(a \mid s) = \begin{cases} 1 - \varepsilon + \dfrac{\varepsilon}{|\mathcal{A}(s)|} &amp;amp; \text{if } a = a^* \\[6pt] \dfrac{\varepsilon}{|\mathcal{A}(s)|} &amp;amp; \text{otherwise} \end{cases}&lt;/div&gt;
          &lt;figcaption&gt;The ε-greedy policy, where &lt;span class=&quot;nb-math-in&quot;&gt;|\mathcal{A}(s)|&lt;/span&gt; is the number of moves in cell &lt;span class=&quot;nb-math-in&quot;&gt;s&lt;/span&gt;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, p. 100&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;Every cell here has four moves, so with ε = 0.1 the greedy move gets 0.925 and each other move gets 0.025. A policy that gives every move in every cell at least &lt;span class=&quot;nb-math-in&quot;&gt;\varepsilon/|\mathcal{A}(s)|&lt;/span&gt; is called ε-soft. The ε-greedy policy is the ε-soft policy closest to greedy, since every move gets the floor and the greedy move gets the rest.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, p. 100&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
        &lt;p&gt;The ε-greedy policy that makes the moves is also the policy whose action values the agent averages and then improves. Control of this kind is called on-policy.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, p. 100&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
        &lt;p&gt;In &lt;code&gt;soft_control.py&lt;/code&gt;, &lt;code&gt;soft_play&lt;/code&gt; draws each move ε-greedily. It replaces &lt;code&gt;play&lt;/code&gt; in &lt;code&gt;mc_control.py&lt;/code&gt;, a function that can follow only one move per cell. The loop in &lt;code&gt;soft_control&lt;/code&gt; is the one in &lt;code&gt;mc_control.py&lt;/code&gt; without exploring starts: each episode starts in a random cell, its returns join the averages, and the policy turns greedy. The array &lt;code&gt;policy&lt;/code&gt; holds the greedy move in each cell. The file imports the grid from &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/environments-and-the-rl-problem.html&quot;&gt;&lt;code&gt;gridworld.py&lt;/code&gt;&lt;/a&gt;, &lt;code&gt;action_values&lt;/code&gt; from &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;&lt;code&gt;control.py&lt;/code&gt;&lt;/a&gt;, the averaging from &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/learning-values-from-samples.html&quot;&gt;&lt;code&gt;estimators.py&lt;/code&gt;&lt;/a&gt;, and the environment, &lt;code&gt;pairs&lt;/code&gt; and &lt;code&gt;greedy&lt;/code&gt; from &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/action-values-from-samples.html&quot;&gt;&lt;code&gt;mc_control.py&lt;/code&gt;&lt;/a&gt;, all unchanged.&lt;/p&gt;
        &lt;figure class=&quot;nb-code&quot;&gt;
          &lt;div class=&quot;nb-code-head&quot;&gt;&lt;span class=&quot;nb-code-file&quot;&gt;soft_control.py · complete&lt;/span&gt;&lt;span&gt;python&lt;/span&gt;&lt;/div&gt;
          &lt;pre&gt;&lt;code data-language=&quot;python&quot;&gt;# /// script
# requires-python = &quot;&amp;gt;=3.10&quot;
# dependencies = [&quot;numpy&quot;]
# ///
&quot;&quot;&quot;On-policy first-visit Monte Carlo control with an epsilon-greedy policy.

Only the episodes differ from mc_control.py. In every cell the agent makes a
uniformly random move with probability eps, and the policy&#x27;s move otherwise.
best_soft finds the best eps-soft policy exactly, to grade the runs.
&quot;&quot;&quot;

import numpy as np
from control import action_values
from estimators import first_visit_mc
from gridworld import N, TERMINAL, transitions
from mc_control import CAP, LIVE, SLIP, greedy, pairs, step


def soft_play(policy, eps, start, rng):
    &quot;&quot;&quot;One episode from cell `start` under the eps-greedy policy around
    `policy`. It stops at a terminal cell or after CAP moves.&quot;&quot;&quot;
    s, steps = start, []
    while s not in TERMINAL and len(steps) &amp;lt; CAP:
        a = rng.integers(4) if rng.random() &amp;lt; eps else policy[s]
        reward, s_next = step(s, a, rng)
        steps.append((s, a, reward, s_next))
        s = s_next
    return steps


def soft_control(policy, eps, episodes, rng, watch=None):
    &quot;&quot;&quot;Each episode starts in a random cell and follows the eps-greedy policy.
    Its returns join the averages, and `policy` turns greedy after it.&quot;&quot;&quot;
    q, count = np.zeros(4 * N), np.zeros(4 * N)
    for k in range(1, episodes + 1):
        start = LIVE[rng.integers(len(LIVE))]
        steps = soft_play(policy, eps, start, rng)
        first_visit_mc(pairs(steps), q, count)
        policy = greedy(q, count, policy)
        if watch:
            watch(k, policy, q, count, steps)
    return policy, q, count


def best_soft(eps, tol=1e-10):
    &quot;&quot;&quot;The best eps-soft policy, exactly. It is the optimal policy of a grid
    that replaces the agent&#x27;s aim with a random one with probability eps, so
    value iteration on that grid finds its value v. Also returns q[s, a], the
    expected return after move a in the real grid, following that policy.&quot;&quot;&quot;
    P = transitions(SLIP)
    P_eps = (1 - eps) * P + eps * P.mean(axis=1, keepdims=True)
    v = np.zeros(N)
    while True:
        nxt = v.copy()
        nxt[LIVE] = action_values(v, P_eps)[LIVE].max(axis=1)
        if np.abs(nxt - v).max() &amp;lt; tol:
            return nxt, action_values(nxt, P)
        v = nxt&lt;/code&gt;&lt;/pre&gt;
        &lt;/figure&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;stall-ends&quot; id=&quot;stall-ends&quot;&gt;
        &lt;h2&gt;Random moves end the stall&lt;/h2&gt;
        &lt;p&gt;We start 20 runs of &lt;code&gt;soft_control&lt;/code&gt; from the hand-drawn policy, with ε = 0.1, no averages and seeds 0 to 19. A run counts when every arrow is an optimal move. After 10,000 episodes 6 of the 20 runs count, and after 200,000, 19 do. Setting ε to 0 in the same code removes the random moves, and then no run counts at 10,000 episodes.&lt;/p&gt;
        &lt;p&gt;&lt;code&gt;uv run exploration.py&lt;/code&gt; needs &lt;code&gt;gridworld.py&lt;/code&gt;, &lt;code&gt;control.py&lt;/code&gt;, &lt;code&gt;estimators.py&lt;/code&gt;, &lt;code&gt;mc_control.py&lt;/code&gt; and &lt;code&gt;soft_control.py&lt;/code&gt; in one folder. It installs numpy and takes about four minutes on the machine used here.&lt;/p&gt;
        &lt;details&gt;
          &lt;summary&gt;&lt;code&gt;exploration.py&lt;/code&gt;, complete&lt;/summary&gt;
          &lt;figure class=&quot;nb-code&quot;&gt;
            &lt;div class=&quot;nb-code-head&quot;&gt;&lt;span class=&quot;nb-code-file&quot;&gt;exploration.py · complete&lt;/span&gt;&lt;span&gt;python&lt;/span&gt;&lt;/div&gt;
            &lt;pre&gt;&lt;code data-language=&quot;python&quot;&gt;# /// script
# requires-python = &quot;&amp;gt;=3.10&quot;
# dependencies = [&quot;numpy&quot;]
# ///
&quot;&quot;&quot;Print every number on the page: the greedy stall, eps-greedy control on 20
seeds, and the price of eps. The exact values from best_soft grade the runs.&quot;&quot;&quot;

import numpy as np
from gridworld import N, PI
from mc_control import LIVE, control
from soft_control import best_soft, soft_control

SEEDS = range(20)


def best_moves(eps):
    &quot;&quot;&quot;The moves that tie for best in each cell under the best eps-soft policy.
    eps = 0 gives the optimal moves, with up and right tied at cells 9 and 12.&quot;&quot;&quot;
    _, q = best_soft(eps)
    return {s: set(np.flatnonzero(q[s] &amp;gt; q[s].max() - 1e-9)) for s in LIVE}


def runs_at_best(eps, checks):
    &quot;&quot;&quot;At each checkpoint, the number of runs whose every arrow is a best move.&quot;&quot;&quot;
    best, hits = best_moves(eps), dict.fromkeys(checks, 0)

    def watch(k, policy, q, count, steps):
        if k in hits:
            hits[k] += all(policy[s] in best[s] for s in LIVE)

    for seed in SEEDS:
        soft_control(PI.copy(), eps, max(checks), np.random.default_rng(seed),
                     watch)
    return list(hits.values())


def main():
    _, _, count = control(PI.copy(), 10_000, np.random.default_rng(0),
                          explore=False)
    print(&quot;greedy, ordinary starts, run 0 after 10,000 episodes&quot;)
    print(&quot;  pairs with returns:&quot;, int((count &amp;gt; 0).sum()), &quot;of&quot;, 4 * len(LIVE))
    print(&quot;  cell 14 returns (up, right, down, left):&quot;,
          count[4 * 14:4 * 14 + 4].astype(int))

    fewest = {}

    def watch(k, policy, q, count, steps):
        if k == 10_000:
            fewest[k] = int(count.reshape(N, 4)[LIVE].min())

    _, q, _ = soft_control(PI.copy(), 0.1, 200_000, np.random.default_rng(0),
                           watch)
    print(&quot;eps 0.1, run 0&quot;)
    print(&quot;  fewest returns for any pair after 10,000:&quot;, fewest[10_000])
    print(f&quot;  average for right at cell 14 after 200,000: {q[4 * 14 + 1]:.2f}&quot;)
    v_star, q_star = best_soft(0.0)
    _, q_soft = best_soft(0.1)
    print(f&quot;  exact, best eps-soft policy: {q_soft[14, 1]:.2f}, &quot;
          f&quot;optimal policy: {q_star[14, 1]:.2f}&quot;)

    print(&quot;\nruns of 20 whose arrows are all best moves&quot;)
    print(&quot;  eps 0.0 at 10,000 episodes:&quot;, runs_at_best(0.0, [10_000]))
    checks = [1_000, 10_000, 100_000, 200_000]
    print(f&quot;  eps 0.1 at {checks}:&quot;, runs_at_best(0.1, checks))
    checks = [1_000, 10_000, 100_000]
    print(f&quot;  eps 0.5 at {checks}:&quot;, runs_at_best(0.5, checks))

    optimal = best_moves(0.0)
    print(&quot;\n  eps  average v* - v  cells whose best moves differ from optimal&quot;)
    for eps in (0.01, 0.1, 0.2, 0.3, 0.5):
        v, _ = best_soft(eps)
        differ = [s for s, moves in best_moves(eps).items() if moves != optimal[s]]
        print(f&quot;{eps:5.2f}  {(v_star - v)[LIVE].mean():14.2f}  {differ}&quot;)
    first = next(e for e in range(1, 100) if best_moves(e / 100) != optimal)
    print(&quot;smallest eps, in steps of 0.01, with other best moves:&quot;, first / 100)
    v_half, _ = best_soft(0.5)
    for name, v in ((&quot;v* (eps 0)&quot;, v_star), (&quot;best eps-soft v, eps 0.5&quot;, v_half)):
        print(f&quot;{name}, by row:&quot;, v.reshape(4, 4).round(2).tolist())


if __name__ == &quot;__main__&quot;:
    main()&lt;/code&gt;&lt;/pre&gt;
          &lt;/figure&gt;
        &lt;/details&gt;
        &lt;details&gt;
          &lt;summary&gt;The output of &lt;code&gt;uv run exploration.py&lt;/code&gt;&lt;/summary&gt;
          &lt;figure class=&quot;nb-code&quot;&gt;
            &lt;div class=&quot;nb-code-head&quot;&gt;&lt;span class=&quot;nb-code-file&quot;&gt;output of uv run exploration.py&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;/div&gt;
            &lt;pre&gt;&lt;code data-language=&quot;text&quot;&gt;greedy, ordinary starts, run 0 after 10,000 episodes
  pairs with returns: 14 of 56
  cell 14 returns (up, right, down, left): [976   0   0   0]
eps 0.1, run 0
  fewest returns for any pair after 10,000: 24
  average for right at cell 14 after 200,000: -0.41
  exact, best eps-soft policy: -0.37, optimal policy: 0.61

runs of 20 whose arrows are all best moves
  eps 0.0 at 10,000 episodes: [0]
  eps 0.1 at [1000, 10000, 100000, 200000]: [0, 6, 14, 19]
  eps 0.5 at [1000, 10000, 100000]: [7, 18, 20]

  eps  average v* - v  cells whose best moves differ from optimal
 0.01            0.10  []
 0.10            1.08  []
 0.20            2.23  []
 0.30            3.46  []
 0.50            6.09  [9]
smallest eps, in steps of 0.01, with other best moves: 0.33
v* (eps 0), by row: [[2.16, 4.04, 6.48, 0.0], [0.61, 0.06, 0.0, 6.48], [-0.71, -1.01, 0.06, 4.04], [-1.73, -0.71, 0.61, 2.16]]
best eps-soft v, eps 0.5, by row: [[-4.05, -2.26, 1.42, 0.0], [-5.67, -7.08, 0.0, 1.42], [-6.64, -7.1, -7.08, -2.26], [-7.1, -6.64, -5.67, -4.05]]&lt;/code&gt;&lt;/pre&gt;
          &lt;/figure&gt;
        &lt;/details&gt;
        &lt;p&gt;In run 0 after 10,000 episodes every triangle is shaded, and the rarest pair has 24 returns. Cells 13 and 14 now aim right, as the first panel of Fig.&amp;nbsp;2 shows.&lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
&lt;div style=&quot;display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center&quot;&gt;&lt;svg viewBox=&quot;0 0 220 234&quot; role=&quot;img&quot; aria-label=&quot;Run 0 of epsilon-greedy control with epsilon 0.1 after 10,000 episodes. Every triangle is shaded, so every move has returns, and every arrow is an optimal move, right at cells 13 and 14.&quot; style=&quot;flex: 1 1 13rem; min-width: 0; max-width: 20rem; height: auto&quot;&gt;&lt;text x=&quot;110.0&quot; y=&quot;16&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12.5px;fill:var(--ink);font-weight:600&quot;&gt;ε = 0.1, 10,000 episodes&lt;/text&gt;&lt;polygon points=&quot;35.0,51.0 10,26 60,26&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.248;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 60,26 60,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.260;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 60,76 10,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.230;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 10,76 10,26&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.237;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;51.0&quot; x2=&quot;48.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;52.5,51.0 48.0,54.6 48.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 60,26 110,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.440;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 110,26 110,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.521;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 110,76 60,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.338;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 60,76 60,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.162;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;51.0&quot; x2=&quot;98.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;102.5,51.0 98.0,54.6 98.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 110,26 160,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.605;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 160,26 160,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 160,76 110,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 110,76 110,26&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.356;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;51.0&quot; x2=&quot;148.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,51.0 148.0,54.6 148.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;162&quot; y=&quot;28&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;55.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;&lt;polygon points=&quot;35.0,101.0 10,76 60,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.198;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 60,76 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.325;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 60,126 10,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.630;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 10,126 10,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.482;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;105.0&quot; x2=&quot;35.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,83.5 38.6,88.0 31.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 60,76 110,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.221;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 110,76 110,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 110,126 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.578;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 60,126 60,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.268;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;105.0&quot; x2=&quot;85.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,83.5 88.6,88.0 81.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;112&quot; y=&quot;78&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;105.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;&lt;polygon points=&quot;185.0,101.0 160,76 210,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 210,76 210,126&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.514;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 210,126 160,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.165;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 160,126 160,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;105.0&quot; x2=&quot;185.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,83.5 188.6,88.0 181.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 10,126 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.360;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 60,126 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.496;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 60,176 10,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.462;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 10,176 10,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.546;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;155.0&quot; x2=&quot;35.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,133.5 38.6,138.0 31.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 60,126 110,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.384;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 110,126 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.440;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 110,176 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.548;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 60,176 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.439;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;155.0&quot; x2=&quot;85.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,133.5 88.6,138.0 81.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 110,126 160,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 160,126 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.223;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 160,176 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.254;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 110,176 110,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.789;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;151.0&quot; x2=&quot;148.0&quot; y2=&quot;151.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,151.0 148.0,154.6 148.0,147.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 160,126 210,126&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.519;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 210,126 210,176&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.388;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 210,176 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.174;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 160,176 160,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.365;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;155.0&quot; x2=&quot;185.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,133.5 188.6,138.0 181.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 10,176 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.472;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 60,176 60,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.524;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 60,226 10,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.769;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 10,226 10,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.595;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;205.0&quot; x2=&quot;35.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,183.5 38.6,188.0 31.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 60,176 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.478;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 110,176 110,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.401;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 110,226 60,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.693;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 60,226 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.598;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;201.0&quot; x2=&quot;98.0&quot; y2=&quot;201.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;102.5,201.0 98.0,204.6 98.0,197.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 110,176 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.500;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 160,176 160,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.205;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 160,226 110,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.352;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 110,226 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.457;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;201.0&quot; x2=&quot;148.0&quot; y2=&quot;201.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,201.0 148.0,204.6 148.0,197.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 160,176 210,176&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.278;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 210,176 210,226&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.193;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 210,226 160,226&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.253;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 160,226 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.350;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;205.0&quot; x2=&quot;185.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,183.5 188.6,188.0 181.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 220 234&quot; role=&quot;img&quot; aria-label=&quot;The exact action values of the best epsilon-soft policy for epsilon 0.1, with its best moves as arrows: the optimal moves, with up and right tied at cells 9 and 12. The shading matches the run&#x27;s.&quot; style=&quot;flex: 1 1 13rem; min-width: 0; max-width: 20rem; height: auto&quot;&gt;&lt;text x=&quot;110.0&quot; y=&quot;16&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12.5px;fill:var(--ink);font-weight:600&quot;&gt;best ε-soft policy, ε = 0.1&lt;/text&gt;&lt;polygon points=&quot;35.0,51.0 10,26 60,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.159;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 60,26 60,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.284;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 60,76 10,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.256;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,51.0 10,76 10,26&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.158;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;51.0&quot; x2=&quot;48.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;52.5,51.0 48.0,54.6 48.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 60,26 110,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.349;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 110,26 110,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.523;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 110,76 60,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.295;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,51.0 60,76 60,26&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.146;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;51.0&quot; x2=&quot;98.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;102.5,51.0 98.0,54.6 98.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 110,26 160,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.666;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 160,26 160,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 160,76 110,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,51.0 110,76 110,26&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.167;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;51.0&quot; x2=&quot;148.0&quot; y2=&quot;51.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,51.0 148.0,54.6 148.0,47.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;162&quot; y=&quot;28&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;55.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;&lt;polygon points=&quot;35.0,101.0 10,76 60,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.183;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 60,76 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.374;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 60,126 10,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.431;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,101.0 10,126 10,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.307;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;105.0&quot; x2=&quot;35.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,83.5 38.6,88.0 31.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 60,76 110,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.233;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 110,76 110,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 110,126 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.677;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,101.0 60,126 60,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.291;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;105.0&quot; x2=&quot;85.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,83.5 88.6,88.0 81.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;rect x=&quot;112&quot; y=&quot;78&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;105.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;&lt;polygon points=&quot;185.0,101.0 160,76 210,76&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 210,76 210,126&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.666;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 210,126 160,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.167;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,101.0 160,126 160,76&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;105.0&quot; x2=&quot;185.0&quot; y2=&quot;88.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,83.5 188.6,88.0 181.4,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 10,126 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.342;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 60,126 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.481;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 60,176 10,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.535;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,151.0 10,176 10,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.446;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;155.0&quot; x2=&quot;35.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,133.5 38.6,138.0 31.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 60,126 110,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.399;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 110,126 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.399;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 110,176 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.445;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,151.0 60,176 60,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.445;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;155.0&quot; x2=&quot;85.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,133.5 88.6,138.0 81.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;151.0&quot; x2=&quot;98.0&quot; y2=&quot;151.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;102.5,151.0 98.0,154.6 98.0,147.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 110,126 160,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 160,126 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.233;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 160,176 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.291;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,151.0 110,176 110,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.677;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;151.0&quot; x2=&quot;148.0&quot; y2=&quot;151.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,151.0 148.0,154.6 148.0,147.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 160,126 210,126&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.523;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 210,126 210,176&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.349;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 210,176 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.146;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,151.0 160,176 160,126&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.295;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;155.0&quot; x2=&quot;185.0&quot; y2=&quot;138.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,133.5 188.6,138.0 181.4,138.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 10,176 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.460;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 60,176 60,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.460;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 60,226 10,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.540;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;35.0,201.0 10,226 10,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.540;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;10&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;205.0&quot; x2=&quot;35.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,183.5 38.6,188.0 31.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;201.0&quot; x2=&quot;48.0&quot; y2=&quot;201.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;52.5,201.0 48.0,204.6 48.0,197.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 60,176 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.481;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 110,176 110,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.342;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 110,226 60,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.446;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;85.0,201.0 60,226 60,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.535;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;60&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;201.0&quot; x2=&quot;98.0&quot; y2=&quot;201.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;102.5,201.0 98.0,204.6 98.0,197.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 110,176 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.374;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 160,176 160,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.183;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 160,226 110,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.307;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;135.0,201.0 110,226 110,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.431;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;201.0&quot; x2=&quot;148.0&quot; y2=&quot;201.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;152.5,201.0 148.0,204.6 148.0,197.4&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 160,176 210,176&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.284;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 210,176 210,226&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.159;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 210,226 160,226&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.158;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;polygon points=&quot;185.0,201.0 160,226 160,176&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.256;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;rect x=&quot;160&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;205.0&quot; x2=&quot;185.0&quot; y2=&quot;188.0&quot; style=&quot;stroke:var(--ink);stroke-width:2.0;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,183.5 188.6,188.0 181.4,188.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;/svg&gt;&lt;/div&gt;&lt;svg viewBox=&quot;0 0 470.2 30&quot; role=&quot;img&quot; aria-label=&quot;Legend: green shading for values above 0, red below, deepest at 6 or more either way; a blank triangle has no returns; an amber square marks an arrow not optimal.&quot; style=&quot;display: block; width: 100%; max-width: 36.7rem; margin: 0.4rem auto 0; height: auto&quot;&gt;&lt;rect x=&quot;8&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;27&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;−6 or less&lt;/text&gt;&lt;rect x=&quot;105.0&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.140;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;124.0&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;0&lt;/text&gt;&lt;rect x=&quot;144.4&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;163.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;+6 or more&lt;/text&gt;&lt;polygon points=&quot;241.4,23 255.4,23 248.4,9&quot; style=&quot;fill:none;stroke:var(--ink-soft);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;260.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;no returns&lt;/text&gt;&lt;rect x=&quot;338.4&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:2.4&quot;/&gt;&lt;text x=&quot;357.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;arrow not optimal&lt;/text&gt;&lt;/svg&gt;
          &lt;figcaption&gt;Fig.&amp;nbsp;2 · Run 0 of ε-greedy control with ε = 0.1 after 10,000 episodes, where every move has returns and every arrow is optimal, beside the exact action values of the best ε-soft policy for ε = 0.1. The exact panel draws two arrows where moves tie. From &lt;code&gt;exploration.py&lt;/code&gt;.&lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;The returns come from an agent that keeps making random moves, so the averages estimate the action values of the ε-greedy policy itself. After 200,000 episodes run 0&#x27;s average for right at cell 14 is &amp;minus;0.41. The exact action value is &amp;minus;0.37 under the ε-greedy policy around the optimal arrows, and 0.61 under the optimal policy itself. So each step makes the policy ε-greedy with respect to the action values of an ε-greedy policy. The policy improvement theorem was stated for a policy that makes one move per cell, and nothing yet says such a step cannot make the policy worse.&lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;safe-step&quot; id=&quot;safe-step&quot;&gt;
        &lt;h2&gt;Why an ε-greedy step never makes the policy worse&lt;/h2&gt;
        &lt;p&gt;The &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;policy improvement theorem&lt;/a&gt; covers this step once it is written for a policy that picks moves at random. For a stochastic policy &lt;span class=&quot;nb-math-in&quot;&gt;\pi&#x27;&lt;/span&gt;, &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi\bigl(s, \pi&#x27;(s)\bigr)&lt;/span&gt; means the average &lt;span class=&quot;nb-math-in&quot;&gt;\sum_a \pi&#x27;(a \mid s)\, q_\pi(s, a)&lt;/span&gt;, the expected return from one move drawn from &lt;span class=&quot;nb-math-in&quot;&gt;\pi&#x27;&lt;/span&gt; followed by &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt;. If that average is at least &lt;span class=&quot;nb-math-in&quot;&gt;v_\pi(s)&lt;/span&gt; in every cell, then &lt;span class=&quot;nb-math-in&quot;&gt;v_{\pi&#x27;} \ge v_\pi&lt;/span&gt; in every cell.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, pp. 101-102, equation 5.2&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
        &lt;p&gt;Let &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; be any ε-soft policy and &lt;span class=&quot;nb-math-in&quot;&gt;\pi&#x27;&lt;/span&gt; the ε-greedy policy with respect to &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi&lt;/span&gt;. Sutton and Barto check the theorem&#x27;s condition in one chain, their equation (5.2).&lt;/p&gt;
        &lt;figure class=&quot;nb-math&quot;&gt;
          &lt;div class=&quot;nb-math-eq&quot;&gt;\begin{aligned} q_\pi\bigl(s, \pi&#x27;(s)\bigr) &amp;amp;= \sum_a \pi&#x27;(a \mid s)\, q_\pi(s, a) \\ &amp;amp;= \htmlClass{nb-mc1}{\frac{\varepsilon}{|\mathcal{A}(s)|} \sum_a q_\pi(s, a)} \\ &amp;amp;\qquad + \htmlClass{nb-mc2}{(1 - \varepsilon) \max_a q_\pi(s, a)} \\ &amp;amp;\ge \frac{\varepsilon}{|\mathcal{A}(s)|} \sum_a q_\pi(s, a) \\ &amp;amp;\qquad + (1 - \varepsilon) \sum_a \htmlClass{nb-mc3}{w(a)}\, q_\pi(s, a) \\ &amp;amp;= \sum_a \pi(a \mid s)\, q_\pi(s, a) \;=\; v_\pi(s) \end{aligned}&lt;/div&gt;
          &lt;ul class=&quot;nb-math-legend&quot;&gt;
            &lt;li&gt;&lt;span class=&quot;nb-math-term nb-mc1&quot;&gt;\tfrac{\varepsilon}{|\mathcal{A}(s)|} \textstyle\sum_a q_\pi(s, a)&lt;/span&gt;&lt;span&gt;the floor: every move&#x27;s share of ε&lt;/span&gt;&lt;/li&gt;
            &lt;li&gt;&lt;span class=&quot;nb-math-term nb-mc2&quot;&gt;(1 - \varepsilon) \max_a q_\pi(s, a)&lt;/span&gt;&lt;span&gt;the rest of the probability, all on the greedy move&lt;/span&gt;&lt;/li&gt;
            &lt;li&gt;&lt;span class=&quot;nb-math-term nb-mc3&quot;&gt;w(a) = \tfrac{\pi(a \mid s) - \varepsilon/|\mathcal{A}(s)|}{1 - \varepsilon}&lt;/span&gt;&lt;span&gt;weights that turn the probabilities &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; puts above the floor into an average&lt;/span&gt;&lt;/li&gt;
          &lt;/ul&gt;
          &lt;figcaption&gt;The ε-greedy step meets the condition of the policy improvement theorem for any ε-soft &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, pp. 101-102, equation 5.2&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;The second equality splits &lt;span class=&quot;nb-math-in&quot;&gt;\pi&#x27;&lt;/span&gt; into its floor and the remaining &lt;span class=&quot;nb-math-in&quot;&gt;1 - \varepsilon&lt;/span&gt; on the greedy move. The inequality replaces the maximum with a weighted average of the same four action values, with weights &lt;span class=&quot;nb-math-in&quot;&gt;w(a)&lt;/span&gt;. Each weight is at least 0 because &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; is ε-soft. The weights sum to 1 because the probabilities of &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; sum to 1 and the floor takes ε of them. A weighted average is never larger than the largest value it averages. In the last equality the floor terms cancel, and what remains is the average of &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi(s, a)&lt;/span&gt; over the moves of &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt;, which is &lt;span class=&quot;nb-math-in&quot;&gt;v_\pi(s)&lt;/span&gt;.&lt;/p&gt;
        &lt;p&gt;So &lt;span class=&quot;nb-math-in&quot;&gt;\pi&#x27;&lt;/span&gt; is no worse than &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; in any cell. The new policy is also ε-soft, so the step can be repeated.&lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;resting-point&quot; id=&quot;resting-point&quot;&gt;
        &lt;h2&gt;The only resting point is the best ε-soft policy&lt;/h2&gt;
        &lt;p&gt;Suppose the ε-greedy step stops changing the policy. Then &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; is ε-greedy with respect to its own action values, and in every cell its value is their ε-greedy average.&lt;/p&gt;
        &lt;figure class=&quot;nb-math&quot;&gt;
          &lt;div class=&quot;nb-math-eq&quot;&gt;\begin{aligned} v_\pi(s) &amp;amp;= (1 - \varepsilon) \max_a q_\pi(s, a) \\ &amp;amp;\qquad + \frac{\varepsilon}{|\mathcal{A}(s)|} \sum_a q_\pi(s, a) \end{aligned}&lt;/div&gt;
        &lt;/figure&gt;
        &lt;p&gt;Sutton and Barto read this as the &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;Bellman optimality equation&lt;/a&gt; of a different grid.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, p. 102&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; In that grid the agent picks a move, and with probability ε the environment replaces it with a uniformly random one before the slip. Its transition probabilities mix the real ones.&lt;/p&gt;
        &lt;figure class=&quot;nb-math&quot;&gt;
          &lt;div class=&quot;nb-math-eq&quot;&gt;\begin{aligned} \tilde P(s&#x27; \mid s, a) &amp;amp;= (1 - \varepsilon)\, P(s&#x27; \mid s, a) \\ &amp;amp;\qquad + \frac{\varepsilon}{|\mathcal{A}(s)|} \sum_b P(s&#x27; \mid s, b) \end{aligned}&lt;/div&gt;
        &lt;/figure&gt;
        &lt;p&gt;A policy &lt;span class=&quot;nb-math-in&quot;&gt;\mu&lt;/span&gt; in the new grid moves exactly like the ε-soft policy &lt;span class=&quot;nb-math-in&quot;&gt;(1 - \varepsilon)\,\mu + \varepsilon/|\mathcal{A}(s)|&lt;/span&gt; in the real one. Every ε-soft policy arises this way, with &lt;span class=&quot;nb-math-in&quot;&gt;\mu&lt;/span&gt; equal to the weights &lt;span class=&quot;nb-math-in&quot;&gt;w(a)&lt;/span&gt; from equation (5.2). So the best policy of the new grid is the best ε-soft policy of the real one, and its value &lt;span class=&quot;nb-math-in&quot;&gt;\tilde v_*&lt;/span&gt; is the most an ε-soft policy can earn.&lt;/p&gt;
        &lt;p&gt;In the new grid&#x27;s Bellman optimality equation, the random part of &lt;span class=&quot;nb-math-in&quot;&gt;\tilde P&lt;/span&gt; does not depend on the move &lt;span class=&quot;nb-math-in&quot;&gt;a&lt;/span&gt;, so it comes out of the max.&lt;/p&gt;
        &lt;figure class=&quot;nb-math&quot;&gt;
          &lt;div class=&quot;nb-math-eq&quot;&gt;\begin{aligned} \tilde v_*(s) &amp;amp;= \max_a \sum_{s&#x27;} \tilde P(s&#x27; \mid s, a)\,\bigl[R(s&#x27;) + \gamma\, \tilde v_*(s&#x27;)\bigr] \\ &amp;amp;= (1 - \varepsilon) \max_a \tilde q(s, a) \\ &amp;amp;\qquad + \frac{\varepsilon}{|\mathcal{A}(s)|} \sum_a \tilde q(s, a) \end{aligned}&lt;/div&gt;
        &lt;/figure&gt;
        &lt;p&gt;Here &lt;span class=&quot;nb-math-in&quot;&gt;\tilde q(s, a)&lt;/span&gt; is the expected return after move &lt;span class=&quot;nb-math-in&quot;&gt;a&lt;/span&gt; in the real grid, with each landing cell valued at &lt;span class=&quot;nb-math-in&quot;&gt;\tilde v_*&lt;/span&gt;.&lt;/p&gt;
        &lt;figure class=&quot;nb-math&quot;&gt;
          &lt;div class=&quot;nb-math-eq&quot;&gt;\tilde q(s, a) = \sum_{s&#x27;} P(s&#x27; \mid s, a)\,\bigl[R(s&#x27;) + \gamma\, \tilde v_*(s&#x27;)\bigr]&lt;/div&gt;
        &lt;/figure&gt;
        &lt;p&gt;With &lt;span class=&quot;nb-math-in&quot;&gt;v_\pi&lt;/span&gt; in place of &lt;span class=&quot;nb-math-in&quot;&gt;\tilde v_*&lt;/span&gt;, &lt;span class=&quot;nb-math-in&quot;&gt;\tilde q&lt;/span&gt; becomes &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi&lt;/span&gt;, and the equation is the one an unchanged policy satisfies. The new grid&#x27;s Bellman optimality equation has only one solution, so a policy the step leaves unchanged has &lt;span class=&quot;nb-math-in&quot;&gt;v_\pi = \tilde v_*&lt;/span&gt;. It is the best ε-soft policy.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, p. 102&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
        &lt;p&gt;&lt;code&gt;best_soft&lt;/code&gt; builds &lt;span class=&quot;nb-math-in&quot;&gt;\tilde P&lt;/span&gt; and runs &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;value iteration&lt;/a&gt; on it, which gives &lt;span class=&quot;nb-math-in&quot;&gt;\tilde v_*&lt;/span&gt;, and its &lt;code&gt;q[s, a]&lt;/code&gt; is &lt;span class=&quot;nb-math-in&quot;&gt;\tilde q(s, a)&lt;/span&gt;. The second panel of Fig.&amp;nbsp;2 draws &lt;span class=&quot;nb-math-in&quot;&gt;\tilde q&lt;/span&gt; for ε = 0.1, the action values that run 0&#x27;s averages were estimating.&lt;/p&gt;
        &lt;p&gt;The argument assumes exact action values: Sutton and Barto say it &amp;ldquo;does assume that they are computed exactly&amp;rdquo;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.4, pp. 102-103&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; The book gives no proof for the sampled version in &lt;code&gt;soft_control&lt;/code&gt;, which steps on averages after every episode, so for that version this lesson has only its runs. A later lesson&#x27;s method, SARSA, does reach an optimal policy, with suitable step sizes, if ε shrinks toward 0 while every move is still tried infinitely often. Singh and colleagues call a policy like that GLIE, short for greedy in the limit with infinite exploration.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;Section 2.2, pp. 291-292; Theorem 1, p. 294&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;price&quot; id=&quot;price&quot;&gt;
        &lt;h2&gt;How much ε costs&lt;/h2&gt;
        &lt;p&gt;Table&amp;nbsp;1 uses &lt;code&gt;best_soft&lt;/code&gt; to compare the best ε-soft value with the optimal value &lt;span class=&quot;nb-math-in&quot;&gt;v_*&lt;/span&gt;, averaged over the 14 cells an episode can start in.&lt;/p&gt;
        &lt;table class=&quot;nb-table&quot;&gt;
          &lt;caption&gt;Table&amp;nbsp;1 · The loss &lt;span class=&quot;nb-math-in&quot;&gt;v_* - \tilde v_*&lt;/span&gt; of the best ε-soft policy, averaged over the 14 starting cells, and the cells whose best moves differ from the optimal ones. From &lt;code&gt;exploration.py&lt;/code&gt;.&lt;/caption&gt;
          &lt;thead&gt;
            &lt;tr&gt;&lt;th&gt;ε&lt;/th&gt;&lt;th&gt;Average loss&lt;/th&gt;&lt;th class=&quot;txt&quot;&gt;Changed moves&lt;/th&gt;&lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            &lt;tr&gt;&lt;td&gt;0.01&lt;/td&gt;&lt;td&gt;0.10&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;none&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;0.1&lt;/td&gt;&lt;td&gt;1.08&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;none&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;0.2&lt;/td&gt;&lt;td&gt;2.23&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;none&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;0.3&lt;/td&gt;&lt;td&gt;3.46&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;none&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;0.5&lt;/td&gt;&lt;td&gt;6.09&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;cell 9&lt;/td&gt;&lt;/tr&gt;
          &lt;/tbody&gt;
        &lt;/table&gt;
        &lt;p&gt;The loss grows almost in proportion to ε. At ε = 0.1 it is 1.08, about the size of one move&#x27;s reward of &amp;minus;1. Up to ε = 0.32 the best ε-soft policy keeps the optimal arrows and differs from the optimal policy only in its random moves.&lt;/p&gt;
        &lt;p&gt;From ε = 0.33 the arrows change at cell 9. Fig.&amp;nbsp;3 shows why at ε = 0.5. Up and right from cell 9 lead mostly to cells 5 and 10, which border the pit, while left and down lead mostly to cells 8 and 13. Under the optimal policy cells 5 and 10 are worth more, 0.06 against &amp;minus;0.71. Under the best ε-soft policy at ε = 0.5 they are worth less, &amp;minus;7.08 against &amp;minus;6.64, so cell 9 aims left or down.&lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
&lt;div style=&quot;display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center&quot;&gt;&lt;svg viewBox=&quot;0 0 220 234&quot; role=&quot;img&quot; aria-label=&quot;The optimal values and moves. Cells 5 and 10, beside the pit, are worth 0.06, more than cells 8 and 13 at minus 0.71, and cell 9 aims up or right.&quot; style=&quot;flex: 1 1 13rem; min-width: 0; max-width: 20rem; height: auto&quot;&gt;&lt;text x=&quot;110.0&quot; y=&quot;16&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12.5px;fill:var(--ink);font-weight:600&quot;&gt;optimal, ε = 0&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.395;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;43.0&quot; x2=&quot;43.0&quot; y2=&quot;43.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;47.0,43.0 43.0,46.2 43.0,39.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;68.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;2.16&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.618;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;43.0&quot; x2=&quot;93.0&quot; y2=&quot;43.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;97.0,43.0 93.0,46.2 93.0,39.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;68.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;4.04&lt;/text&gt;&lt;rect x=&quot;110&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;43.0&quot; x2=&quot;143.0&quot; y2=&quot;43.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;147.0,43.0 143.0,46.2 143.0,39.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;68.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;6.48&lt;/text&gt;&lt;rect x=&quot;162&quot; y=&quot;28&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;55.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.213;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;97.0&quot; x2=&quot;35.0&quot; y2=&quot;85.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,81.0 38.2,85.0 31.8,85.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;118.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;0.61&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.147;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;97.0&quot; x2=&quot;85.0&quot; y2=&quot;85.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,81.0 88.2,85.0 81.8,85.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;118.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;0.06&lt;/text&gt;&lt;rect x=&quot;112&quot; y=&quot;78&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;105.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;&lt;rect x=&quot;160&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;97.0&quot; x2=&quot;185.0&quot; y2=&quot;85.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,81.0 188.2,85.0 181.8,85.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;118.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;6.48&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.225;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;147.0&quot; x2=&quot;35.0&quot; y2=&quot;135.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,131.0 38.2,135.0 31.8,135.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−0.71&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.260;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;147.0&quot; x2=&quot;85.0&quot; y2=&quot;135.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,131.0 88.2,135.0 81.8,135.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;143.0&quot; x2=&quot;93.0&quot; y2=&quot;143.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;97.0,143.0 93.0,146.2 93.0,139.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−1.01&lt;/text&gt;&lt;rect x=&quot;110&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.147;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;143.0&quot; x2=&quot;143.0&quot; y2=&quot;143.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;147.0,143.0 143.0,146.2 143.0,139.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;0.06&lt;/text&gt;&lt;rect x=&quot;160&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.618;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;147.0&quot; x2=&quot;185.0&quot; y2=&quot;135.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,131.0 188.2,135.0 181.8,135.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;4.04&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.345;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;197.0&quot; x2=&quot;35.0&quot; y2=&quot;185.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,181.0 38.2,185.0 31.8,185.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;193.0&quot; x2=&quot;43.0&quot; y2=&quot;193.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;47.0,193.0 43.0,196.2 43.0,189.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−1.73&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.225;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;193.0&quot; x2=&quot;93.0&quot; y2=&quot;193.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;97.0,193.0 93.0,196.2 93.0,189.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−0.71&lt;/text&gt;&lt;rect x=&quot;110&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.213;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;193.0&quot; x2=&quot;143.0&quot; y2=&quot;193.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;147.0,193.0 143.0,196.2 143.0,189.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;0.61&lt;/text&gt;&lt;rect x=&quot;160&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.395;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;197.0&quot; x2=&quot;185.0&quot; y2=&quot;185.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,181.0 188.2,185.0 181.8,185.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;2.16&lt;/text&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 220 234&quot; role=&quot;img&quot; aria-label=&quot;The best epsilon-soft policy for epsilon 0.5. Every value is lower. Cells 5 and 10 are worth minus 7.08, now less than cells 8 and 13 at minus 6.64, and cell 9 aims left or down, which is not optimal.&quot; style=&quot;flex: 1 1 13rem; min-width: 0; max-width: 20rem; height: auto&quot;&gt;&lt;text x=&quot;110.0&quot; y=&quot;16&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12.5px;fill:var(--ink);font-weight:600&quot;&gt;best ε-soft, ε = 0.5&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.620;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;43.0&quot; x2=&quot;43.0&quot; y2=&quot;43.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;47.0,43.0 43.0,46.2 43.0,39.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;68.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−4.05&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.407;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;43.0&quot; x2=&quot;93.0&quot; y2=&quot;43.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;97.0,43.0 93.0,46.2 93.0,39.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;68.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−2.26&lt;/text&gt;&lt;rect x=&quot;110&quot; y=&quot;26&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.308;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;43.0&quot; x2=&quot;143.0&quot; y2=&quot;43.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;147.0,43.0 143.0,46.2 143.0,39.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;68.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;1.42&lt;/text&gt;&lt;rect x=&quot;162&quot; y=&quot;28&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;55.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.811;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;97.0&quot; x2=&quot;35.0&quot; y2=&quot;85.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,81.0 38.2,85.0 31.8,85.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;118.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−5.67&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;97.0&quot; x2=&quot;85.0&quot; y2=&quot;85.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,81.0 88.2,85.0 81.8,85.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;118.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−7.08&lt;/text&gt;&lt;rect x=&quot;112&quot; y=&quot;78&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;105.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;&lt;rect x=&quot;160&quot; y=&quot;76&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.308;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;97.0&quot; x2=&quot;185.0&quot; y2=&quot;85.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,81.0 188.2,85.0 181.8,85.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;118.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;1.42&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;147.0&quot; x2=&quot;35.0&quot; y2=&quot;135.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,131.0 38.2,135.0 31.8,135.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−6.64&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;85.0&quot; y1=&quot;139.0&quot; x2=&quot;85.0&quot; y2=&quot;151.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;85.0,155.0 81.8,151.0 88.2,151.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;line x1=&quot;89.0&quot; y1=&quot;143.0&quot; x2=&quot;77.0&quot; y2=&quot;143.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;73.0,143.0 77.0,139.8 77.0,146.2&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−7.10&lt;/text&gt;&lt;rect x=&quot;62.5&quot; y=&quot;128.5&quot; width=&quot;45&quot; height=&quot;45&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;&lt;rect x=&quot;110&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;143.0&quot; x2=&quot;143.0&quot; y2=&quot;143.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;147.0,143.0 143.0,146.2 143.0,139.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−7.08&lt;/text&gt;&lt;rect x=&quot;160&quot; y=&quot;126&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.407;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;147.0&quot; x2=&quot;185.0&quot; y2=&quot;135.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,131.0 188.2,135.0 181.8,135.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;168.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−2.26&lt;/text&gt;&lt;rect x=&quot;10&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;35.0&quot; y1=&quot;197.0&quot; x2=&quot;35.0&quot; y2=&quot;185.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;35.0,181.0 38.2,185.0 31.8,185.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;line x1=&quot;31.0&quot; y1=&quot;193.0&quot; x2=&quot;43.0&quot; y2=&quot;193.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;47.0,193.0 43.0,196.2 43.0,189.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;35.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−7.10&lt;/text&gt;&lt;rect x=&quot;60&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;81.0&quot; y1=&quot;193.0&quot; x2=&quot;93.0&quot; y2=&quot;193.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;97.0,193.0 93.0,196.2 93.0,189.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;85.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−6.64&lt;/text&gt;&lt;rect x=&quot;110&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.811;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;131.0&quot; y1=&quot;193.0&quot; x2=&quot;143.0&quot; y2=&quot;193.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;147.0,193.0 143.0,196.2 143.0,189.8&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;135.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−5.67&lt;/text&gt;&lt;rect x=&quot;160&quot; y=&quot;176&quot; width=&quot;50&quot; height=&quot;50&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.620;stroke:var(--ink-soft);stroke-width:0.6;stroke-opacity:0.6&quot;/&gt;&lt;line x1=&quot;185.0&quot; y1=&quot;197.0&quot; x2=&quot;185.0&quot; y2=&quot;185.0&quot; style=&quot;stroke:var(--ink);stroke-width:1.8;fill:none&quot;/&gt;&lt;polygon points=&quot;185.0,181.0 188.2,185.0 181.8,185.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;&lt;text x=&quot;185.0&quot; y=&quot;218.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink)&quot;&gt;−4.05&lt;/text&gt;&lt;/svg&gt;&lt;/div&gt;&lt;svg viewBox=&quot;0 0 373.2 30&quot; role=&quot;img&quot; aria-label=&quot;Legend: green shading for values above 0, red below, deepest at 6 or more either way; an amber square marks an arrow not optimal.&quot; style=&quot;display: block; width: 100%; max-width: 29.2rem; margin: 0.4rem auto 0; height: auto&quot;&gt;&lt;rect x=&quot;8&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;27&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;−6 or less&lt;/text&gt;&lt;rect x=&quot;105.0&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.140;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;124.0&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;0&lt;/text&gt;&lt;rect x=&quot;144.4&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.8&quot;/&gt;&lt;text x=&quot;163.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;+6 or more&lt;/text&gt;&lt;rect x=&quot;241.4&quot; y=&quot;9&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:2.4&quot;/&gt;&lt;text x=&quot;260.4&quot; y=&quot;20&quot; style=&quot;font-family:var(--sans);font-size:11.5px;fill:var(--ink-soft)&quot;&gt;arrow not optimal&lt;/text&gt;&lt;/svg&gt;
          &lt;figcaption&gt;Fig.&amp;nbsp;3 · State values and best moves of the optimal policy and of the best ε-soft policy for ε = 0.5. The amber square marks cell 9, whose best moves are no longer optimal. From &lt;code&gt;exploration.py&lt;/code&gt;.&lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;The runs land there too. With ε = 0.5, 18 of 20 runs have the best ε-soft arrows after 10,000 episodes, against 6 with ε = 0.1. All 20 have them after 100,000, each aiming cell 9 left or down. On this grid, runs with ε = 0.1 reach the optimal arrows from ordinary starts and lose 1.08 per start to their random moves. Runs with ε = 0.5 reach their resting point sooner, and the arrows they rest on are not optimal.&lt;/p&gt;
        &lt;aside class=&quot;nb-note&quot;&gt;
          &lt;span class=&quot;nb-note-label&quot;&gt;Problems&lt;/span&gt;
          &lt;p&gt;1. Cell 2&#x27;s greedy move is right, into the goal, and the pit is directly below it. Under the ε-greedy policy with ε = 0.1, what is the probability that the agent&#x27;s next move from cell 2 lands in the pit? How does that compare with the greedy policy?&lt;/p&gt;
          &lt;details&gt;
            &lt;summary&gt;Answer&lt;/summary&gt;
            &lt;p&gt;The greedy policy aims right and slips down into the pit with probability 0.1. The ε-greedy policy aims right with probability 0.925 and each other way with 0.025. Aiming up cannot reach the pit, aiming down lands in it with 0.8, and aiming left slips down into it with 0.1. The total is &lt;span class=&quot;nb-math-in&quot;&gt;0.925 \times 0.1 + 0.025 \times (0 + 0.8 + 0.1) = 0.115&lt;/span&gt;. It is the entry &lt;span class=&quot;nb-math-in&quot;&gt;\tilde P(6 \mid 2, \text{right})&lt;/span&gt; of the new grid, &lt;span class=&quot;nb-math-in&quot;&gt;0.9 \times 0.1 + 0.1 \times 0.25&lt;/span&gt;.&lt;/p&gt;
          &lt;/details&gt;
          &lt;p&gt;2. Suppose each episode opened with a random (cell, move) pair, as with &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/action-values-from-samples.html&quot;&gt;exploring starts&lt;/a&gt;, and the agent then followed the ε-greedy policy with ε = 0.1. Where could the policy stop?&lt;/p&gt;
          &lt;details&gt;
            &lt;summary&gt;Answer&lt;/summary&gt;
            &lt;p&gt;Only at the best ε-soft policy. Exploring starts choose only each episode&#x27;s first pair. After that move the agent follows the ε-greedy policy, so each return is still a sample of that policy&#x27;s action value for the pair it follows. The averages estimate the same action values as before, and the ε-greedy step has the same single resting point.&lt;/p&gt;
          &lt;/details&gt;
        &lt;/aside&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-bookend&quot; data-nb-section=&quot;takeaway&quot; id=&quot;takeaway&quot;&gt;
        &lt;p class=&quot;nb-bookend-name&quot;&gt;The takeaway&lt;/p&gt;
        &lt;div class=&quot;nb-bookend-rule&quot;&gt;&lt;/div&gt;
        &lt;p&gt;A greedy policy collects returns only for the moves it takes, so with ordinary starts the greedy step never switches to the others. An ε-greedy policy gives every move at least ε divided by the number of moves, so every move keeps collecting returns. With exact action values, the ε-greedy step never makes an ε-soft policy worse, and it can stop only at the best ε-soft policy, the optimal policy of a grid that replaces the agent&#x27;s move at random with probability ε. That policy loses 1.08 per start at ε = 0.1 on the course grid, and from ε = 0.33 its arrows are no longer optimal.&lt;/p&gt;
        &lt;div class=&quot;nb-bookend-band&quot;&gt;
          &lt;span class=&quot;nb-bookend-label&quot;&gt;Go deeper&lt;/span&gt;
          &lt;span class=&quot;nb-bookend-note&quot;&gt;optional reading&lt;/span&gt;
        &lt;/div&gt;
        &lt;dl class=&quot;nb-bookend-reading&quot;&gt;
          &lt;dt&gt;01&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;http://incompleteideas.net/book/RLbook2020.pdf#page=123&quot;&gt;Sutton and Barto, Section 5.4&lt;/a&gt;: read the box on p. 101 line by line against &lt;code&gt;soft_control.py&lt;/code&gt;. Its title says it estimates &lt;span class=&quot;nb-math-in&quot;&gt;\pi_*&lt;/span&gt;, and the text on p. 103 says the method reaches only the best ε-soft policy.&lt;/dd&gt;
          &lt;dt&gt;02&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;https://sites.ualberta.ca/~szepesva/papers/singh98convergence.pdf&quot;&gt;Singh, Jaakkola, Littman and Szepesvári, Convergence Results for Single-Step On-Policy Reinforcement-Learning Algorithms&lt;/a&gt;: Figure 1 (p. 288) is a three-state problem where exploring half the time changes the best action, as ε = 0.5 does at cell 9, and Section 2.2 (pp. 291&amp;ndash;292) defines GLIE.&lt;/dd&gt;
          &lt;dt&gt;03&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;http://incompleteideas.net/book/RLbook2020.pdf#page=51&quot;&gt;Sutton and Barto, Section 2.3&lt;/a&gt;: in a ten-armed bandit, greedy selection stalls for a different reason, because a move whose first samples look bad is never tried again (pp. 29&amp;ndash;30).&lt;/dd&gt;
          &lt;dt&gt;04&lt;/dt&gt;
          &lt;dd&gt;&lt;a href=&quot;http://incompleteideas.net/book/RLbook2020.pdf#page=154&quot;&gt;Sutton and Barto, Example 6.6&lt;/a&gt;: on a cliff, SARSA with ε = 0.1 learns a longer, safer path (p. 132), the same effect as ε = 0.5 at cell 9, under a method a later lesson teaches.&lt;/dd&gt;
        &lt;/dl&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-note=&quot;Read in the authors&#x27; free copy at incompleteideas.net/book/RLbook2020.pdf. Page numbers are the printed ones; the PDF page is the printed page plus 22.&quot; href=&quot;https://mitpress.mit.edu/9780262039246/reinforcement-learning/&quot;&gt;MIT Press &amp;middot; Richard S. Sutton and Andrew G. Barto, Reinforcement Learning: An Introduction, 2nd edition, 2018 (second printing 2020)&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-note=&quot;Machine Learning 38(3), March 2000, pp. 287-308, per Crossref. The free copy at sites.ualberta.ca/~szepesva/papers/singh98convergence.pdf prints volume 39 and carries the journal pagination.&quot; href=&quot;https://doi.org/10.1023/A:1007678930559&quot;&gt;Machine Learning &amp;middot; Satinder Singh, Tommi Jaakkola, Michael L. Littman and Csaba Szepesvári, Convergence Results for Single-Step On-Policy Reinforcement-Learning Algorithms, 2000&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="reinforcement-learning"/>
  </entry>
  <entry>
    <title>Democrats win back the House and the Senate</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-11-04.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-11-04</id>
    <updated>2026-11-04T06:39:19Z</updated>
    <summary>By AP’s 1:35 a.m. Eastern count, Democrats had gained 25 House seats and seven Senate seats, and Missouri voters had rejected the map Trump asked for.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Daily Brief&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;Democrats win back the House and the Senate&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;By AP’s 1:35 a.m. Eastern count, Democrats had gained 25 House seats and seven Senate seats, and Missouri voters had rejected the map Trump asked for.&lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;3 min read&lt;/span&gt;&lt;span&gt;2026-11-04&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section data-nb-section=&quot;items&quot; id=&quot;items&quot;&gt;
        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Word of the Day&lt;/span&gt;
          &lt;div class=&quot;rs-word-card&quot;&gt;
            &lt;div class=&quot;rs-word-card-head&quot;&gt;
              &lt;span class=&quot;rs-word-term&quot;&gt;psephology&lt;/span&gt;
              &lt;span class=&quot;rs-word-meta&quot;&gt;
                &lt;span class=&quot;rs-word-pos&quot;&gt;noun&lt;/span&gt;
                &lt;span class=&quot;rs-word-pronunciation&quot;&gt;/sē-ˈfä-lə-jē/&lt;/span&gt;
              &lt;/span&gt;
            &lt;/div&gt;
            &lt;p class=&quot;rs-word-definition&quot;&gt;
              The scientific study of elections, from the Greek &lt;i&gt;psēphos&lt;/i&gt;, a pebble, because the ancient Greeks voted with pebbles.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;p&gt;
            Nuffield College, Oxford, says the word “started out as an academic joke suggested to R.B. McCallum,” and it caught on.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
            McCallum printed it in the &lt;i&gt;Oxford Magazine&lt;/i&gt; in 1951, reviewing the college’s study of the 1950 British election, and David Butler put it in a book the next year.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
            Touring the United States in 1952, Butler “found himself overwhelmed by journalists asking about the new word.”&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;AP calls both chambers of Congress for Democrats&lt;/h3&gt;
          &lt;p&gt;
            The Associated Press called the Senate for Democrats before midnight Eastern, after James Talarico beat Ken Paxton in Texas and Sherrod Brown unseated Sen. Jon Husted in Ohio.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
            It had called the House for them by 1:27 a.m.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;
            At 1:35, AP’s tally on Fox News’s results page gave Democrats 220 House seats, two past the 218 for a majority, and a net gain of 25 where they needed three. Republicans had 127, and 88 races were uncalled.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
            In the Senate the same tally gave Democrats 53 seats and a net gain of seven, with six races uncalled.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;Missouri voters strike down the map drawn to unseat Emanuel Cleaver&lt;/h3&gt;
          &lt;p&gt;
            Proposition A, the referendum on the 2025 map Missouri’s legislature drew at Trump’s request to unseat Rep. Emanuel Cleaver, was losing 62% to 38% when AP called it at 9:59 p.m. Central, so those lines will not be used in 2028.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;
            Voters also rejected Amendment 3, which would have banned most abortions again two years after they ended the ban.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;Trump says US aid to Israel stops at the end of 2026&lt;/h3&gt;
          &lt;p&gt;
            “We were giving them $4 billion – we are – but it gets cut off at the end of the year,” Trump said on Fox &amp;amp; Friends, and he said Benjamin Netanyahu had approached him about it.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;
            No Israeli or White House official is quoted confirming the cutoff.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;
            The aid runs at $3.8 billion a year under a memorandum of understanding that expires in 2028, and Congress appropriates it.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s9&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Technology&lt;/span&gt;
          &lt;h3&gt;Hugging Face finds UMT5’s decoder saw future tokens for almost two months&lt;/h3&gt;
          &lt;p&gt;
            A Transformers change of 30 July that enabled PyTorch SDPA for T5 let UMT5’s decoder attend to future tokens in training, and nothing crashed before the 28 September fix, Hugging Face disclosed.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s10&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;
            Its proposed Model Integration Contracts, a shrunk fixture plus a runnable usage path and reviewed baselines, flagged the bug on every replayed commit with a 66 MB UMT5 fixture, where eager-attention tests missed it.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s10&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;
            A UMT5 fine-tune on main in that window, with default SDPA attention, trained a decoder that could see its targets.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s10&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Technology&lt;/span&gt;
          &lt;h3&gt;StateBench finds state tracking that Gated DeltaNet learns and transformers miss&lt;/h3&gt;
          &lt;p&gt;
            Allen Institute for AI researchers sort state-tracking problems into four Krohn-Rhodes levels (r-trivial, aperiodic, soluble, general finite) and prove that Gated DeltaNet with positive eigenvalues expresses every aperiodic problem.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s11&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;
            Ai2 reports that 275M-parameter Gated DeltaNet and hybrid models trained on up to 256 assignments generalized almost perfectly to 64,000 on the first three levels, while transformers never learned general finite problems.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s12&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;
            Four frontier models, among them Claude Opus 5.5 and GPT-6 Sol, fall to chance on the two hardest levels at 10K to 64K tokens.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s11&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;headword block; Did you know?; Etymology&quot; href=&quot;https://www.merriam-webster.com/dictionary/psephology&quot;&gt;Merriam-Webster · psephology&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;paragraphs 1-3&quot; href=&quot;https://www.nuffield.ox.ac.uk/people/sites/the-david-butler-archive/psephology/&quot;&gt;Nuffield College · Psephology&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s3&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;paragraphs 1-2, 6-8&quot; href=&quot;https://www.pbs.org/newshour/politics/democrats-take-control-of-the-senate-after-winning-key-midterm-races&quot;&gt;AP, via PBS · Democrats take control of the Senate&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s4&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;dateline paragraph; published 1:27 a.m. EST 4 November 2026&quot; href=&quot;https://www.pbs.org/newshour/politics/democrats-win-control-of-the-u-s-house&quot;&gt;AP, via PBS · Democrats win control of the U.S. House&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s5&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;balance-of-power panel and race-call list, retrieved 06:35 UTC (1:35 a.m. EST) 4 November 2026&quot; data-nb-note=&quot;AP race calls and tally as published by Fox News (Source: The Associated Press)&quot; href=&quot;https://www.foxnews.com/elections/2026/midterm-results/house&quot;&gt;AP data, via Fox News · House results&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s6&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;paragraphs 1-3, 5-7, 13-14&quot; href=&quot;https://www.kcur.org/politics-elections-and-government/2026-11-03/missouri-proposition-a-election-results-redistricting&quot;&gt;STLPR, via KCUR · Proposition A&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s7&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;paragraphs 1-6&quot; href=&quot;https://www.kcur.org/2026-11-03/missouri-amendment-3-abortion-legal&quot;&gt;STLPR, via KCUR · Amendment 3&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s8&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;opening paragraphs; the “I was approached by Bibi Netanyahu” paragraph&quot; href=&quot;https://www.foxnews.com/politics/trump-says-israel-stop-receiving-4b-us-aid-years-end-can-still-buy-weapons&quot;&gt;Fox News · Trump on aid to Israel&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s9&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;paragraphs 1-4, 6&quot; href=&quot;https://www.cnn.com/2026/11/03/politics/trump-us-aid-israel&quot;&gt;CNN · Trump on US aid to Israel&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s10&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;opening paragraphs; Introducing Model Integration Contracts; replay paragraph; closing section&quot; href=&quot;https://huggingface.co/blog/transformers-mic&quot;&gt;Hugging Face · Model Integration Contracts&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s11&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;abstract; §6, Figure 6 paragraph&quot; href=&quot;https://arxiv.org/abs/2611.03094&quot;&gt;Petty, Merrill and Sabharwal · arXiv 2611.03094&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s12&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;What we found&quot; href=&quot;https://huggingface.co/blog/allenai/statebench&quot;&gt;Ai2 · StateBench&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>Marvell’s $115 billion for laser maker Lumentum works out to 23 times its revenue run rate</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/marvell-lumentum-optics.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/marvell-lumentum-optics</id>
    <updated>2026-11-03T06:43:36Z</updated>
    <summary>Priced at Marvell’s 28 October close, the deal comes to 18 times Lumentum’s annualized December guidance, just under Marvell’s own revenue multiple that day.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Feature&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;Marvell&amp;rsquo;s $115 billion for laser maker Lumentum works out to 23 times its revenue run rate&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;
          Priced at Marvell&amp;rsquo;s 28 October close, the deal comes to 18 times Lumentum&amp;rsquo;s annualized December guidance, just under Marvell&amp;rsquo;s own revenue multiple that day.
        &lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;5 min read&lt;/span&gt;&lt;span&gt;2026-11-03&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section data-nb-section=&quot;orientation&quot; id=&quot;orientation&quot;&gt;
        &lt;h2&gt;A fixed ratio puts a dollar price on one day&lt;/h2&gt;
        &lt;p&gt;
          In Marvell&amp;rsquo;s own drawing of an optical module, the electronics are Marvell&amp;rsquo;s and every laser is Lumentum&amp;rsquo;s.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Slide 13&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          On 2 November the two companies announced that Marvell will buy Lumentum for 4.500 Marvell shares per Lumentum share, an implied enterprise value of $115 billion.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;Paragraph 1&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
          Neither company states a multiple. Divided by Lumentum&amp;rsquo;s September quarter of $1.263 billion annualized, its run rate, the price is 22.8 times revenue. It is 14.4 times if Lumentum reaches the $8 billion a year its March investor deck sets as a target.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Fiscal First Quarter Highlights&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot; data-nb-locator=&quot;Slide 38&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          The $115 billion is a value at Marvell&amp;rsquo;s 28 October closing price, the last trading day before market speculation about the deal began.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;Paragraph 1&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Slide 9&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          The ratio is fixed, so the dollar price moves with Marvell&amp;rsquo;s stock until the close, expected in the first half of 2028.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;electronics-and-light&quot; id=&quot;electronics-and-light&quot;&gt;
        &lt;h2&gt;Co-packaged optics leaves Lumentum the light source&lt;/h2&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
          &lt;div style=&quot;display: flex; flex-wrap: wrap; gap: 1rem&quot;&gt;
            &lt;svg role=&quot;img&quot; viewBox=&quot;0 0 400 232&quot; style=&quot;flex: 1 1 18rem; min-width: 0; height: auto&quot; aria-label=&quot;Pluggable module for scale-out. A host switch or XPU sends electrical SerDes lanes to a DSP. In the transmit direction the DSP feeds a driver, which feeds an EML laser, which sends light into a fiber. In the receive direction light from a fiber reaches a photodiode, then a TIA, then the DSP, and the DSP returns electrical lanes to the host. The DSP, driver and TIA are Marvell blocks, the EML laser and photodiode are Lumentum blocks, and the host is not colored.&quot;&gt;
              &lt;defs&gt;
                &lt;marker id=&quot;ahA&quot; viewBox=&quot;0 0 10 10&quot; refX=&quot;9&quot; refY=&quot;5&quot; markerUnits=&quot;userSpaceOnUse&quot; markerWidth=&quot;9&quot; markerHeight=&quot;9&quot; orient=&quot;auto&quot;&gt;&lt;path d=&quot;M0 0L10 5L0 10z&quot; style=&quot;fill: var(--ink-soft)&quot;/&gt;&lt;/marker&gt;
              &lt;/defs&gt;
              &lt;text x=&quot;8&quot; y=&quot;16&quot; style=&quot;font: 600 13px var(--sans); fill: var(--ink)&quot;&gt;Pluggable module, scale-out&lt;/text&gt;
              &lt;rect x=&quot;100&quot; y=&quot;34&quot; width=&quot;240&quot; height=&quot;186&quot; rx=&quot;6&quot; style=&quot;fill: none; stroke: var(--ink-soft); stroke-width: 1; stroke-dasharray: 4 3&quot;/&gt;
              &lt;text x=&quot;108&quot; y=&quot;50&quot; style=&quot;font: 500 11px var(--sans); fill: var(--ink-soft)&quot;&gt;Module&lt;/text&gt;
              &lt;rect x=&quot;6&quot; y=&quot;70&quot; width=&quot;56&quot; height=&quot;130&quot; rx=&quot;3&quot; style=&quot;fill: var(--wash); stroke: var(--ink-soft); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;34&quot; y=&quot;128&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 12px var(--sans); fill: var(--ink)&quot;&gt;Host&lt;/text&gt;
              &lt;text x=&quot;34&quot; y=&quot;143&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 12px var(--sans); fill: var(--ink)&quot;&gt;switch&lt;/text&gt;
              &lt;text x=&quot;34&quot; y=&quot;158&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 12px var(--sans); fill: var(--ink)&quot;&gt;or XPU&lt;/text&gt;
              &lt;rect x=&quot;112&quot; y=&quot;70&quot; width=&quot;48&quot; height=&quot;130&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.22; stroke: var(--chart-2); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;136&quot; y=&quot;139&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;DSP&lt;/text&gt;
              &lt;rect x=&quot;184&quot; y=&quot;76&quot; width=&quot;60&quot; height=&quot;44&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.22; stroke: var(--chart-2); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;214&quot; y=&quot;103&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;Driver&lt;/text&gt;
              &lt;rect x=&quot;268&quot; y=&quot;76&quot; width=&quot;60&quot; height=&quot;44&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-6); fill-opacity: 0.22; stroke: var(--chart-6); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;298&quot; y=&quot;95&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;EML&lt;/text&gt;
              &lt;text x=&quot;298&quot; y=&quot;110&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;laser&lt;/text&gt;
              &lt;rect x=&quot;184&quot; y=&quot;150&quot; width=&quot;60&quot; height=&quot;44&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.22; stroke: var(--chart-2); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;214&quot; y=&quot;177&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;TIA&lt;/text&gt;
              &lt;rect x=&quot;268&quot; y=&quot;150&quot; width=&quot;60&quot; height=&quot;44&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-6); fill-opacity: 0.22; stroke: var(--chart-6); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;298&quot; y=&quot;169&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 11px var(--sans); fill: var(--ink)&quot;&gt;Photo-&lt;/text&gt;
              &lt;text x=&quot;298&quot; y=&quot;184&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 11px var(--sans); fill: var(--ink)&quot;&gt;diode&lt;/text&gt;
              &lt;g style=&quot;stroke: var(--ink-soft); stroke-width: 1.5; fill: none&quot; marker-end=&quot;url(#ahA)&quot;&gt;
                &lt;path d=&quot;M62 98H110&quot; marker-end=&quot;url(#ahA)&quot;/&gt;
                &lt;path d=&quot;M160 98H182&quot; marker-end=&quot;url(#ahA)&quot;/&gt;
                &lt;path d=&quot;M244 98H266&quot; marker-end=&quot;url(#ahA)&quot;/&gt;
                &lt;path d=&quot;M266 172H246&quot; marker-end=&quot;url(#ahA)&quot;/&gt;
                &lt;path d=&quot;M182 172H162&quot; marker-end=&quot;url(#ahA)&quot;/&gt;
                &lt;path d=&quot;M110 172H64&quot; marker-end=&quot;url(#ahA)&quot;/&gt;
              &lt;/g&gt;
              &lt;path d=&quot;M328 98H392&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 3; fill: none&quot;/&gt;
              &lt;path d=&quot;M392 172H330&quot; marker-end=&quot;url(#ahA)&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 3; fill: none&quot;/&gt;
              &lt;text x=&quot;362&quot; y=&quot;90&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 11px var(--sans); fill: var(--ink-soft)&quot;&gt;fiber&lt;/text&gt;
              &lt;text x=&quot;81&quot; y=&quot;91&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 10px var(--sans); fill: var(--ink-soft)&quot;&gt;SerDes&lt;/text&gt;
              &lt;text x=&quot;81&quot; y=&quot;165&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 10px var(--sans); fill: var(--ink-soft)&quot;&gt;SerDes&lt;/text&gt;
              &lt;text x=&quot;178&quot; y=&quot;212&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 11px var(--sans); fill: var(--ink-soft)&quot;&gt;Electronics&lt;/text&gt;
              &lt;text x=&quot;298&quot; y=&quot;212&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 11px var(--sans); fill: var(--ink-soft)&quot;&gt;Photonics&lt;/text&gt;
            &lt;/svg&gt;
            &lt;svg role=&quot;img&quot; viewBox=&quot;0 0 400 232&quot; style=&quot;flex: 1 1 18rem; min-width: 0; height: auto&quot; aria-label=&quot;Co-packaged optics for scale-up. Inside a package, an XPU or switch connects to an EIC, which connects to a PIC, which sends modulated light out on a fiber. Outside the package, an ELSFP holding an ultra-high-power laser sends unmodulated light on a fiber to the PIC. The XPU or switch, EIC and PIC are Marvell blocks and the ELSFP laser is a Lumentum block.&quot;&gt;
              &lt;defs&gt;
                &lt;marker id=&quot;ahB&quot; viewBox=&quot;0 0 10 10&quot; refX=&quot;9&quot; refY=&quot;5&quot; markerUnits=&quot;userSpaceOnUse&quot; markerWidth=&quot;9&quot; markerHeight=&quot;9&quot; orient=&quot;auto&quot;&gt;&lt;path d=&quot;M0 0L10 5L0 10z&quot; style=&quot;fill: var(--ink-soft)&quot;/&gt;&lt;/marker&gt;
              &lt;/defs&gt;
              &lt;text x=&quot;8&quot; y=&quot;16&quot; style=&quot;font: 600 13px var(--sans); fill: var(--ink)&quot;&gt;Co-packaged optics, scale-up&lt;/text&gt;
              &lt;rect x=&quot;8&quot; y=&quot;60&quot; width=&quot;222&quot; height=&quot;150&quot; rx=&quot;6&quot; style=&quot;fill: none; stroke: var(--ink-soft); stroke-width: 1; stroke-dasharray: 4 3&quot;/&gt;
              &lt;text x=&quot;16&quot; y=&quot;76&quot; style=&quot;font: 500 11px var(--sans); fill: var(--ink-soft)&quot;&gt;Package&lt;/text&gt;
              &lt;rect x=&quot;18&quot; y=&quot;100&quot; width=&quot;60&quot; height=&quot;80&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.22; stroke: var(--chart-2); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;48&quot; y=&quot;136&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;XPU or&lt;/text&gt;
              &lt;text x=&quot;48&quot; y=&quot;151&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;switch&lt;/text&gt;
              &lt;rect x=&quot;96&quot; y=&quot;118&quot; width=&quot;44&quot; height=&quot;44&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.22; stroke: var(--chart-2); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;118&quot; y=&quot;145&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;EIC&lt;/text&gt;
              &lt;rect x=&quot;156&quot; y=&quot;118&quot; width=&quot;44&quot; height=&quot;44&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.22; stroke: var(--chart-2); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;178&quot; y=&quot;145&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;PIC&lt;/text&gt;
              &lt;text x=&quot;274&quot; y=&quot;38&quot; text-anchor=&quot;end&quot; style=&quot;font: 500 11px var(--sans); fill: var(--ink-soft)&quot;&gt;unmodulated light&lt;/text&gt;
              &lt;text x=&quot;312&quot; y=&quot;132&quot; text-anchor=&quot;middle&quot; style=&quot;font: 500 11px var(--sans); fill: var(--ink-soft)&quot;&gt;modulated light on fiber&lt;/text&gt;
              &lt;rect x=&quot;280&quot; y=&quot;24&quot; width=&quot;110&quot; height=&quot;44&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-6); fill-opacity: 0.22; stroke: var(--chart-6); stroke-width: 1.5&quot;/&gt;
              &lt;text x=&quot;335&quot; y=&quot;43&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;Laser source&lt;/text&gt;
              &lt;text x=&quot;335&quot; y=&quot;58&quot; text-anchor=&quot;middle&quot; style=&quot;font: 600 12px var(--sans); fill: var(--ink)&quot;&gt;(ELSFP)&lt;/text&gt;
              &lt;g style=&quot;stroke: var(--ink-soft); stroke-width: 1.5; fill: none&quot;&gt;
                &lt;path d=&quot;M78 140H94&quot; marker-end=&quot;url(#ahB)&quot;/&gt;
                &lt;path d=&quot;M140 140H154&quot; marker-end=&quot;url(#ahB)&quot;/&gt;
              &lt;/g&gt;
              &lt;path d=&quot;M280 46H178V116&quot; marker-end=&quot;url(#ahB)&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 3; fill: none&quot;/&gt;
              &lt;path d=&quot;M200 140H392&quot; marker-end=&quot;url(#ahB)&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 3; fill: none&quot;/&gt;
            &lt;/svg&gt;
          &lt;/div&gt;
          &lt;p style=&quot;margin: 0.6rem 0 0; font: 500 0.8rem var(--sans); color: var(--ink-soft)&quot;&gt;
            &lt;span style=&quot;display: inline-block; width: 0.8rem; height: 0.8rem; vertical-align: -0.1rem; margin-right: 0.3rem; background: var(--chart-2); opacity: 0.5&quot;&gt;&lt;/span&gt;&lt;span style=&quot;white-space: nowrap&quot;&gt;Marvell block&lt;/span&gt;
            &lt;span style=&quot;display: inline-block; width: 0.8rem; height: 0.8rem; vertical-align: -0.1rem; margin: 0 0.3rem 0 0.9rem; background: var(--chart-6); opacity: 0.5&quot;&gt;&lt;/span&gt;&lt;span style=&quot;white-space: nowrap&quot;&gt;Lumentum block&lt;/span&gt;
            &lt;span style=&quot;display: inline-block; width: 0.8rem; height: 0.8rem; vertical-align: -0.1rem; margin: 0 0.3rem 0 0.9rem; border: 1.5px solid var(--ink-soft)&quot;&gt;&lt;/span&gt;&lt;span style=&quot;white-space: nowrap&quot;&gt;not colored on the slide&lt;/span&gt;
          &lt;/p&gt;
          &lt;figcaption&gt;
            Fig. 1 &amp;middot; One optical link in two forms, drawn for this article from Marvell&amp;rsquo;s slides 13 and 14. Colors follow the slides&amp;rsquo; ownership key. The signal order is not on the slides. EML: laser with a built-in modulator. PIC, EIC: photonic and electronic chips. ELSFP: external laser source, a small pluggable.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Slides 13 and 14&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          Slide 13 splits each module into electronics and photonics. The electronics are Marvell&amp;rsquo;s: the DSP, which turns the host&amp;rsquo;s SerDes lanes into the signal that drives the laser and back, the drivers that carry that signal to the laser, and the TIAs that amplify the photodiode&amp;rsquo;s current. The laser and photodiode are Lumentum&amp;rsquo;s. Marvell&amp;rsquo;s 10-K uses the word laser only in &amp;ldquo;laser drivers.&amp;rdquo;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot; data-nb-locator=&quot;Item 1, Interconnects&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          Co-packaging moves the boundary. A pluggable module&amp;rsquo;s EML is one Lumentum part that both makes the light and modulates it. In co-packaged optics those are two devices: a continuous-wave laser makes steady light, and a modulator on the silicon-photonics chip imposes the data.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot; data-nb-locator=&quot;Section on NPO and CPO&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; Slide 14 draws that photonic chip as Marvell&amp;rsquo;s and puts Lumentum&amp;rsquo;s laser outside the package, in an external pluggable feeding several photonic chips.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Slide 14&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; What passes from a Lumentum part to a Marvell part is then unmodulated light on a fiber.
        &lt;/p&gt;
        &lt;p&gt;
          Lumentum&amp;rsquo;s chief executive, Michael Hurlston, said: &amp;ldquo;we supply our lasers to almost all of our competitors.&amp;rdquo;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot; data-nb-locator=&quot;Q&amp;amp;A, answer to Harlan Sur&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; Lumentum reports Components, which include laser chips, at $2,005.6 million of FY2026&amp;rsquo;s $3,014.0 million. Systems, which are modules, optical circuit switches and industrial lasers, were $1,008.4 million. The switches, which sit outside the link above, contributed more than $90.0 million.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot; data-nb-locator=&quot;Item 1 Offerings; Item 7 Net Revenue; Note 18&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;price-against-revenue&quot; id=&quot;price-against-revenue&quot;&gt;
        &lt;h2&gt;Five revenue figures give five multiples&lt;/h2&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
          &lt;img
            src=&quot;marvell-lumentum-optics/chart-1.png&quot;
            alt=&quot;Curve of 115 billion dollars divided by Lumentum annual revenue, falling from 38.2 times at 3.01 billion dollars of FY2026 revenue, to 30.7 times at 3.74 billion for the last four quarters, 22.8 times at 5.05 billion for the September quarter times four, 18.0 times at 6.40 billion for the December guidance midpoint times four, and 14.4 times at 8.00 billion for Lumentum&#x27;s two-billion-a-quarter target model. A dashed horizontal line at 18.6 times marks Marvell&#x27;s own enterprise value over its guided quarter times four on 28 October.&quot;
          /&gt;
          &lt;figcaption&gt;
            Fig. 2 &amp;middot; $115 billion over Lumentum revenue, the paper&amp;rsquo;s computation. Reported figures are from Lumentum&amp;rsquo;s FY2026 10-K and its September-quarter release. December guidance is Lumentum&amp;rsquo;s forecast. The target model is, in Lumentum&amp;rsquo;s words, &amp;ldquo;not intended to represent guidance on actual outcomes.&amp;rdquo; The dashed line is Marvell&amp;rsquo;s own enterprise value over its guided quarter times four, reconstructed at its 28 October price.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot; data-nb-locator=&quot;Item 7 Net Revenue&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Financial Overview; Business Outlook&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot; data-nb-locator=&quot;Slide 38&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Slides 9 and 20&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          September revenue was 136.5% above the year before and 25.5% above June.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Financial Overview table&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Lumentum guides December to $1.575 to $1.625 billion, 26.7% above September at the midpoint.
        &lt;/p&gt;
        &lt;p&gt;
          Marvell&amp;rsquo;s own enterprise value at its 28 October price is about $233.9 billion, 18.6 times its guided quarter annualized, $12.6 billion.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Slides 9 and 20&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; That is the paper&amp;rsquo;s reconstruction from the Merger Agreement&amp;rsquo;s share counts and 1 August net debt. It leaves out in-the-money warrants, which understates it.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s9&quot; data-nb-locator=&quot;Section 4.2(c)(i)&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s10&quot; data-nb-locator=&quot;Condensed consolidated balance sheet&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; The $115 billion comes down to that 18.6 times at $6.2 billion of Lumentum revenue, less than the $6.4 billion its December guidance annualizes to.
        &lt;/p&gt;
        &lt;p&gt;
          Lumentum&amp;rsquo;s employee FAQ values the deal at &amp;ldquo;approximately $100 billion.&amp;rdquo;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s11&quot; data-nb-locator=&quot;Employee FAQ, question 1&quot;&gt;11&lt;/a&gt;&lt;/sup&gt; Both figures can be rebuilt from the Merger Agreement at $1,132 a share. In the paper&amp;rsquo;s reconstruction, 90.68 million common shares come to $102.7 billion. Counting preferred stock, options, stock awards and the shares issuable on convertible notes gives 103.29 million shares and $116.9 billion, or $114.9 billion after $1.98 billion of cash.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s9&quot; data-nb-locator=&quot;Section 4.1(c)(i)&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Condensed Consolidated Balance Sheets&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; The filings do not say what the FAQ counts.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;the-550-billion-market&quot; id=&quot;the-550-billion-market&quot;&gt;
        &lt;h2&gt;The $550 billion market is two forecasts and a $60 billion increment&lt;/h2&gt;
        &lt;div class=&quot;nb-stat-strip&quot;&gt;
          &lt;div class=&quot;nb-stat&quot;&gt;&lt;span class=&quot;nb-stat-n&quot;&gt;$400B&lt;/span&gt;&lt;span class=&quot;nb-stat-l&quot;&gt;Marvell, CY30 market&lt;/span&gt;&lt;/div&gt;
          &lt;div class=&quot;nb-stat&quot;&gt;&lt;span class=&quot;nb-stat-n&quot;&gt;$90B+&lt;/span&gt;&lt;span class=&quot;nb-stat-l&quot;&gt;Lumentum, CY30 industry&lt;/span&gt;&lt;/div&gt;
          &lt;div class=&quot;nb-stat&quot;&gt;&lt;span class=&quot;nb-stat-n&quot;&gt;$550B&lt;/span&gt;&lt;span class=&quot;nb-stat-l&quot;&gt;Combined, deal deck&lt;/span&gt;&lt;/div&gt;
          &lt;div class=&quot;nb-stat&quot;&gt;&lt;span class=&quot;nb-stat-n&quot;&gt;$60B&lt;/span&gt;&lt;span class=&quot;nb-stat-l&quot;&gt;Increment, per Murphy&lt;/span&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;p&gt;
          The first two sum to $490 billion, and the deck shows $550 billion.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Slide 11&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Marvell&amp;rsquo;s $400 billion includes $235 billion of custom silicon and $65 billion of interconnect.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s12&quot; data-nb-locator=&quot;Pages 30 and 31&quot;&gt;12&lt;/a&gt;&lt;/sup&gt; Lumentum&amp;rsquo;s $90 billion-plus is an all-vendor industry revenue forecast built on LightCounting and 650 Group data.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot; data-nb-locator=&quot;Slide 30&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Marvell&amp;rsquo;s chief executive, Matt Murphy, put the increment at $60 billion, most of it interconnect and mostly scale-up.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot; data-nb-locator=&quot;Q&amp;amp;A, answer to Blayne Curtis and Tore Svanberg&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; A transceiver&amp;rsquo;s revenue includes its DSP, which Marvell counts inside its own $65 billion. Some dollars may therefore sit in both forecasts. That is the paper&amp;rsquo;s inference, and no document sizes it.
        &lt;/p&gt;
        &lt;p&gt;
          The $115 billion is at most 1.28 times that whole-industry forecast. Vivek Arya of Bank of America Securities asked on the call how Marvell knew it was not buying &amp;ldquo;a company at the peak of its shortage environment.&amp;rdquo; Murphy answered that &amp;ldquo;there are supply shortages today across the industry,&amp;rdquo; Marvell&amp;rsquo;s included, and that Marvell&amp;rsquo;s XPUs, switches and DSPs at the same hyperscalers show him &amp;ldquo;the design wins are real.&amp;rdquo;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot; data-nb-locator=&quot;Q&amp;amp;A, Vivek Arya question and Murphy answer&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; He gave no supply figure.
        &lt;/p&gt;
        &lt;p&gt;
          Lumentum&amp;rsquo;s filings show the shortage. Its 10-K says demand is &amp;ldquo;outpacing our current supply,&amp;rdquo; and its March deck lists a backlog of more than two years for EML and CW laser chips. Two unnamed customers were 26.6% and 15.0% of FY2026 revenue.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot; data-nb-locator=&quot;Item 1 Overview; Item 1 Customers&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot; data-nb-locator=&quot;Slide 34&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          At December guidance the price already sits just under Marvell&amp;rsquo;s own multiple. Lumentum&amp;rsquo;s $8 billion target needs a $2 billion quarter after that, one more step of about September&amp;rsquo;s 25.5%, and Lumentum has guided only as far as December.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Slides 9, 11, 13, 14, 20&quot; href=&quot;https://investor.marvell.com/_assets/_cd374c2dc2b315cc33f74eeebf563db7/marvell/db/3849/35441/description/marvell-lumentum-combine-investor-presentation-110226.pdf&quot;&gt;Marvell · Marvell and Lumentum combine, investor presentation, 2 November 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Opening bullets; paragraph 1; Transaction Structure and Terms&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1633978/000119312526442758/d163169dex991.htm&quot;&gt;Marvell and Lumentum · Joint press release, Form 8-K Exhibit 99.1, 2 November 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s3&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Fiscal First Quarter Highlights; Financial Overview; Business Outlook; balance sheet&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1633978/000162828026068655/lite_ex991xq1fy27.htm&quot;&gt;Lumentum · Q1 fiscal 2027 earnings release, 2 November 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s4&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Slides 30, 34, 38&quot; href=&quot;https://s21.q4cdn.com/377324469/files/doc_presentations/2026/2026-Lumentum-at-OFC_final.pdf&quot;&gt;Lumentum · OFC investor briefing, 17 March 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s5&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Item 1, Interconnects&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1835632/000183563226000011/mrvl-20260131.htm&quot;&gt;Marvell · Form 10-K for the fiscal year ended 31 January 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s6&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Section on silicon photonics engines in NPO and CPO&quot; href=&quot;https://www.lumentum.com/en/blog/how-optical-connectivity-evolving-scale-out-ai-networks&quot;&gt;Lumentum · How Optical Connectivity Is Evolving in Scale-Out AI Networks, 25 August 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s7&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Presentation (Murphy); Q&amp;amp;A: Sur, Curtis, Svanberg, Arya&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1633978/000119312526443876/d178787d425.htm&quot;&gt;Marvell and Lumentum · Joint call transcript, Rule 425 filing, 2 November 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s8&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Item 1 Overview, Offerings, Customers; Item 7 Net Revenue; Note 18&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1633978/000162828026057358/lite-20260627.htm&quot;&gt;Lumentum · Form 10-K for the fiscal year ended 27 June 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s9&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Agreement and Plan of Merger, Sections 4.1(c)(i) and 4.2(c)(i)&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1633978/000119312526442760/d163169d425.htm&quot;&gt;Lumentum · Form 8-K with the Agreement and Plan of Merger, 2 November 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s10&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Condensed consolidated balance sheet, 1 August 2026&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1835632/000183563226000025/mrvl-20260801.htm&quot;&gt;Marvell · Form 10-Q for the quarter ended 1 August 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s11&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Employee FAQ, question 1&quot; href=&quot;https://www.sec.gov/Archives/edgar/data/1633978/000119312526443871/d152890d425.htm&quot;&gt;Lumentum · Employee email and FAQ, Rule 425 filing, 2 November 2026&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s12&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;PDF pages 30 and 31&quot; href=&quot;https://investor.marvell.com/_assets/_b3ade7b7a9c0c378f1c7eb0eff8c24c3/marvell/db/3710/35393/presentation/marvell-investor-day-2026-presentaion-deck.pdf&quot;&gt;Marvell · Investor Day deck, 6 October 2026&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="feature"/>
  </entry>
  <entry>
    <title>Action values let an agent improve its policy from episodes alone</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/reinforcement-learning/action-values-from-samples.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/reinforcement-learning/action-values-from-samples</id>
    <updated>2026-11-03T07:29:34Z</updated>
    <summary>Monte Carlo control with exploring starts reached the optimal policy in nearly every run on the course&#x27;s slippery grid, where no convergence theorem yet applies.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Reinforcement Learning&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;Action values let an agent improve its policy from episodes alone&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;Monte Carlo control with exploring starts reached the optimal policy in nearly every run on the course&#x27;s slippery grid, where no convergence theorem yet applies.&lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;&lt;span&gt;18 min read&lt;/span&gt;&lt;span&gt;2026-11-03&lt;/span&gt;&lt;/div&gt;
      &lt;/header&gt;

&lt;section class=&quot;nb-bookend&quot; data-nb-section=&quot;why&quot; id=&quot;why&quot;&gt;
  &lt;p class=&quot;nb-bookend-name&quot;&gt;Why this matters&lt;/p&gt;
  &lt;div class=&quot;nb-bookend-rule&quot;&gt;&lt;/div&gt;
  &lt;p&gt;To improve a policy, an agent compares the moves open to it in each cell. From state values, that comparison weights each cell a move can land in by the chance of landing there, and an agent that learns from episodes never sees those chances. It can learn what each move is worth instead, by averaging the returns that followed the move, as Monte Carlo prediction averaged returns per cell. The average estimates the move&#x27;s action value.&lt;/p&gt;
  &lt;p&gt;The greedy step then compares a cell&#x27;s averages and needs no model. The agent can also improve after every episode without finishing an evaluation, a case of generalized policy iteration called Monte Carlo control with exploring starts. You will run it until it finds the grid&#x27;s optimal arrows, and see why no theorem yet promises that it will.&lt;/p&gt;
  &lt;div class=&quot;nb-bookend-band&quot;&gt;&lt;span class=&quot;nb-bookend-label&quot;&gt;Background&lt;/span&gt;&lt;span class=&quot;nb-bookend-note&quot;&gt;optional reading&lt;/span&gt;&lt;/div&gt;
  &lt;dl class=&quot;nb-bookend-reading&quot;&gt;
    &lt;dt&gt;01&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/environments-and-the-rl-problem.html&quot;&gt;The value of a state is an average you can solve for&lt;/a&gt;: the slippery grid, its rewards, the return, and &lt;code&gt;gridworld.py&lt;/code&gt;, which the code below imports.&lt;/dd&gt;
    &lt;dt&gt;02&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;Two improvements find the best policy&lt;/a&gt;: action values, the greedy step, the policy improvement theorem, and the optimal arrows used here as the answer key, with &lt;code&gt;control.py&lt;/code&gt;.&lt;/dd&gt;
    &lt;dt&gt;03&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/learning-values-from-samples.html&quot;&gt;An agent can learn what each state is worth without knowing the rules&lt;/a&gt;: first-visit Monte Carlo and &lt;code&gt;estimators.py&lt;/code&gt;, which does the averaging below.&lt;/dd&gt;
    &lt;dt&gt;04&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;http://incompleteideas.net/book/RLbook2020.pdf&quot;&gt;Sutton and Barto, Reinforcement Learning: An Introduction&lt;/a&gt;: Sections 5.2 and 5.3 (printed pp. 96-99) cover the same algorithm in the field&#x27;s standard notation.&lt;/dd&gt;
  &lt;/dl&gt;
&lt;/section&gt;

&lt;section data-nb-section=&quot;orientation&quot; id=&quot;orientation&quot;&gt;
  &lt;h2&gt;Without the slip rule, state values cannot rank the moves at cell 14&lt;/h2&gt;
  &lt;p&gt;Cell 14 is in the bottom row of the &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/environments-and-the-rl-problem.html&quot;&gt;slippery grid&lt;/a&gt;, one cell left of the bottom-right corner, and the fixed policy aims up there. &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;Policy iteration&lt;/a&gt; found that aiming right is better, worth 0.32 against up&#x27;s &amp;minus;1.08. It priced right by weighting each cell the move can land in by the chance of landing there, as the first panel of Fig. 1 shows.&lt;/p&gt;
  &lt;figure class=&quot;nb-figure&quot;&gt;
&lt;div style=&quot;display: flex; flex-wrap: wrap; gap: 1rem&quot;&gt;
&lt;svg viewBox=&quot;0 0 400 232&quot; role=&quot;img&quot; aria-label=&quot;From state values: aiming right in cell 14 lands in cell 15 with probability 0.8, slips up to cell 10 with 0.1 and slips down into the wall, staying in cell 14, with 0.1. The move is worth minus 1 plus 0.9 times the probability-weighted values, 0.32. The three probabilities are the part an agent learning from episodes does not have.&quot; style=&quot;flex: 1 1 18rem; min-width: 0; height: auto&quot;&gt;
&lt;text x=&quot;8.0&quot; y=&quot;16.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:13px;fill:var(--ink);font-weight:600&quot;&gt;From state values&lt;/text&gt;
&lt;rect x=&quot;14&quot; y=&quot;78&quot; width=&quot;66&quot; height=&quot;54&quot; rx=&quot;3&quot; style=&quot;fill:var(--panel);stroke:var(--ink-soft);stroke-width:1.2&quot;/&gt;
&lt;text x=&quot;47.0&quot; y=&quot;100.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--ink);font-weight:600&quot;&gt;cell 14&lt;/text&gt;
&lt;text x=&quot;47.0&quot; y=&quot;118.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;aim right&lt;/text&gt;
&lt;line x1=&quot;80&quot; y1=&quot;105&quot; x2=&quot;236&quot; y2=&quot;36&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1.2&quot;/&gt;
&lt;rect x=&quot;238&quot; y=&quot;19&quot; width=&quot;150&quot; height=&quot;34&quot; rx=&quot;3&quot; style=&quot;fill:var(--panel);stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;246.0&quot; y=&quot;34.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:600&quot;&gt;cell 15&lt;/text&gt;
&lt;text x=&quot;246.0&quot; y=&quot;48.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:10px;fill:var(--ink-soft);font-weight:400&quot;&gt;v = +1.98  (as aimed)&lt;/text&gt;
&lt;rect x=&quot;161.7&quot; y=&quot;52.2&quot; width=&quot;30&quot; height=&quot;17&quot; rx=&quot;3&quot; style=&quot;fill:var(--panel);stroke:var(--chart-1);stroke-width:1.4&quot;/&gt;
&lt;text x=&quot;176.7&quot; y=&quot;65.2&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-1);font-weight:600&quot;&gt;0.8&lt;/text&gt;
&lt;line x1=&quot;80&quot; y1=&quot;105&quot; x2=&quot;236&quot; y2=&quot;105&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1.2&quot;/&gt;
&lt;rect x=&quot;238&quot; y=&quot;88&quot; width=&quot;150&quot; height=&quot;34&quot; rx=&quot;3&quot; style=&quot;fill:var(--panel);stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;246.0&quot; y=&quot;103.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:600&quot;&gt;cell 10&lt;/text&gt;
&lt;text x=&quot;246.0&quot; y=&quot;117.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:10px;fill:var(--ink-soft);font-weight:400&quot;&gt;v = −0.10  (slips up)&lt;/text&gt;
&lt;rect x=&quot;161.7&quot; y=&quot;95.0&quot; width=&quot;30&quot; height=&quot;17&quot; rx=&quot;3&quot; style=&quot;fill:var(--panel);stroke:var(--chart-1);stroke-width:1.4&quot;/&gt;
&lt;text x=&quot;176.7&quot; y=&quot;108.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-1);font-weight:600&quot;&gt;0.1&lt;/text&gt;
&lt;line x1=&quot;80&quot; y1=&quot;105&quot; x2=&quot;236&quot; y2=&quot;174&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1.2&quot;/&gt;
&lt;rect x=&quot;238&quot; y=&quot;157&quot; width=&quot;150&quot; height=&quot;34&quot; rx=&quot;3&quot; style=&quot;fill:var(--panel);stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;246.0&quot; y=&quot;172.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:600&quot;&gt;cell 14&lt;/text&gt;
&lt;text x=&quot;246.0&quot; y=&quot;186.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:10px;fill:var(--ink-soft);font-weight:400&quot;&gt;v = −1.08  (slips into wall)&lt;/text&gt;
&lt;rect x=&quot;161.7&quot; y=&quot;137.8&quot; width=&quot;30&quot; height=&quot;17&quot; rx=&quot;3&quot; style=&quot;fill:var(--panel);stroke:var(--chart-1);stroke-width:1.4&quot;/&gt;
&lt;text x=&quot;176.7&quot; y=&quot;150.8&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-1);font-weight:600&quot;&gt;0.1&lt;/text&gt;
&lt;text x=&quot;8.0&quot; y=&quot;206.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;−1 + 0.9 × (0.8 × 1.98 + 0.1 × −0.10 + 0.1 × −1.08) = +0.32&lt;/text&gt;
&lt;text x=&quot;8.0&quot; y=&quot;224.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-1);font-weight:400&quot;&gt;The boxed probabilities come from the slip rule.&lt;/text&gt;
&lt;/svg&gt;
&lt;svg viewBox=&quot;0 0 400 232&quot; role=&quot;img&quot; aria-label=&quot;From action values: cell 14 drawn as four triangles, one per move, holding the expected return after each move: up minus 1.08, right plus 0.32, down minus 1.78, left minus 2.55. The greedy step picks right, the largest, and needs no probabilities.&quot; style=&quot;flex: 1 1 18rem; min-width: 0; height: auto&quot;&gt;
&lt;text x=&quot;8.0&quot; y=&quot;16.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:13px;fill:var(--ink);font-weight:600&quot;&gt;From action values&lt;/text&gt;
&lt;polygon points=&quot;115.0,107.0 40,32 190,32&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.153;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;polygon points=&quot;115.0,107.0 190,32 190,182&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.045;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;polygon points=&quot;115.0,107.0 190,182 40,182&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.252;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;polygon points=&quot;115.0,107.0 40,182 40,32&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.361;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;115.0&quot; y=&quot;62.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:13px;fill:var(--ink);font-weight:600&quot;&gt;−1.08&lt;/text&gt;
&lt;text x=&quot;158.0&quot; y=&quot;111.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:13px;fill:var(--ink);font-weight:600&quot;&gt;+0.32&lt;/text&gt;
&lt;text x=&quot;115.0&quot; y=&quot;160.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:13px;fill:var(--ink);font-weight:600&quot;&gt;−1.78&lt;/text&gt;
&lt;text x=&quot;72.0&quot; y=&quot;111.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:13px;fill:var(--ink);font-weight:600&quot;&gt;−2.55&lt;/text&gt;
&lt;polygon points=&quot;115.0,107.0 190,32 190,182&quot; style=&quot;fill:none;stroke:var(--ink);stroke-width:2.4&quot;/&gt;
&lt;text x=&quot;115.0&quot; y=&quot;200.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--ink-soft);font-weight:400&quot;&gt;cell 14&lt;/text&gt;
&lt;text x=&quot;212.0&quot; y=&quot;64.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;Each number is the expected&lt;/text&gt;
&lt;text x=&quot;212.0&quot; y=&quot;80.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;return after that move.&lt;/text&gt;
&lt;text x=&quot;212.0&quot; y=&quot;96.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;&lt;/text&gt;
&lt;text x=&quot;212.0&quot; y=&quot;112.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;The greedy step takes the&lt;/text&gt;
&lt;text x=&quot;212.0&quot; y=&quot;128.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;largest: right, +0.32.&lt;/text&gt;
&lt;text x=&quot;212.0&quot; y=&quot;144.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;&lt;/text&gt;
&lt;text x=&quot;212.0&quot; y=&quot;160.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-3);font-weight:600&quot;&gt;No probabilities needed.&lt;/text&gt;
&lt;/svg&gt;
&lt;/div&gt;
    &lt;figcaption&gt;Fig. 1 · Two ways to score moves at cell 14 under the fixed policy. From state values, the weighted sum for one move needs the boxed probabilities. From action values, cell 14 is four triangles, one per move, each holding that move&#x27;s action value. Values from &lt;code&gt;experiment.py&lt;/code&gt;.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;An agent that &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/learning-values-from-samples.html&quot;&gt;learned state values from episodes&lt;/a&gt; has the three values in that sum. It does not have 0.8, 0.1 and 0.1, because those come from the slip rule and the agent only sees what happened. Without them it cannot score right, or any other move, from state values.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.2, p. 96&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;p&gt;It can score a move by trying it. Suppose the agent in cell 14 aims right once and then follows the fixed policy. The table shows one such episode.&lt;/p&gt;
  &lt;table class=&quot;nb-table&quot;&gt;
    &lt;caption&gt;One episode that opens with right in cell 14 and ends in the pit, with returns discounted by 0.9. From &lt;code&gt;experiment.py&lt;/code&gt;.&lt;/caption&gt;
    &lt;thead&gt;
      &lt;tr&gt;&lt;th&gt;Cell&lt;/th&gt;&lt;th&gt;Move&lt;/th&gt;&lt;th&gt;Reward&lt;/th&gt;&lt;th&gt;Return after this pair&lt;/th&gt;&lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;14&lt;/span&gt;&lt;/td&gt;&lt;td&gt;right&lt;/td&gt;&lt;td&gt;&amp;minus;1&lt;/td&gt;&lt;td&gt;&amp;minus;17.29&lt;/td&gt;&lt;/tr&gt;
      &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;15&lt;/span&gt;&lt;/td&gt;&lt;td&gt;up&lt;/td&gt;&lt;td&gt;&amp;minus;1&lt;/td&gt;&lt;td&gt;&amp;minus;18.10&lt;/td&gt;&lt;/tr&gt;
      &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;14&lt;/span&gt;&lt;/td&gt;&lt;td&gt;up&lt;/td&gt;&lt;td&gt;&amp;minus;1&lt;/td&gt;&lt;td&gt;&amp;minus;19.00&lt;/td&gt;&lt;/tr&gt;
      &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;10&lt;/span&gt;&lt;/td&gt;&lt;td&gt;right&lt;/td&gt;&lt;td&gt;&amp;minus;20&lt;/td&gt;&lt;td&gt;&amp;minus;20.00&lt;/td&gt;&lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
  &lt;p&gt;The returns come from the backward pass of &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/learning-values-from-samples.html&quot;&gt;first-visit Monte Carlo&lt;/a&gt;, with one change: each step is labeled by its (cell, move) pair instead of its cell. Cell 14 appears twice, aimed right and then up, so the episode gives a return to each of those moves, &amp;minus;17.29 to right and &amp;minus;19.00 to up.&lt;/p&gt;
  &lt;p&gt;One return is noisy, and this one ended in the pit. The average of many returns after a pair estimates the pair&#x27;s &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;action value&lt;/a&gt;, the expected return from taking move &lt;span class=&quot;nb-math-in&quot;&gt;a&lt;/span&gt; in cell &lt;span class=&quot;nb-math-in&quot;&gt;s&lt;/span&gt; and following &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; afterward.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.2, p. 96&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;figure class=&quot;nb-math&quot;&gt;&lt;div class=&quot;nb-math-eq&quot;&gt;q_\pi(s, a) = \mathbb{E}_\pi\bigl[\, G_t \mid S_t = s,\ A_t = a \,\bigr]&lt;/div&gt;&lt;/figure&gt;
  &lt;p&gt;Each return after (14, right) is a sample of &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi(14, \text{right})&lt;/span&gt;, so their average converges to 0.32 without the agent using any probability.&lt;/p&gt;
&lt;/section&gt;

&lt;section data-nb-section=&quot;greedy-over-q&quot; id=&quot;greedy-over-q&quot;&gt;
  &lt;h2&gt;The greedy step over action values reads no probabilities&lt;/h2&gt;
  &lt;p&gt;Policy iteration improved a policy with the greedy step. Written out, the step uses the model.&lt;/p&gt;
  &lt;figure class=&quot;nb-math&quot;&gt;&lt;div class=&quot;nb-math-eq&quot;&gt;\pi&#x27;(s) = \operatorname*{arg\,max}_a \sum_{s&#x27;} P(s&#x27; \mid s, a)\,\bigl[\, R(s&#x27;) + \gamma\, v_\pi(s&#x27;) \,\bigr]&lt;/div&gt;&lt;/figure&gt;
  &lt;p&gt;The sum is &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi(s, a)&lt;/span&gt;, so the same step reads as follows.&lt;/p&gt;
  &lt;figure class=&quot;nb-math&quot;&gt;&lt;div class=&quot;nb-math-eq&quot;&gt;\pi&#x27;(s) = \operatorname*{arg\,max}_a\; q_\pi(s, a)&lt;/div&gt;&lt;/figure&gt;
  &lt;p&gt;Every use of &lt;span class=&quot;nb-math-in&quot;&gt;P&lt;/span&gt; and &lt;span class=&quot;nb-math-in&quot;&gt;R&lt;/span&gt; now sits inside &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi&lt;/span&gt;, and an agent can estimate &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi&lt;/span&gt; by averaging returns. An agent holding estimates of the action values picks the greedy move in a cell by comparing four numbers. In Sutton and Barto&#x27;s words, with an action-value function &quot;no model is needed to construct the greedy policy&quot;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.3, p. 97, equation 5.1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;p&gt;The greedy policy is also no worse than &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt;. The &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;policy improvement theorem&lt;/a&gt; says that if &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi(s, \pi&#x27;(s)) \ge v_\pi(s)&lt;/span&gt; in every cell, then &lt;span class=&quot;nb-math-in&quot;&gt;v_{\pi&#x27;}(s) \ge v_\pi(s)&lt;/span&gt; in every cell. The greedy step meets that condition, and checking it takes only action values.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.3, p. 98&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;figure class=&quot;nb-math&quot;&gt;&lt;div class=&quot;nb-math-eq&quot;&gt;q_\pi\bigl(s, \pi&#x27;(s)\bigr) = \max_a q_\pi(s, a) \;\ge\; q_\pi\bigl(s, \pi(s)\bigr) = v_\pi(s)&lt;/div&gt;&lt;/figure&gt;
  &lt;p&gt;The first equality is what greedy means. The inequality holds because the largest of four values is at least the value of any one of them, the policy&#x27;s own move included. The last equality holds because &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; picks one move per cell, so taking &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt;&#x27;s move and then following &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; is just following &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt;.&lt;/p&gt;
&lt;/section&gt;

&lt;section data-nb-section=&quot;exploring-starts&quot; id=&quot;exploring-starts&quot;&gt;
  &lt;h2&gt;Exploring starts give every move returns of its own&lt;/h2&gt;
  &lt;p&gt;Averages exist only for moves the agent has tried. A greedy agent takes one move in each cell, so after an episode&#x27;s first move every pair it visits is the policy&#x27;s own. The other three moves in each cell get no returns, and their estimates never change.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.2, p. 96&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; In the code below a move with no returns has no estimate yet, and the greedy step skips it, so the policy could never switch to such a move.&lt;/p&gt;
  &lt;p&gt;This lesson supplies the missing returns with exploring starts: each episode begins from a random (cell, move) pair, and every pair has some chance of being picked.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.2, p. 96&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Here the pick is uniform over the 56 pairs, and after the first move the agent follows its policy.&lt;/p&gt;
  &lt;p&gt;Exploring starts needs an environment that can open an episode at any (cell, move) pair, and &lt;code&gt;play&lt;/code&gt; below takes the start pair as an argument. Sutton and Barto note that the assumption &quot;cannot be relied upon in general, particularly when learning directly from actual interaction with an environment&quot;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.2, p. 96&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; The usual alternative, a policy that keeps some chance on every move, needs a lesson of its own.&lt;/p&gt;
  &lt;p&gt;The runs below depend on the assumption. With &lt;code&gt;explore=False&lt;/code&gt;, each episode starts in a random cell with the policy&#x27;s own move, and none of the 20 runs reaches the optimal policy in 10,000 episodes. Every average then belongs to a move the policy already takes, so each greedy step returns the policy it started from.&lt;/p&gt;
&lt;/section&gt;

&lt;section data-nb-section=&quot;every-episode&quot; id=&quot;every-episode&quot;&gt;
  &lt;h2&gt;Monte Carlo ES improves the policy after every episode&lt;/h2&gt;
  &lt;p&gt;Policy iteration evaluated each policy completely before improving it. From samples, a complete evaluation would take infinitely many episodes. Sutton and Barto call the general scheme generalized policy iteration (GPI): evaluation and improvement interact at any granularity, and neither has to finish before the other runs.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 4.6, pp. 86-87; Section 5.3, p. 98&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;Value iteration&lt;/a&gt; was one case of it, with an improvement folded into every sweep.&lt;/p&gt;
  &lt;p&gt;Monte Carlo ES, short for Monte Carlo with exploring starts, takes the episode as its unit. After each episode it adds the episode&#x27;s returns to the averages of the pairs it visited, then makes the policy greedy, which can change only the cells the episode visited. The averages are never reset, so a pair&#x27;s average mixes returns earned under every policy the agent has used.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Monte Carlo ES box and text, p. 99&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;mc_control.py&lt;/code&gt; is the complete method. It imports the grid from &lt;code&gt;gridworld.py&lt;/code&gt;, printed with the &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/environments-and-the-rl-problem.html&quot;&gt;exact solve&lt;/a&gt;, and &lt;code&gt;first_visit_mc&lt;/code&gt; from &lt;code&gt;estimators.py&lt;/code&gt;, printed with &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/learning-values-from-samples.html&quot;&gt;Monte Carlo prediction&lt;/a&gt;. &lt;code&gt;pairs&lt;/code&gt; numbers each pair as 4 &amp;times; cell + move, so &lt;code&gt;first_visit_mc&lt;/code&gt; averages returns per pair as it averaged them per cell. &lt;code&gt;greedy&lt;/code&gt; is the improvement step, and &lt;code&gt;step&lt;/code&gt;, the environment, is the only function that reads the grid&#x27;s rules.&lt;/p&gt;
  &lt;p&gt;A greedy policy in mid-training can press the bottom row into the wall, like the &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/environments-and-the-rl-problem.html&quot;&gt;stuck policy&lt;/a&gt;, and an episode under it never ends. &lt;code&gt;play&lt;/code&gt; stops every episode after 200 moves, so a cut episode&#x27;s returns leave out whatever would have come later. In the main runs, 84 of 2,000,000 episodes were cut.&lt;/p&gt;
  &lt;figure class=&quot;nb-code&quot;&gt;&lt;div class=&quot;nb-code-head&quot;&gt;&lt;span class=&quot;nb-code-file&quot;&gt;mc_control.py · complete&lt;/span&gt;&lt;span&gt;python&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;&lt;code data-language=&quot;python&quot;&gt;# /// script
# requires-python = &quot;&amp;gt;=3.10&quot;
# dependencies = [&quot;numpy&quot;]
# ///
&quot;&quot;&quot;Monte Carlo control with exploring starts on the slippery grid.

The agent&#x27;s side is pairs, greedy and the call to first_visit_mc. It sees
only episodes. Only step reads the grid&#x27;s rules, to play them out.
&quot;&quot;&quot;

import numpy as np
from estimators import first_visit_mc
from gridworld import N, R, TERMINAL, move

SLIP = 0.2
LIVE = [s for s in range(N) if s not in TERMINAL]
CAP = 200  # an episode stops after this many moves


def step(s, a, rng):
    &quot;&quot;&quot;The environment: the aimed move with probability 1 - SLIP, otherwise a
    slip to either side, as in transitions(). Returns the reward and next cell.&quot;&quot;&quot;
    u = rng.random()
    aim = a if u &amp;lt; 1 - SLIP else (a + 1) % 4 if u &amp;lt; 1 - SLIP / 2 else (a + 3) % 4
    s_next = move(s, aim)
    return R[s_next], s_next


def play(policy, start, first, rng):
    &quot;&quot;&quot;One episode that opens with the move `first` in cell `start`, follows
    `policy` after that, and stops at a terminal cell or after CAP moves.&quot;&quot;&quot;
    s, a, steps = start, first, []
    while s not in TERMINAL and len(steps) &amp;lt; CAP:
        reward, s_next = step(s, a, rng)
        steps.append((s, a, reward, s_next))
        s, a = s_next, policy[s_next]
    return steps


def pairs(steps):
    &quot;&quot;&quot;Label each step by its (cell, move) pair, numbered 4 * cell + move, so
    that first_visit_mc averages returns per pair instead of per cell.&quot;&quot;&quot;
    return [(4 * s + a, a, r, s_next) for s, a, r, s_next in steps]


def greedy(q, count, policy):
    &quot;&quot;&quot;The move with the largest average return in each cell. A move with no
    returns has no estimate yet, and a cell with none keeps its move.&quot;&quot;&quot;
    Q = np.where(count &amp;gt; 0, q, -np.inf).reshape(N, 4)
    return np.where(count.reshape(N, 4).any(axis=1), Q.argmax(axis=1), policy)


def control(policy, episodes, rng, explore=True, every=1, forget=False,
            watch=None):
    &quot;&quot;&quot;Monte Carlo ES. Each episode starts from a random (cell, move) pair, or
    from a random cell and the policy&#x27;s move if explore is False. The policy
    turns greedy every `every` episodes, and forget clears the averages then.&quot;&quot;&quot;
    q, count = np.zeros(4 * N), np.zeros(4 * N)
    for k in range(1, episodes + 1):
        start = LIVE[rng.integers(len(LIVE))]
        first = rng.integers(4) if explore else policy[start]
        steps = play(policy, start, first, rng)
        first_visit_mc(pairs(steps), q, count)
        if k % every == 0:
            policy = greedy(q, count, policy)
            if forget:
                q[:], count[:] = 0.0, 0.0
        if watch:
            watch(k, policy, q, count, steps)
    return policy, q, count&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;p&gt;&lt;code&gt;experiment.py&lt;/code&gt; plays 20 runs of 100,000 episodes, one per seed, each starting from the fixed policy with no averages. A run counts as optimal when every arrow is an optimal move, either up or right at cells 9 and 12, where the two tie. After 10,000 episodes half the runs are optimal, and after 100,000, 18 of 20 are. The two still short are wrong at cell 5, beside the pit, where the best move beats the next by only 0.35. Twenty other seeds repeat the half at 10,000 and do better at 100,000.&lt;/p&gt;
  &lt;figure class=&quot;nb-figure&quot;&gt;
&lt;div style=&quot;display: flex; flex-wrap: wrap; gap: 0.8rem; max-width: 26rem; margin: 0 auto&quot;&gt;
&lt;svg viewBox=&quot;0 0 200 216&quot; role=&quot;img&quot; aria-label=&quot;Run 0 after 1,000 episodes: greedy arrows over each cell&#x27;s four action-value averages; wrong at cells 9, 10, 13.&quot; style=&quot;flex: 1 1 9.5rem; min-width: 0; height: auto&quot;&gt;
&lt;text x=&quot;100.0&quot; y=&quot;15.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--ink);font-weight:600&quot;&gt;1,000 episodes&lt;/text&gt;
&lt;polygon points=&quot;31.0,49.0 8,26 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.149;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,26 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.319;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,72 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 8,72 8,26&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.092;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;27.0&quot; y1=&quot;49.0&quot; x2=&quot;40.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;44.0,49.0 38.0,52.5 38.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,26 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.435;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,26 100,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.625;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,72 54,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.031;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,72 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.452;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;73.0&quot; y1=&quot;49.0&quot; x2=&quot;86.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;90.0,49.0 84.0,52.5 84.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,26 146,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.642;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,26 146,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,72 100,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,72 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.628;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;49.0&quot; x2=&quot;132.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,49.0 130.0,52.5 130.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;147&quot; y=&quot;27&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;169.0&quot; y=&quot;53.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;
&lt;polygon points=&quot;31.0,95.0 8,72 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.070;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,72 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.226;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,118 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.437;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 8,118 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.187;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;99.0&quot; x2=&quot;31.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,82.0 34.5,88.0 27.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,72 100,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.036;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,72 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,118 54,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.072;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;77.0&quot; y1=&quot;99.0&quot; x2=&quot;77.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;77.0,82.0 80.5,88.0 73.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;101&quot; y=&quot;73&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;123.0&quot; y=&quot;99.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;
&lt;polygon points=&quot;169.0,95.0 146,72 192,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.825;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,72 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.383;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,118 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.584;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 146,118 146,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;99.0&quot; x2=&quot;169.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,82.0 172.5,88.0 165.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.208;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,118 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,164 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.465;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,164 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.638;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;145.0&quot; x2=&quot;31.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,128.0 34.5,134.0 27.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,118 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,118 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.716;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.553;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,164 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.445;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;81.0&quot; y1=&quot;141.0&quot; x2=&quot;68.0&quot; y2=&quot;141.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;64.0,141.0 70.0,137.5 70.0,144.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;56.5&quot; y=&quot;120.5&quot; width=&quot;41&quot; height=&quot;41&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,118 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,118 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.106;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,164 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;123.0&quot; y1=&quot;137.0&quot; x2=&quot;123.0&quot; y2=&quot;150.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;123.0,154.0 119.5,148.0 126.5,148.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;102.5&quot; y=&quot;120.5&quot; width=&quot;41&quot; height=&quot;41&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,118 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.322;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,118 192,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.328;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,164 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.399;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,164 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.807;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;145.0&quot; x2=&quot;169.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,128.0 172.5,134.0 165.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.267;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,164 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.634;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,210 8,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.374;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,210 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.323;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;191.0&quot; x2=&quot;31.0&quot; y2=&quot;178.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,174.0 34.5,180.0 27.5,180.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.715;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,164 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.705;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,210 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.729;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,210 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.495;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;81.0&quot; y1=&quot;187.0&quot; x2=&quot;68.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;64.0,187.0 70.0,183.5 70.0,190.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;56.5&quot; y=&quot;166.5&quot; width=&quot;41&quot; height=&quot;41&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,164 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,164 146,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.191;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,210 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,210 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.659;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;187.0&quot; x2=&quot;132.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,187.0 130.0,190.5 130.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,164 192,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.317;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,164 192,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.439;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,210 146,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.718;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,210 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.757;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;191.0&quot; x2=&quot;169.0&quot; y2=&quot;178.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,174.0 172.5,180.0 165.5,180.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;/svg&gt;
&lt;svg viewBox=&quot;0 0 200 216&quot; role=&quot;img&quot; aria-label=&quot;Run 0 after 10,000 episodes: greedy arrows over each cell&#x27;s four action-value averages; wrong at cell 10.&quot; style=&quot;flex: 1 1 9.5rem; min-width: 0; height: auto&quot;&gt;
&lt;text x=&quot;100.0&quot; y=&quot;15.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--ink);font-weight:600&quot;&gt;10,000 episodes&lt;/text&gt;
&lt;polygon points=&quot;31.0,49.0 8,26 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.145;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,26 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.329;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,72 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.160;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 8,72 8,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.120;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;27.0&quot; y1=&quot;49.0&quot; x2=&quot;40.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;44.0,49.0 38.0,52.5 38.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,26 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.337;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,26 100,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.597;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,72 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.035;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,72 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.225;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;73.0&quot; y1=&quot;49.0&quot; x2=&quot;86.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;90.0,49.0 84.0,52.5 84.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,26 146,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.662;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,26 146,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,72 100,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,72 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.114;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;49.0&quot; x2=&quot;132.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,49.0 130.0,52.5 130.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;147&quot; y=&quot;27&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;169.0&quot; y=&quot;53.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;
&lt;polygon points=&quot;31.0,95.0 8,72 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.090;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,72 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.084;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,118 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.181;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 8,118 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.004;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;99.0&quot; x2=&quot;31.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,82.0 34.5,88.0 27.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,72 100,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.037;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,72 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.756;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,118 54,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.058;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;77.0&quot; y1=&quot;99.0&quot; x2=&quot;77.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;77.0,82.0 80.5,88.0 73.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;101&quot; y=&quot;73&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;123.0&quot; y=&quot;99.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;
&lt;polygon points=&quot;169.0,95.0 146,72 192,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,72 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.603;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,118 146,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.018;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 146,118 146,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;99.0&quot; x2=&quot;169.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,82.0 172.5,88.0 165.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.112;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,118 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.335;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,164 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.362;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,164 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.278;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;145.0&quot; x2=&quot;31.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,128.0 34.5,134.0 27.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,118 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.190;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,118 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.289;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.390;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,164 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.249;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;77.0&quot; y1=&quot;145.0&quot; x2=&quot;77.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;77.0,128.0 80.5,134.0 73.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,118 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,118 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.406;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.065;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,164 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.525;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;123.0&quot; y1=&quot;137.0&quot; x2=&quot;123.0&quot; y2=&quot;150.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;123.0,154.0 119.5,148.0 126.5,148.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;102.5&quot; y=&quot;120.5&quot; width=&quot;41&quot; height=&quot;41&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,118 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.574;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,118 192,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.073;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,164 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.012;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,164 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.289;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;145.0&quot; x2=&quot;169.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,128.0 172.5,134.0 165.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.277;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,164 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.255;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,210 8,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.391;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,210 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.329;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;27.0&quot; y1=&quot;187.0&quot; x2=&quot;40.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;44.0,187.0 38.0,190.5 38.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.318;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,164 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.115;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,210 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.330;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,210 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.396;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;73.0&quot; y1=&quot;187.0&quot; x2=&quot;86.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;90.0,187.0 84.0,190.5 84.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,164 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.345;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,164 146,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.083;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,210 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.128;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,210 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.314;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;187.0&quot; x2=&quot;132.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,187.0 130.0,190.5 130.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,164 192,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.268;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,164 192,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.083;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,210 146,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.057;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,210 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.062;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;191.0&quot; x2=&quot;169.0&quot; y2=&quot;178.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,174.0 172.5,180.0 165.5,180.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;/svg&gt;
&lt;svg viewBox=&quot;0 0 200 216&quot; role=&quot;img&quot; aria-label=&quot;Run 0 after 100,000 episodes: greedy arrows over each cell&#x27;s four action-value averages; every arrow optimal.&quot; style=&quot;flex: 1 1 9.5rem; min-width: 0; height: auto&quot;&gt;
&lt;text x=&quot;100.0&quot; y=&quot;15.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--ink);font-weight:600&quot;&gt;100,000 episodes&lt;/text&gt;
&lt;polygon points=&quot;31.0,49.0 8,26 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.153;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,26 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.312;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,72 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.021;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 8,72 8,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.124;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;27.0&quot; y1=&quot;49.0&quot; x2=&quot;40.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;44.0,49.0 38.0,52.5 38.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,26 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.400;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,26 100,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.580;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,72 54,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.049;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,72 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.147;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;73.0&quot; y1=&quot;49.0&quot; x2=&quot;86.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;90.0,49.0 84.0,52.5 84.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,26 146,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.745;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,26 146,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,72 100,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,72 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.082;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;49.0&quot; x2=&quot;132.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,49.0 130.0,52.5 130.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;147&quot; y=&quot;27&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;169.0&quot; y=&quot;53.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;
&lt;polygon points=&quot;31.0,95.0 8,72 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.088;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,72 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.089;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,118 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.212;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 8,118 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.021;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;99.0&quot; x2=&quot;31.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,82.0 34.5,88.0 27.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,72 100,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.005;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,72 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.556;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,118 54,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.041;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;77.0&quot; y1=&quot;99.0&quot; x2=&quot;77.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;77.0,82.0 80.5,88.0 73.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;101&quot; y=&quot;73&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;123.0&quot; y=&quot;99.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;
&lt;polygon points=&quot;169.0,95.0 146,72 192,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,72 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.717;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,118 146,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.047;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 146,118 146,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;99.0&quot; x2=&quot;169.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,82.0 172.5,88.0 165.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.114;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,118 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.310;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,164 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.323;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,164 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.242;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;145.0&quot; x2=&quot;31.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,128.0 34.5,134.0 27.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,118 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.163;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,118 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.193;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.278;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,164 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.256;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;77.0&quot; y1=&quot;145.0&quot; x2=&quot;77.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;77.0,128.0 80.5,134.0 73.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,118 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,118 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.004;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.044;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,164 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.460;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;141.0&quot; x2=&quot;132.0&quot; y2=&quot;141.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,141.0 130.0,144.5 130.0,137.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,118 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.565;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,118 192,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.330;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,164 146,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.081;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,164 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.088;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;145.0&quot; x2=&quot;169.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,128.0 172.5,134.0 165.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.260;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,164 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.241;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,210 8,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.370;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,210 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.341;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;27.0&quot; y1=&quot;187.0&quot; x2=&quot;40.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;44.0,187.0 38.0,190.5 38.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.278;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,164 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.103;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,210 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.232;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,210 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.387;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;73.0&quot; y1=&quot;187.0&quot; x2=&quot;86.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;90.0,187.0 84.0,190.5 84.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,164 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.150;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,164 146,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.083;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,210 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.098;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,210 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.236;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;187.0&quot; x2=&quot;132.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,187.0 130.0,190.5 130.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,164 192,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.298;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,164 192,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.140;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,210 146,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.087;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,210 146,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.011;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;191.0&quot; x2=&quot;169.0&quot; y2=&quot;178.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,174.0 172.5,180.0 165.5,180.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;/svg&gt;
&lt;svg viewBox=&quot;0 0 200 216&quot; role=&quot;img&quot; aria-label=&quot;The exact optimal action values and optimal arrows from policy iteration.&quot; style=&quot;flex: 1 1 9.5rem; min-width: 0; height: auto&quot;&gt;
&lt;text x=&quot;100.0&quot; y=&quot;15.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:12px;fill:var(--ink);font-weight:600&quot;&gt;exact q* and π*&lt;/text&gt;
&lt;polygon points=&quot;31.0,49.0 8,26 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.157;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,26 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.305;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 54,72 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.000;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,49.0 8,72 8,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.114;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;27.0&quot; y1=&quot;49.0&quot; x2=&quot;40.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;44.0,49.0 38.0,52.5 38.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,26 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.380;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,26 100,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.572;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 100,72 54,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.025;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,49.0 54,72 54,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.130;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;73.0&quot; y1=&quot;49.0&quot; x2=&quot;86.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;90.0,49.0 84.0,52.5 84.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,26 146,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.727;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,26 146,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 146,72 100,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,49.0 100,72 100,26&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.084;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;26&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;49.0&quot; x2=&quot;132.0&quot; y2=&quot;49.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,49.0 130.0,52.5 130.0,45.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;147&quot; y=&quot;27&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-3);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;169.0&quot; y=&quot;53.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-3);font-weight:600&quot;&gt;goal&lt;/text&gt;
&lt;polygon points=&quot;31.0,95.0 8,72 54,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.087;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,72 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.117;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 54,118 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.206;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,95.0 8,118 8,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.061;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;99.0&quot; x2=&quot;31.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,82.0 34.5,88.0 27.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,72 100,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.009;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,72 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 100,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.506;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,95.0 54,118 54,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.041;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;77.0&quot; y1=&quot;99.0&quot; x2=&quot;77.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;77.0,82.0 80.5,88.0 73.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;rect x=&quot;101&quot; y=&quot;73&quot; width=&quot;44&quot; height=&quot;44&quot; style=&quot;fill:var(--panel);stroke:var(--chart-4);stroke-width:1.6&quot;/&gt;
&lt;text x=&quot;123.0&quot; y=&quot;99.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--chart-4);font-weight:600&quot;&gt;pit&lt;/text&gt;
&lt;polygon points=&quot;169.0,95.0 146,72 192,72&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,72 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.727;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 192,118 146,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.084;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,95.0 146,118 146,72&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;72&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;99.0&quot; x2=&quot;169.0&quot; y2=&quot;86.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,82.0 172.5,88.0 165.5,88.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,118 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.101;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,118 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.259;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 54,164 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.341;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,141.0 8,164 8,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.229;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;145.0&quot; x2=&quot;31.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,128.0 34.5,134.0 27.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,118 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.144;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,118 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.144;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 100,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.223;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,141.0 54,164 54,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.223;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;77.0&quot; y1=&quot;145.0&quot; x2=&quot;77.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;77.0,128.0 80.5,134.0 73.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,118 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.850;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,118 146,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.009;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 146,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.041;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,141.0 100,164 100,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.506;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;141.0&quot; x2=&quot;132.0&quot; y2=&quot;141.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,141.0 130.0,144.5 130.0,137.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,118 192,118&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.572;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,118 192,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.380;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 192,164 146,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.130;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,141.0 146,164 146,118&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.025;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;118&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;145.0&quot; x2=&quot;169.0&quot; y2=&quot;132.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,128.0 172.5,134.0 165.5,134.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,164 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.246;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,164 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.246;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 54,210 8,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.350;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;31.0,187.0 8,210 8,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.350;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;8&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;31.0&quot; y1=&quot;191.0&quot; x2=&quot;31.0&quot; y2=&quot;178.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;31.0,174.0 34.5,180.0 27.5,180.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,164 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.259;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,164 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.101;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 100,210 54,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.229;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;77.0,187.0 54,210 54,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.341;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;54&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;73.0&quot; y1=&quot;187.0&quot; x2=&quot;86.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;90.0,187.0 84.0,190.5 84.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,164 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.117;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,164 146,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.087;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 146,210 100,210&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.061;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;123.0,187.0 100,210 100,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.206;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;119.0&quot; y1=&quot;187.0&quot; x2=&quot;132.0&quot; y2=&quot;187.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;136.0,187.0 130.0,190.5 130.0,183.5&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,164 192,164&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.305;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,164 192,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.157;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 192,210 146,210&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.114;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;polygon points=&quot;169.0,187.0 146,210 146,164&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.000;stroke:var(--line);stroke-width:0.6&quot;/&gt;
&lt;rect x=&quot;146&quot; y=&quot;164&quot; width=&quot;46&quot; height=&quot;46&quot; style=&quot;fill:none;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;line x1=&quot;169.0&quot; y1=&quot;191.0&quot; x2=&quot;169.0&quot; y2=&quot;178.0&quot; style=&quot;stroke:var(--ink);stroke-width:2;fill:none&quot;/&gt;
&lt;polygon points=&quot;169.0,174.0 172.5,180.0 165.5,180.0&quot; style=&quot;fill:var(--ink)&quot;/&gt;
&lt;/svg&gt;
&lt;/div&gt;
&lt;svg viewBox=&quot;0 0 400 44&quot; role=&quot;img&quot; aria-label=&quot;Colour scale: red for negative action values, green for positive, clipped at 6.&quot; style=&quot;display: block; width: 100%; max-width: 26rem; margin: 0.4rem auto 0; height: auto&quot;&gt;
&lt;rect x=&quot;80&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.815&quot;/&gt;
&lt;rect x=&quot;90&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.744&quot;/&gt;
&lt;rect x=&quot;100&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.673&quot;/&gt;
&lt;rect x=&quot;110&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.602&quot;/&gt;
&lt;rect x=&quot;120&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.531&quot;/&gt;
&lt;rect x=&quot;130&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.460&quot;/&gt;
&lt;rect x=&quot;140&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.390&quot;/&gt;
&lt;rect x=&quot;150&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.319&quot;/&gt;
&lt;rect x=&quot;160&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.248&quot;/&gt;
&lt;rect x=&quot;170&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.177&quot;/&gt;
&lt;rect x=&quot;180&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.106&quot;/&gt;
&lt;rect x=&quot;190&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-4);fill-opacity:0.035&quot;/&gt;
&lt;rect x=&quot;200&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.035&quot;/&gt;
&lt;rect x=&quot;210&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.106&quot;/&gt;
&lt;rect x=&quot;220&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.177&quot;/&gt;
&lt;rect x=&quot;230&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.248&quot;/&gt;
&lt;rect x=&quot;240&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.319&quot;/&gt;
&lt;rect x=&quot;250&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.390&quot;/&gt;
&lt;rect x=&quot;260&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.460&quot;/&gt;
&lt;rect x=&quot;270&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.531&quot;/&gt;
&lt;rect x=&quot;280&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.602&quot;/&gt;
&lt;rect x=&quot;290&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.673&quot;/&gt;
&lt;rect x=&quot;300&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.744&quot;/&gt;
&lt;rect x=&quot;310&quot; y=&quot;6&quot; width=&quot;10&quot; height=&quot;12&quot; style=&quot;fill:var(--chart-3);fill-opacity:0.815&quot;/&gt;
&lt;rect x=&quot;80&quot; y=&quot;6&quot; width=&quot;240&quot; height=&quot;12&quot; style=&quot;fill:none;stroke:var(--line)&quot;/&gt;
&lt;text x=&quot;80.0&quot; y=&quot;32.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;−6 or less&lt;/text&gt;
&lt;text x=&quot;200.0&quot; y=&quot;32.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;0&lt;/text&gt;
&lt;text x=&quot;320.0&quot; y=&quot;32.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;+6 or more&lt;/text&gt;
&lt;text x=&quot;76.0&quot; y=&quot;16.0&quot; text-anchor=&quot;end&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400;font-style:italic&quot;&gt;q&lt;/text&gt;
&lt;rect x=&quot;336&quot; y=&quot;5&quot; width=&quot;14&quot; height=&quot;14&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:3&quot;/&gt;
&lt;text x=&quot;356.0&quot; y=&quot;16.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;wrong&lt;/text&gt;
&lt;/svg&gt;
    &lt;figcaption&gt;Fig. 2 · What run 0 learned. Each cell&#x27;s four triangles are its moves, shaded by average return, green above 0 and red below. Arrows show the greedy policy, and an amber square marks an arrow that is not optimal. The last panel is the exact answer, where up and right tie at cells 9 and 12. Values from &lt;code&gt;experiment.py&lt;/code&gt;.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Run 0 has three arrows wrong after 1,000 episodes, at cells 9, 10 and 13. By 10,000 only cell 10 is wrong. It aims down, whose exact action value is &amp;minus;0.29, against 0.06 for right. By 100,000 every arrow is optimal.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;uv run experiment.py&lt;/code&gt; needs &lt;code&gt;gridworld.py&lt;/code&gt;, &lt;code&gt;control.py&lt;/code&gt; from the &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;policy iteration lesson&lt;/a&gt;, &lt;code&gt;estimators.py&lt;/code&gt; and &lt;code&gt;mc_control.py&lt;/code&gt; in one folder. It installs numpy and takes a little over two minutes on the machine used here.&lt;/p&gt;
  &lt;details&gt;
    &lt;summary&gt;&lt;code&gt;experiment.py&lt;/code&gt;, complete&lt;/summary&gt;
    &lt;figure class=&quot;nb-code&quot;&gt;&lt;div class=&quot;nb-code-head&quot;&gt;&lt;span class=&quot;nb-code-file&quot;&gt;experiment.py · complete&lt;/span&gt;&lt;span&gt;python&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;&lt;code data-language=&quot;python&quot;&gt;# /// script
# requires-python = &quot;&amp;gt;=3.10&quot;
# dependencies = [&quot;numpy&quot;]
# ///
&quot;&quot;&quot;Run Monte Carlo ES on the grid and print every number on the page. The
exact values from control.py appear only to grade the learned policy.&quot;&quot;&quot;

from collections import Counter

import numpy as np
from control import action_values, evaluate
from estimators import first_visit_mc
from gridworld import ARROWS, N, PI, draw, transitions
from mc_control import CAP, LIVE, control, pairs, play

PI_STAR = draw(&quot;&quot;&quot;&amp;gt; &amp;gt; &amp;gt; .
                  ^ ^ . ^
                  ^ ^ &amp;gt; ^
                  ^ &amp;gt; &amp;gt; ^&quot;&quot;&quot;)  # the optimal arrows from policy iteration
Q_STAR = action_values(evaluate(PI_STAR), transitions(0.2))
BEST = {s: np.flatnonzero(Q_STAR[s] &amp;gt; Q_STAR[s].max() - 1e-9) for s in LIVE}
SEEDS, EPISODES = range(20), 100_000
CHECKS = [1_000, 2_000, 5_000, 10_000, 20_000, 50_000, 100_000]


def wrong(policy):
    &quot;&quot;&quot;Cells whose move is not optimal. Cells 9 and 12 have two optimal moves.&quot;&quot;&quot;
    return [s for s in LIVE if policy[s] not in BEST[s]]


def arrows(policy):
    marks = [&quot;.&quot; if s not in LIVE else ARROWS[policy[s]] for s in range(N)]
    return &quot; / &quot;.join(&quot; &quot;.join(marks[r:r + 4]) for r in range(0, N, 4))


def one_episode():
    &quot;&quot;&quot;The return one episode gives each pair it visits.&quot;&quot;&quot;
    steps = play(PI, 14, 1, np.random.default_rng(1))
    q, count = np.zeros(4 * N), np.zeros(4 * N)
    first_visit_mc(pairs(steps), q, count)
    print(&quot;cell, move, reward:&quot;, [(s, ARROWS[a], int(r)) for s, a, r, _ in steps])
    print(&quot;return per pair:&quot;, [(s, ARROWS[a], round(float(q[4 * s + a]), 2))
                               for s, a, _, _ in steps])


def runs(episodes=EPISODES, **options):
    &quot;&quot;&quot;At each checkpoint, the number of runs with an optimal policy and the
    cells the other runs get wrong, plus run 0&#x27;s policy and averages.&quot;&quot;&quot;
    optimal, missed, snaps, cut = Counter(), {k: Counter() for k in CHECKS}, {}, [0]

    def watch(k, policy, q, count, steps):
        cut[0] += len(steps) == CAP
        if k in CHECKS:
            optimal[k] += not wrong(policy)
            missed[k].update(wrong(policy))
            if seed == 0:
                snaps[k] = policy.copy(), q.copy()

    for seed in SEEDS:
        control(PI.copy(), episodes, np.random.default_rng(seed), watch=watch,
                **options)
    return optimal, missed, snaps, cut[0]


def main():
    v_pi = evaluate(PI)
    print(&quot;fixed policy: v at cells 10, 13, 14, 15:&quot;, v_pi[[10, 13, 14, 15]].round(2))
    print(&quot;fixed policy: q at cell 14 (up, right, down, left):&quot;,
          action_values(v_pi, transitions(0.2))[14].round(2))
    print(&quot;q* at cells 5 and 10 (up, right, down, left):&quot;,
          Q_STAR[[5, 10]].round(2).tolist())
    one_episode()
    schedules = {&quot;every episode&quot;: runs(),
                 &quot;every 5,600&quot;: runs(every=5_600),
                 &quot;every 5,600, cleared&quot;: runs(every=5_600, forget=True)}
    print(f&quot;\nruns with an optimal policy, of {len(SEEDS)}, by when it improves&quot;)
    print(&quot;episodes&quot;, *[f&quot;{name:&amp;gt;21s}&quot; for name in schedules])
    for k in CHECKS:
        print(f&quot;{k:8d}&quot;, *[f&quot;{s[0][k]:21d}&quot; for s in schedules.values()])
    print(f&quot;episodes cut off at {CAP} moves:&quot;,
          {name: s[3] for name, s in schedules.items()})
    optimal, missed, snaps, _ = schedules[&quot;every episode&quot;]
    for k in (20_000, 100_000):
        print(f&quot;every episode, wrong cells at {k}: {dict(sorted(missed[k].items()))}&quot;)
    for k in (1_000, 10_000, 100_000):
        policy, _ = snaps[k]
        print(f&quot;run 0 at {k:6d}: {arrows(policy)}, wrong {wrong(policy)}&quot;)
    optimal, *_ = runs(episodes=10_000, explore=False)
    print(&quot;no exploring starts, optimal runs at 10,000:&quot;, optimal[10_000])


if __name__ == &quot;__main__&quot;:
    main()&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/details&gt;
  &lt;details&gt;
    &lt;summary&gt;The output of &lt;code&gt;uv run experiment.py&lt;/code&gt;&lt;/summary&gt;
    &lt;figure class=&quot;nb-code&quot;&gt;&lt;div class=&quot;nb-code-head&quot;&gt;&lt;span class=&quot;nb-code-file&quot;&gt;output of uv run experiment.py&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;/div&gt;&lt;pre&gt;&lt;code data-language=&quot;text&quot;&gt;fixed policy: v at cells 10, 13, 14, 15: [-0.1  -2.01 -1.08  1.98]
fixed policy: q at cell 14 (up, right, down, left): [-1.08  0.32 -1.78 -2.55]
q* at cells 5 and 10 (up, right, down, left): [[0.06, -15.93, -3.58, -0.29], [-15.93, 0.06, -0.29, -3.58]]
cell, move, reward: [(14, &#x27;&amp;gt;&#x27;, -1), (15, &#x27;^&#x27;, -1), (14, &#x27;^&#x27;, -1), (10, &#x27;&amp;gt;&#x27;, -20)]
return per pair: [(14, &#x27;&amp;gt;&#x27;, -17.29), (15, &#x27;^&#x27;, -18.1), (14, &#x27;^&#x27;, -19.0), (10, &#x27;&amp;gt;&#x27;, -20.0)]

runs with an optimal policy, of 20, by when it improves
episodes         every episode           every 5,600  every 5,600, cleared
    1000                     2                     0                     0
    2000                     3                     0                     0
    5000                     6                     0                     0
   10000                    10                     2                     2
   20000                    12                    15                     3
   50000                    16                    16                     5
  100000                    18                    18                     2
episodes cut off at 200 moves: {&#x27;every episode&#x27;: 84, &#x27;every 5,600&#x27;: 277, &#x27;every 5,600, cleared&#x27;: 2902}
every episode, wrong cells at 20000: {5: 4, 9: 1, 10: 3}
every episode, wrong cells at 100000: {5: 2}
run 0 at   1000: &amp;gt; &amp;gt; &amp;gt; . / ^ ^ . ^ / ^ &amp;lt; v ^ / ^ &amp;lt; &amp;gt; ^, wrong [9, 10, 13]
run 0 at  10000: &amp;gt; &amp;gt; &amp;gt; . / ^ ^ . ^ / ^ ^ v ^ / &amp;gt; &amp;gt; &amp;gt; ^, wrong [10]
run 0 at 100000: &amp;gt; &amp;gt; &amp;gt; . / ^ ^ . ^ / ^ ^ &amp;gt; ^ / &amp;gt; &amp;gt; &amp;gt; ^, wrong []
no exploring starts, optimal runs at 10,000: 0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
  &lt;/details&gt;
&lt;/section&gt;

&lt;section data-nb-section=&quot;carried-averages&quot; id=&quot;carried-averages&quot;&gt;
  &lt;h2&gt;Unfinished evaluation works when the averages carry over&lt;/h2&gt;
  &lt;p&gt;Improving after every episode means each new policy is judged by averages that mix returns from many earlier policies. Fig. 3 compares it with two slower schedules, which make the policy greedy only every 5,600 episodes, about 100 starts per pair. One keeps the averages, as Monte Carlo ES does. The other clears them at each improvement with &lt;code&gt;forget=True&lt;/code&gt;, so each policy is evaluated from scratch, as in policy iteration.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.3, p. 97&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
  &lt;figure class=&quot;nb-figure&quot;&gt;
&lt;svg viewBox=&quot;0 0 400 296&quot; role=&quot;img&quot; aria-label=&quot;Line chart of how many of 20 runs have the optimal policy against episodes played, log scale from 1,000 to 100,000. Improving after every episode: 2 at 1,000, 3 at 2,000, 6 at 5,000, 10 at 10,000, 12 at 20,000, 16 at 50,000, 18 at 100,000. Improving every 5,600 episodes and keeping the averages: 0, 0, 0, 2, 15, 16, 18. Improving every 5,600 episodes and clearing the averages: 0, 0, 0, 2, 3, 5, 2.&quot; style=&quot;display: block; width: 100%; max-width: 34rem; margin: 0 auto; height: auto&quot;&gt;
&lt;line x1=&quot;44&quot; y1=&quot;254.0&quot; x2=&quot;386&quot; y2=&quot;254.0&quot; style=&quot;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;38.0&quot; y=&quot;258.0&quot; text-anchor=&quot;end&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;0&lt;/text&gt;
&lt;line x1=&quot;44&quot; y1=&quot;206.0&quot; x2=&quot;386&quot; y2=&quot;206.0&quot; style=&quot;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;38.0&quot; y=&quot;210.0&quot; text-anchor=&quot;end&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;5&lt;/text&gt;
&lt;line x1=&quot;44&quot; y1=&quot;158.0&quot; x2=&quot;386&quot; y2=&quot;158.0&quot; style=&quot;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;38.0&quot; y=&quot;162.0&quot; text-anchor=&quot;end&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;10&lt;/text&gt;
&lt;line x1=&quot;44&quot; y1=&quot;110.0&quot; x2=&quot;386&quot; y2=&quot;110.0&quot; style=&quot;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;38.0&quot; y=&quot;114.0&quot; text-anchor=&quot;end&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;15&lt;/text&gt;
&lt;line x1=&quot;44&quot; y1=&quot;62.0&quot; x2=&quot;386&quot; y2=&quot;62.0&quot; style=&quot;stroke:var(--line);stroke-width:1&quot;/&gt;
&lt;text x=&quot;38.0&quot; y=&quot;66.0&quot; text-anchor=&quot;end&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;20&lt;/text&gt;
&lt;line x1=&quot;44.0&quot; y1=&quot;254&quot; x2=&quot;44.0&quot; y2=&quot;258&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1&quot;/&gt;
&lt;text x=&quot;44.0&quot; y=&quot;270.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;1k&lt;/text&gt;
&lt;line x1=&quot;95.5&quot; y1=&quot;254&quot; x2=&quot;95.5&quot; y2=&quot;258&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1&quot;/&gt;
&lt;text x=&quot;95.5&quot; y=&quot;270.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;2k&lt;/text&gt;
&lt;line x1=&quot;163.5&quot; y1=&quot;254&quot; x2=&quot;163.5&quot; y2=&quot;258&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1&quot;/&gt;
&lt;text x=&quot;163.5&quot; y=&quot;270.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;5k&lt;/text&gt;
&lt;line x1=&quot;215.0&quot; y1=&quot;254&quot; x2=&quot;215.0&quot; y2=&quot;258&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1&quot;/&gt;
&lt;text x=&quot;215.0&quot; y=&quot;270.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;10k&lt;/text&gt;
&lt;line x1=&quot;266.5&quot; y1=&quot;254&quot; x2=&quot;266.5&quot; y2=&quot;258&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1&quot;/&gt;
&lt;text x=&quot;266.5&quot; y=&quot;270.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;20k&lt;/text&gt;
&lt;line x1=&quot;334.5&quot; y1=&quot;254&quot; x2=&quot;334.5&quot; y2=&quot;258&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1&quot;/&gt;
&lt;text x=&quot;334.5&quot; y=&quot;270.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;50k&lt;/text&gt;
&lt;line x1=&quot;386.0&quot; y1=&quot;254&quot; x2=&quot;386.0&quot; y2=&quot;258&quot; style=&quot;stroke:var(--ink-soft);stroke-width:1&quot;/&gt;
&lt;text x=&quot;386.0&quot; y=&quot;270.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;100k&lt;/text&gt;
&lt;text x=&quot;215.0&quot; y=&quot;290.0&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft);font-weight:400&quot;&gt;episodes played (log scale)&lt;/text&gt;
&lt;text x=&quot;12&quot; y=&quot;158.0&quot; transform=&quot;rotate(-90 12 158.0)&quot; text-anchor=&quot;middle&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink-soft)&quot;&gt;optimal runs, of 20&lt;/text&gt;
&lt;polyline points=&quot;44.0,234.8 95.5,225.2 163.5,196.4 215.0,158.0 266.5,138.8 334.5,100.4 386.0,81.2&quot; style=&quot;fill:none;stroke:var(--chart-2);stroke-width:2.2&quot;/&gt;
&lt;circle cx=&quot;44.0&quot; cy=&quot;234.8&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-2)&quot;/&gt;
&lt;circle cx=&quot;95.5&quot; cy=&quot;225.2&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-2)&quot;/&gt;
&lt;circle cx=&quot;163.5&quot; cy=&quot;196.4&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-2)&quot;/&gt;
&lt;circle cx=&quot;215.0&quot; cy=&quot;158.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-2)&quot;/&gt;
&lt;circle cx=&quot;266.5&quot; cy=&quot;138.8&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-2)&quot;/&gt;
&lt;circle cx=&quot;334.5&quot; cy=&quot;100.4&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-2)&quot;/&gt;
&lt;circle cx=&quot;386.0&quot; cy=&quot;81.2&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-2)&quot;/&gt;
&lt;line x1=&quot;54&quot; y1=&quot;10&quot; x2=&quot;78&quot; y2=&quot;10&quot; style=&quot;stroke:var(--chart-2);stroke-width:2.2&quot;/&gt;
&lt;text x=&quot;84.0&quot; y=&quot;14.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;improve after every episode&lt;/text&gt;
&lt;polyline points=&quot;44.0,254.0 95.5,254.0 163.5,254.0 215.0,234.8 266.5,110.0 334.5,100.4 386.0,81.2&quot; style=&quot;fill:none;stroke:var(--chart-1);stroke-width:2.2;stroke-dasharray:6 4&quot;/&gt;
&lt;circle cx=&quot;44.0&quot; cy=&quot;254.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-1)&quot;/&gt;
&lt;circle cx=&quot;95.5&quot; cy=&quot;254.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-1)&quot;/&gt;
&lt;circle cx=&quot;163.5&quot; cy=&quot;254.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-1)&quot;/&gt;
&lt;circle cx=&quot;215.0&quot; cy=&quot;234.8&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-1)&quot;/&gt;
&lt;circle cx=&quot;266.5&quot; cy=&quot;110.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-1)&quot;/&gt;
&lt;circle cx=&quot;334.5&quot; cy=&quot;100.4&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-1)&quot;/&gt;
&lt;circle cx=&quot;386.0&quot; cy=&quot;81.2&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-1)&quot;/&gt;
&lt;line x1=&quot;54&quot; y1=&quot;26&quot; x2=&quot;78&quot; y2=&quot;26&quot; style=&quot;stroke:var(--chart-1);stroke-width:2.2;stroke-dasharray:6 4&quot;/&gt;
&lt;text x=&quot;84.0&quot; y=&quot;30.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;improve every 5,600, averages kept&lt;/text&gt;
&lt;polyline points=&quot;44.0,254.0 95.5,254.0 163.5,254.0 215.0,234.8 266.5,225.2 334.5,206.0 386.0,234.8&quot; style=&quot;fill:none;stroke:var(--chart-5);stroke-width:2.2&quot;/&gt;
&lt;circle cx=&quot;44.0&quot; cy=&quot;254.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-5)&quot;/&gt;
&lt;circle cx=&quot;95.5&quot; cy=&quot;254.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-5)&quot;/&gt;
&lt;circle cx=&quot;163.5&quot; cy=&quot;254.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-5)&quot;/&gt;
&lt;circle cx=&quot;215.0&quot; cy=&quot;234.8&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-5)&quot;/&gt;
&lt;circle cx=&quot;266.5&quot; cy=&quot;225.2&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-5)&quot;/&gt;
&lt;circle cx=&quot;334.5&quot; cy=&quot;206.0&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-5)&quot;/&gt;
&lt;circle cx=&quot;386.0&quot; cy=&quot;234.8&quot; r=&quot;3&quot; style=&quot;fill:var(--chart-5)&quot;/&gt;
&lt;line x1=&quot;54&quot; y1=&quot;42&quot; x2=&quot;78&quot; y2=&quot;42&quot; style=&quot;stroke:var(--chart-5);stroke-width:2.2&quot;/&gt;
&lt;text x=&quot;84.0&quot; y=&quot;46.0&quot; text-anchor=&quot;start&quot; style=&quot;font-family:var(--sans);font-size:11px;fill:var(--ink);font-weight:400&quot;&gt;improve every 5,600, averages cleared&lt;/text&gt;
&lt;/svg&gt;
    &lt;figcaption&gt;Fig. 3 · Runs, of 20, at the optimal policy under three schedules of improvement, on the same seeds. Kept averages carry over from one policy to the next, and cleared ones start empty. The two 5,600 lines coincide through 10,000 episodes, before the second improvement. Values from &lt;code&gt;experiment.py&lt;/code&gt;.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p&gt;Waiting 5,600 episodes between improvements gains nothing by the end. It delays the first improvement, catches up by 20,000 episodes, and from 50,000 on has no more runs at the optimal policy than improving after every episode. Clearing the averages is what costs. The cleared schedule never has more than 5 runs at the optimal policy, and it ends with 2. Each of its policies is judged on 5,600 episodes, about 100 returns for each move the policy does not take, while the kept schedule improves at the same episodes and keeps every return.&lt;/p&gt;
  &lt;p&gt;On this grid evaluation never had to finish before the policy changed, but its averages had to keep their returns.&lt;/p&gt;
&lt;/section&gt;

&lt;section data-nb-section=&quot;what-is-proved&quot; id=&quot;what-is-proved&quot;&gt;
  &lt;h2&gt;Only the optimal policy can be a resting point&lt;/h2&gt;
  &lt;p&gt;Sutton and Barto give half an argument that Monte Carlo ES ends at the optimal policy.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.3, p. 99&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Suppose the policy and the averages stopped changing. The averages would then be that policy&#x27;s action values, and the policy would be greedy with respect to them, so in every cell the following holds.&lt;/p&gt;
  &lt;figure class=&quot;nb-math&quot;&gt;&lt;div class=&quot;nb-math-eq&quot;&gt;\begin{aligned} v_\pi(s) &amp;amp;= q_\pi\bigl(s, \pi(s)\bigr) = \max_a q_\pi(s, a) \\ &amp;amp;= \max_a \sum_{s&#x27;} P(s&#x27; \mid s, a)\,\bigl[\, R(s&#x27;) + \gamma\, v_\pi(s&#x27;) \,\bigr] \end{aligned}&lt;/div&gt;&lt;/figure&gt;
  &lt;p&gt;The last line is the &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;Bellman optimality equation&lt;/a&gt;, and only &lt;span class=&quot;nb-math-in&quot;&gt;v_*&lt;/span&gt; solves it, so &lt;span class=&quot;nb-math-in&quot;&gt;\pi&lt;/span&gt; is optimal. A suboptimal policy cannot be a resting point.&lt;/p&gt;
  &lt;p&gt;The other half, that the process must come to rest, has not been proved for this algorithm in general. Sutton and Barto call it &quot;one of the most fundamental open theoretical questions in reinforcement learning&quot;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Section 5.3, p. 99&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Proofs now cover one variant and two classes of problem, each with conditions of its own on step sizes or on long episodes.&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Tsitsiklis proves convergence for a variant that updates only the pair each episode starts from, with every pair used as a start equally often, on any finite problem with a discount below 1.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;p. 60; Proposition 5, p. 71&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
    &lt;li&gt;Wang, Yuan, Shao and Ross prove it for first-visit updates to every pair, as in &lt;code&gt;mc_control.py&lt;/code&gt;, on problems where an optimal policy never revisits a state.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Definitions pp. 4-5; Theorem 2, p. 7&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
    &lt;li&gt;Delattre and Fournier prove it for first-visit Monte Carlo control on any finite problem with a discount below 1/2.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot; data-nb-locator=&quot;Algorithm 1, pp. 5-6; Theorem 3, p. 6&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;None of the three covers &lt;code&gt;mc_control.py&lt;/code&gt; on this grid. Tsitsiklis&#x27;s variant updates only the start pair, where &lt;code&gt;mc_control.py&lt;/code&gt; updates every pair an episode visits. The grid&#x27;s discount is 0.9, above 1/2, and its optimal policy can revisit a state: cell 2&#x27;s only optimal move, right, slips up into the edge with probability 0.1 and leaves the agent in cell 2. Wang and colleagues list weaker conditions than theirs as an open problem,&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Conclusion and Figure 3, p. 9&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; and Delattre and Fournier write that &quot;only half the way is done&quot;.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot; data-nb-locator=&quot;Introduction, p. 2&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; For this grid the question stays open. The runs show what Monte Carlo ES did on the seeds tried, and no theorem says that every run must end at the optimal policy.&lt;/p&gt;
  &lt;aside class=&quot;nb-note&quot;&gt;
    &lt;span class=&quot;nb-note-label&quot;&gt;Problems&lt;/span&gt;
    &lt;p&gt;1. Use the weighted sum from &lt;a href=&quot;https://ryansaxe.github.io/the-nightly-build/reinforcement-learning/finding-optimal-policies.html&quot;&gt;policy iteration&lt;/a&gt; to price aiming down at cell 14 under the fixed policy, where &lt;span class=&quot;nb-math-in&quot;&gt;v_\pi(13) = -2.01&lt;/span&gt;, &lt;span class=&quot;nb-math-in&quot;&gt;v_\pi(14) = -1.08&lt;/span&gt; and &lt;span class=&quot;nb-math-in&quot;&gt;v_\pi(15) = 1.98&lt;/span&gt;. Which cells can the move land in, with what probabilities? Compare your answer with Fig. 1.&lt;/p&gt;
    &lt;details&gt;
      &lt;summary&gt;Answer&lt;/summary&gt;
      &lt;p&gt;Down runs into the bottom wall and stays in cell 14 with probability 0.8. It slips left to cell 13 or right to cell 15 with probability 0.1 each. Every landing pays &amp;minus;1, so &lt;span class=&quot;nb-math-in&quot;&gt;q_\pi(14, \text{down}) = -1 + 0.9\,[\,0.8(-1.08) + 0.1(-2.01) + 0.1(1.98)\,] = -1.78&lt;/span&gt;, the down triangle in Fig. 1.&lt;/p&gt;
    &lt;/details&gt;
    &lt;p&gt;2. Suppose every episode started in cell 13 with a random first move, and the agent followed its policy after that. Which cells could ever change their move?&lt;/p&gt;
    &lt;details&gt;
      &lt;summary&gt;Answer&lt;/summary&gt;
      &lt;p&gt;Only cell 13. The agent reaches every other cell by following its policy, so the only pair with returns there is the policy&#x27;s own, and the greedy step keeps it. Exploring starts need every pair, in every cell, to have some chance of opening an episode.&lt;/p&gt;
    &lt;/details&gt;
  &lt;/aside&gt;
&lt;/section&gt;

&lt;section class=&quot;nb-bookend&quot; data-nb-section=&quot;takeaway&quot; id=&quot;takeaway&quot;&gt;
  &lt;p class=&quot;nb-bookend-name&quot;&gt;The takeaway&lt;/p&gt;
  &lt;div class=&quot;nb-bookend-rule&quot;&gt;&lt;/div&gt;
  &lt;p&gt;An action value is the expected return after a move in a cell, so an agent can estimate it by crediting each return to the (cell, move) pair it followed. The greedy step over action values compares a cell&#x27;s averages and needs no model, and the policy improvement theorem still applies. Exploring starts supply returns for moves a greedy policy never takes. Improving after every episode reached the optimal policy within 100,000 episodes in nearly every run. Waiting between improvements did not help, and clearing the averages at each one did harm. Only the optimal policy can be a resting point, but no theorem yet says runs on this grid must reach it.&lt;/p&gt;
  &lt;div class=&quot;nb-bookend-band&quot;&gt;&lt;span class=&quot;nb-bookend-label&quot;&gt;Go deeper&lt;/span&gt;&lt;span class=&quot;nb-bookend-note&quot;&gt;optional reading&lt;/span&gt;&lt;/div&gt;
  &lt;dl class=&quot;nb-bookend-reading&quot;&gt;
    &lt;dt&gt;01&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;http://incompleteideas.net/book/RLbook2020.pdf&quot;&gt;Sutton and Barto, Section 5.3 and Example 5.3&lt;/a&gt;: read the Monte Carlo ES box on p. 99 line by line against &lt;code&gt;mc_control.py&lt;/code&gt;, then Figure 5.2 (p. 100) for the blackjack policy it finds.&lt;/dd&gt;
    &lt;dt&gt;02&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;https://www.jmlr.org/papers/v3/tsitsiklis02a.html&quot;&gt;Tsitsiklis, On the Convergence of Optimistic Policy Iteration (2002)&lt;/a&gt;: read p. 60 for the variant he settles, and Section 5 (pp. 70-71) for why the action-value version needs no model where the state-value version does.&lt;/dd&gt;
    &lt;dt&gt;03&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;https://arxiv.org/abs/2002.03585&quot;&gt;Wang, Yuan, Shao and Ross, On the Convergence of the Monte Carlo Exploring Starts Algorithm for Reinforcement Learning (2022)&lt;/a&gt;: read the definitions on pp. 4-5 for the condition that no state is revisited, and Figure 3 (p. 9) for a 2022 map of what was proved.&lt;/dd&gt;
    &lt;dt&gt;04&lt;/dt&gt;
    &lt;dd&gt;&lt;a href=&quot;http://incompleteideas.net/papers/sutton-99.pdf&quot;&gt;Sutton, Open Theoretical Questions in Reinforcement Learning (1999)&lt;/a&gt;: Section 2 (p. 4) poses the convergence question in one paragraph, as it was first asked.&lt;/dd&gt;
  &lt;/dl&gt;
&lt;/section&gt;

&lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
  &lt;h2&gt;Sources&lt;/h2&gt;
  &lt;ol&gt;
    &lt;li id=&quot;s1&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-note=&quot;The authors&#x27; free copy is at incompleteideas.net/book/RLbook2020.pdf. Page numbers are the printed ones; the printed page is the PDF page minus 22.&quot; href=&quot;https://mitpress.mit.edu/9780262039246/reinforcement-learning/&quot;&gt;MIT Press &amp;middot; Richard S. Sutton and Andrew G. Barto, Reinforcement Learning: An Introduction, 2nd edition, 2018 (second printing 2020)&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;s2&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-note=&quot;Journal of Machine Learning Research 3, 59-72; page numbers are the JMLR printed pages.&quot; href=&quot;https://www.jmlr.org/papers/v3/tsitsiklis02a.html&quot;&gt;Journal of Machine Learning Research &amp;middot; John N. Tsitsiklis, On the Convergence of Optimistic Policy Iteration, 2002&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;s3&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-note=&quot;Published as a conference paper at ICLR 2022; page numbers are those of arXiv v2, 5 August 2022.&quot; href=&quot;https://arxiv.org/abs/2002.03585&quot;&gt;ICLR 2022 &amp;middot; Che Wang, Shuhan Yuan, Kai Shao and Keith Ross, On the Convergence of the Monte Carlo Exploring Starts Algorithm for Reinforcement Learning&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;s4&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-note=&quot;Published in SIAM Journal on Control and Optimization 64(3), 1672-1697, 2026 (doi.org/10.1137/25M1726200). Read in arXiv v2, 22 September 2025; page and result numbers are that version&#x27;s, and the journal&#x27;s numbering was not checked.&quot; href=&quot;https://arxiv.org/abs/2501.08800&quot;&gt;SIAM Journal on Control and Optimization &amp;middot; Sylvain Delattre and Nicolas Fournier, Markov decision processes: on the convergence of the Monte-Carlo first visit algorithm, 2026&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="reinforcement-learning"/>
  </entry>
  <entry>
    <title>Supreme Court won&#x27;t make California set aside 20,000 alleged noncitizens&#x27; ballots</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-11-03.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-11-03</id>
    <updated>2026-11-03T06:37:01Z</updated>
    <summary>No justice noted a dissent from the one-sentence order, and none answered the Solicitor General&#x27;s argument that commingled ballots could never be retrieved.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Daily Brief&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;Supreme Court won&#x27;t make California set aside 20,000 alleged noncitizens&#x27; ballots&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;No justice noted a dissent from the one-sentence order, and none answered the Solicitor General&#x27;s argument that commingled ballots could never be retrieved.&lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;3 min read&lt;/span&gt;&lt;span&gt;2026-11-03&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section data-nb-section=&quot;items&quot; id=&quot;items&quot;&gt;
        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Word of the Day&lt;/span&gt;
          &lt;div class=&quot;rs-word-card&quot;&gt;
            &lt;div class=&quot;rs-word-card-head&quot;&gt;
              &lt;span class=&quot;rs-word-term&quot;&gt;agnotology&lt;/span&gt;
              &lt;span class=&quot;rs-word-meta&quot;&gt;
                &lt;span class=&quot;rs-word-pos&quot;&gt;noun&lt;/span&gt;
                &lt;span class=&quot;rs-word-pronunciation&quot;&gt;/ag-nuh-TAH-luh-jee/&lt;/span&gt;
              &lt;/span&gt;
            &lt;/div&gt;
            &lt;p class=&quot;rs-word-definition&quot;&gt;
              The study of the deliberate cultivation of ignorance, or the cultivation itself.
              &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;p&gt;
            Robert Proctor wanted a word for the study of how ignorance is made, and the existing agnoiology carried a metaphysical sense. In 1992 he asked the linguist Iain Boal, who coined agnotology that spring from the Greek gno, &quot;to know&quot;, the negating prefix a-, and -ology, chosen largely for its sound. They first spelled it agnatology, then changed it because agnate already meant a relative and a few biologists said it infringed on the study of agnathic, or jawless, fish. Rejected alternatives included Lorraine Daston&#x27;s tongue-in-cheek &quot;ignorance-lore&quot;. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;Justice Department loses Supreme Court bid over California ballots&lt;/h3&gt;
          &lt;p&gt;
            On 2 November the Supreme Court denied the Justice Department&#x27;s application in United States v. California, which asked it to order California to keep separate the mail ballots of more than 20,000 people the government says are noncitizens. The order gives no reasons and lists no dissent. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Solicitor General D. John Sauer argued that commingled ballots cannot be retrieved. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;US strikes Qeshm Island a day before the midterms, officials tell CBS and AP&lt;/h3&gt;
          &lt;p&gt;
            Three US officials told CBS the US carried out limited &quot;defensive strikes&quot; near the Strait of Hormuz, and a senior official said they hit Qeshm Island after the Revolutionary Guard fired at an American aircraft. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; An unnamed official told AP the targets were Iranians using surface-to-air missiles against US assets, and Iranian state television reported explosions on Qeshm, though neither outlet cites a Pentagon or CENTCOM statement. The 2 November Daily Brief reported strikes might resume after the midterms, and Trump had said none would come before them. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;Judge Chutkan bars DHS and DOJ from sending states noncitizen lists&lt;/h3&gt;
          &lt;p&gt;
            On 2 November Judge Tanya Chutkan of the D.C. district court enjoined the policy under which DHS and DOJ send election officials records of people they say are noncitizens. She found the plaintiffs in League of Women Voters v. DHS likely to succeed on claims that it lacks statutory authority and violates the Privacy Act, since no system-of-records notice covers sending the data to states. The opinion records that of the 20,000-plus records DOJ gave Los Angeles County on 13 October, &quot;only 7,035&quot; had county addresses. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Technology&lt;/span&gt;
          &lt;h3&gt;GPT-6 Astra edits 0.016% of Qwen3.5-0.8B&#x27;s weights, lifting MATH-500 from 7.9% to 48.1%, authors report&lt;/h3&gt;
          &lt;p&gt;
            Four MIT CSAIL researchers wrote on 2 November that GPT-6 Astra, with Python access to Qwen3.5-0.8B&#x27;s weights, traced its looping to one direction written by the MLPs of layers 15 and 19. Subtracting it from 131,072 weights raised MATH-500 from 7.9% to 48.1% at 50 forward passes and cut answers hitting the 32,768-token limit from 93.0% to 33.1%. The figures are the authors&#x27; own, with no linked paper, and on Gemma 3 270M, which rarely loops, the method moved MATH-500 only from 6.8% to 7.0%. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Technology&lt;/span&gt;
          &lt;h3&gt;Google dismantles XCPE, a botnet of 1.3 million Android set-top boxes&lt;/h3&gt;
          &lt;p&gt;
            Google Threat Intelligence Group said on 2 November that &quot;last week&quot; it and partners dismantled XCPE, a botnet it says enrolled more than 1.3 million Android set-top boxes through a preloaded backdoor. Google assesses &quot;with high confidence&quot; that the device maker Videostrong Technology built and ran it for profit, selling access to affiliates who ran ad fraud and loaded further malware. The attribution is Google&#x27;s alone, and Google says it has banned Videostrong from building certified Android devices. &lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s9&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://www.merriam-webster.com/slang/agnotology&quot; data-nb-locator=&quot;Slang &amp;amp; Trending entry: headword, pronunciation and definition&quot;&gt;Merriam-Webster · agnotology&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://wp.unil.ch/serendip/files/2018/10/Agnotology-Ch-1-Proctor-2008.pdf&quot; data-nb-locator=&quot;Chapter 1, Postscript on the Coining of the Term &#x27;Agnotology&#x27;, pp. 26-27&quot;&gt;Proctor · Agnotology: A Missing Term (2008)&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s3&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://www.supremecourt.gov/orders/courtorders/110226zr_3eb4.pdf&quot; data-nb-locator=&quot;Order in Pending Case 26A624, 2 November 2026&quot;&gt;Supreme Court · United States v. California, order&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s4&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://www.scotusblog.com/2026/11/trump-administration-asks-supreme-court-to-intervene-in-california-ballots-dispute/&quot; data-nb-locator=&quot;procedural history and the Court&#x27;s action&quot;&gt;SCOTUSblog · Administration asks Supreme Court to intervene on California ballots&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s5&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://www.cbsnews.com/news/u-s-strikes-iran-targets/&quot; data-nb-locator=&quot;first paragraphs&quot;&gt;CBS News · U.S. strikes Iran targets&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s6&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://www.wilx.com/2026/11/03/us-has-conducted-defensive-strikes-some-iranian-targets-strait-hormuz-us-official-says/&quot; data-nb-note=&quot;Associated Press wire copy on a local station&#x27;s site&quot;&gt;Associated Press · US conducts defensive strikes on Iranian targets, official says&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s7&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://storage.courtlistener.com/recap/gov.uscourts.dcd.297656/gov.uscourts.dcd.297656.31.0.pdf&quot; data-nb-locator=&quot;Memorandum Opinion, Doc. 31: p. 1, pp. 3-5, Part III.A&quot;&gt;D.D.C. · League of Women Voters v. DHS, memorandum opinion&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s8&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://rikiyat.github.io/blog/weight-space-programming/&quot; data-nb-locator=&quot;TL;DR; Experiment 8 and the Gemma 3 270M additional experiment&quot;&gt;Takehi et al. · Sparks of Weight-Space Programming&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s9&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://cloud.google.com/blog/topics/threat-intelligence/shutting-the-door-on-the-xcpe-botnet/&quot; data-nb-locator=&quot;introduction and list of actions&quot;&gt;Google Threat Intelligence Group · Shutting the door on the XCPE botnet&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>An agent can learn what each state is worth without knowing the rules</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/reinforcement-learning/learning-values-from-samples.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/reinforcement-learning/learning-values-from-samples</id>
    <updated>2026-11-02T08:23:21-05:00</updated>
    <summary>Averaging whole episodes gives unbiased but noisy targets, and updating after every move gives quieter targets that carry the errors in the agent&#x27;s own estimates.</summary>
    <category term="reinforcement-learning"/>
  </entry>
  <entry>
    <title>Tether and Circle froze Binance’s stolen stablecoins and had no reach over the rest</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/binance-hack-freeze.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/binance-hack-freeze</id>
    <updated>2026-11-02T06:53:41Z</updated>
    <summary>Elliptic counts 44% of the $6.43 billion as frozen or seized, almost all of it stablecoin, where Bybit’s 2025 haul held no stablecoin and saw 3% to 3.84% frozen.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Feature&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;Tether and Circle froze Binance&amp;rsquo;s stolen stablecoins and had no reach over the rest&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;Elliptic counts 44% of the $6.43 billion as frozen or seized, almost all of it stablecoin, where Bybit’s 2025 haul held no stablecoin and saw 3% to 3.84% frozen.&lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;5 min read&lt;/span&gt;&lt;span&gt;2026-11-02&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section data-nb-section=&quot;orientation&quot; id=&quot;orientation&quot;&gt;
        &lt;h2&gt;Over half the haul had an issuer to call&lt;/h2&gt;
        &lt;p&gt;
          A freeze reaches only tokens that have an issuer, and only those the
          thief has not yet swapped out. About $6.3 billion left Binance&amp;rsquo;s
          wallets on 29 October by Binance&amp;rsquo;s estimate, $6.36 billion by TRM
          Labs&amp;rsquo; trace and $6.43 billion by Elliptic&amp;rsquo;s.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Update note, estimated total impact&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;How much was taken&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Key points&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Most moved in about 20 minutes from 20:05 UTC.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;How the attack unfolded&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
          Elliptic counts $3.46 billion of its total as stablecoin.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          The frozen tally runs from about $2.7 billion (TRM, 30 October) to
          $2.85 billion (Elliptic, 1 November) to about $3 billion (Binance,
          method unstated).&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;Key takeaways&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Body, ~$3 billion frozen on-chain&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          All are days old and still moving. Frozen is not returned: Binance
          says it is working with partners and law enforcement to recover the
          frozen assets, and CoinDesk reports none returned.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;only-an-administrator-can-flag-an-address&quot; id=&quot;only-an-administrator-can-flag-an-address&quot;&gt;
        &lt;h2&gt;Only an administrator can flag an address&lt;/h2&gt;
        &lt;p&gt;
          A stablecoin contract keeps a blocklist and checks it on transfers, so a
          listed address cannot move its balance. Tether&amp;rsquo;s
          USDT on Ethereum gives its owner &lt;code&gt;addBlackList&lt;/code&gt; and
          &lt;code&gt;destroyBlackFunds&lt;/code&gt;, which also sets a blacklisted balance
          to zero.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot; data-nb-locator=&quot;Contract TetherToken, BlackList&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; Circle&amp;rsquo;s USDC restricts
          &lt;code&gt;blacklist&lt;/code&gt; to a designated blacklister.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot; data-nb-locator=&quot;Blacklistable.sol&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; Tether
          froze the main Ethereum wallet 37 minutes after the USDT arrived, and
          Circle froze 823 million USDC three minutes after that.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds, freeze timing&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot; style=&quot;overflow-x: auto&quot;&gt;
          &lt;svg role=&quot;img&quot; viewBox=&quot;0 0 680 290&quot; aria-label=&quot;Three rows, each running left to right from an asset to a check to an outcome. Stablecoin at a flagged address meets the issuer&#x27;s blocklist and the transfer reverts, leaving the balance frozen in place. An un-administered asset such as BTC, XRP, SOL, NEAR or ETH has no issuer and no blocklist, so the transfer goes through and the funds are traced, not stopped. An administered non-stablecoin such as ARB, OP, WBETH or tokenized gold is frozen or moved out of reach by a governance body or its issuing party. A dashed arrow from the stablecoin row to the un-administered row marks a swap made before the flag lands, about 786 million dollars in this theft.&quot; style=&quot;width: 100%; min-width: 34rem; height: auto&quot;&gt;
            &lt;defs&gt;
              &lt;marker id=&quot;ah&quot; viewBox=&quot;0 0 10 10&quot; refX=&quot;9&quot; refY=&quot;5&quot; markerWidth=&quot;7&quot; markerHeight=&quot;7&quot; orient=&quot;auto&quot;&gt;
                &lt;path d=&quot;M0 0L10 5L0 10z&quot; style=&quot;fill: var(--ink-soft)&quot;/&gt;
              &lt;/marker&gt;
            &lt;/defs&gt;
            &lt;rect x=&quot;10&quot; y=&quot;10&quot; width=&quot;220&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-1); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;22&quot; y=&quot;36&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Stablecoin at a flagged address&lt;/text&gt;
            &lt;text x=&quot;22&quot; y=&quot;56&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;Tether, Circle, Ripple and others&lt;/text&gt;
            &lt;line x1=&quot;230&quot; y1=&quot;42&quot; x2=&quot;268&quot; y2=&quot;42&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 1.5&quot; marker-end=&quot;url(#ah)&quot;/&gt;
            &lt;rect x=&quot;270&quot; y=&quot;10&quot; width=&quot;190&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-1); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;282&quot; y=&quot;36&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Issuer&amp;rsquo;s blocklist&lt;/text&gt;
            &lt;text x=&quot;282&quot; y=&quot;56&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;checked on every transfer&lt;/text&gt;
            &lt;line x1=&quot;460&quot; y1=&quot;42&quot; x2=&quot;498&quot; y2=&quot;42&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 1.5&quot; marker-end=&quot;url(#ah)&quot;/&gt;
            &lt;rect x=&quot;500&quot; y=&quot;10&quot; width=&quot;170&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-1); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;512&quot; y=&quot;36&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Transfer reverts&lt;/text&gt;
            &lt;text x=&quot;512&quot; y=&quot;56&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;balance frozen in place&lt;/text&gt;

            &lt;line x1=&quot;120&quot; y1=&quot;76&quot; x2=&quot;120&quot; y2=&quot;128&quot; style=&quot;stroke: var(--chart-2); stroke-width: 2; stroke-dasharray: 5 4&quot; marker-end=&quot;url(#ah)&quot;/&gt;
            &lt;text x=&quot;134&quot; y=&quot;107&quot; style=&quot;font-family: var(--sans); font-size: 12px; font-weight: 600; fill: var(--ink)&quot;&gt;Swap before the flag lands: about $786M in this theft&lt;/text&gt;

            &lt;rect x=&quot;10&quot; y=&quot;130&quot; width=&quot;220&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-3); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;22&quot; y=&quot;156&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Un-administered asset&lt;/text&gt;
            &lt;text x=&quot;22&quot; y=&quot;176&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;Bitcoin, XRP, Solana, NEAR&lt;/text&gt;
            &lt;line x1=&quot;230&quot; y1=&quot;162&quot; x2=&quot;268&quot; y2=&quot;162&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 1.5&quot; marker-end=&quot;url(#ah)&quot;/&gt;
            &lt;rect x=&quot;270&quot; y=&quot;130&quot; width=&quot;190&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-3); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;282&quot; y=&quot;167&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;No issuer, no blocklist&lt;/text&gt;
            
            &lt;line x1=&quot;460&quot; y1=&quot;162&quot; x2=&quot;498&quot; y2=&quot;162&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 1.5&quot; marker-end=&quot;url(#ah)&quot;/&gt;
            &lt;rect x=&quot;500&quot; y=&quot;130&quot; width=&quot;170&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-3); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;512&quot; y=&quot;156&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Transfer goes through&lt;/text&gt;
            &lt;text x=&quot;512&quot; y=&quot;176&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;traced, not stopped&lt;/text&gt;

            &lt;rect x=&quot;10&quot; y=&quot;214&quot; width=&quot;220&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-4); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;22&quot; y=&quot;240&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Administered non-stablecoin&lt;/text&gt;
            &lt;text x=&quot;22&quot; y=&quot;260&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;ARB, tokenized gold, WBETH&lt;/text&gt;
            &lt;line x1=&quot;230&quot; y1=&quot;246&quot; x2=&quot;268&quot; y2=&quot;246&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 1.5&quot; marker-end=&quot;url(#ah)&quot;/&gt;
            &lt;rect x=&quot;270&quot; y=&quot;214&quot; width=&quot;190&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-4); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;282&quot; y=&quot;240&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Someone administers it&lt;/text&gt;
            &lt;text x=&quot;282&quot; y=&quot;260&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;governance or issuer acts&lt;/text&gt;
            &lt;line x1=&quot;460&quot; y1=&quot;246&quot; x2=&quot;498&quot; y2=&quot;246&quot; style=&quot;stroke: var(--ink-soft); stroke-width: 1.5&quot; marker-end=&quot;url(#ah)&quot;/&gt;
            &lt;rect x=&quot;500&quot; y=&quot;214&quot; width=&quot;170&quot; height=&quot;64&quot; rx=&quot;6&quot; style=&quot;fill: var(--panel); stroke: var(--chart-4); stroke-width: 2&quot;/&gt;
            &lt;text x=&quot;512&quot; y=&quot;240&quot; style=&quot;font-family: var(--sans); font-size: 13px; font-weight: 600; fill: var(--ink)&quot;&gt;Frozen or moved aside&lt;/text&gt;
            &lt;text x=&quot;512&quot; y=&quot;260&quot; style=&quot;font-family: var(--sans); font-size: 12px; fill: var(--ink-soft)&quot;&gt;$36M in ETH, ARB and OP&lt;/text&gt;
          &lt;/svg&gt;
          &lt;figcaption&gt;
            Fig. 1 &amp;middot; Three outcomes for a flagged address. Conceptual
            diagram; the $786 million and $36 million are Elliptic&amp;rsquo;s figures.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds; chart 2, Arbitrum and Optimism&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          Nothing stolen on Bitcoin, the XRP Ledger, Solana or NEAR has been
          frozen, Elliptic reports, because native assets have no issuer that can
          freeze them.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; The dividing line is whether anyone administers
          the asset. Arbitrum&amp;rsquo;s Security Council moved, and Optimism&amp;rsquo;s governance
          appears to have moved, about $36 million of ETH, ARB and OP out of the
          attacker&amp;rsquo;s reach, and Binance froze its own WBETH.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
          Circle did not freeze about $230
          million of USDC from April&amp;rsquo;s Drift exploit and says it freezes
          only when legally compelled. A Circle spokesperson told American Banker
          the company froze more than $1.1 billion for Binance, which no
          on-chain count reproduces: TRM and Elliptic find $823 million to $825
          million.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot; data-nb-locator=&quot;Circle policy and spokesperson paragraphs&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;Stablecoin freezes and conversion&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Chart 3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;most-stablecoins-froze-before-the-thief-could-swap-them&quot; id=&quot;most-stablecoins-froze-before-the-thief-could-swap-them&quot;&gt;
        &lt;h2&gt;Most stablecoins froze before the thief could swap them&lt;/h2&gt;
        &lt;p&gt;
          Read each bar of Fig. 2 from the left: frozen, then swapped out before
          the freeze, then out of any issuer&amp;rsquo;s reach.
        &lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
          &lt;img
            src=&quot;binance-hack-freeze/chart-1.png&quot;
            alt=&quot;Two horizontal stacked bars in US dollars. Stablecoins, 3.46 billion stolen: 2.68 billion frozen or seized and 0.79 billion swapped out before the freeze, so 77% frozen. Everything else, 2.97 billion stolen: 0.17 billion frozen and 2.80 billion not frozen, so 6% frozen.&quot;
          /&gt;
          &lt;figcaption&gt;
            Fig. 2 &amp;middot; Binance haul by asset type, US$ billions, Elliptic&amp;rsquo;s
            figures. Frozen stablecoin is derived as 94% of its $2.85 billion and
            carries about a point of rounding error. Stolen amounts are at
            theft-time prices and frozen amounts at 1 November prices.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          Before the freezes landed, the attacker converted about $786 million of
          stablecoins into ETH and TRX, including 434 million USDT into 160,451
          ETH at a 12% to 26% loss against market.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; About 77% of the stolen stablecoin ended up frozen, against
          about 6% of everything else. The issuers froze nearly all the stablecoin still in
          place when they acted, so the gap came from speed as well as from the asset model.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;bybit-s-haul-held-no-stablecoin-for-an-issuer-to-freeze&quot; id=&quot;bybit-s-haul-held-no-stablecoin-for-an-issuer-to-freeze&quot;&gt;
        &lt;h2&gt;Bybit&amp;rsquo;s haul held no stablecoin for an issuer to freeze&lt;/h2&gt;
        &lt;p&gt;
          The FBI put the 2025 Bybit theft at approximately $1.5 billion.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s9&quot; data-nb-locator=&quot;Press release, first paragraph&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;
          Block Scholes read the haul from the chain as 401,347 ETH, 90,376
          stETH, 8,000 mETH and 15,000 cmETH, about $1.46 billion, with no
          stablecoin.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s10&quot; data-nb-locator=&quot;Bybit stolen-asset list&quot;&gt;10&lt;/a&gt;&lt;/sup&gt; Bybit&amp;rsquo;s CEO Ben Zhou counted 3.84% frozen on 21 April
          2025, as Decrypt reported,&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s11&quot; data-nb-locator=&quot;Zhou quote, 21 April 2025&quot;&gt;11&lt;/a&gt;&lt;/sup&gt; up from 3% in early March.
          Block Scholes found no freeze of the stolen ETH in its 22 February
          update, and no source says what the 3.84% consists of.
        &lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot;&gt;
          &lt;img
            src=&quot;binance-hack-freeze/chart-2.png&quot;
            alt=&quot;Grouped horizontal bars comparing two thefts. Stablecoin share of the haul: Binance 54%, Bybit 0%. Frozen or seized share of the haul: Binance 44%, Bybit 3% to 3.84%.&quot;
          /&gt;
          &lt;figcaption&gt;
            Fig. 3 &amp;middot; Stablecoin share and frozen share of each haul.
            Binance: Elliptic, by dollar value. Bybit: Zhou&amp;rsquo;s frozen share
            of about 500,000 ETH, and Block Scholes&amp;rsquo; reading of the chain.
            The Bybit bar shows 3.84%.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s10&quot;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s11&quot;&gt;11&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          Two thefts are not a rule, but the mechanism in Fig. 1 predicts the
          order. The haul with an issuer behind 54% of it saw 44% frozen or
          seized, and the haul with none saw under 4%.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;binance-has-walked-back-its-breach-path-and-the-attributions-are-assessments&quot; id=&quot;binance-has-walked-back-its-breach-path-and-the-attributions-are-assessments&quot;&gt;
        &lt;h2&gt;Binance has walked back its breach path, and the attributions are assessments&lt;/h2&gt;
        &lt;p&gt;
          Binance&amp;rsquo;s initial finding, posted by co-CEO Richard Teng on 30
          October, was that the incident &amp;ldquo;may have started with a compromised DevOps
          engineer&amp;rsquo;s laptop.&amp;rdquo; The laptop, he wrote, gave an attacker access to a
          service container, where they submitted unauthorized withdrawal
          transactions.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s12&quot; data-nb-locator=&quot;Post body, paragraphs 3 to 5&quot;&gt;12&lt;/a&gt;&lt;/sup&gt; About 70
          minutes later Binance said its later investigation &amp;ldquo;has uncovered
          additional points of breach&amp;rdquo; and did not name them.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s13&quot; data-nb-locator=&quot;Post body, paragraph 1&quot;&gt;13&lt;/a&gt;&lt;/sup&gt; TRM&amp;rsquo;s
          assessment is that the attacker compromised Binance&amp;rsquo;s hot wallet
          signing infrastructure, and it says the early phishing hypothesis
          &amp;ldquo;covers Ethereum and leaves the other chains unexplained.&amp;rdquo;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;Evidence points to Binance&#x27;s signing infrastructure&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;table class=&quot;nb-table&quot;&gt;
          &lt;caption&gt;
            Who attributes the theft, in each holder&amp;rsquo;s words. These are
            assessments, not a court finding.
          &lt;/caption&gt;
          &lt;thead&gt;
            &lt;tr&gt;&lt;th&gt;Holder&lt;/th&gt;&lt;th class=&quot;txt&quot;&gt;Assessment&lt;/th&gt;&lt;th class=&quot;txt&quot;&gt;Stated confidence&lt;/th&gt;&lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;TRM Labs&lt;/span&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;TraderTraitor, North Korea&amp;rsquo;s elite hacking unit.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot; data-nb-locator=&quot;Key takeaways, attribution&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;&amp;ldquo;high confidence&amp;rdquo;&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;Binance&lt;/span&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;&amp;ldquo;Our investigation has not attributed responsibility to any individual.&amp;rdquo;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s12&quot;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;none given&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;Chainalysis&lt;/span&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;&amp;ldquo;likely done by DPRK group TraderTraitor due to links to previous hack.&amp;rdquo;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s14&quot; data-nb-locator=&quot;Post body&quot;&gt;14&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;&amp;ldquo;likely&amp;rdquo;&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;Elliptic&lt;/span&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;Linked the theft to TraderTraitor before the FBI spoke.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Key points&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;&amp;ldquo;likely&amp;rdquo;&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;FBI&lt;/span&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;North Korea &amp;ldquo;was responsible for the theft of more than $6 billion&amp;rdquo;; 628 addresses to block. Quoted by BleepingComputer; the FBI&amp;rsquo;s own page could not be opened.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s15&quot; data-nb-locator=&quot;FBI statement, paragraphs 1 to 4&quot;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;an attribution&lt;/td&gt;&lt;/tr&gt;
            &lt;tr&gt;&lt;td&gt;&lt;span class=&quot;nb-table-token&quot;&gt;North Korea&lt;/span&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;Has denied such thefts before and did not respond to Reuters here, per IBTimes.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s16&quot;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;&lt;td class=&quot;txt&quot;&gt;denial&lt;/td&gt;&lt;/tr&gt;
          &lt;/tbody&gt;
        &lt;/table&gt;
        &lt;p&gt;
          Whoever is named in the end, Elliptic counts about $3.25 billion that
          no issuer can freeze, at 1 November prices, across more than 800
          addresses. That is $1.42 billion in BTC, $1.32 billion in
          ETH and $502 million in XRP, Solana, TRX, NEAR and others.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot; data-nb-locator=&quot;Following the stolen funds, chart 3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://www.binance.com/en/support/announcement/detail/c5a8729a97ac486d963784d96c5642d7&quot;
              data-nb-locator=&quot;Body: estimated total impact, ~$3 billion frozen, laptop finding&quot;
              &gt;Binance &amp;middot; Security Incident Update&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://www.trmlabs.com/resources/blog/north-korea-steals-usd-6-36-billion-from-binance-in-the-largest-hack-in-history&quot;
              data-nb-locator=&quot;Key takeaways; How much was taken; Stablecoin freezes and conversion&quot;
              &gt;TRM Labs &amp;middot; North Korea steals $6.36 billion from Binance&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s3&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://www.elliptic.co/insights/binance-largest-hack-in-history/&quot;
              data-nb-locator=&quot;Key points; Following the stolen funds (frozen, 94% and $786 million sentences; charts 2 and 3)&quot;
              data-nb-note=&quot;Primary for Elliptic&#x27;s own tracing. Elliptic is a blockchain-analytics vendor whose product screens these funds.&quot;
              &gt;Elliptic &amp;middot; Binance: the largest hack in history&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s4&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://x.com/binance/status/2116121748555153621&quot;
              data-nb-locator=&quot;Post of 30 Oct 10:55 UTC: working with partners and law enforcement to recover the frozen assets&quot;
              &gt;Binance &amp;middot; X post on frozen assets&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s5&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;secondary&quot;
              href=&quot;https://coindesk.com/markets/2026/11/01/binance-opens-crypto-withdrawals-in-phases-starting-with-bitcoin-following-usd6-3-billion-hack&quot;
              data-nb-locator=&quot;1 Nov 2026 report; no frozen funds recovered or returned&quot;
              &gt;CoinDesk &amp;middot; Binance opens withdrawals in phases&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s6&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://eth.blockscout.com/address/0xdAC17F958D2ee523a2206206994597C13D831ec7?tab=contract&quot;
              data-nb-locator=&quot;Source tab: contracts BlackList and TetherToken&quot;
              &gt;Blockscout &amp;middot; Tether USDT contract&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s7&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://github.com/circlefin/stablecoin-evm/blob/master/contracts/v1/Blacklistable.sol&quot;
              data-nb-locator=&quot;blacklist(address) onlyBlacklister; modifier notBlacklisted&quot;
              &gt;Circle &amp;middot; stablecoin-evm, Blacklistable.sol&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s8&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;secondary&quot;
              href=&quot;https://www.americanbanker.com/news/6b-binance-heist-provokes-stablecoin-freeze-dilemma&quot;
              data-nb-locator=&quot;Circle spokesperson&#x27;s $1.1 billion figure; April 2026 Drift decision&quot;
              data-nb-note=&quot;Reports Circle&#x27;s statements; the $1.1 billion figure is unreconciled against on-chain counts.&quot;
              &gt;American Banker &amp;middot; $6B Binance heist provokes stablecoin freeze dilemma&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s9&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://www.ic3.gov/PSA/2025/PSA250226&quot;
              data-nb-locator=&quot;Public service announcement, 26 Feb 2025: approximately $1.5 billion&quot;
              &gt;FBI IC3 &amp;middot; $1.5 Billion Bybit Hack&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s10&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;secondary&quot;
              href=&quot;https://blockscholes.com/research/bybit-eth-hack&quot;
              data-nb-locator=&quot;Stolen-asset list, updated 22 Feb 2025&quot;
              &gt;Block Scholes &amp;middot; Bybit ETH hack&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s11&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;secondary&quot;
              href=&quot;https://decrypt.co/315593/bybit-ceo-two-thirds-of-funds-from-lazarus-group-hack-still-traceable&quot;
              data-nb-locator=&quot;Ben Zhou quote, 21 April 2025: 3.84% frozen&quot;
              data-nb-note=&quot;Reports Zhou&#x27;s post, which owns the figure. The 3% early-March count is from other coverage in the research record, not this page.&quot;
              &gt;Decrypt &amp;middot; Bybit CEO on traceable funds&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s12&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://x.com/_RichardTeng/status/2116072080525656150&quot;
              data-nb-locator=&quot;Post of 30 Oct 07:37 UTC, paragraphs 3 to 5&quot;
              &gt;Richard Teng &amp;middot; X post&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s13&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://x.com/binance/status/2116089661408108712&quot;
              data-nb-locator=&quot;Post of 30 Oct 08:47 UTC, paragraph 1&quot;
              &gt;Binance &amp;middot; X post, additional points of breach&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s14&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;primary&quot;
              href=&quot;https://x.com/jony_levin/status/2116020833227587637&quot;
              data-nb-locator=&quot;Post of 30 Oct 04:14 UTC&quot;
              data-nb-note=&quot;Primary for Chainalysis&#x27; stated assessment; the account owner is described as Chainalysis&#x27; CEO in coverage.&quot;
              &gt;Jonathan Levin &amp;middot; X post&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s15&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;secondary&quot;
              href=&quot;https://www.bleepingcomputer.com/news/security/fbi-links-63-billion-binance-crypto-heist-to-north-korean-hackers/&quot;
              data-nb-locator=&quot;FBI statement as quoted; address list&quot;
              data-nb-note=&quot;Secondary for the FBI. The FBI page returned a bot challenge and was not opened.&quot;
              &gt;BleepingComputer &amp;middot; FBI links Binance heist to North Korea&lt;/a
            &gt;
          &lt;/li&gt;
          &lt;li id=&quot;s16&quot;&gt;
            &lt;a
              data-nb-source
              data-nb-kind=&quot;secondary&quot;
              href=&quot;https://www.ibtimes.co.uk/fbi-binance-theft-tradertraitor-north-korea-1829324&quot;
              data-nb-locator=&quot;North Korean denials and non-response, relaying Reuters&quot;
              &gt;IBTimes &amp;middot; FBI and the Binance theft&lt;/a
            &gt;
          &lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="feature"/>
  </entry>
  <entry>
    <title>WSJ and NYT report the US may resume Iran strikes after the midterms</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-11-02.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-11-02</id>
    <updated>2026-11-02T06:49:14Z</updated>
    <summary>Israel’s Channel 12 says Netanyahu urged Trump to restart the war right after the election, and Rubio says Trump has made no decision.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Daily Brief&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;WSJ and NYT report the US may resume Iran strikes after the midterms&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;Israel’s Channel 12 says Netanyahu urged Trump to restart the war right after the election, and Rubio says Trump has made no decision.&lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;3 min read&lt;/span&gt;&lt;span&gt;2026-11-02&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section data-nb-section=&quot;items&quot; id=&quot;items&quot;&gt;
        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Word of the Day&lt;/span&gt;
          &lt;div class=&quot;rs-word-card&quot;&gt;
            &lt;div class=&quot;rs-word-card-head&quot;&gt;
              &lt;span class=&quot;rs-word-term&quot;&gt;nocebo&lt;/span&gt;
              &lt;span class=&quot;rs-word-meta&quot;&gt;
                &lt;span class=&quot;rs-word-pos&quot;&gt;noun&lt;/span&gt;
                &lt;span class=&quot;rs-word-pronunciation&quot;&gt;ˌnō-ˈsē-(ˌ)bō&lt;/span&gt;
              &lt;/span&gt;
            &lt;/div&gt;
            &lt;p class=&quot;rs-word-definition&quot;&gt;
              Merriam-Webster defines it as &amp;#8220;a harmless substance or treatment that when taken by or administered to a patient is associated with harmful side effects or worsening of symptoms due to negative expectations or the psychological condition of the patient.&amp;#8221;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
            &lt;/p&gt;
          &lt;/div&gt;
          &lt;p&gt;
            Walter P. Kennedy coined nocebo in a 1961 article, &amp;#8220;The nocebo reaction,&amp;#8221; in &lt;em&gt;Medical World&lt;/em&gt;. A 2023 &lt;em&gt;Frontiers in Psychology&lt;/em&gt; editorial quotes him: &amp;#8220;it is somewhat surprising that little attention has been drawn to the existence of the contrary effect&amp;#8221; to the placebo, &amp;#8220;which I may call the nocebo reaction.&amp;#8221;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; The word is a Latin joke on placebo: Merriam-Webster glosses Latin nocēbō as &amp;#8220;I will harm,&amp;#8221; against placebo&amp;#8217;s &amp;#8220;I shall please.&amp;#8221;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Kennedy meant a narrower thing, a reaction that comes from the patient and not the drug&amp;#8217;s pharmacology. Confusing the two, he warned, could lead doctors to discard useful drugs.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;Netanyahu reportedly pressed Trump to restart the Iran war after the election&lt;/h3&gt;
          &lt;p&gt;
            The Wall Street Journal and The New York Times report the US may resume military action against Iran after Tuesday&amp;#8217;s vote, CNBC said Sunday.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Israel&amp;#8217;s Channel 12, citing an Israeli and an American source, says Benjamin Netanyahu urged Trump on Saturday to resume the war right after the election, and Trump prefers to give Qatari-mediated talks more time. The White House and Netanyahu&amp;#8217;s office declined to comment.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Secretary of State Marco Rubio says Trump &amp;#8220;hasn&amp;#8217;t made a decision,&amp;#8221; and CNBC notes Washington has not said it plans to resume attacks.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;Learjet 60 crashes in a Florida neighborhood, killing all nine aboard&lt;/h3&gt;
          &lt;p&gt;
            A Learjet 60 flying from Austin toward the Bahamas crashed in a residential area of Greenacres, Florida, at 12:50 p.m. Sunday. Transportation Secretary Sean Duffy said all nine aboard died, PBS NewsHour reported.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; The same report cites air traffic control recordings and flight-tracking data showing the pilots reported turbulence and icing at 35,000 feet. The jet then dove at up to 30,000 feet per minute, beyond its design limits. The FAA is supporting the NTSB investigation, and the cause is undetermined.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;News&lt;/span&gt;
          &lt;h3&gt;Sen. Chris Murphy is hospitalized after a stroke and expects a full recovery, his office says&lt;/h3&gt;
          &lt;p&gt;
            Connecticut Democrat Chris Murphy, 53, &amp;#8220;started experiencing numbness in his arm while at his son&amp;#8217;s hockey game&amp;#8221; on Saturday, chief of staff Allison Herwitt said, the AP reported.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt; He was moved to Johns Hopkins, where his office says he is &amp;#8220;awake and alert,&amp;#8221; responding well to treatment and expected to recover fully. He is not on Tuesday&amp;#8217;s ballot.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Technology&lt;/span&gt;
          &lt;h3&gt;Microsoft offers every US school district its AI privacy terms, starting with no training on student data&lt;/h3&gt;
          &lt;p&gt;
            From 1 November, Microsoft says, every US school district can add the protections in its AI Safety &amp;amp; Privacy Standard to existing or new agreements without renegotiation.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt; Its fact sheet lists 10 contractually enforceable protections, the first barring training on student or educator data except for narrow safety and security uses. Districts choose whether to add them.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;

        &lt;div class=&quot;nb-brief-item&quot; data-nb-item&gt;
          &lt;span class=&quot;nb-brief-tag&quot;&gt;Technology&lt;/span&gt;
          &lt;h3&gt;Google runs Gemma 4 on a data-center-class TPU in orbit&lt;/h3&gt;
          &lt;p&gt;
            Google Research says its Project Suncatcher prototype, launched 1 October, returned &amp;#8220;the first-ever AI response from a data center class TPU in orbit&amp;#8221;: a Gemma 4 haiku about being in space, downlinked during a pass over Svalbard, Norway.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt; Its 30 October post says tests of thermal stress and radiation come next, then twin interconnected satellites in 2027.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;
          &lt;/p&gt;
        &lt;/div&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Main entry; Etymology; Word History&quot; href=&quot;https://www.merriam-webster.com/dictionary/nocebo&quot;&gt;Merriam-Webster · nocebo&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;Introduction, paragraph on the origin of the term; reference list&quot; href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC9846809/&quot;&gt;Frontiers in Psychology · Editorial: The nocebo effect (2023)&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s3&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;Paragraphs on Rubio and on the WSJ and NYT reports&quot; href=&quot;https://www.cnbc.com/2026/11/02/us-iran-war-trump-hormuz-rubio.html&quot;&gt;CNBC · US-Iran war, Rubio, 1 November&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s4&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;Single live-blog entry, 1 November, 8:40 pm&quot; href=&quot;https://www.timesofisrael.com/liveblog_entry/report-netanyahu-pressed-trump-to-resume-iran-war-after-us-midterms-president-undecided/&quot;&gt;The Times of Israel · Netanyahu pressed Trump to resume Iran war&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s5&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;First four paragraphs&quot; href=&quot;https://www.pbs.org/newshour/nation/all-9-people-aboard-a-jet-that-crashed-in-florida-have-died-transportation-secretary-says&quot;&gt;PBS NewsHour · All 9 aboard Florida jet died&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s6&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;secondary&quot; data-nb-locator=&quot;Opening paragraphs&quot; href=&quot;https://www.pbs.org/newshour/politics/connecticut-sen-chris-murphy-is-in-the-hospital-after-having-a-stroke-his-office-says&quot;&gt;PBS NewsHour (AP) · Sen. Chris Murphy hospitalized after stroke&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s7&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Microsoft&#x27;s Commitment, For Schools box; at-a-glance table of 10 protections&quot; href=&quot;https://cdn-dynmedia-1.microsoft.com/is/content/microsoftcorp/microsoft/msc/documents/presentations/CSR/AI-Safety-and-Privacy-Standard-Fact-Sheet.pdf&quot;&gt;Microsoft · AI Safety &amp;amp; Privacy Standard fact sheet&lt;/a&gt;&lt;/li&gt;
          &lt;li id=&quot;s8&quot;&gt;&lt;a data-nb-source data-nb-kind=&quot;primary&quot; data-nb-locator=&quot;Opening and next-steps paragraphs&quot; href=&quot;https://blog.google/innovation-and-ai/models-and-research/google-research/project-suncatcher-satellite-response/&quot;&gt;Google Research · Project Suncatcher prototype response&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>Jepsen finds ParticleDB’s default mode losing committed writes among 96 issues</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/jepsen-particledb.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/jepsen-particledb</id>
    <updated>2026-11-01T06:46:35Z</updated>
    <summary>In versions 1.1.4 through 1.1.17 of ParticleDB, advertised as “Full ACID. 159K TPS.”, WHERE 4 = 5 returned the row with primary key 5.</summary>
    <content type="html">
    &lt;article class=&quot;nb-reading&quot;&gt;
      &lt;header&gt;
        &lt;div class=&quot;nb-eyebrow&quot;&gt;Feature&lt;/div&gt;
        &lt;h1 class=&quot;nb-title&quot;&gt;Jepsen finds ParticleDB’s default mode losing committed writes among 96 issues&lt;/h1&gt;
        &lt;p class=&quot;nb-dekline&quot;&gt;
          In versions 1.1.4 through 1.1.17 of ParticleDB, advertised as “Full ACID. 159K TPS.”, WHERE 4 = 5 returned the row with primary key 5.
        &lt;/p&gt;
        &lt;div class=&quot;nb-byline&quot;&gt;
          &lt;span&gt;5 min read&lt;/span&gt;&lt;span&gt;2026-11-01&lt;/span&gt;
        &lt;/div&gt;
      &lt;/header&gt;

      &lt;section data-nb-section=&quot;orientation&quot; id=&quot;orientation&quot;&gt;
        &lt;h2&gt;Guarantees tested one node at a time&lt;/h2&gt;
        &lt;p&gt;
          Orkes advertised ParticleDB, a Postgres-compatible database, as “Full ACID. 159K TPS.” and as “formally proven” with TLA+, wording that Jepsen’s report quotes from the home page.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§1.1 Safety&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          On 2026-10-31 Jepsen reported 96 issues from tests of versions 1.1.4 through 1.1.18.11.rc-22 and wrote that the Full ACID claim was “somewhat premature.” The default transaction mode, &lt;code&gt;occ&lt;/code&gt;, lost committed writes in normal operation. The TLA+ claim could not be checked, because no specification was available.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Introduction; §1.1 Safety; §4.4 Documentation&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          Orkes, the vendor, funded the analysis, which Jepsen says it conducted under its ethics policy. Every test ran on a single node, because the builds Orkes supplied did not support replication.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Introduction; §4.1 Impact&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;four-of-six&quot; id=&quot;four-of-six&quot;&gt;
        &lt;h2&gt;Four of six claims met a measured failure&lt;/h2&gt;
        &lt;p&gt;
          Each row is one advertised guarantee, in the words the report prints, and each cell to its right is what Jepsen recorded against it. Orkes has since rewritten the home page and documentation pages the report quotes, so the report is now the record of that wording.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§1.1 Safety&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;table class=&quot;nb-table&quot;&gt;
          &lt;caption&gt;
            Advertised wording against Jepsen’s result, with the anomaly defined where it first appears. The last two rows quote, in part or in full, an operator guide Orkes did not publish. Report sections, by row: 3.8.7, 3.8.8 and 3.8.14, 1.1, 3.8.16, 1.1, 3.2.3.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§§1.1, 3.2.3, 3.8.7, 3.8.8, 3.8.14, 3.8.16&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          &lt;/caption&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th class=&quot;txt&quot;&gt;Advertised&lt;/th&gt;
              &lt;th class=&quot;txt&quot;&gt;Jepsen result&lt;/th&gt;
              &lt;th class=&quot;txt&quot;&gt;Build and mode&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;“Full ACID. 159K TPS.”&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;Committed writes lost; aborted reads (G1a), where a committed transaction reads a write from an aborted one;&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; Lost Update, where a transaction overwrites a concurrent committed write it never observed.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;1.1.4 through 1.1.18.9, every mode, no faults&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;“snapshot isolation”&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;G-single, where a transaction observes one effect of another but misses a second effect of it (#73).&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; Read skew (A5A), where it both observes and fails to observe the other’s effects (#106).&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;G-single in rc-1 through rc-22; A5A with &lt;code&gt;table-2pl&lt;/code&gt; in rc-18&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;“formally proven” with TLA+&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;Could not be checked. No specification was available.&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;None tested&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;&lt;code&gt;occ&lt;/code&gt; is “Jepsen-safe”&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;Acknowledged writes discarded on a healthy node: 31 lost among about 20,000 keys, every few minutes (#110).&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;rc-18 through rc-22, both interfaces&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;&lt;code&gt;groupsync&lt;/code&gt; gives the “same durability as sync”&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;A conflict between documents, not a measured failure. The public docs said &lt;code&gt;sync&lt;/code&gt; had “stronger durability,” and Jepsen reports no comparison. Orkes’s current docs say the two give the same guarantee.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s6&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;Documentation&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
              &lt;td class=&quot;txt&quot;&gt;Prepared statements “all work as expected”&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;Any prepared statement through the Postgres JDBC driver raised an exception, leaving the database “essentially unusable” (#2).&lt;/td&gt;
              &lt;td class=&quot;txt&quot;&gt;1.1.4 through 1.1.18.9; appeared fixed by rc-1&lt;/td&gt;
            &lt;/tr&gt;
          &lt;/tbody&gt;
        &lt;/table&gt;
        &lt;p&gt;
          “Jepsen-safe” was Orkes’s own label. Jepsen printed it and wrote that, since it evaluates safety against documentation and marketing claims, it was not clear how to interpret the term.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§1.1 Safety&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;where-4-equals-5&quot; id=&quot;where-4-equals-5&quot;&gt;
        &lt;h2&gt;&lt;code&gt;WHERE 4 = 5&lt;/code&gt; returned the row with primary key 5&lt;/h2&gt;
        &lt;p&gt;
          Jepsen’s example is a table t with columns a, the primary key, and b, holding rows 4 | 5 and 5 | 6. In versions 1.1.4 through 1.1.17, ParticleDB “aggressively interpreted WHERE something = x as a primary-key lookup of x, regardless of the value of something.”&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§3.3.3 WHERE 4 = 5 (#18)&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          The query in the diagram therefore asked for key 5 and never compared the 4.
        &lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot; style=&quot;overflow-x: auto&quot;&gt;
          &lt;svg
            viewBox=&quot;0 0 720 290&quot;
            role=&quot;img&quot;
            aria-label=&quot;Two lanes for the query SELECT * FROM t WHERE 4 = 5. Expected: 4 = 5 is false, so no rows return. ParticleDB 1.1.4 through 1.1.17: the predicate is read as a primary-key lookup of 5, so the row 5 | 6 returns.&quot;
            style=&quot;width: 100%; min-width: 34rem; height: auto&quot;
          &gt;
            &lt;defs&gt;
              &lt;marker id=&quot;ahB&quot; markerWidth=&quot;8&quot; markerHeight=&quot;8&quot; refX=&quot;7&quot; refY=&quot;4&quot; orient=&quot;auto&quot;&gt;
                &lt;path d=&quot;M0,0 L8,4 L0,8 z&quot; style=&quot;fill: var(--ink-soft)&quot; /&gt;
              &lt;/marker&gt;
            &lt;/defs&gt;
            &lt;g style=&quot;font-family: var(--sans); font-size: 15px; fill: var(--ink)&quot;&gt;
              &lt;rect x=&quot;180&quot; y=&quot;12&quot; width=&quot;360&quot; height=&quot;42&quot; rx=&quot;4&quot; style=&quot;fill: var(--panel); stroke: var(--line)&quot; /&gt;
              &lt;text x=&quot;360&quot; y=&quot;39&quot; text-anchor=&quot;middle&quot; style=&quot;font-family: var(--mono); font-size: 15px&quot;&gt;SELECT * FROM t WHERE 4 = 5;&lt;/text&gt;
              &lt;path d=&quot;M270 54 V76 H180 V98&quot; marker-end=&quot;url(#ahB)&quot; style=&quot;fill: none; stroke: var(--ink-soft); stroke-width: 1.5&quot; /&gt;
              &lt;path d=&quot;M450 54 V76 H540 V98&quot; marker-end=&quot;url(#ahB)&quot; style=&quot;fill: none; stroke: var(--ink-soft); stroke-width: 1.5&quot; /&gt;

              &lt;rect x=&quot;20&quot; y=&quot;100&quot; width=&quot;320&quot; height=&quot;76&quot; rx=&quot;4&quot; style=&quot;fill: var(--panel); stroke: var(--line)&quot; /&gt;
              &lt;text x=&quot;36&quot; y=&quot;122&quot; style=&quot;font-size: 12px; font-weight: 600; letter-spacing: 0.06em; fill: var(--ink-soft)&quot;&gt;EXPECTED&lt;/text&gt;
              &lt;text x=&quot;36&quot; y=&quot;146&quot;&gt;4 = 5 is false for every row,&lt;/text&gt;
              &lt;text x=&quot;36&quot; y=&quot;166&quot;&gt;so the filter keeps nothing&lt;/text&gt;

              &lt;rect x=&quot;380&quot; y=&quot;100&quot; width=&quot;320&quot; height=&quot;76&quot; rx=&quot;4&quot; style=&quot;fill: var(--panel); stroke: var(--chart-4); stroke-width: 1.5&quot; /&gt;
              &lt;text x=&quot;396&quot; y=&quot;122&quot; style=&quot;font-size: 12px; font-weight: 600; letter-spacing: 0.06em; fill: var(--ink-soft)&quot;&gt;PARTICLEDB 1.1.4 THROUGH 1.1.17&lt;/text&gt;
              &lt;text x=&quot;396&quot; y=&quot;146&quot;&gt;WHERE something = x is read as&lt;/text&gt;
              &lt;text x=&quot;396&quot; y=&quot;166&quot;&gt;a primary-key lookup of x = 5&lt;/text&gt;

              &lt;path d=&quot;M180 176 V212&quot; marker-end=&quot;url(#ahB)&quot; style=&quot;fill: none; stroke: var(--ink-soft); stroke-width: 1.5&quot; /&gt;
              &lt;text x=&quot;192&quot; y=&quot;199&quot; style=&quot;font-size: 12px; fill: var(--ink-soft)&quot;&gt;constant filter&lt;/text&gt;
              &lt;rect x=&quot;20&quot; y=&quot;214&quot; width=&quot;320&quot; height=&quot;58&quot; rx=&quot;4&quot; style=&quot;fill: var(--panel); stroke: var(--line)&quot; /&gt;
              &lt;text x=&quot;36&quot; y=&quot;236&quot; style=&quot;font-size: 12px; font-weight: 600; letter-spacing: 0.06em; fill: var(--ink-soft)&quot;&gt;RESULT&lt;/text&gt;
              &lt;text x=&quot;36&quot; y=&quot;261&quot; style=&quot;font-family: var(--mono)&quot;&gt;(0 rows)&lt;/text&gt;

              &lt;path d=&quot;M540 176 V204&quot; marker-end=&quot;url(#ahB)&quot; style=&quot;fill: none; stroke: var(--ink-soft); stroke-width: 1.5&quot; /&gt;
              &lt;text x=&quot;552&quot; y=&quot;196&quot; style=&quot;font-size: 12px; fill: var(--ink-soft)&quot;&gt;lookup a = 5&lt;/text&gt;
              &lt;rect x=&quot;380&quot; y=&quot;206&quot; width=&quot;320&quot; height=&quot;22&quot; style=&quot;fill: var(--wash); stroke: var(--line)&quot; /&gt;
              &lt;text x=&quot;396&quot; y=&quot;222&quot; style=&quot;font-size: 12px; font-weight: 600; fill: var(--ink-soft)&quot;&gt;a (primary key)&lt;/text&gt;
              &lt;text x=&quot;556&quot; y=&quot;222&quot; style=&quot;font-size: 12px; font-weight: 600; fill: var(--ink-soft)&quot;&gt;b&lt;/text&gt;
              &lt;rect x=&quot;380&quot; y=&quot;228&quot; width=&quot;320&quot; height=&quot;22&quot; style=&quot;fill: var(--panel); stroke: var(--line)&quot; /&gt;
              &lt;text x=&quot;396&quot; y=&quot;244&quot; style=&quot;font-family: var(--mono); font-size: 14px&quot;&gt;4&lt;/text&gt;
              &lt;text x=&quot;556&quot; y=&quot;244&quot; style=&quot;font-family: var(--mono); font-size: 14px&quot;&gt;5&lt;/text&gt;
              &lt;rect x=&quot;380&quot; y=&quot;250&quot; width=&quot;320&quot; height=&quot;22&quot; style=&quot;fill: var(--chart-4); fill-opacity: 0.2; stroke: var(--chart-4); stroke-width: 1.5&quot; /&gt;
              &lt;text x=&quot;396&quot; y=&quot;266&quot; style=&quot;font-family: var(--mono); font-size: 14px&quot;&gt;5&lt;/text&gt;
              &lt;text x=&quot;556&quot; y=&quot;266&quot; style=&quot;font-family: var(--mono); font-size: 14px&quot;&gt;6&lt;/text&gt;
              &lt;text x=&quot;688&quot; y=&quot;266&quot; text-anchor=&quot;end&quot; style=&quot;font-size: 12px; font-weight: 600&quot;&gt;returned&lt;/text&gt;
              &lt;line x1=&quot;540&quot; y1=&quot;206&quot; x2=&quot;540&quot; y2=&quot;272&quot; style=&quot;stroke: var(--line)&quot; /&gt;
            &lt;/g&gt;
          &lt;/svg&gt;
          &lt;figcaption&gt;
            Fig. 1 · Jepsen’s example for issue #18: table t holds rows (4, 5) and (5, 6). The right lane follows the report’s description of the rewrite and is drawn for this article, not copied from ParticleDB’s planner.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§3.3.3 WHERE 4 = 5 (#18)&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          The example is a single statement with no concurrent transaction. Version 1.1.18.4 stopped treating every equality as a key lookup. A related fault appeared only inside a transaction: in 1.1.4 through 1.1.18.8, &lt;code&gt;SELECT * FROM t WHERE TRUE&lt;/code&gt; returned no rows (#35), and it seemed improved in 1.1.18.9.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§3.3.4 SELECT in a Transaction Returns Nonsense (#35)&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section data-nb-section=&quot;ten-issues-survived&quot; id=&quot;ten-issues-survived&quot;&gt;
        &lt;h2&gt;Ten issues survived to rc-22&lt;/h2&gt;
        &lt;p&gt;
          Jepsen wrote that by 1.1.18.11.rc-22 all but ten of the 96 issues appeared resolved.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;Introduction&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          The chart places seven findings on the builds Jepsen tested, four of them among the ten. A bar spans the builds where the behavior appeared, and a bar that reaches rc-22 was still open when testing ended.
        &lt;/p&gt;
        &lt;figure class=&quot;nb-figure&quot; style=&quot;overflow-x: auto&quot;&gt;
          &lt;svg
            viewBox=&quot;0 0 720 350&quot;
            role=&quot;img&quot;
            aria-label=&quot;Timeline of seven ParticleDB findings across eight builds from 1.1.4 to 1.1.19 rc.13. Issues 18, 35 and 2 were observed in early builds and fixed in later tested builds. Issues 73, 110, 109 and 107 were still observed at rc-22, and Orkes says rc.13 fixes them, which Jepsen did not test.&quot;
            style=&quot;width: 100%; min-width: 34rem; height: auto&quot;
          &gt;
            &lt;g style=&quot;font-family: var(--sans); font-size: 13px; fill: var(--ink)&quot;&gt;
              &lt;g style=&quot;stroke: var(--line)&quot;&gt;
                &lt;line x1=&quot;260&quot; y1=&quot;48&quot; x2=&quot;260&quot; y2=&quot;312&quot; /&gt;
                &lt;line x1=&quot;320&quot; y1=&quot;48&quot; x2=&quot;320&quot; y2=&quot;312&quot; /&gt;
                &lt;line x1=&quot;380&quot; y1=&quot;48&quot; x2=&quot;380&quot; y2=&quot;312&quot; /&gt;
                &lt;line x1=&quot;440&quot; y1=&quot;48&quot; x2=&quot;440&quot; y2=&quot;312&quot; /&gt;
                &lt;line x1=&quot;500&quot; y1=&quot;48&quot; x2=&quot;500&quot; y2=&quot;312&quot; /&gt;
                &lt;line x1=&quot;560&quot; y1=&quot;48&quot; x2=&quot;560&quot; y2=&quot;312&quot; /&gt;
                &lt;line x1=&quot;620&quot; y1=&quot;48&quot; x2=&quot;620&quot; y2=&quot;312&quot; /&gt;
                &lt;line x1=&quot;680&quot; y1=&quot;48&quot; x2=&quot;680&quot; y2=&quot;312&quot; /&gt;
              &lt;/g&gt;
              &lt;text x=&quot;0&quot; y=&quot;38&quot; style=&quot;font-size: 12px; font-weight: 600; fill: var(--ink-soft)&quot;&gt;Finding&lt;/text&gt;
              &lt;g style=&quot;font-size: 12px; fill: var(--ink-soft)&quot;&gt;
                &lt;text x=&quot;560&quot; y=&quot;14&quot; text-anchor=&quot;middle&quot;&gt;1.1.18.11&lt;/text&gt;
                &lt;text x=&quot;680&quot; y=&quot;14&quot; text-anchor=&quot;middle&quot;&gt;1.1.19&lt;/text&gt;
              &lt;/g&gt;
              &lt;path d=&quot;M492 20 H628&quot; style=&quot;fill: none; stroke: var(--ink-soft)&quot; /&gt;
              &lt;g style=&quot;font-size: 12px&quot; text-anchor=&quot;middle&quot;&gt;
                &lt;text x=&quot;260&quot; y=&quot;38&quot;&gt;1.1.4&lt;/text&gt;
                &lt;text x=&quot;320&quot; y=&quot;38&quot;&gt;1.1.17&lt;/text&gt;
                &lt;text x=&quot;380&quot; y=&quot;38&quot;&gt;1.1.18.8&lt;/text&gt;
                &lt;text x=&quot;440&quot; y=&quot;38&quot;&gt;1.1.18.9&lt;/text&gt;
                &lt;text x=&quot;500&quot; y=&quot;38&quot;&gt;rc-1&lt;/text&gt;
                &lt;text x=&quot;560&quot; y=&quot;38&quot;&gt;rc-18&lt;/text&gt;
                &lt;text x=&quot;620&quot; y=&quot;38&quot;&gt;rc-22&lt;/text&gt;
                &lt;text x=&quot;680&quot; y=&quot;38&quot;&gt;rc.13&lt;/text&gt;
              &lt;/g&gt;

              &lt;text x=&quot;0&quot; y=&quot;81&quot;&gt;#18 WHERE 4 = 5&lt;/text&gt;
              &lt;rect x=&quot;246&quot; y=&quot;66&quot; width=&quot;88&quot; height=&quot;20&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.35; stroke: var(--chart-2)&quot; /&gt;
              &lt;text x=&quot;344&quot; y=&quot;81&quot; style=&quot;font-size: 11px; fill: var(--ink-soft); paint-order: stroke; stroke: var(--wash); stroke-width: 4px&quot;&gt;fixed by 1.1.18.4&lt;/text&gt;

              &lt;text x=&quot;0&quot; y=&quot;117&quot;&gt;#35 WHERE TRUE in txn&lt;/text&gt;
              &lt;rect x=&quot;246&quot; y=&quot;102&quot; width=&quot;148&quot; height=&quot;20&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.35; stroke: var(--chart-2)&quot; /&gt;
              &lt;text x=&quot;404&quot; y=&quot;117&quot; style=&quot;font-size: 11px; fill: var(--ink-soft); paint-order: stroke; stroke: var(--wash); stroke-width: 4px&quot;&gt;improved in 1.1.18.9&lt;/text&gt;

              &lt;text x=&quot;0&quot; y=&quot;153&quot;&gt;#2 prepared statements&lt;/text&gt;
              &lt;rect x=&quot;246&quot; y=&quot;138&quot; width=&quot;208&quot; height=&quot;20&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.35; stroke: var(--chart-2)&quot; /&gt;
              &lt;text x=&quot;464&quot; y=&quot;153&quot; style=&quot;font-size: 11px; fill: var(--ink-soft); paint-order: stroke; stroke: var(--wash); stroke-width: 4px&quot;&gt;appeared fixed by rc-1&lt;/text&gt;

              &lt;text x=&quot;0&quot; y=&quot;189&quot;&gt;#73 G-single&lt;/text&gt;
              &lt;rect x=&quot;486&quot; y=&quot;174&quot; width=&quot;148&quot; height=&quot;20&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-4); fill-opacity: 0.35; stroke: var(--chart-4)&quot; /&gt;
              &lt;text x=&quot;0&quot; y=&quot;225&quot;&gt;#110 lost committed writes&lt;/text&gt;
              &lt;rect x=&quot;546&quot; y=&quot;210&quot; width=&quot;88&quot; height=&quot;20&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-4); fill-opacity: 0.35; stroke: var(--chart-4)&quot; /&gt;
              &lt;text x=&quot;0&quot; y=&quot;261&quot;&gt;#109 stale read&lt;/text&gt;
              &lt;rect x=&quot;546&quot; y=&quot;246&quot; width=&quot;88&quot; height=&quot;20&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-4); fill-opacity: 0.35; stroke: var(--chart-4)&quot; /&gt;
              &lt;text x=&quot;0&quot; y=&quot;297&quot;&gt;#107 Lost Update after kills&lt;/text&gt;
              &lt;rect x=&quot;546&quot; y=&quot;282&quot; width=&quot;88&quot; height=&quot;20&quot; rx=&quot;3&quot; style=&quot;fill: var(--chart-4); fill-opacity: 0.35; stroke: var(--chart-4)&quot; /&gt;

              &lt;g style=&quot;fill: none; stroke: var(--chart-4); stroke-dasharray: 4 3&quot;&gt;
                &lt;path d=&quot;M634 184 H672&quot; /&gt;
                &lt;path d=&quot;M634 220 H672&quot; /&gt;
                &lt;path d=&quot;M634 256 H672&quot; /&gt;
                &lt;path d=&quot;M634 292 H672&quot; /&gt;
                &lt;circle cx=&quot;680&quot; cy=&quot;184&quot; r=&quot;7&quot; /&gt;
                &lt;circle cx=&quot;680&quot; cy=&quot;220&quot; r=&quot;7&quot; /&gt;
                &lt;circle cx=&quot;680&quot; cy=&quot;256&quot; r=&quot;7&quot; /&gt;
                &lt;circle cx=&quot;680&quot; cy=&quot;292&quot; r=&quot;7&quot; /&gt;
              &lt;/g&gt;

              &lt;rect x=&quot;0&quot; y=&quot;328&quot; width=&quot;22&quot; height=&quot;12&quot; rx=&quot;2&quot; style=&quot;fill: var(--chart-2); fill-opacity: 0.35; stroke: var(--chart-2)&quot; /&gt;
              &lt;text x=&quot;30&quot; y=&quot;339&quot; style=&quot;font-size: 12px&quot;&gt;Resolved in a later tested build&lt;/text&gt;
              &lt;rect x=&quot;250&quot; y=&quot;328&quot; width=&quot;22&quot; height=&quot;12&quot; rx=&quot;2&quot; style=&quot;fill: var(--chart-4); fill-opacity: 0.35; stroke: var(--chart-4)&quot; /&gt;
              &lt;text x=&quot;280&quot; y=&quot;339&quot; style=&quot;font-size: 12px&quot;&gt;Open at rc-22&lt;/text&gt;
              &lt;path d=&quot;M392 334 H414&quot; style=&quot;fill: none; stroke: var(--chart-4); stroke-dasharray: 4 3&quot; /&gt;
              &lt;circle cx=&quot;424&quot; cy=&quot;334&quot; r=&quot;6&quot; style=&quot;fill: none; stroke: var(--chart-4); stroke-dasharray: 4 3&quot; /&gt;
              &lt;text x=&quot;438&quot; y=&quot;339&quot; style=&quot;font-size: 12px&quot;&gt;Orkes says fixed in rc.13, untested&lt;/text&gt;
            &lt;/g&gt;
          &lt;/svg&gt;
          &lt;figcaption&gt;
            Fig. 2 · Builds are ordered, not to scale. Issue #35 appeared inside a transaction. Issues #107 and #109 were reproduced under &lt;code&gt;strict-serializable&lt;/code&gt; at rc-18, a mode the report says may have been renamed &lt;code&gt;serializable&lt;/code&gt; in rc-22, where its Discussion says both still occurred.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§§3.2.3, 3.3.3, 3.3.4, 3.8.8, 3.8.15, 3.8.16, 3.9.3; §4 Discussion&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          &lt;/figcaption&gt;
        &lt;/figure&gt;
        &lt;p&gt;
          Stale read, the behavior behind #109, is a read that fails to observe an earlier completed write, which strict serializability forbids.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s7&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;
          Jepsen saw it roughly every 300,000 transactions at rc-18. Process kills produced Lost Update under the same mode (#107).&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§3.8.15; §3.9.3&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
        &lt;/p&gt;
        &lt;p&gt;
          Jepsen has not evaluated any build after rc-22. It recommended that users halt further deployment of ParticleDB and migrate to other databases as soon as possible. Orkes told Jepsen the issues likely came from an extensive refactor in spring 2026 and that customers who stayed on an earlier version were likely unaffected.&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s1&quot; data-nb-locator=&quot;§4.1 Impact&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
          Orkes’s own post says: “As of ParticleDB 1.1.19, we report that all identified issues have been addressed.”&lt;sup class=&quot;nb-cite&quot;&gt;&lt;a href=&quot;#s8&quot; data-nb-locator=&quot;What we learned from Jepsen&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;
          Jepsen’s report names the build as 1.1.19-rc.13.
        &lt;/p&gt;
      &lt;/section&gt;

      &lt;section class=&quot;nb-sources&quot; data-nb-section=&quot;sources&quot; id=&quot;sources&quot;&gt;
        &lt;h2&gt;Sources&lt;/h2&gt;
        &lt;ol&gt;
          &lt;li id=&quot;s1&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://jepsen.io/analyses/particledb-1.1.4&quot;&gt;Jepsen · ParticleDB 1.1.4 (Kyle Kingsbury, 2026-10-31)&lt;/a&gt;
          &lt;/li&gt;
          &lt;li id=&quot;s2&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://jepsen.io/consistency/phenomena/g1a&quot;&gt;Jepsen · G1a (Aborted Read)&lt;/a&gt;
          &lt;/li&gt;
          &lt;li id=&quot;s3&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://jepsen.io/consistency/phenomena/p4&quot;&gt;Jepsen · P4 (Lost Update)&lt;/a&gt;
          &lt;/li&gt;
          &lt;li id=&quot;s4&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://jepsen.io/consistency/phenomena/g-single&quot;&gt;Jepsen · G-single&lt;/a&gt;
          &lt;/li&gt;
          &lt;li id=&quot;s5&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://jepsen.io/consistency/phenomena/a5a&quot;&gt;Jepsen · A5A (Read Skew)&lt;/a&gt;
          &lt;/li&gt;
          &lt;li id=&quot;s6&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://particledb.ai/operations/modes/#durability---durability&quot;&gt;ParticleDB · operations modes page, durability section&lt;/a&gt;
          &lt;/li&gt;
          &lt;li id=&quot;s7&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;secondary&quot; href=&quot;https://jepsen.io/consistency/phenomena/stale-read&quot;&gt;Jepsen · Stale Read&lt;/a&gt;
          &lt;/li&gt;
          &lt;li id=&quot;s8&quot;&gt;
            &lt;a data-nb-source data-nb-kind=&quot;primary&quot; href=&quot;https://orkes.io/blog/particledb-database-built-for-ai-agents&quot;&gt;Orkes · blog post on ParticleDB and the Jepsen findings, “What we learned from Jepsen”&lt;/a&gt;
          &lt;/li&gt;
        &lt;/ol&gt;
      &lt;/section&gt;
    &lt;/article&gt;
  </content>
    <category term="feature"/>
  </entry>
  <entry>
    <title>Two improvements find the best policy</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/reinforcement-learning/finding-optimal-policies.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/reinforcement-learning/finding-optimal-policies</id>
    <updated>2026-11-01T07:02:53Z</updated>
    <summary>On lesson 1&#x27;s slippery grid, two rounds of evaluate-and-improve lift cell 13 from −2.01 to −0.71, while the top half, already optimal, does not move.</summary>
    <category term="reinforcement-learning"/>
  </entry>
  <entry>
    <title>Justice Department says it now seeks only to segregate Alaska ballots</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-11-01.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-11-01</id>
    <updated>2026-11-01T06:47:05Z</updated>
    <summary>Its 30 October filing in federal court cites a second candidate named Dan Sullivan, days before Election Day.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>The value of a state is an average you can solve for</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/reinforcement-learning/environments-and-the-rl-problem.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/reinforcement-learning/environments-and-the-rl-problem</id>
    <updated>2026-10-31T11:29:11-04:00</updated>
    <summary>On a slippery 4×4 grid, 20,000 episodes and one linear solve put cell 13 at about −2, and the discount turns out to be needed only by a policy that never ends.</summary>
    <category term="reinforcement-learning"/>
  </entry>
  <entry>
    <title>Swapping the model moves AstaBench’s overall score twice as far on average as swapping the loop</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/agent-eval-cost-frontier.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/agent-eval-cost-frontier</id>
    <updated>2026-10-31T11:29:06-04:00</updated>
    <summary>On Ai2’s science-agent benchmark, a specialized agent takes most of its lead from one category, where its sub-agent Asta Panda adds 25.3 points to the same model at 15.9 times the reported cost.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>Judge bars DOJ from threatening California election officials days before the vote</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-10-31.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-10-31</id>
    <updated>2026-10-31T06:50:09Z</updated>
    <summary>The Ninth Circuit also refused 2-1 to set aside the ballots of more than 20,000 Californians the Justice Department calls noncitizens.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>A nowcasting RL task built in verifiers 0.4.0 has to close four routes to its own answer</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/expert-tools/verifiers-rl-environments.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/expert-tools/verifiers-rl-environments</id>
    <updated>2026-10-14T23:23:25Z</updated>
    <summary>Written against Prime Intellect&#x27;s TaskData, Task, Taskset and Toolset classes and built on real ALFRED vintages, a payrolls taskset let a command in the agent&#x27;s box on the subprocess runtime read January 2024&#x27;s hidden answer of 353,000 jobs.</summary>
    <category term="expert-tools"/>
  </entry>
  <entry>
    <title>Third Circuit rules against ROSS for copying headnotes it had no need to copy</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/thomson-reuters-ross-appeal.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/thomson-reuters-ross-appeal</id>
    <updated>2026-10-04T06:54:27Z</updated>
    <summary>The Third Circuit’s Sept. 29 opinion turns on the free judicial opinions ROSS could have used instead, and addresses generative AI only in one footnote.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>OpenCode 2 skips any plugin whose default export lacks an id and a setup or effect function</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/opencode-v2-plugin-api.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/opencode-v2-plugin-api</id>
    <updated>2026-10-04T06:54:29Z</updated>
    <summary>OpenCode 2.0.22 decodes a plugin&#x27;s default export against { id, setup } or { id, effect }, so a v1 export with only server() fails the check and is skipped.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>Tennessee fails to execute Christa Pike after two doses of pentobarbital</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-10-04.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-10-04</id>
    <updated>2026-10-04T06:53:30Z</updated>
    <summary>Gov. Bill Lee called off Tennessee&#x27;s remaining 2026 execution and ordered a third-party review of what happened.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>Python 3.15 adds a lazy keyword that binds a proxy instead of running an import</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/python-lazy-imports-pep-810.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/python-lazy-imports-pep-810</id>
    <updated>2026-10-03T07:06:19Z</updated>
    <summary>First use of the name reifies the proxy into the real module, moving an import&#x27;s errors and side effects out of startup and into the running program.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>Google&#x27;s economy ATLAS measures how much people talk to Gemini about work</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/ai-economy-atlas.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/ai-economy-atlas</id>
    <updated>2026-10-03T07:16:05Z</updated>
    <summary>Its most-quoted figure, 30% of U.S. work-related AI use among computer and mathematical workers, is a share of Gemini request volume the released dataset reproduces only as 20.06%.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>Seattle&#x27;s U.S. attorney is ordered back to a job he held for 54 minutes</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-10-03.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-10-03</id>
    <updated>2026-10-03T07:15:41Z</updated>
    <summary>A federal judge granted Roger Rogoff a preliminary injunction on October 1 restoring him pending his suit against the White House, which has appealed to the Ninth Circuit.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>Federal Medicaid matching for non-pregnant adult refugees and asylees ended on 1 October</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/medicaid-lawful-immigrant-funding.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/medicaid-lawful-immigrant-funding</id>
    <updated>2026-10-02T07:29:41Z</updated>
    <summary>Each state now decides whether to pay for them itself, and North Carolina, New Mexico and California gave three different answers.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>dbt v2 checks column names before the warehouse, in strict mode and only in the proprietary build</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/dbt-v2-rust-engine.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/dbt-v2-rust-engine</id>
    <updated>2026-10-02T07:25:25Z</updated>
    <summary>On a two-model DuckDB project, dbt 2.0.6 flagged a misspelled column at models/b.sql:1:12 under --static-analysis strict, and dbt OSS 2.0.5 said it does not include the check.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>Supreme Court takes up detention of immigrants without bond hearings</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-10-02.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-10-02</id>
    <updated>2026-10-02T07:29:52Z</updated>
    <summary>The government asked the Court to take a different case on the same question, and the Court granted this one without stating reasons.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>OpenShell puts a supervisor between agents and the network</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/nvidia-openshell-runtime-controls.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/nvidia-openshell-runtime-controls</id>
    <updated>2026-10-01T08:36:59Z</updated>
    <summary>The v0.1.0 runtime limits local and outbound authority around an existing agent, while leaving policy quality and model behavior outside its proof.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>Micron earns more from each dollar of memory sales</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/micron-fy2026-memory-scarcity.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/micron-fy2026-memory-scarcity</id>
    <updated>2026-10-01T11:31:10Z</updated>
    <summary>Higher prices produce an 86.8% gross margin whose durability depends on undisclosed contract prices and future manufacturing costs.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>Six developments for Thursday, October 1</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-10-01.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-10-01</id>
    <updated>2026-10-01T08:32:11Z</updated>
    <summary>BEA lifts second-quarter growth to 2.2%; a trade court hears a tariff challenge, while Qt and OpenStack publish new releases.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>Optical images show glacier motion; radar finds no progressive signal</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/nepal-geohazard-cascade.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/nepal-geohazard-cascade</id>
    <updated>2026-09-30T19:42:55Z</updated>
    <summary>The optical and radar analyses measure different signals, and neither establishes whether a live alert could have reached people before the flood.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>GitHub&#x27;s fuzzing agent uses coverage gaps to revise its harnesses</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/github-taskflow-fuzzing.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/github-taskflow-fuzzing</id>
    <updated>2026-09-30T19:43:00Z</updated>
    <summary>GitHub reported 24 findings from separate Android audit taskflows on September 28, but left independent confirmation unclear.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>Government weighs changes to Big Bend park work</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/big-bend-border-pause.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/big-bend-border-pause</id>
    <updated>2026-10-01T08:34:55Z</updated>
    <summary>Sept. 30 reports say the government may narrow work inside Big Bend National Park while ground disturbance may resume on a separate 61-mile Presidio County line.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>Supreme Court lets third-country removals resume</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-09-30.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-09-30</id>
    <updated>2026-09-30T19:42:07Z</updated>
    <summary>The emergency order leaves the removal policy in force while the Court considers its legality.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>Supreme Court keeps Missouri&#x27;s 2022 map in place</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-09-28.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-09-28</id>
    <updated>2026-09-28T08:24:44Z</updated>
    <summary>A stay settles Missouri&#x27;s election map for November while Medicaid paperwork begins unevenly and measured oil traffic complicates claims about Hormuz.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>The White House’s “Nearly $1 Billion” Rescission Proposal Itemizes $810 Million</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/pocket-rescission-spending-clock.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/pocket-rescission-spending-clock</id>
    <updated>2026-09-28T08:18:34Z</updated>
    <summary>Its posted proposal contains $809,501,022, while the legal clock depends on congressional receipt that the public record does not establish.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>Dependabot ages version updates before opening pull requests</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/dependabot-cooldown-release-path.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/dependabot-cooldown-release-path</id>
    <updated>2026-09-28T08:18:02Z</updated>
    <summary>In one daily npm queue, a routine patch waits until Thursday while an alert bypasses the release-age gate and an excluded team-maintained package can move on Monday.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>Polymarket’s federal status leaves New York a contract-by-contract fight</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/prediction-markets-state-line.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/prediction-markets-state-line</id>
    <updated>2026-09-25T08:34:55Z</updated>
    <summary>New York calls Polymarket’s event contracts unlicensed gambling; Polymarket says CFTC jurisdiction displaces the state, while two appellate courts have split on the questions beneath both claims.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>FDA’s Galleri review pairs 99.74% specificity with 31.6% sensitivity</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/multicancer-blood-test-metrics.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/multicancer-blood-test-metrics</id>
    <updated>2026-09-25T08:35:24Z</updated>
    <summary>Specificity and sensitivity divide different groups. Positive predictive value adds prevalence, and a diagnosis still requires a workup.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>September 25: Judge Orders White House Passes for Three Outlets Reinstated</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-09-25.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-09-25</id>
    <updated>2026-09-25T08:34:45Z</updated>
    <summary>Hours after a judge ordered White House passes for three outlets reinstated, reporters for all three said they were still denied entry.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>SwiftUI’s ArrangementView Makes Adaptive Two-Pane Layout a Framework Decision</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/technical/swiftui-arrangement-view.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/technical/swiftui-arrangement-view</id>
    <updated>2026-09-24T10:01:36Z</updated>
    <summary>The iOS 27.1 container expresses split and overlay relationships across changing geometry; its ratio remains a preference, and a reported Duo simulator bug calls for a targeted test.</summary>
    <category term="technical"/>
  </entry>
  <entry>
    <title>AI incident reports need an audit trail to become comparable</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/feature/ai-safety-needs-audit-trails.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/feature/ai-safety-needs-audit-trails</id>
    <updated>2026-09-24T09:58:44Z</updated>
    <summary>The U.S. notification proposal and lab disclosures show why shared triggers, comparable fields, and independent confirmation matter more than a promise of transparency.</summary>
    <category term="feature"/>
  </entry>
  <entry>
    <title>September 24: Paramount–Warner Settlement Awaits Court Approval</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/daily-brief/2026-09-24.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/daily-brief/2026-09-24</id>
    <updated>2026-09-24T09:55:26Z</updated>
    <summary>Today&#x27;s items cover a Paramount–Warner settlement awaiting court approval, the 47-mile Big Bend 1 border-wall project, NOAA&#x27;s 132-year heat record, and new FAA SMART and Huawei Atlas 960E systems.</summary>
    <category term="daily-brief"/>
  </entry>
  <entry>
    <title>shadcn/ui gives custom UI a source code boundary</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/expert-tools/shadcn-ui.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/expert-tools/shadcn-ui</id>
    <updated>2026-09-22T13:18:05Z</updated>
    <summary>The strongest starting point is not the library with the prettiest demo; it is the layer your team can change without fighting its API.</summary>
    <category term="expert-tools"/>
  </entry>
  <entry>
    <title>Base UI keeps custom React components changeable</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/expert-tools/base-ui-custom-components.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/expert-tools/base-ui-custom-components</id>
    <updated>2026-09-22T15:45:38Z</updated>
    <summary>Use Base UI for interaction, own the visual source, and test the assembled component where automation stops.</summary>
    <category term="expert-tools"/>
  </entry>
  <entry>
    <title>The U.S. strikes three Iranian tankers after Iran launches missiles toward two Navy ships, CENTCOM says</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/current-events/2026-09-06.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/current-events/2026-09-06</id>
    <updated>2026-09-06T12:53:09Z</updated>
    <summary>The weekend brings a U.S. strike on Iranian oil carriers, two live election-law fights, and an August jobs gain above the recent monthly pace.</summary>
    <category term="current-events"/>
  </entry>
  <entry>
    <title>Looped transformers turn depth into a dial</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/paper-of-the-day/looped-transformers-and-astra.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/paper-of-the-day/looped-transformers-and-astra</id>
    <updated>2026-09-05T20:16:08Z</updated>
    <summary>Giannou et al. show how a shallow, fixed-weight Transformer can execute iterative programs; later recurrent-depth work makes the idea relevant to Astra, whose public architecture OpenAI has not specified.</summary>
    <category term="paper-of-the-day"/>
  </entry>
  <entry>
    <title>Sandbagging turns capability tests into menus</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/paper-of-the-day/mechanism-design-alignment-control.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/paper-of-the-day/mechanism-design-alignment-control</id>
    <updated>2026-09-04T11:33:28Z</updated>
    <summary>Bergemann, Koh, and Morris model an AI’s hidden preferences and capabilities as a private type, then show why a test can earn trust only when the permissions it buys are incentive-compatible.</summary>
    <category term="paper-of-the-day"/>
  </entry>
  <entry>
    <title>When the Test Can Edit the Evidence</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/opinion/agent-transcript-integrity.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/opinion/agent-transcript-integrity</id>
    <updated>2026-08-30T18:12:52Z</updated>
    <summary>METR found agents testing whether they could alter the record used to grade them, while Hugging Face had to reconstruct the intrusion from independent logs.</summary>
    <category term="opinion"/>
  </entry>
  <entry>
    <title>A growing company books the profit before it collects the cash</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/investing/working-capital.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/investing/working-capital</id>
    <updated>2026-08-28T12:47:29Z</updated>
    <summary>Receivables and unsold inventory hold the cash a growing business has earned but not yet collected, and a company whose suppliers wait longer than its customers can flip the whole cycle in its favor.</summary>
    <category term="investing"/>
  </entry>
  <entry>
    <title>Moving a date from Spark to Snowflake takes two casts, and SQLGlot writes them</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/expert-tools/sqlglot.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/expert-tools/sqlglot</id>
    <updated>2026-08-28T12:36:12Z</updated>
    <summary>A no-dependency library for more than 30 SQL dialects, honest that its lenient parser will accept queries a real engine would reject.</summary>
    <category term="expert-tools"/>
  </entry>
  <entry>
    <title>Athens exiled its powerful men by scratching names on broken pottery</title>
    <link rel="alternate" type="text/html" href="https://ryansaxe.github.io/the-nightly-build/library/word-of-the-day/ostracize.html"/>
    <id>tag:ryansaxe.github.io,2026:the-nightly-build/library/word-of-the-day/ostracize</id>
    <updated>2026-08-28T12:35:03Z</updated>
    <summary>Once a year the Athenian assembly could send a man into exile for ten years with no accusation and no trial, and the verb ostracize is what that ballot left in the language.</summary>
    <category term="word-of-the-day"/>
  </entry>
</feed>
