 bondscell_results $f68952bd-4c0b-4331-a09c-5b118c8fa5a9queued¤logsrunning¦outputbodyHstate_aggregation_action_gradient_setup (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6n3persist_js_state·has_pluto_hook_features§cell_id$f68952bd-4c0b-4331-a09c-5b118c8fa5a9depends_on_disabled_cells§runtime (Ppublished_object_keysdepends_on_skipped_cells§errored$9df1a18d-137c-4ea5-8d15-05697f7bbf07queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 10.4</em></h3>
<p>Give pseudocode for a differential version of semi-gradient Q-learning.</p>
</blockquote>
<p>Given the pseudocode for semi-gradient Sarsa, make the following changes:</p>
<p class="tex">$$\vdots$$</p>
<p>Initialize S</p>
<p>Loop for each step of episode:</p>
<p>Choose A from S using ϵ-greedy policy Take action A, observe R, S&#39;</p>
<p class="tex">$$\delta \leftarrow R - \bar R &#43; \max_a \hat q&#40;S^\prime, a, \mathbf&#123;w&#125;&#41; - \hat q&#40;S, A, \mathbf&#123;w&#125;&#41;$$</p>
<p class="tex">$$\vdots$$</p>
<p class="tex">$$S \leftarrow S^\prime$$</p>
<p>See implementation above</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Fpersist_js_state·has_pluto_hook_features§cell_id$9df1a18d-137c-4ea5-8d15-05697f7bbf07depends_on_disabled_cells§runtime ٵpublished_object_keysdepends_on_skipped_cells§errored$c11aa069-93c2-435a-8f0e-353ced9633b6queued¤logsrunning¦outputbody7mountaincar_fcann_test (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6
persist_js_state·has_pluto_hook_features§cell_id$c11aa069-93c2-435a-8f0e-353ced9633b6depends_on_disabled_cells§runtime )ܵpublished_object_keysdepends_on_skipped_cellsçerrored$7812e801-70fd-4331-ad0a-fad02c1a399fqueued¤logsrunning¦outputbody>semi_gradient_expected_sarsa! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6 Opersist_js_state·has_pluto_hook_features§cell_id$7812e801-70fd-4331-ad0a-fad02c1a399fdepends_on_disabled_cells§runtime !published_object_keysdepends_on_skipped_cells§errored$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18queued¤logsrunning¦outputbody<div class="markdown"><h4>Sampling Tabular Case</h4>
<h5>Problem conditions</h5>
<ul>
<li><p>All states and actions can be enumerated: <span class="tex">$\mathcal&#123;S&#125; &#61; \&#123;s_1, s_2, \cdots, s_n\&#125;$</span> and <span class="tex">$\mathcal&#123;A&#125; &#61; \&#123;a_1, a_2, \cdots, a_m\&#125;$</span></p>
</li>
<li><p><span class="tex">$p&#40;s^\prime, r \vert s, a&#41;$</span> is not available</p>
</li>
<li><p>Observations from the environment can be collected: <span class="tex">$S_t, A_t \implies R_&#123;t&#43;1&#125;, S_&#123;t&#43;1&#125;$</span></p>
</li>
</ul>
<h5>Solution Techniques</h5>
<p>In the absence of <span class="tex">$p$</span>, we cannot use value iteration which is the only technique that circumvents the need for a policy.  So we must use some form of policy iteration.  It turns out that as long as we continue to update both the policy and the value function, neither need to converge to the correct values at any intermediate step.  The idea behind <em>Generalized Policy Iteration</em> is to maintain a value estimate for a given policy and update the policy periodically prior to knowing whether or not the value function has converged.  This interval could be as short as a single time step or as it takes to converge.  For episodic tasks, using a single episode of samples to update the value function followed by the policy is a natural choice.  For continuing tasks, one or more steps can be used in place of an episode.  All of the techniques will have the following in common:</p>
<ul>
<li><p>A list of state-action value estimates: <span class="tex">$q &#61; &#91;q_&#123;1, 1&#125;, q_&#123;1, 2&#125;, \cdots, q_&#123;1, m&#125;, \cdots q_&#123;n, m&#125;&#93;$</span>, one for each state-action pair initialized to some value</p>
</li>
<li><p>An initial random policy <span class="tex">$\pi$</span> &#40;probability distribution over actions for each state, could be a matrix&#41;</p>
</li>
<li><p>State-action values will be updated by averaging together samples which are unbiased estimates of <span class="tex">$q_\pi&#40;s, a&#41;$</span></p>
</li>
</ul>
<p>The primary difference between the techniques will be which equation is used to calculate the sample values.</p>
<ul>
<li><p>Monte Carlo Control: uses samples of the expected value in the definition of <span class="tex">$q_\pi&#40;s, a&#41; &#61; \mathbb&#123;E&#125;_\pi &#91;G_t \vert S_t &#61; s, A_t &#61; a&#93;$</span></p>
<ul>
<li><p>repeat the following for a set number of episodes</p>
<ul>
<li><p>Collect a trajectory under the policy <span class="tex">$\pi$</span>: <span class="tex">$S_0 \overset&#123;\pi&#125;&#123;\rightarrow&#125; A_0 \rightarrow R_1, S_1 \overset&#123;\pi&#125;&#123;\rightarrow&#125; A_1 \rightarrow R_2, S_2 \overset&#123;\pi&#125;&#123;\rightarrow&#125; A_2 \rightarrow \cdots\rightarrow R_T, S_T$</span></p>
</li>
<li><p>Use the reward sequence to compute an unbiased estimate of <span class="tex">$\mathbb&#123;E&#125;_\pi&#91;G_t&#93; &#61; \mathbb&#123;E&#125;&#91;q_\pi&#40;S_t, A_t&#41;&#93;$</span></p>
</li>
<li><p>Update the existing value for each state-action pair <span class="tex">$S_t, A_t$</span> observed in the episode using the estimate &#40;can use any number of averaging techniques&#41;</p>
</li>
<li><p>Update <span class="tex">$\pi$</span> to select greedy actions with respect to the state-action value estimates and random actions occassionally &#40;this is required to ensure visits to all state-action pairs and convergence of the expected values&#41;</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Sarsa/Expected Sarsa: uses samples of the expected value in the Bellman equation for <span class="tex">$q_\pi&#40;s, a&#41; &#61; \mathbb&#123;E&#125; &#91;R_&#123;t&#43;1&#125; &#43; \gamma\sum_&#123;a^\prime&#125; \pi&#40;a^\prime \vert s^\prime&#41; q_\pi&#40;s^\prime, a^\prime&#41; \mid S_t &#61; s, A_t &#61; a&#93;$</span></p>
<ul>
<li><p>initialize a state <span class="tex">$S_0$</span></p>
</li>
<li><p>repeat the following for a set number of steps</p>
<ul>
<li><p>Use <span class="tex">$\pi$</span> to select an action <span class="tex">$A_t$</span></p>
</li>
<li><p>Sample from the environment <span class="tex">$R_&#123;t&#43;1&#125;, S_&#123;t&#43;1&#125;$</span></p>
</li>
<li><p>Calculate an unbiased estimate for <span class="tex">$q_\pi&#40;S_t, A_t&#41;$</span> using <span class="tex">$R_&#123;t&#43;1&#125; &#43; \gamma\sum_&#123;a^\prime&#125; \pi&#40;a^\prime \vert s^\prime&#41; q&#40;S_&#123;t&#43;1&#125;, a^\prime&#41;$</span> OR use <span class="tex">$\pi$</span> to select the next action <span class="tex">$A_&#123;t&#43;1&#125;$</span> and use <span class="tex">$R_&#123;t&#43;1&#125; &#43; \gamma q&#40;S_&#123;t&#43;1&#125;, A_&#123;t&#43;1&#125;&#41;$</span></p>
</li>
<li><p>Use some averaging method to update the estimated state-action value for <span class="tex">$S_t, A_t$</span></p>
</li>
<li><p>Update <span class="tex">$\pi$</span> to select greedy actions with respect to the state-action value estimates and random actions occassionally &#40;this is required to ensure visits to all state-action pairs and convergence of the expected values&#41;</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Q-learning: uses samples of the expected value in the Bellman optimality equation for <span class="tex">$q_*&#40;s, a&#41; &#61; \mathbb&#123;E&#125; \left &#91; R_t &#43; γ \max_&#123;a^\prime&#125; q_*&#40;s^\prime, a^\prime&#41; \mid S_t &#61; s, A_t &#61; a \right &#93;$</span></p>
<ul>
<li><p>initialize a state <span class="tex">$S_0$</span></p>
</li>
<li><p>repeat the following for a set number of steps</p>
<ul>
<li><p>Use <span class="tex">$\pi$</span> to select an action <span class="tex">$A_t$</span></p>
</li>
<li><p>Sample from the environment <span class="tex">$R_&#123;t&#43;1&#125;, S_&#123;t&#43;1&#125;$</span></p>
</li>
<li><p>Calculate an unbiased estimate for <span class="tex">$q_*&#40;S_t, A_t&#41;$</span> using <span class="tex">$R_&#123;t&#43;1&#125; &#43; \gamma \max_&#123;a^\prime&#125; q&#40;S_&#123;t&#43;1&#125;, a^\prime&#41;$</span></p>
</li>
<li><p>Use some averaging method ot update the state-action value for <span class="tex">$S_t, A_t$</span></p>
</li>
<li><p>Update <span class="tex">$\pi$</span> to select greedy actions with respect to the state-action value estimates and random actions occassionally &#40;this is required to ensure visits to all state-action pairs and convergence of the expected values&#41;</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>Note that technically, Monte Carlo Control and Sarsa find the optimal <span class="tex">$\epsilon$</span>-greedy policy and value function; however in practice <span class="tex">$\epsilon$</span> can be reduced over time to arbitrarily approach the true optimal policy.  Q-learning, on the other hand can work even if the policy is never updated since the value update does not depend at all on the policy.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6B5persist_js_state·has_pluto_hook_features§cell_id$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18depends_on_disabled_cells§runtime )cpublished_object_keysdepends_on_skipped_cells§errored$dae59fd9-0397-4307-afd8-bafb6f0bfa52queued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktrace call_short(::var"#34#35")(i::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#dae59fd9-0397-4307-afd8-bafb6f0bfa52#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#dae59fd9-0397-4307-afd8-bafb6f0bfa52source_packageMaincall(::var"#34#35")(i::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#dae59fd9-0397-4307-afd8-bafb6f0bfa52func#34parent_moduleMain.var"workspace#5"from_ccall_shortnextinlinedãurlpath=/home/runner/.julia/packages/Transducers/fnznF/src/library.jlsource_packagecallnextlinfo_typeNothingline6filelibrary.jlfuncnextparent_modulefrom_ccall_shortnextinlinedãurlpath:/home/runner/.julia/packages/Transducers/fnznF/src/core.jlsource_packagecallnextlinfo_typeNothinglinefilecore.jlfuncnextparent_modulefrom_ccall_shortmacro expansioninlinedãurlpath:/home/runner/.julia/packages/Transducers/fnznF/src/core.jlsource_packagecallmacro expansionlinfo_typeNothingline̵filecore.jlfuncmacro expansionparent_modulefrom_ccall_short_foldl_arrayinlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecall_foldl_arraylinfo_typeNothingline̻fileprocesses.jlfunc_foldl_arrayparent_modulefrom_ccall_short__foldl__inlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecall__foldl__linfo_typeNothingline̶fileprocesses.jlfunc__foldl__parent_modulefrom_ccall_shortfoldl_basecaseinlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecallfoldl_basecaselinfo_typeNothinglineifileprocesses.jlfuncfoldl_basecaseparent_modulefrom_ccall_short{_reduce_basecase(rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlLfile:///home/runner/.julia/packages/Transducers/fnznF/src/threading_utils.jlpathE/home/runner/.julia/packages/Transducers/fnznF/src/threading_utils.jlsource_packageTransducerscall_reduce_basecase(rf::Transducers.Reduction{Transducers.Map{var"#34#35"}, Transducers.BottomRF{Transducers.Completing{typeof(+)}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline:filethreading_utils.jlfunc_reduce_basecaseparent_moduleTransducersfrom_ccall_shortٚ_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscall_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{Transducers.Map{var"#34#35"}, Transducers.BottomRF{Transducers.Completing{typeof(+)}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline̋filereduce.jlfunc_reduceparent_moduleTransducersfrom_ccall_shortٚ_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscall_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{Transducers.Map{var"#34#35"}, Transducers.BottomRF{Transducers.Completing{typeof(+)}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline̔filereduce.jlfunc_reduceparent_moduleTransducersfrom_ccall_short_transduce_assoc_nocompleteinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecall_transduce_assoc_nocompletelinfo_typeNothinglinẽfilereduce.jlfunc_transduce_assoc_nocompleteparent_modulefrom_ccall_shorttransduce_assoc(xform::Transducers.Map{…}, step::Transducers.Completing{…}, init::Transducers.InitOf{…}, coll0::UnitRange{…}; simd::Val{…}, basesize::Nothing, stoppable::Nothing, nestlevel::Nothing)inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscalltransduce_assoc(xform::Transducers.Map{var"#34#35"}, step::Transducers.Completing{typeof(+)}, init::Transducers.InitOf{Transducers.DefaultInitOf}, coll0::UnitRange{Int64}; simd::Val{false}, basesize::Nothing, stoppable::Nothing, nestlevel::Nothing)linfo_typeCore.MethodInstancelinelfilereduce.jlfunc#transduce_assoc#253parent_moduleTransducersfrom_ccall_shorttransduce_associnlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecalltransduce_assoclinfo_typeNothinglineTfilereduce.jlfunctransduce_assocparent_modulefrom_ccall_shortfoldxtinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecallfoldxtlinfo_typeNothinglinefilereduce.jlfuncfoldxtparent_modulefrom_ccall_shortfoldxtinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecallfoldxtlinfo_typeNothinglinefilereduce.jlfuncfoldxtparent_modulefrom_ccall_short#264inlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecall#264linfo_typeNothinglinefilereduce.jlfunc#264parent_modulefrom_ccall_shortC|>(x::Transducers.Eduction{…}, f::Transducers.var"#264#265"{…})inlined£urlghttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/operators.jl#L926path./operators.jlsource_packageMaincall|>(x::Transducers.Eduction{Transducers.Reduction{Transducers.Map{var"#34#35"}, Transducers.BottomRF{Transducers.Completing{typeof(BangBang.push!!)}}}, UnitRange{Int64}}, f::Transducers.var"#264#265"{@Kwargs{}, typeof(+)})linfo_typeCore.MethodInstancelinefileoperators.jlfunc|>parent_moduleBasefrom_ccall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#dae59fd9-0397-4307-afd8-bafb6f0bfa52source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#dae59fd9-0397-4307-afd8-bafb6f0bfa52functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6MUpersist_js_state·has_pluto_hook_features§cell_id$dae59fd9-0397-4307-afd8-bafb6f0bfa52depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$c678846c-aaff-4266-8b2c-07a3a92445efqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#c678846c-aaff-4266-8b2c-07a3a92445efsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#c678846c-aaff-4266-8b2c-07a3a92445effunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6)persist_js_state·has_pluto_hook_features§cell_id$c678846c-aaff-4266-8b2c-07a3a92445efdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$528533f7-68f1-4d19-9a37-6d4d0d7c38e2queued¤logsrunning¦outputbody3<bond def="constant_params" unique_id="pjVDdOIHF1kn"><span style='display: contents;'>
	<span style='display: contents;'><div class="markdown"><p>Number of Steps: <pl-combined-child key='hzcydrrskn' style='display: contents;'><input type='range' min='1' max='1000' value='200'><script>
					const input_el = currentScript.previousElementSibling
					const output_el = currentScript.nextElementSibling
					const displays = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", "990", "991", "992", "993", "994", "995", "996", "997", "998", "999", "1000"]

					let update_output = () => {
						output_el.value = displays[input_el.valueAsNumber - 1]
					}
					
					input_el.addEventListener("input", update_output)
					// We also poll for changes because the `input_el.value` can change from the outside, e.g. https://github.com/JuliaPluto/PlutoUI.jl/issues/277
					let id = setInterval(update_output, 200)
					invalidation.then(() => {
						clearInterval(id)
						input_el.removeEventListener("input", update_output)
					})
					</script><output style='
						font-family: system-ui;
    					font-size: 15px;
    					margin-left: 3px;
    					transform: translateY(-4px);
    					display: inline-block;'>200</output></pl-combined-child></p>
<p>Select Constant Action: <pl-combined-child key='hzcydrrskn' style='display: contents;'><select><option value='puiselect-1'>Decelerate</option><option value='puiselect-2'>Nothing</option><option value='puiselect-3'>Accelerate</option></select></pl-combined-child></p>
</div><script id='hzcydrrskn'>
const div = currentScript.parentElement
let key = "hzcydrrskn"
const inputs = div.querySelectorAll(`pl-combined-child[key='${key}'] > *:first-child`)

const values = Array(inputs.length)

inputs.forEach(async (el,i) => {
	el.oninput = (e) => {
		e.stopPropagation()
	}
	const gen = Generators.input(el)
	while(true) {
		values[i] = await gen.next().value
		div.dispatchEvent(new CustomEvent("input", {}))
	}
})


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()


Object.defineProperty(div, 'value', {
	get: () => values,
	set: (newvals) => {
		if(!newvals) {
			return
		}
		inputs.forEach((el, i) => {
			values[i] = newvals[i]
			set_input_value(el, newvals[i])
		})
},
	configurable: true,
});

</script></span>
	<input type=submit id='lfhcjazzej'>
	<script id='lfhcjazzej'>

let key = "lfhcjazzej"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond>mimetext/htmlrootassigneelast_run_timestampA6Rpersist_js_state·has_pluto_hook_features§cell_id$528533f7-68f1-4d19-9a37-6d4d0d7c38e2depends_on_disabled_cells§runtimeDTpublished_object_keysdepends_on_skipped_cellsçerrored$cafb20b4-a2bd-46a9-9660-b0ace84d6e4cqueued¤logsrunning¦outputbody5initialize_car_state (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA65İpersist_js_state·has_pluto_hook_features§cell_id$cafb20b4-a2bd-46a9-9660-b0ace84d6e4cdepends_on_disabled_cells§runtime (ߵpublished_object_keysdepends_on_skipped_cells§errored$66d6a4b0-ddf8-4781-b3b4-20f02b25199aqueued¤logsrunning¦outputbodymsgٯUndefVarError: `tabular_mountaincar_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#66d6a4b0-ddf8-4781-b3b4-20f02b25199asource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#66d6a4b0-ddf8-4781-b3b4-20f02b25199afunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6T8persist_js_state·has_pluto_hook_features§cell_id$66d6a4b0-ddf8-4781-b3b4-20f02b25199adepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$b0265b93-ae5f-48f2-a9fd-44fd6115164bqueued¤logsrunning¦outputbodyn<div class="markdown"><h2>Solving the Control Problem</h2>
<h3>Goal: Maximizing <span class="tex">$G_t$</span></h3>
<p>For a given MDP problem with a state space <span class="tex">$\mathcal&#123;S&#125;$</span> and action space <span class="tex">$\mathcal&#123;A&#125;$</span>, there exists some optimal policy <span class="tex">$\pi_*$</span> for which taking actions under that policy will result in a higher expected discounted reward sum than any other policy.  In short:</p>
<p class="tex">$$\mathbb&#123;E&#125;_&#123;\pi_*&#125;&#91;G_t \vert S_t &#61; s&#93; \ge \mathbb&#123;E&#125;_&#123;\pi&#125;&#91;G_t \vert S_t &#61; s&#93; \quad \forall s,\pi$$</p>
<p>where <span class="tex">$G_t \doteq \sum_&#123;k&#61;0&#125;^\infty \gamma^k R_&#123;t&#43;k&#43;1&#125; \text&#123; or &#125; \sum_&#123;k &#61; t&#43;1&#125; ^ T \gamma^&#123;k-t-1&#125;R_k$</span></p>
</div>mimetext/htmlrootassigneelast_run_timestampA6@persist_js_state·has_pluto_hook_features§cell_id$b0265b93-ae5f-48f2-a9fd-44fd6115164bdepends_on_disabled_cells§runtime Opublished_object_keysdepends_on_skipped_cells§errored$57659c52-de1b-46e6-a863-8eeec0cee601queued¤logsrunning¦outputbody;π_optimal_value_iteration (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6Rpersist_js_state·has_pluto_hook_features§cell_id$57659c52-de1b-46e6-a863-8eeec0cee601depends_on_disabled_cells§runtime Apublished_object_keysdepends_on_skipped_cellsçerrored$a9fdb1fd-3f62-4e1c-9157-c4eee6215261queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#a9fdb1fd-3f62-4e1c-9157-c4eee6215261source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#a9fdb1fd-3f62-4e1c-9157-c4eee6215261functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6|persist_js_state·has_pluto_hook_features§cell_id$a9fdb1fd-3f62-4e1c-9157-c4eee6215261depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93queued¤logsrunning¦outputbody<show_mountaincar_trajectory (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6}@persist_js_state·has_pluto_hook_features§cell_id$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93depends_on_disabled_cells§runtime ~]published_object_keysdepends_on_skipped_cellsçerrored$e86bc86f-9909-458d-b86d-0a4ac4b9d43dqueued¤logsrunning¦outputbody<bond def="nsamples" unique_id="tseOBflPBk5h"><span style='display: contents;'>
	<input type='number' min='1' step='1' max='100000' value='1000'>
	<input type=submit id='qkeawawmda'>
	<script id='qkeawawmda'>

let key = "qkeawawmda"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond>mimetext/htmlrootassigneelast_run_timestampA6hpersist_js_state·has_pluto_hook_features§cell_id$e86bc86f-9909-458d-b86d-0a4ac4b9d43ddepends_on_disabled_cells§runtime~>published_object_keysdepends_on_skipped_cellsçerrored$bc1d7cce-c0f4-47a8-b674-8acb82491c7fqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#bc1d7cce-c0f4-47a8-b674-8acb82491c7fsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#bc1d7cce-c0f4-47a8-b674-8acb82491c7ffunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassignee#const mountain_car_differential_mdplast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$bc1d7cce-c0f4-47a8-b674-8acb82491c7fdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2queued¤logsrunning¦outputbody|500-element LinRange{Float32, Int64}:
 -0.07, -0.0697194, -0.0694389, -0.0691583, …, 0.0691583, 0.0694389, 0.0697194, 0.07mimetext/plainrootassigneeconst mountaincar_velocitieslast_run_timestampA6mLpersist_js_state·has_pluto_hook_features§cell_id$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cellsçerrored$c12070a9-df63-4b25-99e6-26ff876af1b4queued¤logsrunning¦outputbodyCupdate_mountaincar_feature_vector! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6uCpersist_js_state·has_pluto_hook_features§cell_id$c12070a9-df63-4b25-99e6-26ff876af1b4depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$991492f4-7dfc-43aa-ab6c-a6b1f3e38225queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#991492f4-7dfc-43aa-ab6c-a6b1f3e38225source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#991492f4-7dfc-43aa-ab6c-a6b1f3e38225functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6/persist_js_state·has_pluto_hook_features§cell_id$991492f4-7dfc-43aa-ab6c-a6b1f3e38225depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$28e0d632-0df3-4a5b-85c4-571c845ff827queued¤logsrunning¦outputbodyprefixStringelements"Decelerate"text/plain"Nothing"text/plain"Accelerate"text/plaintypeArrayprefix_shortobjectid79f5439950e906b5mime!application/vnd.pluto.tree+objectrootassigneeconst mountain_car_action_nameslast_run_timestampA6upersist_js_state·has_pluto_hook_features§cell_id$28e0d632-0df3-4a5b-85c4-571c845ff827depends_on_disabled_cells§runtime 7npublished_object_keysdepends_on_skipped_cells§errored$b191d3f9-cf25-4fb4-8f5a-8da86e96e125queued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93source_packageMaincallIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93funcshow_mountaincar_trajectoryparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b191d3f9-cf25-4fb4-8f5a-8da86e96e125source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b191d3f9-cf25-4fb4-8f5a-8da86e96e125func##function_wrapped_cell#574parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Qnpersist_js_state·has_pluto_hook_features§cell_id$b191d3f9-cf25-4fb4-8f5a-8da86e96e125depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$e338be2b-05f1-43f4-a194-45ffd710777equeued¤logsrunning¦outputbodymsgٯUndefVarError: `tabular_mountaincar_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#e338be2b-05f1-43f4-a194-45ffd710777esource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#e338be2b-05f1-43f4-a194-45ffd710777efunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneeconst accelerate_mountaincar_πlast_run_timestampA6°persist_js_state·has_pluto_hook_features§cell_id$e338be2b-05f1-43f4-a194-45ffd710777edepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$224b4bec-9ec5-434d-a950-f5974cd786d0queued¤logsrunning¦outputbody0<div class="markdown"><h5>Linear Tile Coding</h5>
<p>Since we are only learning the value function, the same tiling setup will have fewer parameters than the action value techniques.  Empirically, more tilings are necessary to learn a state value function that can approach the optimal policy.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Epersist_js_state·has_pluto_hook_features§cell_id$224b4bec-9ec5-434d-a950-f5974cd786d0depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$8752c98d-fac1-4b3b-b20b-70acc0677fcbqueued¤logsrunning¦outputbodym<div class="markdown"><blockquote>
<h3><em>Exercise 10.9</em></h3>
<p>In the differential semi-gradient n-step Sarsa algorithm, the step-size parameter on the average reward, <span class="tex">$\beta$</span>, needs to be quite small so that <span class="tex">$\bar R$</span> becomes a good long-term estimate of the average reward. Unfortunately, <span class="tex">$\bar R$</span> will then be biased by its initial value for many steps, which may make learning inefficient. Alternatively, one could use a sample average of the observed rewards for <span class="tex">$\bar R$</span>. That would initially adapt rapidly but in the long run would also adapt slowly. As the policy slowly changed, <span class="tex">$\bar R$</span> would also change; the potential for such long-term nonstationarity makes sample-average methods ill-suited. In fact, the step-size parameter on the average reward is a perfect place to use the unbiased constant-step-size trick from Exercise 2.7. Describe the specific changes needed to the boxed algorithm for differential semi-gradient n-step Sarsa to use this trick.</p>
</blockquote>
<p>At the start initialize <span class="tex">$\bar o &#61; 0$</span> and select <span class="tex">$\lambda &gt; 0$</span> small instead of <span class="tex">$\beta$</span>. </p>
<p>Within the loop under the <span class="tex">$\tau \geq 0$</span> line, add two lines; one to update <span class="tex">$\bar o$</span> and one to calculate the update rate for the average reward: </p>
<p>Line 1: <span class="tex">$\bar o \leftarrow \bar o &#43; \lambda &#40;1 - \bar o&#41;$</span></p>
<p>Line 2: <span class="tex">$\beta &#61; \lambda / \bar o$</span></p>
<p>As steps progress <span class="tex">$\beta$</span> will approach <span class="tex">$\lambda$</span> but early on will take on much larger values as <span class="tex">$\bar o$</span> starts close to 0 and approaches 1.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Hpersist_js_state·has_pluto_hook_features§cell_id$8752c98d-fac1-4b3b-b20b-70acc0677fcbdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$dd472c0f-7b43-4abe-ada9-9dc8004a18cbqueued¤logsrunning¦outputbody.add_elements (generic function with 4 methods)mimetext/plainrootassigneelast_run_timestampA6PLpersist_js_state·has_pluto_hook_features§cell_id$dd472c0f-7b43-4abe-ada9-9dc8004a18cbdepends_on_disabled_cells§runtime@published_object_keysdepends_on_skipped_cellsçerrored$ab4cb3db-3a2d-4145-826b-b1001114eeffqueued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93source_packageMaincallIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93funcshow_mountaincar_trajectoryparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#ab4cb3db-3a2d-4145-826b-b1001114eeffsource_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#ab4cb3db-3a2d-4145-826b-b1001114eefffunc##function_wrapped_cell#652parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6U
Rpersist_js_state·has_pluto_hook_features§cell_id$ab4cb3db-3a2d-4145-826b-b1001114eeffdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$1410db13-4b73-4a87-af34-30a5232af4baqueued¤logsrunning¦outputbody9compute_q_learning_value (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$1410db13-4b73-4a87-af34-30a5232af4badepends_on_disabled_cells§runtime /published_object_keysdepends_on_skipped_cells§errored$eb28458f-b222-4f8e-9a5b-8203d3997f7bqueued¤logsrunning¦outputbody?mountain_car_differential_step (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$eb28458f-b222-4f8e-9a5b-8203d3997f7bdepends_on_disabled_cells§runtime pѵpublished_object_keysdepends_on_skipped_cells§errored$a97e3b12-b7a5-4f88-bdb9-c3158203e0ffqueued¤logsrunning¦outputbodymsgٯUndefVarError: `tabular_mountaincar_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#a97e3b12-b7a5-4f88-bdb9-c3158203e0ffsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#a97e3b12-b7a5-4f88-bdb9-c3158203e0fffunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Ppersist_js_state·has_pluto_hook_features§cell_id$a97e3b12-b7a5-4f88-bdb9-c3158203e0ffdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6aqueued¤logsrunning¦outputbodymsgلUndefVarError: `mountain_car_fcann` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#4ccb8a52-c6af-445d-a39e-d4d9b10c0d6asource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#4ccb8a52-c6af-445d-a39e-d4d9b10c0d6afunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Bpersist_js_state·has_pluto_hook_features§cell_id$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6adepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$1e224a46-91ef-4a5f-ae35-ef4062147f2dqueued¤logsrunning¦outputbodymsgَUndefVarError: `mountaincar_fcann_dp_results` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1e224a46-91ef-4a5f-ae35-ef4062147f2dsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#1e224a46-91ef-4a5f-ae35-ef4062147f2dfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Jpersist_js_state·has_pluto_hook_features§cell_id$1e224a46-91ef-4a5f-ae35-ef4062147f2ddepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$5b2ffd90-ead0-42ce-999a-584ed8995910queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#5b2ffd90-ead0-42ce-999a-584ed8995910source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#5b2ffd90-ead0-42ce-999a-584ed8995910functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneeconst mountain_car_dist_mdplast_run_timestampA6{!persist_js_state·has_pluto_hook_features§cell_id$5b2ffd90-ead0-42ce-999a-584ed8995910depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$62839b2a-398a-4445-87d1-b15ff2acc1d1queued¤logsrunning¦outputbody;create_access_control_task (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6wðpersist_js_state·has_pluto_hook_features§cell_id$62839b2a-398a-4445-87d1-b15ff2acc1d1depends_on_disabled_cells§runtime Mpublished_object_keysdepends_on_skipped_cells§errored$8d096d0d-8fea-421a-aa33-82269d3fe7e2queued¤logsrunning¦outputbodyf<div class="markdown"><h3><em>Action-Value Implementation of Non-Linear Approximation</em></h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6Cpersist_js_state·has_pluto_hook_features§cell_id$8d096d0d-8fea-421a-aa33-82269d3fe7e2depends_on_disabled_cells§runtime Nҵpublished_object_keysdepends_on_skipped_cells§errored$39b0f100-a7e7-4633-b296-ccc87a5a35abqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#39b0f100-a7e7-4633-b296-ccc87a5a35absource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#39b0f100-a7e7-4633-b296-ccc87a5a35abfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6-v.persist_js_state·has_pluto_hook_features§cell_id$39b0f100-a7e7-4633-b296-ccc87a5a35abdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$1a82ae95-3c3e-4281-bc1d-9eb19bf50286queued¤logsrunning¦outputbody,figure_10_2 (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6&persist_js_state·has_pluto_hook_features§cell_id$1a82ae95-3c3e-4281-bc1d-9eb19bf50286depends_on_disabled_cells§runtime Pepublished_object_keysdepends_on_skipped_cellsçerrored$99e3ec39-24f0-43d6-b6fd-9910b738ce2cqueued¤logsrunning¦outputbodymsgٯUndefVarError: `tabular_mountaincar_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#99e3ec39-24f0-43d6-b6fd-9910b738ce2csource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#99e3ec39-24f0-43d6-b6fd-9910b738ce2cfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Opersist_js_state·has_pluto_hook_features§cell_id$99e3ec39-24f0-43d6-b6fd-9910b738ce2cdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$f11787a1-57f8-4077-8d60-bc760ece7cc6queued¤logsrunning¦outputbodymsgUndefVarError: `SparseVector` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing SparseArrays in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#f11787a1-57f8-4077-8d60-bc760ece7cc6source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#f11787a1-57f8-4077-8d60-bc760ece7cc6functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$f11787a1-57f8-4077-8d60-bc760ece7cc6depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$fc3e0577-45aa-4bba-a275-fa7a352fc5ccqueued¤logsrunning¦outputbodymsgلUndefVarError: `mountain_car_fcann` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#fc3e0577-45aa-4bba-a275-fa7a352fc5ccsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#fc3e0577-45aa-4bba-a275-fa7a352fc5ccfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6.persist_js_state·has_pluto_hook_features§cell_id$fc3e0577-45aa-4bba-a275-fa7a352fc5ccdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$98a5d65e-4253-4523-a74e-99d03be03b89queued¤logsrunning¦outputbody~<div class="markdown"><h3><em>Semi-gradient Expected Sarsa Implementation</em></h3>
<p>Since we already update the policy and action values in the sarsa algorithm, the only difference in expected sarsa is to compute the action-value using the entire policy distribution instead of just the sampled action.  Similarly for Q-learning we would only select the maximum value.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6E	persist_js_state·has_pluto_hook_features§cell_id$98a5d65e-4253-4523-a74e-99d03be03b89depends_on_disabled_cells§runtime 
Gpublished_object_keysdepends_on_skipped_cells§errored$4271151d-d5a6-4a29-96c3-f2102b142b95queued¤logsrunning¦outputbody2get_action_value (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA6^Ppersist_js_state·has_pluto_hook_features§cell_id$4271151d-d5a6-4a29-96c3-f2102b142b95depends_on_disabled_cells§runtime ӵpublished_object_keysdepends_on_skipped_cells§errored$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#56b0d69b-b7c3-4365-9b02-e0d5e8a85f94source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#56b0d69b-b7c3-4365-9b02-e0d5e8a85f94functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Ppersist_js_state·has_pluto_hook_features§cell_id$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$3f7484b3-272d-410d-92b1-ca13e5d7a8b7queued¤logslinemsg
<script id='html_reload_button'>
  const container = html`<fromparent-container class='@frompackage'>`
  // We set the errored state
  container.classList.toggle('errored', true)
  const style = container.appendChild(html`<style>`)
  style.innerHTML = `fromparent-container {
  height: 20px;
  position: fixed;
  top: 40px;
  right: 10px;
  margin-top: 5px;
  padding-right: 5px;
  z-index: 200;
  background: var(--overlay-button-bg);
  padding: 5px 8px;
  border: 3px solid var(--overlay-button-border);
  border-radius: 12px;
  height: 35px;
  font-family: "Segoe UI Emoji", "Roboto Mono", monospace;
  font-size: 0.75rem;
  visibility: visible;
}

fromparent-container.PlutoDevMacros {
  right: auto;
  left: 10px;
}
fromparent-container.PlutoDevMacros:before {
  content: "Reload PlutoDevMacros"
}

fromparent-container.errored {
  border-color: var(--error-cell-color);
}
fromparent-container:hover {
  font-weight: 800;
  cursor: pointer;
}
body.disable_ui fromparent-container {
  display: none;
}
fromparent-container:before {
  content: 'Reload @frompackage';
}
    `
  const cell = document.getElementById('3f7484b3-272d-410d-92b1-ca13e5d7a8b7')
  const actions = cell._internal_pluto_actions
  container.onclick = (e) => {
    if (e.ctrlKey) {
      history.pushState({}, '')
      cell.scrollIntoView({
        behavior: 'auto',
        block: 'center',
      })
    } else {
      actions.set_and_run_multiple(['3f7484b3-272d-410d-92b1-ca13e5d7a8b7'])
    }
  }

  return container
</script>
    <script id = 'R4Q9aOT' class='hide-this-log'>
  const logs_positioner = currentScript.closest('pluto-log-dot-positioner')
  if (logs_positioner == undefined) { return }
  const logs = logs_positioner.parentElement
  const logs_container = logs.parentElement

  const style = html`<style>
    pluto-logs-container[hidden] {
      height: 0px;
      padding: 0px;
      visibility: hidden;
    }
    pluto-log-dot-positioner[hidden] {
      height: 0px;
      margin: 0px;
      visibility: hidden;
    }
    </style>`
  
  function callBack(mutationList, observer) {
    let hide_container = true
    for (const child of logs.children) {
        const should_hide = child.querySelector('script.hide-this-log') != undefined
        child.toggleAttribute('hidden', should_hide)
        hide_container = hide_container && should_hide
    }
    // We eventualy hide the container
    logs_container.toggleAttribute('hidden', hide_container)
  }

  const observer = new MutationObserver(callBack)

  observer.observe(logs, { subtree: true, attributes: true, childList: true })
  logs_positioner.toggleAttribute('hidden', true)
  invalidation.then(() => {
    console.log('invalidation of logs hider script')
    callBack()
    observer.disconnect()
  })
  return style
    </script>text/htmlcell_id$3f7484b3-272d-410d-92b1-ca13e5d7a8b7kwargsid#PlutoDevMacros_FromPackage_7f8806d9fileJ/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlgroupmacrolevelInfolinemsg0ERROR: LoadError: ArgumentError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Stacktrace:
  [1] _empty_reduce_error()
    @ Base ./reduce.jl:319
  [2] reduce_empty(f::Function, T::Type)
    @ Base ./reduce.jl:320
  [3] mapreduce_empty(::typeof(identity), op::Function, T::Type)
    @ Base ./reduce.jl:369
  [4] reduce_empty(op::Base.MappingRF{typeof(identity), typeof(max)}, ::Type{VersionNumber})
    @ Base ./reduce.jl:358
  [5] reduce_empty_iter
    @ ./reduce.jl:381 [inlined]
  [6] mapreduce_empty_iter(f::Function, op::Function, itr::Vector{VersionNumber}, ItrEltype::Base.HasEltype)
    @ Base ./reduce.jl:377
  [7] _mapreduce(f::typeof(identity), op::typeof(max), ::IndexLinear, A::Vector{VersionNumber})
    @ Base ./reduce.jl:429
  [8] _mapreduce_dim
    @ ./reducedim.jl:337 [inlined]
  [9] mapreduce
    @ ./reducedim.jl:329 [inlined]
 [10] reduce
    @ ./reducedim.jl:378 [inlined]
 [11] set_default_nvlib_settings()
    @ NVIDIALibraries ~/.julia/packages/NVIDIALibraries/vbzF8/src/NVIDIALibraries.jl:312
 [12] var"@using_nvidialib_settings"(__source__::LineNumberNode, __module__::Module)
    @ NVIDIALibraries ~/.julia/packages/NVIDIALibraries/vbzF8/src/NVIDIALibraries.jl:443
 [13] include(mod::Module, _path::String)
    @ Base ./Base.jl:557
 [14] include(x::String)
    @ FCANN ~/.julia/packages/FCANN/b5rcg/src/FCANN.jl:1
 [15] top-level scope
    @ ~/.julia/packages/FCANN/b5rcg/src/cuda/ADAMAXTRAINGPU_FCN_ABSERR_NFLOATOUT.jl:2
 [16] include(mod::Module, _path::String)
    @ Base ./Base.jl:557
 [17] include(x::String)
    @ FCANN ~/.julia/packages/FCANN/b5rcg/src/FCANN.jl:1
 [18] top-level scope
    @ ~/.julia/packages/FCANN/b5rcg/src/MASTER_FCN_ABSERR_NFLOATOUT.jl:7
 [19] include(mod::Module, _path::String)
    @ Base ./Base.jl:557
 [20] include(x::String)
    @ FCANN ~/.julia/packages/FCANN/b5rcg/src/FCANN.jl:1
 [21] top-level scope
    @ ~/.julia/packages/FCANN/b5rcg/src/FCANN.jl:18
 [22] include
    @ ./Base.jl:557 [inlined]
 [23] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
    @ Base ./loading.jl:2790
 [24] top-level scope
    @ stdin:5
in expression starting at /home/runner/.julia/packages/FCANN/b5rcg/src/cuda/FCN_ABSERR_NFLOATOUT_CUDACOSTFUNCTION.jl:3
in expression starting at /home/runner/.julia/packages/FCANN/b5rcg/src/cuda/FCN_ABSERR_NFLOATOUT_CUDACOSTFUNCTION.jl:3
in expression starting at /home/runner/.julia/packages/FCANN/b5rcg/src/cuda/ADAMAXTRAINGPU_FCN_ABSERR_NFLOATOUT.jl:2
in expression starting at /home/runner/.julia/packages/FCANN/b5rcg/src/MASTER_FCN_ABSERR_NFLOATOUT.jl:7
in expression starting at /home/runner/.julia/packages/FCANN/b5rcg/src/FCANN.jl:1
in expression starting at stdin:5
text/plaincell_id$3f7484b3-272d-410d-92b1-ca13e5d7a8b7kwargsidPlutoRunner_d1acb81efileP/home/runner/.julia/packages/Pluto/6smog/src/runner/PlutoRunner/src/io/stdout.jlgroupstdoutlevelLogLevel(-555)running¦outputbodymsgzFailed to precompile FCANN [8c01af00-eda8-11e9-3d27-59b8c7aa8fdd] to "/home/runner/.julia/compiled/v1.11/FCANN/jl_ZHk5wu".stacktrace call_shorterror(s::String)inlined£urlbhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/error.jl#L35path./error.jlsource_packageMaincallerror(s::String)linfo_typeCore.MethodInstanceline#fileerror.jlfuncerrorparent_moduleBasefrom_ccall_shortٺcompilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool; flags::Cmd, cacheflags::Base.CacheFlags, reasons::Dict{…}, isext::Bool)inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L2949path./loading.jlsource_packageMaincallcompilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool; flags::Cmd, cacheflags::Base.CacheFlags, reasons::Dict{String, Int64}, isext::Bool)linfo_typeCore.MethodInstancelinefileloading.jlfunc#compilecache#1094parent_moduleBasefrom_ccall_short(::Base.var"#1082#1083"{…})()inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L2490path./loading.jlsource_packageMaincall&(::Base.var"#1082#1083"{Base.PkgId})()linfo_typeCore.MethodInstanceline	fileloading.jlfunc#1082parent_moduleBasefrom_ccall_shortUmkpidlock(f::Base.var"#1082#1083"{…}, at::String, pid::Int32; kwopts::@Kwargs{…})inlined£urlvfile:///cache/build/builder-demeter6-6/julialang/julia-master/usr/share/julia/stdlib/v1.11/FileWatching/src/pidfile.jlpatho/cache/build/builder-demeter6-6/julialang/julia-master/usr/share/julia/stdlib/v1.11/FileWatching/src/pidfile.jlsource_packageFileWatchingcallumkpidlock(f::Base.var"#1082#1083"{Base.PkgId}, at::String, pid::Int32; kwopts::@Kwargs{stale_age::Int64, wait::Bool})linfo_typeCore.MethodInstanceline_filepidfile.jlfunc#mkpidlock#7parent_moduleFileWatching.Pidfilefrom_ccall_short#mkpidlock#6inlinedãurlpatho/cache/build/builder-demeter6-6/julialang/julia-master/usr/share/julia/stdlib/v1.11/FileWatching/src/pidfile.jlsource_packagecall#mkpidlock#6linfo_typeNothinglineZfilepidfile.jlfunc#mkpidlock#6parent_modulefrom_ccall_short=trymkpidlock(::Function, ::Vararg{…}; kwargs::@Kwargs{…})inlined£urlvfile:///cache/build/builder-demeter6-6/julialang/julia-master/usr/share/julia/stdlib/v1.11/FileWatching/src/pidfile.jlpatho/cache/build/builder-demeter6-6/julialang/julia-master/usr/share/julia/stdlib/v1.11/FileWatching/src/pidfile.jlsource_packageFileWatchingcallJtrymkpidlock(::Function, ::Vararg{Any}; kwargs::@Kwargs{stale_age::Int64})linfo_typeCore.MethodInstancelinetfilepidfile.jlfunc#trymkpidlock#11parent_moduleFileWatching.Pidfilefrom_ccall_short#invokelatest#2inlinedãurlpath./essentials.jlsource_packagecall#invokelatest#2linfo_typeNothingline!fileessentials.jlfunc#invokelatest#2parent_modulefrom_ccall_shortinvokelatestinlinedãurlpath./essentials.jlsource_packagecallinvokelatestlinfo_typeNothinglinefileessentials.jlfuncinvokelatestparent_modulefrom_ccall_shortfmaybe_cachefile_lock(f::Base.var"#1082#1083"{…}, pkg::Base.PkgId, srcpath::String; stale_age::Int64)inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L3606path./loading.jlsource_packageMaincallmmaybe_cachefile_lock(f::Base.var"#1082#1083"{Base.PkgId}, pkg::Base.PkgId, srcpath::String; stale_age::Int64)linfo_typeCore.MethodInstancelinefileloading.jlfunc#maybe_cachefile_lock#1104parent_moduleBasefrom_ccall_shortmaybe_cachefile_lockinlinedãurlpath./loading.jlsource_packagecallmaybe_cachefile_locklinfo_typeNothinglinefileloading.jlfuncmaybe_cachefile_lockparent_modulefrom_ccall_short&_require(pkg::Base.PkgId, env::String)inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L2432path./loading.jlsource_packageMaincall&_require(pkg::Base.PkgId, env::String)linfo_typeCore.MethodInstanceline	fileloading.jlfunc_requireparent_moduleBasefrom_ccall_short5__require_prelocked(uuidkey::Base.PkgId, env::String)inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L2308path./loading.jlsource_packageMaincall5__require_prelocked(uuidkey::Base.PkgId, env::String)linfo_typeCore.MethodInstanceline	fileloading.jlfunc__require_prelockedparent_moduleBasefrom_ccall_short#invoke_in_world#3inlinedãurlpath./essentials.jlsource_packagecall#invoke_in_world#3linfo_typeNothinglineAfileessentials.jlfunc#invoke_in_world#3parent_modulefrom_ccall_shortinvoke_in_worldinlinedãurlpath./essentials.jlsource_packagecallinvoke_in_worldlinfo_typeNothingline>fileessentials.jlfuncinvoke_in_worldparent_modulefrom_ccall_short4_require_prelocked(uuidkey::Base.PkgId, env::String)inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L2300path./loading.jlsource_packageMaincall4_require_prelocked(uuidkey::Base.PkgId, env::String)linfo_typeCore.MethodInstancelinefileloading.jlfunc_require_prelockedparent_moduleBasefrom_ccall_shortmacro expansioninlinedãurlpath./loading.jlsource_packagecallmacro expansionlinfo_typeNothinglinefileloading.jlfuncmacro expansionparent_modulefrom_ccall_shortmacro expansioninlinedãurlpath./lock.jlsource_packagecallmacro expansionlinfo_typeNothinglinefilelock.jlfuncmacro expansionparent_modulefrom_ccall_short$__require(into::Module, mod::Symbol)inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L2197path./loading.jlsource_packageMaincall$__require(into::Module, mod::Symbol)linfo_typeCore.MethodInstancelinefileloading.jlfunc__requireparent_moduleBasefrom_ccall_short#invoke_in_world#3inlinedãurlpath./essentials.jlsource_packagecall#invoke_in_world#3linfo_typeNothinglineAfileessentials.jlfunc#invoke_in_world#3parent_modulefrom_ccall_shortinvoke_in_worldinlinedãurlpath./essentials.jlsource_packagecallinvoke_in_worldlinfo_typeNothingline>fileessentials.jlfuncinvoke_in_worldparent_modulefrom_ccall_short"require(into::Module, mod::Symbol)inlined£urlfhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/loading.jl#L2184path./loading.jlsource_packageMaincall"require(into::Module, mod::Symbol)linfo_typeCore.MethodInstancelinefileloading.jlfuncrequireparent_moduleBasefrom_ccall_shortevalinlinedãurlpath./boot.jlsource_packagecallevallinfo_typeNothinglinefileboot.jlfuncevalparent_modulefrom_ccall_shortEload_direct_deps(p::PlutoDevMacros.FromPackage.FromPackageController)inlined£urlSfile:///home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/loading.jlpathL/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/loading.jlsource_packagePlutoDevMacroscallEload_direct_deps(p::PlutoDevMacros.FromPackage.FromPackageController)linfo_typeCore.MethodInstancelinegfileloading.jlfuncload_direct_depsparent_modulePlutoDevMacros.FromPackagefrom_ccall_shortRload_module!(p::PlutoDevMacros.FromPackage.FromPackageController{…}; reset::Any)inlined£urlSfile:///home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/loading.jlpathL/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/loading.jlsource_packagePlutoDevMacroscallbload_module!(p::PlutoDevMacros.FromPackage.FromPackageController{:ApproximationUtils}; reset::Any)linfo_typeCore.MethodInstancelinefileloading.jlfunc#load_module!#33parent_modulePlutoDevMacros.FromPackagefrom_ccall_shortFload_module!(p::PlutoDevMacros.FromPackage.FromPackageController{…})inlined£urlSfile:///home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/loading.jlpathL/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/loading.jlsource_packagePlutoDevMacroscallVload_module!(p::PlutoDevMacros.FromPackage.FromPackageController{:ApproximationUtils})linfo_typeCore.MethodInstancelinekfileloading.jlfuncload_module!parent_modulePlutoDevMacros.FromPackagefrom_ccall_shortقfrompackage(ex::Expr, target_file::String, caller_module::Module; macroname::String, cell_id::SubString{…}, extra_args::Tuple{})inlined£urlQfile:///home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlpathJ/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlsource_packagePlutoDevMacroscallمfrompackage(ex::Expr, target_file::String, caller_module::Module; macroname::String, cell_id::SubString{String}, extra_args::Tuple{})linfo_typeCore.MethodInstancelinefilemacro.jlfunc#frompackage#44parent_modulePlutoDevMacros.FromPackagefrom_ccall_shortfrompackageinlinedãurlpathJ/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlsource_packagecallfrompackagelinfo_typeNothinglinefilemacro.jlfuncfrompackageparent_modulefrom_ccall_shortv_combined(ex::Expr, target::Expr, calling_file::String, caller_module::Module; macroname::String, extra_args::Tuple{})inlined£urlQfile:///home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlpathJ/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlsource_packagePlutoDevMacroscallv_combined(ex::Expr, target::Expr, calling_file::String, caller_module::Module; macroname::String, extra_args::Tuple{})linfo_typeCore.MethodInstanceline4filemacro.jlfunc#_combined#45parent_modulePlutoDevMacros.FromPackagefrom_ccall_shortwvar"@frompackage"(__source__::LineNumberNode, __module__::Module, target::Union{…}, ex::Any, extra_args::Vararg{…})inlined£urlQfile:///home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlpathJ/home/runner/.julia/packages/PlutoDevMacros/P5wei/src/frompackage/macro.jlsource_packagePlutoDevMacroscallِvar"@frompackage"(__source__::LineNumberNode, __module__::Module, target::Union{AbstractString, Expr, Symbol}, ex::Any, extra_args::Vararg{Any})linfo_typeCore.MethodInstancelinegfilemacro.jlfunc@frompackageparent_modulePlutoDevMacros.FromPackagefrom_ccall_short#macroexpand#74inlinedãurlpath./expr.jlsource_packagecall#macroexpand#74linfo_typeNothingline}fileexpr.jlfunc#macroexpand#74parent_modulefrom_ccall_shortmacroexpandinlinedãurlpath./expr.jlsource_packagecallmacroexpandlinfo_typeNothingline{fileexpr.jlfuncmacroexpandparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6G=persist_js_state·has_pluto_hook_features§cell_id$3f7484b3-272d-410d-92b1-ca13e5d7a8b7depends_on_disabled_cells§runtime   

published_object_keysdepends_on_skipped_cells§errored$1a7ba296-52ca-4069-85fa-792d08d77b0equeued¤logsrunning¦outputbody
<div class="markdown"><h3>Example: Differential Sarsa and Q-learning with Mountain Car Task</h3>
<p>In order to apply differential learning to the mountain car task, we need to change the rewards per step.  Previously, the rewards were assigned in a manner appropriate for learning with a discount rate of 1.  The reward of -1 per episode step ensures that policies that finish the task faster have a higher reward.  In the average reward setting, every policy would have an average reward per step of -1 making the task ill posed.  Instead, we can assign a reward of 1 for finishing to the right and 0 at all other steps.  These rewards would produce an ill posed task for <span class="tex">$\gamma &#61; 1$</span> but are perfectly fine for the average reward setting.  Now our learning procedure should find a policy that produces the highest average reward <span class="tex">$\frac&#123;1&#125;&#123;\text&#123;num steps&#125;&#125;$</span> which is maximized when the number of steps to finish an episode is minimized.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Fypersist_js_state·has_pluto_hook_features§cell_id$1a7ba296-52ca-4069-85fa-792d08d77b0edepends_on_disabled_cells§runtime Epublished_object_keysdepends_on_skipped_cells§errored$39eada35-8c3e-4ddc-8df9-7cf9f120928dqueued¤logsrunning¦outputbody[<div class="markdown"><h2>10.5 Differential Semi-gradient <em>n</em>-step Sarsa</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA6Hpersist_js_state·has_pluto_hook_features§cell_id$39eada35-8c3e-4ddc-8df9-7cf9f120928ddepends_on_disabled_cells§runtime fpublished_object_keysdepends_on_skipped_cells§errored$b55d50a4-b039-4240-b434-42f7b724d24dqueued¤logsrunning¦outputbodymsgyUndefVarError: `mc_test` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b55d50a4-b039-4240-b434-42f7b724d24dsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b55d50a4-b039-4240-b434-42f7b724d24dfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6\persist_js_state·has_pluto_hook_features§cell_id$b55d50a4-b039-4240-b434-42f7b724d24ddepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$41c626c7-908d-4ff6-9730-4ad0b8c3cc25queued¤logsrunning¦outputbodymsg UndefVarError: `StateMDPTransitionSampler` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortNcreate_access_control_task(num_servers::Int64, priority_payments::Vector{…})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#62839b2a-398a-4445-87d1-b15ff2acc1d1#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#62839b2a-398a-4445-87d1-b15ff2acc1d1source_packageMaincallRcreate_access_control_task(num_servers::Int64, priority_payments::Vector{Float32})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#62839b2a-398a-4445-87d1-b15ff2acc1d1funccreate_access_control_taskparent_moduleMain.var"workspace#5"from_ccall_shortفrun_access_control_differential_sarsa(max_steps::Int64; num_servers::Int64, priority_payments::Vector{…}, kwargs::@Kwargs{…})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b4af8d87-a6e5-4e09-92b4-b07757f58f7f#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b4af8d87-a6e5-4e09-92b4-b07757f58f7fsource_packageMaincall٧run_access_control_differential_sarsa(max_steps::Int64; num_servers::Int64, priority_payments::Vector{Float32}, kwargs::@Kwargs{β::Float32, α::Float32, ϵ::Float32})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b4af8d87-a6e5-4e09-92b4-b07757f58f7ffunc*#run_access_control_differential_sarsa#121parent_moduleMain.var"workspace#5"from_ccall_shortEfigure_10_5(; numsteps::Int64, α::Float32, β::Float32, ϵ::Float32)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#546a775e-d3c9-4693-9f64-d4c47a84fb9f#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#546a775e-d3c9-4693-9f64-d4c47a84fb9fsource_packageMaincallEfigure_10_5(; numsteps::Int64, α::Float32, β::Float32, ϵ::Float32)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#546a775e-d3c9-4693-9f64-d4c47a84fb9ffunc#figure_10_5#125parent_moduleMain.var"workspace#5"from_ccall_shortfigure_10_5()inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#546a775e-d3c9-4693-9f64-d4c47a84fb9f#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#546a775e-d3c9-4693-9f64-d4c47a84fb9fsource_packageMaincallfigure_10_5()linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#546a775e-d3c9-4693-9f64-d4c47a84fb9ffuncfigure_10_5parent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#41c626c7-908d-4ff6-9730-4ad0b8c3cc25source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#41c626c7-908d-4ff6-9730-4ad0b8c3cc25func##function_wrapped_cell#680parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$41c626c7-908d-4ff6-9730-4ad0b8c3cc25depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$1e9c537a-a731-4b81-8f6a-cb658b52c5bequeued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1e9c537a-a731-4b81-8f6a-cb658b52c5besource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#1e9c537a-a731-4b81-8f6a-cb658b52c5befunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneeconst mountain_car_mdplast_run_timestampA6zJpersist_js_state·has_pluto_hook_features§cell_id$1e9c537a-a731-4b81-8f6a-cb658b52c5bedepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$13e477f0-dc15-46cb-9691-c04a1b4c83c8queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#13e477f0-dc15-46cb-9691-c04a1b4c83c8source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#13e477f0-dc15-46cb-9691-c04a1b4c83c8functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA64persist_js_state·has_pluto_hook_features§cell_id$13e477f0-dc15-46cb-9691-c04a1b4c83c8depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$47710ddd-79d9-464d-b5dd-27180f2d6b31queued¤logsrunning¦outputbodyf<div class="markdown"><h3>Defining the Value Function</h3>
<p>Since we are interested in maximizing the expected value of <span class="tex">$G_t$</span>, it is useful to define functions which calculate this expected value given a state or state action pair Below is the definition of the two types of value functions as well as derived expressions that are used in solution or approximation techniques.  The Bellman equation as well as other definitions are used to derive all of the useful expressions for the value function.</p>
<h4>State Value Function</h4>
<p class="tex">$$\begin&#123;flalign&#125;
v_\pi&#40;s&#41; &amp;\doteq \mathbb&#123;E&#125;_\pi &#91;G_t \mid S_t &#61; s&#93; \tag&#123;Used in Monte Carlo Estimation&#125;\\
&amp;&#61; \sum_a \pi&#40;a \vert s&#41; \mathbb&#123;E&#125;_\pi &#91;G_&#123;t&#125; \mid S_t &#61; s, A_t &#61; a&#93; \tag&#123;exp value def&#125; \\
&amp;&#61; \sum_a \pi&#40;a \vert s&#41; q_\pi&#40;s, a&#41; \tag&#123;by definition of q&#125; \\
&amp;&#61; \sum_a \pi&#40;a \vert s&#41; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; &#91;r &#43; \gamma v_\pi&#40;s^\prime&#41;&#93; \tag&#123;Used in Dynamic Programming when p is available&#125; \\
&amp;&#61; \mathbb&#123;E&#125;_\pi &#91;R_&#123;t&#43;1&#125; &#43; \gamma v_\pi&#40;S_&#123;t&#43;1&#125;&#41; \mid S_t &#61; s&#93; \tag&#123;Used in TD&#40;0&#41; when p is not available&#125;\\
\end&#123;flalign&#125;$$</p>
<h4>State-Action Value Function</h4>
<p class="tex">$$\begin&#123;flalign&#125;
q_\pi&#40;s, a&#41; &amp;\doteq \mathbb&#123;E&#125;_\pi&#91;G_t \mid S_t&#61;s,A_t&#61;a&#93; \tag&#123;Used in Monte Carlo Estimation&#125; \\
&amp; &#61; \mathbb&#123;E&#125;_\pi \left &#91; R_&#123;t&#43;1&#125; &#43; \gamma G_&#123;t&#43;1&#125; \mid S_t &#61; s, A_t &#61; a \right &#93; \tag&#123;by &#40;3.9&#41;&#125; \\
&amp; &#61; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; \mathbb&#123;E&#125;_\pi \left &#91; r &#43; \gamma G_&#123;t&#43;1&#125; \mid S_&#123;t&#43;1&#125; &#61; s^\prime \right &#93; \tag&#123;exp value def&#125;\\
&amp; &#61; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; &#91;r &#43; \gamma v_\pi&#40;s^\prime&#41;&#93; \tag&#123;by definition of v &#40;4.6&#41;&#125; \\
&amp; &#61; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; &#91;r &#43; \gamma\sum_&#123;a^\prime&#125; \pi&#40;a^\prime \vert s^\prime&#41; q_\pi&#40;s^\prime, a^\prime&#41;&#93; \tag&#123;Used in Dynamic Programming when p is available&#125; \\
&amp; &#61; \mathbb&#123;E&#125; &#91;R_&#123;t&#43;1&#125; &#43; \gamma\sum_&#123;a^\prime&#125; \pi&#40;a^\prime \vert s^\prime&#41; q_\pi&#40;s^\prime, a^\prime&#41; \mid S_t &#61; s, A_t &#61; a&#93; \tag&#123;Used in Expected Sarsa when p is not available&#125; \\
\end&#123;flalign&#125;$$</p>
<p>The optimal policy <span class="tex">$\pi_*$</span> will have a value function <span class="tex">$v_&#123;\pi_*&#125;&#40;s&#41;$</span> <span class="tex">$q_&#123;\pi_*&#125;&#40;s, a&#41;$</span> whose values are greather than or equal to any other value function at every state or state action pair.  In short</p>
<p class="tex">$$v_&#123;\pi_*&#125;&#40;s&#41; \geq v_\pi&#40;s&#41; \forall s \in \mathcal&#123;S&#125; \quad \text&#123;and&#125; \quad q_&#123;\pi_*&#125;&#40;s, a&#41; \geq q_\pi&#40;s, a&#41; \forall s \in \mathcal&#123;S&#125;, \forall a \in \mathcal&#123;A&#125;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6@persist_js_state·has_pluto_hook_features§cell_id$47710ddd-79d9-464d-b5dd-27180f2d6b31depends_on_disabled_cells§runtime 蠵published_object_keysdepends_on_skipped_cells§errored$14fe2253-cf2c-4159-a360-1e65f1c82b09queued¤logsrunning¦outputbodyC<div class="markdown"><h4>Distributional Non-Tabular Case</h4>
<h5>Problem conditions</h5>
<ul>
<li><p>All actions can be enumerated: <span class="tex">$\mathcal&#123;A&#125; &#61; \&#123;a_1, a_2, \cdots, a_m\&#125;$</span> but the state space is either infinite or too large to practically count</p>
</li>
<li><p><span class="tex">$p&#40;s^\prime, r \vert s, a&#41;$</span> is available</p>
</li>
</ul>
<p>Previously we considered value estimates in the form of a list.  Since that list is now uncountably large, a different approach, that of approximation, is needed to estimate the value function.  The approximation function must rely on a countable, limited set of information such as a list of parameters <span class="tex">$\mathbf&#123;w&#125;$</span> or a memory of past observations.  Either way, that limited set of information must be used to generalize value estimates accross any state that is encountered.  By construction, this function cannot guarantee that a change to one state value does not affect another, thus the previous goal of optimizing all of the state values is no longer possible.  In order to even define success in this case, a new objective is needed.  Consider the caes of a parameterized function <span class="tex">$\hat v&#40;s, \mathbf&#123;w&#125;&#41;$</span> whose goal is to estimate the true value function of a policy <span class="tex">$v_\pi&#40;s&#41;$</span>.  One natural objective is to find the parameters that minimize the squared error this function has with the true value function under the distribution of states visited under that policy.  This objective is called the <em>value error</em>:</p>
<p class="tex">$$\overline&#123;\text&#123;VE&#125;&#125;&#40;\mathbf&#123;w&#125;&#41; \doteq \sum_&#123;s \in S&#125; \mu&#40;s&#41;&#91;v_\pi&#40;s&#41; - \hat v&#40;s, \mathbf&#123;w&#125;&#41;&#93;^2$$</p>
<p>In Chapter 9, we used stochastic gradient descent to derive an update rule for the parameters in the case of knowning the true value function:</p>
<p class="tex">$$\begin&#123;flalign&#125;
\mathbf&#123;w&#125;_&#123;t&#43;1&#125; &amp; \doteq \mathbf&#123;w&#125;_t - \frac&#123;1&#125;&#123;2&#125; \alpha \nabla &#91;v_\pi&#40;S_t&#41; - \hat v&#40;S_t, \mathbf&#123;w&#125;_t&#41;&#93;^2 \\
&amp; &#61; \mathbf&#123;w&#125;_t &#43; \alpha&#91;v_\pi&#40;S_t&#41; - \hat v&#40;S_t, \mathbf&#123;w&#125;_t&#41;&#93;\nabla\hat v&#40;S_t, \mathbf&#123;w&#125;_t&#41;
\end&#123;flalign&#125;$$</p>
<p>Since we do not know the true value function, we can sample unbiased estimates of it using the methods already described above.  Then the solution techniques would mirror those in the tabular case with the value updates simply replaced with parameter updates using the same sample estimate.</p>
<h5>Solution Techniques</h5>
<p>Since <span class="tex">$p$</span> is available, we can use state value estimates to compute state-action value estimates.  Consider the estimate Bellman optimality equation for state values:</p>
<p class="tex">$$v_* &#61;  \max_&#123;a \in \mathcal&#123;A&#125;&#40;s&#41;&#125; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; \left &#91; r &#43; γ v_* &#40;s^\prime&#41; \right &#93; \: \forall s \in \mathcal&#123;S&#125;$$</p>
<p>This target value can be used in the gradient update as follows:</p>
<p class="tex">$$\mathbf&#123;w&#125;_&#123;t&#43;1&#125; &#61; \mathbf&#123;w&#125;_t &#43; \alpha \left &#91; \max_&#123;a \in \mathcal&#123;A&#125;&#40;s&#41;&#125; \left &#91; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert S_t, a&#41; \left &#91; r &#43; γ \hat v&#40;s^\prime, \mathbf&#123;w&#125;_t&#41; \right &#93; \right &#93;- \hat v&#40;S_t, \mathbf&#123;w&#125;_t&#41; \right &#93;\nabla\hat v&#40;S_t, \mathbf&#123;w&#125;_t&#41;$$</p>
<p>while the optimal policy can be derived as:</p>
<p class="tex">$$\pi&#40;s&#41; &#61; \mathrm&#123;argmax&#125;_a\sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41;&#40; r &#43; \gamma \hat v&#40;s^\prime, \mathbf&#123;w&#125;&#41;&#41;$$</p>
<p>The derivation of the parameter update rule assumed that the sample estimate for <span class="tex">$v_\pi$</span> did not depend on the parameters.  This assumption is violated here as it was in the semi-gradient TD methods from Chapter 9.  Nevertheless, in the linear case, this technique can converge to some bounded region around the true minimum value error.  Updating the parameters in this way is similar to value iteration which used the same target value and swept across the entire state space.  Using this method here highlights the problem with approximation and its connection to the minimum value error objective.  That objective is only defined in terms of the on policy distribution, so in order for this to converge, the states sampled must match the on-policy distribution which would be the greedy policy in this case.  So while the update rule does not explicitely reference the policy &#40;seemingly implying like in Q-learning that we could perform these updates with any policy&#41;, the samples do need to be drawn from the on policy distribution for this to work properly.</p>
<h4>Sample Non-Tabular Case</h4>
<h5>Problem conditions</h5>
<ul>
<li><p>All actions can be enumerated: <span class="tex">$\mathcal&#123;A&#125; &#61; \&#123;a_1, a_2, \cdots, a_m\&#125;$</span> but the state space is either infinite or too large to practically count</p>
</li>
<li><p><span class="tex">$p&#40;s^\prime, r \vert s, a&#41;$</span> is not available</p>
</li>
</ul>
<h5>Solution Techniques</h5>
<p>Finally, we arrive at the case considered at the beginning of Chapter 10 where we must rely on sampling from the environment in the non-tabular case.  Since <span class="tex">$p$</span> is not available, we must instead estimate <span class="tex">$\hat q_\pi&#40;s, a&#41;$</span> for a given policy and proceed with generalized policy iteration as before either with episodic or per step updates to the parameters.  The value error objective can easily be modified to consider all actions as well as states.  Since the actions are enumerable in this case, there is no need to consider the on policy distribution as the error can be minimized across all actions:</p>
<p class="tex">$$\overline&#123;\text&#123;VE&#125;&#125;&#40;\mathbf&#123;w&#125;&#41; \doteq \sum_a \sum_&#123;s \in S&#125; \mu&#40;s&#41;&#91;q_\pi&#40;s, a&#41; - \hat q&#40;s, a, \mathbf&#123;w&#125;&#41;&#93;^2$$</p>
<p>The parameter update will look identical to that for state values with the update target replaced by the true state-action value.  The control algorithms will mirror the tabular case with the gradient update replacing the averaging update.  The techniques are defined by which target value is used:</p>
<ul>
<li><p>Semi-gradient Sarsa: <span class="tex">$q_\pi&#40;s, a&#41; &#61; \mathbb&#123;E&#125; &#91;R_&#123;t&#43;1&#125; &#43; \gamma\sum_&#123;a^\prime&#125; \pi&#40;a^\prime \vert s^\prime&#41; q_\pi&#40;s^\prime, a^\prime&#41; \mid S_t &#61; s, A_t &#61; a&#93;$</span></p>
</li>
<li><p>Gradient Monte Carlo Control: <span class="tex">$q_\pi&#40;s, a&#41; &#61; \mathbb&#123;E&#125;_\pi&#91;G_t \vert S_t &#61; s, A_t &#61; a&#93;$</span></p>
</li>
<li><p>Semi-gradient Q-learning: <span class="tex">$q_*&#40;s, a&#41; &#61; \mathbb&#123;E&#125; \left &#91; R_t &#43; γ \max_&#123;a^\prime&#125; q_*&#40;s^\prime, a^\prime&#41; \mid S_t &#61; s, A_t &#61; a \right &#93;$</span></p>
</li>
</ul>
<p>Note that genearlized policy iteration only works if the policy improvement theorem applies.  In the case of approximation, that is not the case since a policy change cannot be said to only apply to one state.  While many of these techniques can work emphirically, there is no theoretical guarantee that iterating in this manner will produce the optimal policy, even if the approximation is linear.  The only guarantee we can make in that case is that the value function will converge to one that minimizes the value error for the policy at the time.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6B°persist_js_state·has_pluto_hook_features§cell_id$14fe2253-cf2c-4159-a360-1e65f1c82b09depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$5c920177-8e46-49c9-9b95-1a657fdcae4equeued¤logsrunning¦outputbodymsgلUndefVarError: `episode_rewards_dp` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#5c920177-8e46-49c9-9b95-1a657fdcae4esource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#5c920177-8e46-49c9-9b95-1a657fdcae4efunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Øpersist_js_state·has_pluto_hook_features§cell_id$5c920177-8e46-49c9-9b95-1a657fdcae4edepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b5d2776f-4b93-4eaa-8873-c1c4e610e6b0source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b5d2776f-4b93-4eaa-8873-c1c4e610e6b0functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6X}persist_js_state·has_pluto_hook_features§cell_id$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$3c300a2b-4139-4df0-906b-4cae3592cc2bqueued¤logsrunning¦outputbodymsgUndefVarError: `policy_iteration_v` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#3c300a2b-4139-4df0-906b-4cae3592cc2bsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#3c300a2b-4139-4df0-906b-4cae3592cc2bfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassignee"const mountaincar_policy_iterationlast_run_timestampA68Xpersist_js_state·has_pluto_hook_features§cell_id$3c300a2b-4139-4df0-906b-4cae3592cc2bdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bdqueued¤logsrunning¦outputbody?plot_mountaincar_action_values (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6TLpersist_js_state·has_pluto_hook_features§cell_id$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bddepends_on_disabled_cells§runtime*xpublished_object_keysdepends_on_skipped_cellsçerrored$fbf1c64f-1979-4384-a8c6-dc7875174d1fqueued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA6Lpersist_js_state·has_pluto_hook_features§cell_id$fbf1c64f-1979-4384-a8c6-dc7875174d1fdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$0714a1cf-9288-4f1e-ba72-d82608704d69queued¤logsrunning¦outputbodymsgكUndefVarError: `tile_coding_setup` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shortCsetup_mountain_car_tiles(tile_size::Tuple{…}, num_tilings::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527source_packageMaincallPsetup_mountain_car_tiles(tile_size::Tuple{Float32, Float32}, num_tilings::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527funcsetup_mountain_car_tilesparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#0714a1cf-9288-4f1e-ba72-d82608704d69source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#0714a1cf-9288-4f1e-ba72-d82608704d69functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneemc_testlast_run_timestampA6װpersist_js_state·has_pluto_hook_features§cell_id$0714a1cf-9288-4f1e-ba72-d82608704d69depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$f7410fe7-e3d8-4047-8fa7-f076476e9d3aqueued¤logsrunning¦outputbody\<div class="markdown"><h3>Example: Semi-gradient Q-learning on Mountain Car Task</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6E܃persist_js_state·has_pluto_hook_features§cell_id$f7410fe7-e3d8-4047-8fa7-f076476e9d3adepends_on_disabled_cells§runtime Hpublished_object_keysdepends_on_skipped_cells§errored$864450b9-1319-4426-961f-ee6df93463d8queued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93source_packageMaincallIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93funcshow_mountaincar_trajectoryparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#864450b9-1319-4426-961f-ee6df93463d8source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#864450b9-1319-4426-961f-ee6df93463d8func##function_wrapped_cell#418parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Npersist_js_state·has_pluto_hook_features§cell_id$864450b9-1319-4426-961f-ee6df93463d8depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$662759be-282c-460b-adc3-8595475b53c2queued¤logsrunning¦outputbodyl<div class="markdown"><h2>10.4 Deprecating the Discounted Setting</h2>
<p>In a special case of indistinguishable states, we can only use the actions and reward sequences to analyze a continuing task.  For a policy <span class="tex">$\pi$</span>, the average of the discounted returns with discount factor <span class="tex">$\gamma$</span> is always <span class="tex">$\frac&#123;r&#40;\pi&#41;&#125;&#123;1-\gamma&#125;$</span>.  Therefore the <em>ordering</em> of all policies is independent of the discount rate and would match the ordering we get in the average reward setting.  This derivation however depends on states being indistinguishable allowing us to match up the weights on reward sequences from different policies.</p>
<p>We can use discounting in approximate solution methods regardless but then <span class="tex">$\gamma$</span> changes from a problem parameter to a solution method parameter.  Unfortunately, discounting algorithms with function approximation do not optimize discounted value over the on-policy distribution, and thus are not guaranteed to optimze average reward.</p>
<p>The root cause of the problem applying discounting with function approximation is that we have lost the policy improvement theorem which states that a policy <span class="tex">$\pi^\prime$</span> is better than policy <span class="tex">$\pi$</span> if <span class="tex">$v_&#123;\pi^\prime&#125;&#40;s&#41; \geq v_\pi&#40;s&#41; \forall s\in \mathcal&#123;S&#125;$</span>.  Under this theorem we could take a deterministic policy, choose a specific state, and find a new action at that state with a higher expected reward than the current policy.  If the policy is an approximation function that uses states represented by feature vectors, then adjusting the parameters can in general affect the actions at many states including ones that have not been encountered yet.  In fact, with approximate solution methods we cannot guarantee  policy improvement in any setting.  Later we will introduce a theoretical guarantee called the &quot;policy-gradient theorem&quot; but for an alternative class of algorithms based on parametrized policies.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6GHpersist_js_state·has_pluto_hook_features§cell_id$662759be-282c-460b-adc3-8595475b53c2depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$f5e32900-6eb6-4b61-916d-893c0bcaf214queued¤logsrunning¦outputbodyM<script>
	
// Load the library for consistent smooth scrolling
const {default: scrollIntoView} = await import("data:text/javascript;base64,dmFyIFE9ZT0+Im9iamVjdCI9PXR5cGVvZiBlJiZudWxsIT1lJiYxPT09ZS5ub2RlVHlwZSxVPShlLHQpPT4oIXR8fCJoaWRkZW4iIT09ZSkmJiJ2aXNpYmxlIiE9PWUmJiJjbGlwIiE9PWUsQT0oZSx0KT0+e2lmKGUuY2xpZW50SGVpZ2h0PGUuc2Nyb2xsSGVpZ2h0fHxlLmNsaWVudFdpZHRoPGUuc2Nyb2xsV2lkdGgpe2xldCBsPWdldENvbXB1dGVkU3R5bGUoZSxudWxsKTtyZXR1cm4gVShsLm92ZXJmbG93WSx0KXx8VShsLm92ZXJmbG93WCx0KXx8KGU9PntsZXQgdD0oZT0+e2lmKCFlLm93bmVyRG9jdW1lbnR8fCFlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcpcmV0dXJuIG51bGw7dHJ5e3JldHVybiBlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZnJhbWVFbGVtZW50fWNhdGNoe3JldHVybiBudWxsfX0pKGUpO3JldHVybiEhdCYmKHQuY2xpZW50SGVpZ2h0PGUuc2Nyb2xsSGVpZ2h0fHx0LmNsaWVudFdpZHRoPGUuc2Nyb2xsV2lkdGgpfSkoZSl9cmV0dXJuITF9LFg9KGUsdCxsLG8sbixyLGkscyk9PnI8ZSYmaT50fHxyPmUmJmk8dD8wOnI8PWUmJnM8PWx8fGk+PXQmJnM+PWw/ci1lLW86aT50JiZzPGx8fHI8ZSYmcz5sP2ktdCtuOjAsJD1lPT5lLnBhcmVudEVsZW1lbnQ/PyhlLmdldFJvb3ROb2RlKCkuaG9zdHx8bnVsbCksdHQ9KGUsdCk9Pnt2YXIgbCxvLG4scjtpZih0eXBlb2YgZG9jdW1lbnQ+InUiKXJldHVybltdO2xldHtzY3JvbGxNb2RlOmksYmxvY2s6cyxpbmxpbmU6YSxib3VuZGFyeTpoLHNraXBPdmVyZmxvd0hpZGRlbkVsZW1lbnRzOnV9PXQsZz0iZnVuY3Rpb24iPT10eXBlb2YgaD9oOmU9PmUhPT1oO2lmKCFRKGUpKXRocm93IFR5cGVFcnJvcigiSW52YWxpZCB0YXJnZXQiKTtsZXQgdj1kb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50fHxkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsbT1bXSx3PWU7Zm9yKDtRKHcpJiZnKHcpOyl7aWYoKHc9JCh3KSk9PT12KXttLnB1c2godyk7YnJlYWt9bnVsbCE9dyYmdz09PWRvY3VtZW50LmJvZHkmJkEodykmJiFBKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCl8fG51bGwhPXcmJkEodyx1KSYmbS5wdXNoKHcpfWxldCBXPW51bGwhPShvPW51bGw9PShsPXdpbmRvdy52aXN1YWxWaWV3cG9ydCk/dm9pZCAwOmwud2lkdGgpP286aW5uZXJXaWR0aCxIPW51bGwhPShyPW51bGw9PShuPXdpbmRvdy52aXN1YWxWaWV3cG9ydCk/dm9pZCAwOm4uaGVpZ2h0KT9yOmlubmVySGVpZ2h0LHtzY3JvbGxYOl8sc2Nyb2xsWTp4fT13aW5kb3cse2hlaWdodDpFLHdpZHRoOlQsdG9wOk4scmlnaHQ6TCxib3R0b206WSxsZWZ0OkN9PWUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksUj0ic3RhcnQiPT09c3x8Im5lYXJlc3QiPT09cz9OOiJlbmQiPT09cz9ZOk4rRS8yLFY9ImNlbnRlciI9PT1hP0MrVC8yOiJlbmQiPT09YT9MOkMsQj1bXTtmb3IobGV0IEQ9MDtEPG0ubGVuZ3RoO0QrKyl7bGV0IE89bVtEXSx7aGVpZ2h0Omosd2lkdGg6SSx0b3A6UyxyaWdodDpxLGJvdHRvbTp6LGxlZnQ6Rn09Ty5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtpZigiaWYtbmVlZGVkIj09PWkmJk4+PTAmJkM+PTAmJlk8PUgmJkw8PVcmJk4+PVMmJlk8PXomJkM+PUYmJkw8PXEpYnJlYWs7bGV0IEc9Z2V0Q29tcHV0ZWRTdHlsZShPKSxKPXBhcnNlSW50KEcuYm9yZGVyTGVmdFdpZHRoLDEwKSxLPXBhcnNlSW50KEcuYm9yZGVyVG9wV2lkdGgsMTApLFA9cGFyc2VJbnQoRy5ib3JkZXJSaWdodFdpZHRoLDEwKSxaPXBhcnNlSW50KEcuYm9yZGVyQm90dG9tV2lkdGgsMTApLGVlPTAsZXQ9MCxlbD0ib2Zmc2V0V2lkdGgiaW4gTz9PLm9mZnNldFdpZHRoLU8uY2xpZW50V2lkdGgtSi1QOjAsZW89Im9mZnNldEhlaWdodCJpbiBPP08ub2Zmc2V0SGVpZ2h0LU8uY2xpZW50SGVpZ2h0LUstWjowLGVuPSJvZmZzZXRXaWR0aCJpbiBPPzA9PT1PLm9mZnNldFdpZHRoPzA6SS9PLm9mZnNldFdpZHRoOjAsZXI9Im9mZnNldEhlaWdodCJpbiBPPzA9PT1PLm9mZnNldEhlaWdodD8wOmovTy5vZmZzZXRIZWlnaHQ6MDtpZih2PT09TyllZT0ic3RhcnQiPT09cz9SOiJlbmQiPT09cz9SLUg6Im5lYXJlc3QiPT09cz9YKHgseCtILEgsSyxaLHgrUix4K1IrRSxFKTpSLUgvMixldD0ic3RhcnQiPT09YT9WOiJjZW50ZXIiPT09YT9WLVcvMjoiZW5kIj09PWE/Vi1XOlgoXyxfK1csVyxKLFAsXytWLF8rVitULFQpLGVlPU1hdGgubWF4KDAsZWUreCksZXQ9TWF0aC5tYXgoMCxldCtfKTtlbHNle2VlPSJzdGFydCI9PT1zP1ItUy1LOiJlbmQiPT09cz9SLXorWitlbzoibmVhcmVzdCI9PT1zP1goUyx6LGosSyxaK2VvLFIsUitFLEUpOlItKFMrai8yKStlby8yLGV0PSJzdGFydCI9PT1hP1YtRi1KOiJjZW50ZXIiPT09YT9WLShGK0kvMikrZWwvMjoiZW5kIj09PWE/Vi1xK1ArZWw6WChGLHEsSSxKLFArZWwsVixWK1QsVCk7bGV0e3Njcm9sbExlZnQ6ZWksc2Nyb2xsVG9wOmVkfT1PO2VlPU1hdGgubWF4KDAsTWF0aC5taW4oZWQrZWUvZXIsTy5zY3JvbGxIZWlnaHQtai9lcitlbykpLGV0PU1hdGgubWF4KDAsTWF0aC5taW4oZWkrZXQvZW4sTy5zY3JvbGxXaWR0aC1JL2VuK2VsKSksUis9ZWQtZWUsVis9ZWktZXR9Qi5wdXNoKHtlbDpPLHRvcDplZSxsZWZ0OmV0fSl9cmV0dXJuIEJ9LGY9ZT0+e3ZhciB0O3JldHVybiExPT09ZT97YmxvY2s6ImVuZCIsaW5saW5lOiJuZWFyZXN0In06KHQ9ZSk9PT1PYmplY3QodCkmJjAhPT1PYmplY3Qua2V5cyh0KS5sZW5ndGg/ZTp7YmxvY2s6InN0YXJ0IixpbmxpbmU6Im5lYXJlc3QifX07ZnVuY3Rpb24gYyhlLHQpe3ZhciBsO2lmKCFlLmlzQ29ubmVjdGVkfHwhKGU9PntsZXQgdD1lO2Zvcig7dCYmdC5wYXJlbnROb2RlOyl7aWYodC5wYXJlbnROb2RlPT09ZG9jdW1lbnQpcmV0dXJuITA7dD10LnBhcmVudE5vZGUgaW5zdGFuY2VvZiBTaGFkb3dSb290P3QucGFyZW50Tm9kZS5ob3N0OnQucGFyZW50Tm9kZX1yZXR1cm4hMX0pKGUpKXJldHVybjtpZigib2JqZWN0Ij09dHlwZW9mKGw9dCkmJiJmdW5jdGlvbiI9PXR5cGVvZiBsLmJlaGF2aW9yKXJldHVybiB0LmJlaGF2aW9yKHR0KGUsdCkpO2xldCBvPSJib29sZWFuIj09dHlwZW9mIHR8fG51bGw9PXQ/dm9pZCAwOnQuYmVoYXZpb3I7Zm9yKGxldHtlbDpuLHRvcDpyLGxlZnQ6aX1vZiB0dChlLGYodCkpKW4uc2Nyb2xsKHt0b3A6cixsZWZ0OmksYmVoYXZpb3I6b30pfXZhciBkLHA9KCk9PihkfHwoZD0icGVyZm9ybWFuY2UiaW4gd2luZG93P3BlcmZvcm1hbmNlLm5vdy5iaW5kKHBlcmZvcm1hbmNlKTpEYXRlLm5vdyksZCgpKTtmdW5jdGlvbiBiKGUpe2xldCB0PU1hdGgubWluKChwKCktZS5zdGFydFRpbWUpL2UuZHVyYXRpb24sMSksbD1lLmVhc2UodCksbz1lLnN0YXJ0WCsoZS54LWUuc3RhcnRYKSpsLG49ZS5zdGFydFkrKGUueS1lLnN0YXJ0WSkqbDtlLm1ldGhvZChvLG4sdCxsKSxvIT09ZS54fHxuIT09ZS55P3JlcXVlc3RBbmltYXRpb25GcmFtZSgoKT0+YihlKSk6ZS5jYigpfWZ1bmN0aW9uIHkoZSx0LGwpe2xldCBvPWFyZ3VtZW50cy5sZW5ndGg+MyYmdm9pZCAwIT09YXJndW1lbnRzWzNdP2FyZ3VtZW50c1szXTo2MDAsbj1hcmd1bWVudHMubGVuZ3RoPjQmJnZvaWQgMCE9PWFyZ3VtZW50c1s0XT9hcmd1bWVudHNbNF06ZT0+MSstLWUqZSplKmUqZSxyPWFyZ3VtZW50cy5sZW5ndGg+NT9hcmd1bWVudHNbNV06dm9pZCAwLGk9YXJndW1lbnRzLmxlbmd0aD42P2FyZ3VtZW50c1s2XTp2b2lkIDAscz1lLnNjcm9sbExlZnQsYT1lLnNjcm9sbFRvcDtiKHtzY3JvbGxhYmxlOmUsbWV0aG9kKHQsbCxvLG4pe2xldCByPU1hdGguY2VpbCh0KSxzPU1hdGguY2VpbChsKTtlLnNjcm9sbExlZnQ9cixlLnNjcm9sbFRvcD1zLGk/Lih7dGFyZ2V0OmUsZWxhcHNlZDpvLHZhbHVlOm4sbGVmdDpyLHRvcDpzfSl9LHN0YXJ0VGltZTpwKCksc3RhcnRYOnMsc3RhcnRZOmEseDp0LHk6bCxkdXJhdGlvbjpvLGVhc2U6bixjYjpyfSl9dmFyIE09ZT0+ZSYmIWUuYmVoYXZpb3J8fCJzbW9vdGgiPT09ZS5iZWhhdmlvcixrPWZ1bmN0aW9uKGUsdCl7bGV0IGw9dHx8e307cmV0dXJuIE0obCk/YyhlLHtibG9jazpsLmJsb2NrLGlubGluZTpsLmlubGluZSxzY3JvbGxNb2RlOmwuc2Nyb2xsTW9kZSxib3VuZGFyeTpsLmJvdW5kYXJ5LHNraXBPdmVyZmxvd0hpZGRlbkVsZW1lbnRzOmwuc2tpcE92ZXJmbG93SGlkZGVuRWxlbWVudHMsYmVoYXZpb3I6ZT0+UHJvbWlzZS5hbGwoZS5yZWR1Y2UoKGUsdCk9PntsZXR7ZWw6byxsZWZ0Om4sdG9wOnJ9PXQsaT1vLnNjcm9sbExlZnQscz1vLnNjcm9sbFRvcDtyZXR1cm4gaT09PW4mJnM9PT1yP2U6Wy4uLmUsbmV3IFByb21pc2UoZT0+eShvLG4scixsLmR1cmF0aW9uLGwuZWFzZSwoKT0+ZSh7ZWw6byxsZWZ0OltpLG5dLHRvcDpbcyxyXX0pLGwub25TY3JvbGxDaGFuZ2UpKV19LFtdKSl9KTpQcm9taXNlLnJlc29sdmUoYyhlLHQpKX07ZXhwb3J0e2sgYXMgZGVmYXVsdH07")

const indent = true
const aside = true
const title_text = "Table of Contents"
const include_definitions = false


const tocNode = html`<nav class="plutoui-toc">
	<header>
	 <span class="toc-toggle open-toc"></span>
	 <span class="toc-toggle closed-toc"></span>
	 ${title_text}
	</header>
	<section></section>
</nav>`

tocNode.classList.toggle("aside", aside)
tocNode.classList.toggle("indent", indent)


const getParentCell = el => el.closest("pluto-cell")

const getHeaders = () => {
	const depth = Math.max(1, Math.min(6, 3)) // should be in range 1:6
	const range = Array.from({length: depth}, (x, i) => i+1) // [1, ..., depth]
	
	const selector = [
		...(include_definitions ? [
			`pluto-notebook pluto-cell .pluto-docs-binding`, 
			`pluto-notebook pluto-cell assignee:not(:empty)`, 
		] : []),
		...range.map(i => `pluto-notebook pluto-cell h${i}`)
	].join(",")
	return Array.from(document.querySelectorAll(selector)).filter(el => 
		// exclude headers inside of a pluto-docs-binding block
		!(el.nodeName.startsWith("H") && el.closest(".pluto-docs-binding"))
	)
}


const document_click_handler = (event) => {
	const path = (event.path || event.composedPath())
	const toc = path.find(elem => elem?.classList?.contains?.("toc-toggle"))
	if (toc) {
		event.stopImmediatePropagation()
		toc.closest(".plutoui-toc").classList.toggle("hide")
	}
}

document.addEventListener("click", document_click_handler)


const header_to_index_entry_map = new Map()
const currently_highlighted_set = new Set()

const last_toc_element_click_time = { current: 0 }

const intersection_callback = (ixs) => {
	let on_top = ixs.filter(ix => ix.intersectionRatio > 0 && ix.intersectionRect.y < ix.rootBounds.height / 2)
	if(on_top.length > 0){
		currently_highlighted_set.forEach(a => a.classList.remove("in-view"))
		currently_highlighted_set.clear()
		on_top.slice(0,1).forEach(i => {
			let div = header_to_index_entry_map.get(i.target)
			div.classList.add("in-view")
			currently_highlighted_set.add(div)
			
			/// scroll into view
			/*
			const toc_height = tocNode.offsetHeight
			const div_pos = div.offsetTop
			const div_height = div.offsetHeight
			const current_scroll = tocNode.scrollTop
			const header_height = tocNode.querySelector("header").offsetHeight
			
			const scroll_to_top = div_pos - header_height
			const scroll_to_bottom = div_pos + div_height - toc_height
			
			// if we set a scrollTop, then the browser will stop any currently ongoing smoothscroll animation. So let's only do this if you are not currently in a smoothscroll.
			if(Date.now() - last_toc_element_click_time.current >= 2000)
				if(current_scroll < scroll_to_bottom){
					tocNode.scrollTop = scroll_to_bottom
				} else if(current_scroll > scroll_to_top){
					tocNode.scrollTop = scroll_to_top
				}
			*/
		})
	}
}
let intersection_observer_1 = new IntersectionObserver(intersection_callback, {
	root: null, // i.e. the viewport
  	threshold: 1,
	rootMargin: "-15px", // slightly smaller than the viewport
	// delay: 100,
})
let intersection_observer_2 = new IntersectionObserver(intersection_callback, {
	root: null, // i.e. the viewport
  	threshold: 1,
	rootMargin: "15px", // slightly larger than the viewport
	// delay: 100,
})

const render = (elements) => {
	header_to_index_entry_map.clear()
	currently_highlighted_set.clear()
	intersection_observer_1.disconnect()
	intersection_observer_2.disconnect()

		let last_level = `H1`
	return html`${elements.map(h => {
	const parent_cell = getParentCell(h)

		let [className, title_el] = h.matches(`.pluto-docs-binding`) ? ["pluto-docs-binding-el", h.firstElementChild] : [h.nodeName, h]

	const a = html`<a 
		class="${className}" 
		title="${title_el.innerText}"
		href="#${parent_cell.id}"
	>${title_el.innerHTML}</a>`
	/* a.onmouseover=()=>{
		parent_cell.firstElementChild.classList.add(
			'highlight-pluto-cell-shoulder'
		)
	}
	a.onmouseout=() => {
		parent_cell.firstElementChild.classList.remove(
			'highlight-pluto-cell-shoulder'
		)
	} */
		
		
	a.onclick=(e) => {
		e.preventDefault();
		last_toc_element_click_time.current = Date.now()
		scrollIntoView(h, {
			behavior: 'smooth', 
			block: 'start',
		}).then(() => 
			// sometimes it doesn't scroll to the right place
			// solution: try a second time!
			scrollIntoView(h, {
				behavior: 'smooth', 
				block: 'start',
			})
	   )
	}

	const row =  html`<div class="toc-row ${className} after-${last_level}">${a}</div>`
		intersection_observer_1.observe(title_el)
		intersection_observer_2.observe(title_el)
		header_to_index_entry_map.set(title_el, row)

	if(className.startsWith("H"))
		last_level = className
		
	return row
})}`
}

const invalidated = { current: false }

const updateCallback = () => {
	if (!invalidated.current) {
		tocNode.querySelector("section").replaceWith(
			html`<section>${render(getHeaders())}</section>`
		)
	}
}
updateCallback()
setTimeout(updateCallback, 100)
setTimeout(updateCallback, 1000)
setTimeout(updateCallback, 5000)

const notebook = document.querySelector("pluto-notebook")


// We have a mutationobserver for each cell:
const mut_observers = {
	current: [],
}

const createCellObservers = () => {
	mut_observers.current.forEach((o) => o.disconnect())
	mut_observers.current = Array.from(notebook.querySelectorAll("pluto-cell")).map(el => {
		const o = new MutationObserver(updateCallback)
		o.observe(el, {attributeFilter: ["class"]})
		return o
	})
}
createCellObservers()

// And one for the notebook's child list, which updates our cell observers:
const notebookObserver = new MutationObserver(() => {
	updateCallback()
	createCellObservers()
})
notebookObserver.observe(notebook, {childList: true})

// And finally, an observer for the document.body classList, to make sure that the toc also works when it is loaded during notebook initialization
const bodyClassObserver = new MutationObserver(updateCallback)
bodyClassObserver.observe(document.body, {attributeFilter: ["class"]})

// Hide/show the ToC when the screen gets small
let match_listener = () => 
	tocNode.classList.toggle("hide", (tocNode.closest("pluto-editor") ?? document.body).scrollWidth < 1000)
for(let s of [1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000]) {
	let m = matchMedia(`(max-width: ${s}px)`)
	m.addListener(match_listener)
	invalidation.then(() => m.removeListener(match_listener))
}
match_listener()

invalidation.then(() => {
	invalidated.current = true
	intersection_observer_1.disconnect()
	intersection_observer_2.disconnect()
	notebookObserver.disconnect()
	bodyClassObserver.disconnect()
	mut_observers.current.forEach((o) => o.disconnect())
	document.removeEventListener("click", document_click_handler)
})

return tocNode
</script>
<style>
@media not print {

.plutoui-toc {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Cantarell, "Apple Color Emoji",
		"Segoe UI Emoji", "Segoe UI Symbol", system-ui, sans-serif;
	--main-bg-color: #fafafa;
	--pluto-output-color: hsl(0, 0%, 36%);
	--pluto-output-h-color: hsl(0, 0%, 21%);
	--sidebar-li-active-bg: rgb(235, 235, 235);
	--icon-filter: unset;
}

@media (prefers-color-scheme: dark) {
	.plutoui-toc {
		--main-bg-color: #303030;
		--pluto-output-color: hsl(0, 0%, 90%);
		--pluto-output-h-color: hsl(0, 0%, 97%);
		--sidebar-li-active-bg: rgb(82, 82, 82);
		--icon-filter: invert(1);
	}
}

.plutoui-toc.aside {
	color: var(--pluto-output-color);
	position: fixed;
	right: 1rem;
	top: 5rem;
	width: min(80vw, 300px);
	padding: 0.5rem;
	padding-top: 0em;
	/* border: 3px solid rgba(0, 0, 0, 0.15); */
	border-radius: 10px;
	/* box-shadow: 0 0 11px 0px #00000010; */
	max-height: calc(100vh - 5rem - 90px);
	overflow: auto;
	z-index: 40;
	background-color: var(--main-bg-color);
	transition: transform 300ms cubic-bezier(0.18, 0.89, 0.45, 1.12);
}

.plutoui-toc.aside.hide {
	transform: translateX(calc(100% - 28px));
}
.plutoui-toc.aside.hide section {
	display: none;
}
.plutoui-toc.aside.hide header {
	margin-bottom: 0em;
	padding-bottom: 0em;
	border-bottom: none;
}
}  /* End of Media print query */
.plutoui-toc.aside.hide .open-toc,
.plutoui-toc.aside:not(.hide) .closed-toc,
.plutoui-toc:not(.aside) .closed-toc {
	display: none;
}

@media (prefers-reduced-motion) {
  .plutoui-toc.aside {
	transition-duration: 0s;
  }
}

.toc-toggle {
	cursor: pointer;
    padding: 1em;
    margin: -1em;
    margin-right: -0.7em;
    line-height: 1em;
    display: flex;
}

.toc-toggle::before {
    content: "";
    display: inline-block;
    height: 1em;
    width: 1em;
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/list-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LW88L3RpdGxlPjxsaW5lIHgxPSIxNjAiIHkxPSIxNDQiIHgyPSI0NDgiIHkyPSIxNDQiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozMnB4Ii8+PGxpbmUgeDE9IjE2MCIgeTE9IjI1NiIgeDI9IjQ0OCIgeTI9IjI1NiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjMycHgiLz48bGluZSB4MT0iMTYwIiB5MT0iMzY4IiB4Mj0iNDQ4IiB5Mj0iMzY4IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MzJweCIvPjxjaXJjbGUgY3g9IjgwIiBjeT0iMTQ0IiByPSIxNiIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzAwMDtzdHJva2UtbGluZWNhcDpyb3VuZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLXdpZHRoOjMycHgiLz48Y2lyY2xlIGN4PSI4MCIgY3k9IjI1NiIgcj0iMTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDozMnB4Ii8+PGNpcmNsZSBjeD0iODAiIGN5PSIzNjgiIHI9IjE2IiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6MzJweCIvPjwvc3ZnPg==");
    background-size: 1em;
	filter: var(--icon-filter);
}

.aside .toc-toggle.open-toc:hover::before {
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/arrow-forward-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LWE8L3RpdGxlPjxwb2x5bGluZSBwb2ludHM9IjI2OCAxMTIgNDEyIDI1NiAyNjggNDAwIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NDhweCIvPjxsaW5lIHgxPSIzOTIiIHkxPSIyNTYiIHgyPSIxMDAiIHkyPSIyNTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDo0OHB4Ii8+PC9zdmc+");
}
.aside .toc-toggle.closed-toc:hover::before {
    background-image: url("https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/arrow-back-outline.svg");
	/* generated using https://dopiaza.org/tools/datauri/index.php */
    background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PHRpdGxlPmlvbmljb25zLXY1LWE8L3RpdGxlPjxwb2x5bGluZSBwb2ludHM9IjI0NCA0MDAgMTAwIDI1NiAyNDQgMTEyIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2Utd2lkdGg6NDhweCIvPjxsaW5lIHgxPSIxMjAiIHkxPSIyNTYiIHgyPSI0MTIiIHkyPSIyNTYiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOiMwMDA7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDo0OHB4Ii8+PC9zdmc+");
}



.plutoui-toc header {
	display: flex;
	align-items: center;
	gap: .3em;
	font-size: 1.5em;
	/* margin-top: -0.1em; */
	margin-bottom: 0.4em;
	padding: 0.5rem;
	margin-left: 0;
	margin-right: 0;
	font-weight: bold;
	/* border-bottom: 2px solid rgba(0, 0, 0, 0.15); */
	position: sticky;
	top: 0px;
	background: var(--main-bg-color);
	z-index: 41;
}
.plutoui-toc.aside header {
	padding-left: 0;
	padding-right: 0;
}

.plutoui-toc section .toc-row {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	padding: .1em;
	border-radius: .2em;
}

.plutoui-toc section .toc-row.H1 {
	margin-top: 1em;
}


.plutoui-toc.aside section .toc-row.in-view {
	background: var(--sidebar-li-active-bg);
}


	
.highlight-pluto-cell-shoulder {
	background: rgba(0, 0, 0, 0.05);
	background-clip: padding-box;
}

.plutoui-toc section a {
	text-decoration: none;
	font-weight: normal;
	color: var(--pluto-output-color);
}
.plutoui-toc section a:hover {
	color: var(--pluto-output-h-color);
}

.plutoui-toc.indent section a.H1 {
	font-weight: 700;
	line-height: 1em;
}

.plutoui-toc.indent section .after-H2 a { padding-left: 10px; }
.plutoui-toc.indent section .after-H3 a { padding-left: 20px; }
.plutoui-toc.indent section .after-H4 a { padding-left: 30px; }
.plutoui-toc.indent section .after-H5 a { padding-left: 40px; }
.plutoui-toc.indent section .after-H6 a { padding-left: 50px; }

.plutoui-toc.indent section a.H1 { padding-left: 0px; }
.plutoui-toc.indent section a.H2 { padding-left: 10px; }
.plutoui-toc.indent section a.H3 { padding-left: 20px; }
.plutoui-toc.indent section a.H4 { padding-left: 30px; }
.plutoui-toc.indent section a.H5 { padding-left: 40px; }
.plutoui-toc.indent section a.H6 { padding-left: 50px; }


.plutoui-toc.indent section a.pluto-docs-binding-el,
.plutoui-toc.indent section a.ASSIGNEE
	{
	font-family: JuliaMono, monospace;
	font-size: .8em;
	/* background: black; */
	font-weight: 700;
    font-style: italic;
	color: var(--cm-var-color); /* this is stealing a variable from Pluto, but it's fine if that doesnt work */
}
.plutoui-toc.indent section a.pluto-docs-binding-el::before,
.plutoui-toc.indent section a.ASSIGNEE::before
	{
	content: "> ";
	opacity: .3;
}
</style>
mimetext/htmlrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$f5e32900-6eb6-4b61-916d-893c0bcaf214depends_on_disabled_cells§runtime%`published_object_keysdepends_on_skipped_cellsçerrored$e1abf8c7-06b8-4cd5-b557-1d187004bdf1queued¤logsrunning¦outputbody<<div class="markdown"><blockquote>
<h3><em>Exercise 10.2</em></h3>
<p>Give pseudocode for semi-gradient one-step <em>Expected</em> Sarsa for control.</p>
</blockquote>
<p>Use the same pseudocode given for semi-gradient one-step Sarsa but with the following change to the weight update step in the non-terminal case:</p>
<p class="tex">$$\mathbf&#123;w&#125; \leftarrow \mathbf&#123;w&#125; &#43; \alpha&#91;R &#43; \gamma \sum_a \pi&#40;a|S^\prime&#41;\hat q&#40;S^\prime, a, \mathbf&#123;w&#125;&#41; - \hat q&#40;S, A, \mathbf&#123;w&#125;&#41; &#93; \nabla \hat q&#40;S, A, \mathbf&#123;w&#125;&#41;$$</p>
<p>where <span class="tex">$\pi$</span> is the currently used policy which is <span class="tex">$\epsilon$</span> greedy with respect to <span class="tex">$\hat q$</span>.  See complete implementation below. </p>
</div>mimetext/htmlrootassigneelast_run_timestampA6EEpersist_js_state·has_pluto_hook_features§cell_id$e1abf8c7-06b8-4cd5-b557-1d187004bdf1depends_on_disabled_cells§runtime eZpublished_object_keysdepends_on_skipped_cells§errored$b76551e0-c027-4682-b5ae-bba7ea2b987aqueued¤logsrunning¦outputbodymsgyUndefVarError: `mc_test` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b76551e0-c027-4682-b5ae-bba7ea2b987asource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b76551e0-c027-4682-b5ae-bba7ea2b987afunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6:Ұpersist_js_state·has_pluto_hook_features§cell_id$b76551e0-c027-4682-b5ae-bba7ea2b987adepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$d8d5db17-d89c-47db-b258-6ad1635478b7queued¤logsrunning¦outputbody@plot_mountaincar_action_values (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$d8d5db17-d89c-47db-b258-6ad1635478b7depends_on_disabled_cells§runtime @3published_object_keysdepends_on_skipped_cellsçerrored$78087a57-33a0-4581-81de-926476090931queued¤logsrunning¦outputbodymsg|UndefVarError: `policy_num` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#78087a57-33a0-4581-81de-926476090931source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#78087a57-33a0-4581-81de-926476090931functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Vpersist_js_state·has_pluto_hook_features§cell_id$78087a57-33a0-4581-81de-926476090931depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$69fb26ed-763e-44ad-9b70-193e5a1a09b9queued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA6=Ypersist_js_state·has_pluto_hook_features§cell_id$69fb26ed-763e-44ad-9b70-193e5a1a09b9depends_on_disabled_cells§runtimeBpublished_object_keysdepends_on_skipped_cells§errored$35d59eae-77fd-11ef-2790-35dd5a834060queued¤logsrunning¦outputbodyV<div class="markdown"><h1>Chapter 10: On-policy Control with Approximation</h1>
</div>mimetext/htmlrootassigneelast_run_timestampA6@;persist_js_state·has_pluto_hook_features§cell_id$35d59eae-77fd-11ef-2790-35dd5a834060depends_on_disabled_cells§runtime 1published_object_keysdepends_on_skipped_cells§errored$5f8b0254-88f4-4d19-ade1-8e7c40941b43queued¤logsrunning¦outputbodymsgUndefVarError: `SparseVector` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing SparseArrays in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#5f8b0254-88f4-4d19-ade1-8e7c40941b43source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#5f8b0254-88f4-4d19-ade1-8e7c40941b43functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$5f8b0254-88f4-4d19-ade1-8e7c40941b43depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$546a775e-d3c9-4693-9f64-d4c47a84fb9fqueued¤logsrunning¦outputbody,figure_10_5 (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6Mpersist_js_state·has_pluto_hook_features§cell_id$546a775e-d3c9-4693-9f64-d4c47a84fb9fdepends_on_disabled_cells§runtimeupublished_object_keysdepends_on_skipped_cellsçerrored$6351304f-50ac-4755-86e1-cd4680f2d803queued¤logsrunning¦outputbody<div class="markdown"><h2>10.1 Episodic Semi-gradient Control</h2>
<p>It is straightforward to extend the semi-gradient prediction methods in Chapter 9 to action values.  We simply consider examples of the form <span class="tex">$S_t, A_t \rightarrow U_t$</span> where <span class="tex">$U_t$</span> is any of the previously described update targets such as the Monte Carlo Return &#40;<span class="tex">$G_t$</span>&#41;.  The new gradient-decent update for action-value prediction is:</p>
<p class="tex">$$\mathbf&#123;w&#125;_&#123;t&#43;1&#125; \doteq \alpha \left &#91; U_t - \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_t&#41; \right &#93; \nabla \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_t&#41;$$</p>
<p>For example, the one-step Sarsa update is:</p>
<p class="tex">$$\mathbf&#123;w&#125;_&#123;t&#43;1&#125; \doteq \alpha \left &#91; R_&#123;t&#43;1&#125; &#43; \gamma \hat q&#40;S_&#123;t&#43;1&#125;, A_&#123;t&#43;1&#125;, \mathbf&#123;w&#125;_t&#41; - \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_t&#41; \right &#93; \nabla \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_t&#41;$$</p>
<p>If the action set is discrete, then at the next state <span class="tex">$S_&#123;t&#43;1&#125;$</span> we can compute <span class="tex">$\hat q&#40;S_&#123;t&#43;1&#125;, a, \mathbf&#123;w&#125;_t&#41;$</span> for every action and then find the greedy action <span class="tex">$A^*_&#123;t&#43;1&#125; &#61; \text&#123;argmax&#125;_a\hat q&#40;S_&#123;t&#43;1&#125;, a, \mathbf&#123;w&#125;_t&#41;$</span>.  Policy improvement is then done by changing the estimation policy to a soft approximation of the greedy policy such as the <span class="tex">$\epsilon$</span>-greedy policy.  Actions are selected according to this same policy.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6BŠpersist_js_state·has_pluto_hook_features§cell_id$6351304f-50ac-4755-86e1-cd4680f2d803depends_on_disabled_cells§runtime  published_object_keysdepends_on_skipped_cells§errored$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6queued¤logsrunning¦outputbody*<div class="markdown"><h3>Semi-gradient Dynamic Programming</h3>
<p>Typically, to solve the control problem we require action-value estimates.  Even in the non-tabular case; however, we may have access to the transition distribution of an MDP.  A simple example of this is a deterministic problem in which there may be an uncountable number of states, but the transition dynamics are known exactly.  In this case, one can reconstruct the action values from the state values as follows:</p>
<p class="tex">$$\hat q&#40;s, a&#41; &#61; \sum_&#123;s^\prime, r&#125;p&#40;s^\prime, r \vert s, a&#41;\left &#40;r &#43; \gamma \hat v&#40;s^\prime&#41; \right &#41; &#61; \sum_&#123;s^\prime&#125;p&#40;s^\prime \vert s, a&#41; \left&#91; r&#40;s^\prime, s, a&#41; &#43; \gamma \hat v&#40;s^\prime&#41; \right &#93;$$</p>
<p>In the case of a deterministic problem there is only one transition state <span class="tex">$s^\prime &#61; t&#40;s, a&#41;$</span> where <span class="tex">$t$</span> is the deterministic mapping function.  Then the formula simplifies to <span class="tex">$\hat q&#40;s, a&#41; &#61; r&#40;s, a&#41; &#43; \hat v&#40;t&#40;s, a&#41;&#41;$</span>.  We can update the parameters <span class="tex">$\mathbf&#123;w&#125;$</span> for some value function <span class="tex">$\hat v&#40;s, \mathbf&#123;w&#125;&#41;$</span> using the techniques in Chapter 9.  Then, to derive the greedy policy, we can use </p>
<p class="tex">$$\pi&#40;s&#41; &#61; \text&#123;argmax&#125;_a \left &#91; r&#40;s, a&#41; &#43; \gamma \sum_&#123;s^\prime&#125;p&#40;s^\prime \vert s, a&#41; \hat v&#40;s^\prime&#41; \right &#93;$$</p>
<p>From tabular dynamic programming, we have the following update rule for the optimal state value function:</p>
<p class="tex">$$v_*&#40;s&#41; &#61; \max_a \sum_&#123;s^\prime&#125;p&#40;s^\prime \vert s, a&#41; \left&#91; r&#40;s^\prime, s, a&#41; &#43; \gamma v_*&#40;s^\prime&#41; \right &#93;$$</p>
<p>If the right side expression uses the approximate value function, then it is available to use as an update target instead of the usual Sarsa one.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Cpersist_js_state·has_pluto_hook_features§cell_id$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$bc220d14-97fd-486d-9880-6908135fe036queued¤logsrunning¦outputbody<div class="markdown"><p>The reason why the left policy can be better if <span class="tex">$\gamma &lt; 0.5$</span> in the original example is because it has a higher value in each state considered.  Consider <span class="tex">$\gamma &#61; 0.25$</span>.  The left policy has the following approximate discounted value estimates for top, left, right: </p>
<p>1.0667, 0.2667, 2.2667. </p>
<p>Meanwhile the right policy has the corresponding values of: </p>
<p>0.533, 0.133, 2.133.</p>
<p>Each value is smaller for the right policy.  However when we calculate the average value calculated over the long term distribution of states, the left policy averages the first two values while the right policy averages the first and third values because in the long run we expect the left policy to only exist in the top and left state while the right policy will exist in the top and right state.  Because the right state has such a high value for both policies but only the right policy includes it in the average it makes its entire objective estimate higher.  However, we can see that in the event of being in the right state, it is still a higher value expectation following the left policy in this case.  The decision to average based on the final distribution results in a policy ordering that doesn&#39;t match with what we know to be the optimal policy from the policy improvement theorem over finite states.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Hqpersist_js_state·has_pluto_hook_features§cell_id$bc220d14-97fd-486d-9880-6908135fe036depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$e48af9f4-0b47-4a45-b0ad-8f53b094e712queued¤logsrunning¦outputbodymsgٲUndefVarError: `tabular_mountaincar_πrand` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#e48af9f4-0b47-4a45-b0ad-8f53b094e712source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#e48af9f4-0b47-4a45-b0ad-8f53b094e712functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneeconst tabular_policieslast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$e48af9f4-0b47-4a45-b0ad-8f53b094e712depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$5534526a-d790-4379-98b0-8e4ee981fd9fqueued¤logsrunning¦outputbody7update_action_values! (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA6eFpersist_js_state·has_pluto_hook_features§cell_id$5534526a-d790-4379-98b0-8e4ee981fd9fdepends_on_disabled_cells§runtime Llpublished_object_keysdepends_on_skipped_cells§errored$ca970333-fa08-412c-b89d-491e70f0ac79queued¤logsrunning¦outputbodyP<div class="markdown"><h4>Typical Episode Length under Random Policy</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA6DQ"persist_js_state·has_pluto_hook_features§cell_id$ca970333-fa08-412c-b89d-491e70f0ac79depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$db189316-e880-4cc8-9070-ccfe2b4fc545queued¤logsrunning¦outputbodymsgكUndefVarError: `tile_coding_setup` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shortCsetup_mountain_car_tiles(tile_size::Tuple{…}, num_tilings::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527source_packageMaincallPsetup_mountain_car_tiles(tile_size::Tuple{Float32, Float32}, num_tilings::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527funcsetup_mountain_car_tilesparent_moduleMain.var"workspace#5"from_ccall_shortٕmountaincar_differential_test(max_episodes::Int64, α::Float32, β::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{…})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#49e43d51-05d6-415b-a685-76e50904c5bc#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#49e43d51-05d6-415b-a685-76e50904c5bcsource_packageMaincallmountaincar_differential_test(max_episodes::Int64, α::Float32, β::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{compute_value::typeof(compute_q_learning_value)})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#49e43d51-05d6-415b-a685-76e50904c5bcfunc"#mountaincar_differential_test#106parent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#db189316-e880-4cc8-9070-ccfe2b4fc545source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#db189316-e880-4cc8-9070-ccfe2b4fc545func##function_wrapped_cell#646parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6L persist_js_state·has_pluto_hook_features§cell_id$db189316-e880-4cc8-9070-ccfe2b4fc545depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$ddcb50be-5287-47f8-89f9-58c026a6b151queued¤logsrunning¦outputbodymsgكUndefVarError: `tile_coding_setup` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktrace call_shortCsetup_mountain_car_tiles(tile_size::Tuple{…}, num_tilings::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527source_packageMaincallPsetup_mountain_car_tiles(tile_size::Tuple{Float32, Float32}, num_tilings::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527funcsetup_mountain_car_tilesparent_moduleMain.var"workspace#5"from_ccall_shortxmountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4source_packageMaincallxmountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4func#mountaincar_test#92parent_moduleMain.var"workspace#5"from_ccall_short(::var"#95#99"{…})(::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286#L3pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286source_packageMaincall1(::var"#95#99"{Float32, Int64, Float32})(::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286func#95parent_moduleMain.var"workspace#5"from_ccall_shortnextinlinedãurlpath=/home/runner/.julia/packages/Transducers/fnznF/src/library.jlsource_packagecallnextlinfo_typeNothingline6filelibrary.jlfuncnextparent_modulefrom_ccall_shortZnext(rf::Transducers.Reduction{…}, result::Transducers.DefaultInitOf{…}, input::Int64)inlined£urlAfile:///home/runner/.julia/packages/Transducers/fnznF/src/core.jlpath:/home/runner/.julia/packages/Transducers/fnznF/src/core.jlsource_packageTransducerscall<next(rf::Transducers.Reduction{Transducers.NoComplete, Transducers.Reduction{Transducers.Map{var"#95#99"{Float32, Int64, Float32}}, Transducers.BottomRF{Transducers.Completing{InitialValues.AdjoinIdentity{var"#96#100"}}}}}, result::Transducers.DefaultInitOf{InitialValues.AdjoinIdentity{var"#96#100"}}, input::Int64)linfo_typeCore.MethodInstancelinefilecore.jlfuncnextparent_moduleTransducersfrom_ccall_shortmacro expansioninlinedãurlpath:/home/runner/.julia/packages/Transducers/fnznF/src/core.jlsource_packagecallmacro expansionlinfo_typeNothingline̵filecore.jlfuncmacro expansionparent_modulefrom_ccall_short_foldl_arrayinlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecall_foldl_arraylinfo_typeNothingline̻fileprocesses.jlfunc_foldl_arrayparent_modulefrom_ccall_short__foldl__inlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecall__foldl__linfo_typeNothingline̶fileprocesses.jlfunc__foldl__parent_modulefrom_ccall_shortfoldl_basecaseinlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecallfoldl_basecaselinfo_typeNothinglineifileprocesses.jlfuncfoldl_basecaseparent_modulefrom_ccall_short{_reduce_basecase(rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlLfile:///home/runner/.julia/packages/Transducers/fnznF/src/threading_utils.jlpathE/home/runner/.julia/packages/Transducers/fnznF/src/threading_utils.jlsource_packageTransducerscall1_reduce_basecase(rf::Transducers.Reduction{Transducers.Map{var"#95#99"{Float32, Int64, Float32}}, Transducers.BottomRF{Transducers.Completing{InitialValues.AdjoinIdentity{var"#96#100"}}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline:filethreading_utils.jlfunc_reduce_basecaseparent_moduleTransducersfrom_ccall_shortٓ_reduce(ctx::Transducers.NoopDACContext, rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscallI_reduce(ctx::Transducers.NoopDACContext, rf::Transducers.Reduction{Transducers.Map{var"#95#99"{Float32, Int64, Float32}}, Transducers.BottomRF{Transducers.Completing{InitialValues.AdjoinIdentity{var"#96#100"}}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline̋filereduce.jlfunc_reduceparent_moduleTransducersfrom_ccall_shortٓ_reduce(ctx::Transducers.NoopDACContext, rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscallI_reduce(ctx::Transducers.NoopDACContext, rf::Transducers.Reduction{Transducers.Map{var"#95#99"{Float32, Int64, Float32}}, Transducers.BottomRF{Transducers.Completing{InitialValues.AdjoinIdentity{var"#96#100"}}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline̔filereduce.jlfunc_reduceparent_moduleTransducersfrom_ccall_short_transduce_assoc_nocompleteinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecall_transduce_assoc_nocompletelinfo_typeNothinglinẽfilereduce.jlfunc_transduce_assoc_nocompleteparent_modulefrom_ccall_shorttransduce_assoc(xform::Transducers.Map{…}, step::Transducers.Completing{…}, init::Transducers.InitOf{…}, coll0::UnitRange{…}; simd::Val{…}, basesize::Nothing, stoppable::Nothing, nestlevel::Nothing)inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscalltransduce_assoc(xform::Transducers.Map{var"#95#99"{Float32, Int64, Float32}}, step::Transducers.Completing{var"#96#100"}, init::Transducers.InitOf{Transducers.DefaultInitOf}, coll0::UnitRange{Int64}; simd::Val{false}, basesize::Nothing, stoppable::Nothing, nestlevel::Nothing)linfo_typeCore.MethodInstancelinelfilereduce.jlfunc#transduce_assoc#253parent_moduleTransducersfrom_ccall_shorttransduce_associnlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecalltransduce_assoclinfo_typeNothinglineTfilereduce.jlfunctransduce_assocparent_modulefrom_ccall_shortfoldxtinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecallfoldxtlinfo_typeNothinglinefilereduce.jlfuncfoldxtparent_modulefrom_ccall_shortfoldxtinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecallfoldxtlinfo_typeNothinglinefilereduce.jlfuncfoldxtparent_modulefrom_ccall_short#264inlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecall#264linfo_typeNothinglinefilereduce.jlfunc#264parent_modulefrom_ccall_short|>inlinedãurlpath./operators.jlsource_packagecall|>linfo_typeNothinglinefileoperators.jlfunc|>parent_modulefrom_ccall_short!(::var"#94#98"{…})(α::Float32)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286#L3pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286source_packageMaincall,(::var"#94#98"{Int64, Float32})(α::Float32)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286func#94parent_moduleMain.var"workspace#5"from_ccall_shortiterateinlinedãurlpath./generator.jlsource_packagecalliteratelinfo_typeNothingline0filegenerator.jlfunciterateparent_modulefrom_ccall_shorta_collect(c::Vector{…}, itr::Base.Generator{…}, ::Base.EltypeUnknown, isz::Base.HasShape{…})inlined£urlchttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/array.jl#L797path./array.jlsource_packageMaincallٌ_collect(c::Vector{Float32}, itr::Base.Generator{Vector{Float32}, var"#94#98"{Int64, Float32}}, ::Base.EltypeUnknown, isz::Base.HasShape{1})linfo_typeCore.MethodInstanceline filearray.jlfunc_collectparent_moduleBasefrom_ccall_shortcollect_similarinlinedãurlpath./array.jlsource_packagecallcollect_similarlinfo_typeNothinglineŤfilearray.jlfunccollect_similarparent_modulefrom_ccall_shortmapinlinedãurlpath./abstractarray.jlsource_packagecallmaplinfo_typeNothingline+fileabstractarray.jlfuncmapparent_modulefrom_ccall_short#figure_10_2#93inlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286source_packagecall#figure_10_2#93linfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286func#figure_10_2#93parent_modulefrom_ccall_shortfigure_10_2()inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286source_packageMaincallfigure_10_2()linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#1a82ae95-3c3e-4281-bc1d-9eb19bf50286funcfigure_10_2parent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#ddcb50be-5287-47f8-89f9-58c026a6b151source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#ddcb50be-5287-47f8-89f9-58c026a6b151func##function_wrapped_cell#622parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA69ABpersist_js_state·has_pluto_hook_features§cell_id$ddcb50be-5287-47f8-89f9-58c026a6b151depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$e7bf61d7-c362-433d-9b83-6537d308c255queued¤logsrunning¦outputbody<div class="markdown"><h3><em>Semi-gradient Sarsa Implementation</em></h3>
<p>Below is an implementation of Semi-gradient Sarsa in a similar style to the algorithms in Chapter 9.  This function updates the provided parameters using the <code>update_parameters&#33;</code> function and also requires an <code>estimate_value</code> function.  The linear function approximation version of this simplifies the required arguments greatly, needing only a state representation update function.  </p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Bpersist_js_state·has_pluto_hook_features§cell_id$e7bf61d7-c362-433d-9b83-6537d308c255depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$69a06405-57cd-42e5-96b1-5cc77d74aa03queued¤logsrunning¦outputbody^<div class="markdown"><h3><em>Differential Semi-gradient Sarsa Implementation</em></h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6F\>persist_js_state·has_pluto_hook_features§cell_id$69a06405-57cd-42e5-96b1-5cc77d74aa03depends_on_disabled_cells§runtime b	published_object_keysdepends_on_skipped_cells§errored$c44dd6c6-8213-49fb-8d33-ba8f2c766b2equeued¤logsrunning¦outputbodymsgىUndefVarError: `q̂_mountain_car2_fcann` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#c44dd6c6-8213-49fb-8d33-ba8f2c766b2esource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#c44dd6c6-8213-49fb-8d33-ba8f2c766b2efunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6npersist_js_state·has_pluto_hook_features§cell_id$c44dd6c6-8213-49fb-8d33-ba8f2c766b2edepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$ac80958a-73ec-4342-b553-b33df6612a50queued¤logsrunning¦outputbodymsg UndefVarError: `StateMDPTransitionSampler` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#ac80958a-73ec-4342-b553-b33df6612a50source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#ac80958a-73ec-4342-b553-b33df6612a50functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneeconst mountain_car_transitionlast_run_timestampA6wZpersist_js_state·has_pluto_hook_features§cell_id$ac80958a-73ec-4342-b553-b33df6612a50depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$09088eee-4cb3-40ac-b127-658ce1332fbaqueued¤logsrunning¦outputbodymsgكUndefVarError: `episode_rewards_q` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#09088eee-4cb3-40ac-b127-658ce1332fbasource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#09088eee-4cb3-40ac-b127-658ce1332fbafunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6npersist_js_state·has_pluto_hook_features§cell_id$09088eee-4cb3-40ac-b127-658ce1332fbadepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$33ea5f09-3a1f-476d-875a-1f3635a40295queued¤logsrunning¦outputbodyi<bond def="tabular_mountaincar_args" unique_id="7d5vz/6UAzAB"><span style='display: contents;'>
	<span style='display: contents;'><div class="markdown"><p>Policy View Selection: <pl-combined-child key='xkwsbfukhk' style='display: contents;'><select><option value='puiselect-1'>Random</option><option value='puiselect-2'>Accelerate Only</option></select></pl-combined-child> Number of Positions: <pl-combined-child key='xkwsbfukhk' style='display: contents;'><input type='number' min='1' step='1' max='10000' value='500'></pl-combined-child> Number of Velocities: <pl-combined-child key='xkwsbfukhk' style='display: contents;'><input type='number' min='1' step='1' max='10000' value='500'></pl-combined-child></p>
</div><script id='xkwsbfukhk'>
const div = currentScript.parentElement
let key = "xkwsbfukhk"
const inputs = div.querySelectorAll(`pl-combined-child[key='${key}'] > *:first-child`)

const values = Array(inputs.length)

inputs.forEach(async (el,i) => {
	el.oninput = (e) => {
		e.stopPropagation()
	}
	const gen = Generators.input(el)
	while(true) {
		values[i] = await gen.next().value
		div.dispatchEvent(new CustomEvent("input", {}))
	}
})


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()


Object.defineProperty(div, 'value', {
	get: () => values,
	set: (newvals) => {
		if(!newvals) {
			return
		}
		inputs.forEach((el, i) => {
			values[i] = newvals[i]
			set_input_value(el, newvals[i])
		})
},
	configurable: true,
});

</script></span>
	<input type=submit id='haszxlbiig'>
	<script id='haszxlbiig'>

let key = "haszxlbiig"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond>mimetext/htmlrootassigneelast_run_timestampA6̸persist_js_state·has_pluto_hook_features§cell_id$33ea5f09-3a1f-476d-875a-1f3635a40295depends_on_disabled_cells§runtimeo"published_object_keysdepends_on_skipped_cellsçerrored$318b398a-d8f2-4f39-a45d-fd9023961bf8queued¤logsrunning¦outputbodymsgLoadError: UndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Main
in expression starting at /home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-9/Chapter_9_On-policy_Prediction_with_Approximation.jl:110stacktracecall_shorttop-level scopeinlined£urlpathn/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-9/Chapter_9_On-policy_Prediction_with_Approximation.jlsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinenfile4Chapter_9_On-policy_Prediction_with_Approximation.jlfunctop-level scopeparent_modulefrom_ccall_short#include(mod::Module, _path::String)inlined£urlbhttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/Base.jl#L557path./Base.jlsource_packageMaincall#include(mod::Module, _path::String)linfo_typeCore.MethodInstanceline-fileBase.jlfuncincludeparent_moduleBasefrom_ccall_shortinclude(x::String)inlined£urlbfile:///home/runner/.julia/packages/Pluto/6smog/src/runner/PlutoRunner/src/evaluation/workspace.jlpath[/home/runner/.julia/packages/Pluto/6smog/src/runner/PlutoRunner/src/evaluation/workspace.jlsource_packageMaincallinclude(x::String)linfo_typeCore.MethodInstancelinefileworkspace.jlfuncincludeparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#318b398a-d8f2-4f39-a45d-fd9023961bf8source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#318b398a-d8f2-4f39-a45d-fd9023961bf8functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6)persist_js_state·has_pluto_hook_features§cell_id$318b398a-d8f2-4f39-a45d-fd9023961bf8depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$be77b538-d106-4ca0-a974-289415588c47queued¤logsrunning¦outputbody`<div class="markdown"><h5>Solving Mountain Car Tabular Problem with Policy Iteration</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA6D4persist_js_state·has_pluto_hook_features§cell_id$be77b538-d106-4ca0-a974-289415588c47depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$5bc2eda5-5f4c-4165-9afb-16920f30b0c5queued¤logsrunning¦outputbody<π_optimal_policy_iteration (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6F|persist_js_state·has_pluto_hook_features§cell_id$5bc2eda5-5f4c-4165-9afb-16920f30b0c5depends_on_disabled_cells§runtime 8published_object_keysdepends_on_skipped_cellsçerrored$f9ee13e8-7406-4fba-9a30-1e2714bd7cfcqueued¤logsrunning¦outputbodymsgلUndefVarError: `q̂_mountain_car_q` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#f9ee13e8-7406-4fba-9a30-1e2714bd7cfcsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#f9ee13e8-7406-4fba-9a30-1e2714bd7cfcfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6?ذpersist_js_state·has_pluto_hook_features§cell_id$f9ee13e8-7406-4fba-9a30-1e2714bd7cfcdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$afee7bc9-aff0-4c71-a227-9845cb23d4e9queued¤logsrunning¦outputbody)<div class="markdown"><p>Number of Steps: <bond def="rand_nsteps" unique_id="cW9&#43;Dt8XjML1"><span style='display: contents;'>
	<input type='range' min='1' max='1000' value='200'><script>
					const input_el = currentScript.previousElementSibling
					const output_el = currentScript.nextElementSibling
					const displays = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", "990", "991", "992", "993", "994", "995", "996", "997", "998", "999", "1000"]

					let update_output = () => {
						output_el.value = displays[input_el.valueAsNumber - 1]
					}
					
					input_el.addEventListener("input", update_output)
					// We also poll for changes because the `input_el.value` can change from the outside, e.g. https://github.com/JuliaPluto/PlutoUI.jl/issues/277
					let id = setInterval(update_output, 200)
					invalidation.then(() => {
						clearInterval(id)
						input_el.removeEventListener("input", update_output)
					})
					</script><output style='
						font-family: system-ui;
    					font-size: 15px;
    					margin-left: 3px;
    					transform: translateY(-4px);
    					display: inline-block;'>200</output>
	<input type=submit id='ehydulxsho'>
	<script id='ehydulxsho'>

let key = "ehydulxsho"

let div = currentScript.parentElement
let button = currentScript.previousElementSibling
let input = div.firstElementChild
if(input === button) {
	return
}


let set_input_value = (() => {
	let result = null
	try {
	result = setBoundElementValueLikePluto
} catch (e) {
	result = ((input, new_value) => {
	// fallback in case https://github.com/fonsp/Pluto.jl/pull/1755 is not available
    if (new_value == null) {
        //@ts-ignore
        input.value = new_value
        return
    }
    if (input instanceof HTMLInputElement) {
        switch (input.type) {
            case "range":
            case "number": {
                if (input.valueAsNumber !== new_value) {
                    input.valueAsNumber = new_value
                }
                return
            }
            case "date": {
                if (input.valueAsDate == null || Number(input.valueAsDate) !== Number(new_value)) {
                    input.valueAsDate = new_value
                }
                return
            }
            case "checkbox": {
                if (input.checked !== new_value) {
                    input.checked = new_value
                }
                return
            }
            case "file": {
                // Can't set files :(
                return
            }
        }
    } else if (input instanceof HTMLSelectElement && input.multiple) {
        for (let option of Array.from(input.options)) {
            option.selected = new_value.includes(option.value)
        }
        return
    }
    //@ts-ignore
    if (input.value !== new_value) {
        //@ts-ignore
        input.value = new_value
    }
})
}
return result
})()



let private_value = null
let public_value = null




private_value = public_value = div.value
if(private_value != null) {
	set_input_value(input, private_value)
} else {

	// private_value = public_value = input.value
}

input.oninput = (e) => {
	e.stopPropagation()
}
const gen = Generators.input(input)

// If the child does not have an initial value, the `gen.next().value` promise will never resolve. If it does, then it resolves instantly.
let first_value = await Promise.any([
	gen.next().value,
	Promise.resolve(undefined)
])
private_value = public_value = first_value

;(async () => {
	while(true) {
		private_value = await gen.next().value
		// div.dispatchEvent(new CustomEvent("input", {}))
	}
})()

button.addEventListener("click", () => {
	public_value = private_value
	div.dispatchEvent(new CustomEvent("input", {}))
})


Object.defineProperty(div, 'value', {
	get: () => public_value,
	set: (newval) => {
		private_value = newval
		public_value = newval
		
		set_input_value(input, newval)
	},
	configurable: true,
});

</script></span></bond></p>
</div>mimetext/htmlrootassigneelast_run_timestampA6qrmpersist_js_state·has_pluto_hook_features§cell_id$afee7bc9-aff0-4c71-a227-9845cb23d4e9depends_on_disabled_cells§runtimeʊpublished_object_keysdepends_on_skipped_cellsçerrored$4775126e-4374-49be-b25f-4597401f3642queued¤logsrunning¦outputbodymsgمUndefVarError: `average_step_reward` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#4775126e-4374-49be-b25f-4597401f3642source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#4775126e-4374-49be-b25f-4597401f3642functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Xpersist_js_state·has_pluto_hook_features§cell_id$4775126e-4374-49be-b25f-4597401f3642depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$d291541d-ddba-4b71-a4eb-37fef758b71bqueued¤logsrunning¦outputbody<div class="markdown"><h4>Tabular Version of Mountain Car</h4>
<p>If we discretize the positions and velocities then we can transform this into a tabular problem.  The number of states will be NxM where N and M are the number of distinct values for position and velocity respectively.  As N and M approach infinity this problem will approach the original MDP, so we can study the limiting behavior of the optimal policy and value function using tabular methods that are guaranteed to converge.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Dm7persist_js_state·has_pluto_hook_features§cell_id$d291541d-ddba-4b71-a4eb-37fef758b71bdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$e2cd69c5-eda7-4897-9e64-0adf940d4d96queued¤logsrunning¦outputbodymsgٴUndefVarError: `mountaincar_policy_iteration` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shortmacro expansioninlinedãurlpathv/home/runner/.julia/packages/Pluto/6smog/src/runner/PlutoRunner/src/bonds.jl#@#==#e2cd69c5-eda7-4897-9e64-0adf940d4d96source_packagecallmacro expansionlinfo_typeNothingline}file2bonds.jl#@#==#e2cd69c5-eda7-4897-9e64-0adf940d4d96funcmacro expansionparent_modulefrom_ccall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#e2cd69c5-eda7-4897-9e64-0adf940d4d96source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#e2cd69c5-eda7-4897-9e64-0adf940d4d96functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$e2cd69c5-eda7-4897-9e64-0adf940d4d96depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$cbac1927-b087-4c4c-98ae-6aa5f0b824adqueued¤logsrunning¦outputbodymsgكUndefVarError: `tile_coding_setup` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shortCsetup_mountain_car_tiles(tile_size::Tuple{…}, num_tilings::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527source_packageMaincallPsetup_mountain_car_tiles(tile_size::Tuple{Float32, Float32}, num_tilings::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527funcsetup_mountain_car_tilesparent_moduleMain.var"workspace#5"from_ccall_short{mountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{…})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4source_packageMaincall٧mountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{compute_value::typeof(compute_q_learning_value)})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4func#mountaincar_test#92parent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cbac1927-b087-4c4c-98ae-6aa5f0b824adsource_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cbac1927-b087-4c4c-98ae-6aa5f0b824adfunc##function_wrapped_cell#626parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6<persist_js_state·has_pluto_hook_features§cell_id$cbac1927-b087-4c4c-98ae-6aa5f0b824addepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$ee59176e-24b6-4213-8f8e-759a70bc1d5equeued¤logsrunning¦outputbodymsg٭UndefVarError: `mountain_car_dist_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shortـmountaincar_fcann_dp(max_episodes::Int64, α::Float32, ϵ::Float32; layers::Vector{…}, max_steps::Int64, kwargs::@Kwargs{…})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#0f958535-6b18-46de-a1ba-81f64c217ee0#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#0f958535-6b18-46de-a1ba-81f64c217ee0source_packageMaincallىmountaincar_fcann_dp(max_episodes::Int64, α::Float32, ϵ::Float32; layers::Vector{Int64}, max_steps::Int64, kwargs::@Kwargs{c::Float32})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#0f958535-6b18-46de-a1ba-81f64c217ee0func#mountaincar_fcann_dp#64parent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#ee59176e-24b6-4213-8f8e-759a70bc1d5esource_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#ee59176e-24b6-4213-8f8e-759a70bc1d5efunc##function_wrapped_cell#468parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneemountaincar_fcann_dp_resultslast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$ee59176e-24b6-4213-8f8e-759a70bc1d5edepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$54b92594-04b8-4a8a-82c2-773b4a24680dqueued¤logsrunning¦outputbody<div class="markdown"><h3><em>Action-Value Implementation of Linear Approximation</em></h3>
<p>If we update the techniques from Chapter 9 to accomodate action-value estimates, then all of the linear techniques explored there can be used for these control algorihtms.  Previously, we only considered state value estimates, but we can adapt all of those techniques to action values in the linear case quite easily.  The main difference is that the action index needs to be included as an argument to the parameter update function.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6CFEpersist_js_state·has_pluto_hook_features§cell_id$54b92594-04b8-4a8a-82c2-773b4a24680ddepends_on_disabled_cells§runtime T5published_object_keysdepends_on_skipped_cells§errored$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0queued¤logsrunning¦outputbodymsg~UndefVarError: `π_greedy_dp` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7d21c4cd-ab79-4f40-9b8b-f637b3efcab0source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#7d21c4cd-ab79-4f40-9b8b-f637b3efcab0functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6mfpersist_js_state·has_pluto_hook_features§cell_id$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$c316c5d3-f484-4e8e-bd56-be1e236d96bcqueued¤logsrunning¦outputbodyk<div class="markdown"><p>Applying the derivation of discount independence to the MDP in exercise 3.22 who&#39;s optimal policy depends on <span class="tex">$\gamma$</span></p>
<p class="tex">$$J&#40;\pi&#41; &#61; \sum_s \mu_\pi&#40;s&#41;v_\pi^\gamma&#40;s&#41;$$</p>
<p>Consider <span class="tex">$\pi_&#123;left&#125;$</span>: <span class="tex">$J&#40;\pi_&#123;left&#125;&#41;&#61;0.5 \times &#40;1 &#43; 0 &#43; \gamma^2 &#43; 0 &#43; \gamma^4 &#43; 0 &#43; \cdots&#41; &#43; 0.5 \times&#40;0 &#43; \gamma &#43; 0 &#43; \gamma^3 &#43; 0 &#43; \gamma^5 &#43; \cdots&#41;$</span> <span class="tex">$J&#40;\pi_&#123;left&#125;&#41; &#61; 0.5 \times &#40;1 &#43; \gamma &#43; \gamma^2 &#43; \gamma^3 &#43; \gamma^4 &#43; \gamma^5 &#43; \cdots&#41;$</span></p>
<p>Consider <span class="tex">$\pi_&#123;right&#125;$</span>: <span class="tex">$J&#40;\pi_&#123;right&#125;&#41;&#61;0.5 \times &#40;0 &#43; 2\gamma &#43; 0 &#43; 2\gamma^3 &#43; 0 &#43; \cdots&#41; &#43; 0.5 \times&#40;2 &#43; 0 &#43; 2\gamma^2 &#43; 0 &#43; 2\gamma^4 &#43; \cdots&#41;$</span> <span class="tex">$J&#40;\pi_&#123;right&#125;&#41; &#61; 0.5 \times 2 \times &#40;1 &#43; \gamma &#43; \gamma^2 &#43; \gamma^3 &#43; \gamma^4 &#43; \gamma^5 &#43; \cdots&#41;$</span></p>
<p>So both average reward values have the same factor for the discount rate and thus the right policy appears better since the average reward value is higher.  Previously, we had calculated that a discount rate less than 0.5 made the left policy favorable since the reward was obtained sooner going left vs right.  In the original problem we can consider the value of the top state for both left and right policies: <span class="tex">$v_&#123;\pi_&#123;left&#125;&#125; &#40;top&#41; &#61; 1 &#43; 0 &#43; \gamma^2 &#43; 0 &#43; \gamma^4 &#43; \cdots &#61; 1 &#43; \gamma^2 &#43; \gamma^4 &#43; \cdots$</span> <span class="tex">$v_&#123;\pi_&#123;right&#125;&#125; &#40;top&#41; &#61; 0 &#43; 2\gamma &#43; 0 &#43; 2\gamma^3 &#43; \cdots &#61; 2 \times &#40;\gamma &#43; \gamma^3 &#43; \cdots&#41; &#61; 2\gamma&#40;v_&#123;\pi_&#123;left&#125;&#125;&#40;top&#41;&#41;$</span></p>
<p>Clearly for <span class="tex">$\gamma &gt; 0.5$</span> the right policy is better.</p>
<p>Similarly, we can consider the value of the left state for both left and right policies: <span class="tex">$v_&#123;\pi_&#123;left&#125;&#125; &#40;left&#41; &#61; 0 &#43; \gamma &#43; 0 &#43; \gamma^3 &#43; \cdots &#61; \gamma &#43; \gamma^3 &#43; \cdots$</span> <span class="tex">$v_&#123;\pi_&#123;right&#125;&#125; &#40;left&#41; &#61; 0 &#43; 0 &#43; 2\gamma^2 &#43; 0  &#43; 2\gamma^4 &#43; \cdots &#61; 2 \times &#40;\gamma^2 &#43; \gamma^4 &#43; \cdots&#41; &#61; 2\gamma&#40;v_&#123;\pi_&#123;left&#125;&#125;&#40;left&#41;&#41;$</span></p>
<p>Again, for <span class="tex">$\gamma &gt; 0.5$</span> the right policy is better.</p>
<p>And finally for the right state: <span class="tex">$v_&#123;\pi_&#123;left&#125;&#125; &#40;right&#41; &#61; 2 &#43; \gamma &#43; 0 &#43; \gamma^3 &#43; 0 &#43; \gamma^5 \cdots &#61; 2&#43;\gamma&#40;1 &#43; \gamma^2 &#43; \gamma^4 &#43; \cdots&#41;&#61;2 &#43; \frac&#123;\gamma&#125;&#123;1-\gamma^2&#125;$</span>  <span class="tex">$&#61; \frac&#123;2&#40;1-\gamma^2&#41; &#43; \gamma&#125;&#123;1-\gamma^2&#125; &#61; \frac&#123;2 - 2\gamma^2 &#43; \gamma&#125;&#123;1-\gamma^2&#125;$</span> <span class="tex">$v_&#123;\pi_&#123;right&#125;&#125; &#40;right&#41; &#61; 2 &#43; 0 &#43; 2\gamma^2 &#43; 0 &#43; 2\gamma^4 &#43;  \cdots &#61; 2 \times &#40;1&#43;\gamma^2 &#43; \gamma^4 &#43; \cdots&#41; &#61; \frac&#123;2&#125;&#123;1-\gamma^2&#125;$</span></p>
<p class="tex">$$\frac&#123;v_&#123;\pi_&#123;left&#125;&#125; &#40;right&#41;&#125;&#123;v_&#123;\pi_&#123;right&#125;&#125; &#40;right&#41;&#125;&#61;\frac&#123;2 - 2\gamma^2 &#43; \gamma&#125;&#123;2&#125;$$</p>
<p>For <span class="tex">$\gamma&#61;0$</span> this quantity is 1 meaning the policies are equal and for <span class="tex">$\gamma&#61;1$</span> this quantity is 0.5 meaning that the right policy is better.  At <span class="tex">$\gamma&#61;0.5$</span> the quantity is <span class="tex">$\frac&#123;2 - 0.5 &#43; 0.5&#125;&#123;2&#125;&#61;\frac&#123;2&#125;&#123;2&#125;&#61;1$</span> meaning they are equal.  The maximum value occurs at <span class="tex">$2\gamma &#61; 0.5 \implies \gamma &#61; 0.25$</span> with a ratio value of <span class="tex">$\frac&#123;2 - 0.125 &#43; 0.25&#125;&#123;2&#125;&#61;\frac&#123;2.125&#125;&#123;2&#125;&#61;1.0625$</span> meaning that the left policy is slightly better or equal from <span class="tex">$0 \leq \gamma \leq 0.5$</span> and worse at <span class="tex">$\gamma &gt; 0.5$</span> which matches the earlier states.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6HJpersist_js_state·has_pluto_hook_features§cell_id$c316c5d3-f484-4e8e-bd56-be1e236d96bcdepends_on_disabled_cells§runtime 
ipublished_object_keysdepends_on_skipped_cells§errored$f2201afe-8952-4dde-9e39-02beeb920f6fqueued¤logsrunning¦outputbodymsgفUndefVarError: `π_mountain_car` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#f2201afe-8952-4dde-9e39-02beeb920f6fsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#f2201afe-8952-4dde-9e39-02beeb920f6ffunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6i4persist_js_state·has_pluto_hook_features§cell_id$f2201afe-8952-4dde-9e39-02beeb920f6fdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$31fb07d2-1c34-44ec-b932-a598e78ec8dcqueued¤logsrunning¦outputbody0<div class="markdown"><h4>Non-linear Neural Network</h4>
<p>Compared to tile coding, the feature vector for non-linear learning will simply be two values: one for the position and another for the velocity.  Both values will be scaled so the mean value is 0 and the variance is approximately 1.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6E$persist_js_state·has_pluto_hook_features§cell_id$31fb07d2-1c34-44ec-b932-a598e78ec8dcdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$5db29488-a150-42ee-aedb-380a3a4fd548queued¤logsrunning¦outputbody@plot_mountaincar_action_values (generic function with 3 methods)mimetext/plainrootassigneelast_run_timestampA6=\persist_js_state·has_pluto_hook_features§cell_id$5db29488-a150-42ee-aedb-380a3a4fd548depends_on_disabled_cells§runtime *"ppublished_object_keysdepends_on_skipped_cellsçerrored$39c63495-36c3-4e62-b8fb-36865f2c6243queued¤logsrunning¦outputbodyR<div class="markdown"><h5>Visualizing Policies in Tabular Mountain Car</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA6Dpersist_js_state·has_pluto_hook_features§cell_id$39c63495-36c3-4e62-b8fb-36865f2c6243depends_on_disabled_cells§runtime Եpublished_object_keysdepends_on_skipped_cells§errored$d42bb733-07e2-4932-aab4-09229ff67492queued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93source_packageMaincallIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93funcshow_mountaincar_trajectoryparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#d42bb733-07e2-4932-aab4-09229ff67492source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#d42bb733-07e2-4932-aab4-09229ff67492func##function_wrapped_cell#414parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6J persist_js_state·has_pluto_hook_features§cell_id$d42bb733-07e2-4932-aab4-09229ff67492depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$58a0b622-1b51-4b42-a416-24109ae41a90queued¤logsrunning¦outputbodymsgٯUndefVarError: `tabular_mountaincar_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#58a0b622-1b51-4b42-a416-24109ae41a90source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#58a0b622-1b51-4b42-a416-24109ae41a90functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6$persist_js_state·has_pluto_hook_features§cell_id$58a0b622-1b51-4b42-a416-24109ae41a90depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$954848db-6dcc-4666-90f8-b5a900203242queued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93source_packageMaincallIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93funcshow_mountaincar_trajectoryparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#954848db-6dcc-4666-90f8-b5a900203242source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#954848db-6dcc-4666-90f8-b5a900203242functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Ȱpersist_js_state·has_pluto_hook_features§cell_id$954848db-6dcc-4666-90f8-b5a900203242depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$df07524f-b3fe-4a66-98ac-8f80df66bcffqueued¤logsrunning¦outputbody7mountain_car_dist_step (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6lh'persist_js_state·has_pluto_hook_features§cell_id$df07524f-b3fe-4a66-98ac-8f80df66bcffdepends_on_disabled_cells§runtime ۵published_object_keysdepends_on_skipped_cells§errored$c85033e1-3ee6-42ad-9ef0-144ce6238ce4queued¤logsrunning¦outputbody-smooth_error (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$c85033e1-3ee6-42ad-9ef0-144ce6238ce4depends_on_disabled_cells§runtime 2published_object_keysdepends_on_skipped_cellsçerrored$f6e08689-040f-4565-9dfb-e9a65d1c1f18queued¤logsrunning¦outputbody><div class="markdown"><h4>Visualizing Trajectories</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA6D8Gpersist_js_state·has_pluto_hook_features§cell_id$f6e08689-040f-4565-9dfb-e9a65d1c1f18depends_on_disabled_cells§runtime |published_object_keysdepends_on_skipped_cells§errored$e7372e2b-a2db-4a93-9efc-f75aa74c197bqueued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA6 !6persist_js_state·has_pluto_hook_features§cell_id$e7372e2b-a2db-4a93-9efc-f75aa74c197bdepends_on_disabled_cells§runtime }published_object_keysdepends_on_skipped_cells§errored$dc2cffeb-9adf-4956-afa3-ac82af377c59queued¤logsrunning¦outputbody)<div class="markdown"><p>Finally we can create the action-value function and parameter update for the generic linear case.  If a vector of action values is provided as the first argument to the value function, that vector will be updated with all of the action values for a given state.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Cpersist_js_state·has_pluto_hook_features§cell_id$dc2cffeb-9adf-4956-afa3-ac82af377c59depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$fc0b88f3-fbf9-450d-b770-b34357ffad49queued¤logsrunning¦outputbody4compute_sarsa_value (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6ǂpersist_js_state·has_pluto_hook_features§cell_id$fc0b88f3-fbf9-450d-b770-b34357ffad49depends_on_disabled_cells§runtime qFpublished_object_keysdepends_on_skipped_cells§errored$50f6ff51-d81b-4e97-9f8a-0daf03af7192queued¤logsrunning¦outputbodyB<div class="markdown"><h2>Monte Carlo Gradient Control</h2>
</div>mimetext/htmlrootassigneelast_run_timestampA6Hհpersist_js_state·has_pluto_hook_features§cell_id$50f6ff51-d81b-4e97-9f8a-0daf03af7192depends_on_disabled_cells§runtime ҵpublished_object_keysdepends_on_skipped_cells§errored$5cbaeb8e-bc02-47c9-87b4-57df554cea9dqueued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93source_packageMaincallIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93funcshow_mountaincar_trajectoryparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#5cbaeb8e-bc02-47c9-87b4-57df554cea9dsource_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#5cbaeb8e-bc02-47c9-87b4-57df554cea9dfunc##function_wrapped_cell#526parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6YKpersist_js_state·has_pluto_hook_features§cell_id$5cbaeb8e-bc02-47c9-87b4-57df554cea9ddepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$b094bf9f-bb97-4f23-acdc-f39411a07fb9queued¤logsrunning¦outputbody7π_mountain_car2_fcann (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6ðpersist_js_state·has_pluto_hook_features§cell_id$b094bf9f-bb97-4f23-acdc-f39411a07fb9depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cellsçerrored$1d417a66-205f-4883-b49c-a6fc900af4cequeued¤logsrunning¦outputbodyz500-element LinRange{Float32, Int64}:
 -1.2, -1.19659, -1.19319, -1.18978, -1.18637, …, 0.48978, 0.493186, 0.496593, 0.5mimetext/plainrootassigneeconst mountaincar_positionslast_run_timestampA6gpersist_js_state·has_pluto_hook_features§cell_id$1d417a66-205f-4883-b49c-a6fc900af4cedepends_on_disabled_cells§runtime }published_object_keysdepends_on_skipped_cellsçerrored$17d11fea-883b-4ddb-bec2-c4ad491b39ddqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#17d11fea-883b-4ddb-bec2-c4ad491b39ddsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#17d11fea-883b-4ddb-bec2-c4ad491b39ddfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$17d11fea-883b-4ddb-bec2-c4ad491b39dddepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$b4af8d87-a6e5-4e09-92b4-b07757f58f7fqueued¤logsrunning¦outputbodyFrun_access_control_differential_sarsa (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6}䂰persist_js_state·has_pluto_hook_features§cell_id$b4af8d87-a6e5-4e09-92b4-b07757f58f7fdepends_on_disabled_cells§runtime E;εpublished_object_keysdepends_on_skipped_cells§errored$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5bqueued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 10.3</em></h3>
<p>Why do the results shown in Figure 10.4 have higher standard errors at large <em>n</em> than at small <em>n</em>?</p>
</blockquote>
<p>At large n more of the reward function comes from the actual trajectory observed during a run.  Since random actions are taken initially there will be more spread in the observed reward estimates than with 1 step bootstrapping which is more dependent on the initialization of the action value function.  If ties are broken randomly then you would select random actions for the first n-steps of bootstrapping thus experience more spread in the early trajectories for higher n.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Epersist_js_state·has_pluto_hook_features§cell_id$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5bdepends_on_disabled_cells§runtime Cpublished_object_keysdepends_on_skipped_cells§errored$c799ffe4-f4af-487d-b557-8b50d13632b7queued¤logsrunning¦outputbodymsgٯUndefVarError: `tabular_mountaincar_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#c799ffe4-f4af-487d-b557-8b50d13632b7source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#c799ffe4-f4af-487d-b557-8b50d13632b7functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$c799ffe4-f4af-487d-b557-8b50d13632b7depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$0e66a941-1ec1-4d3b-b064-e5f25cc93bafqueued¤logsrunning¦outputbody=<div class="markdown"><h3>Connection to Chapter 3</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6Hpersist_js_state·has_pluto_hook_features§cell_id$0e66a941-1ec1-4d3b-b064-e5f25cc93bafdepends_on_disabled_cells§runtime rpublished_object_keysdepends_on_skipped_cells§errored$c5c839f7-1806-463d-b63a-bd7e1384f203queued¤logsrunning¦outputbody<div class="markdown"><p>The action value calculation also depends on how parameters are represented.  Either a dot product is used by extracting the appropriate parameter vector, or the parameter matrix needs to be iterated over the appropriate column</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Cðpersist_js_state·has_pluto_hook_features§cell_id$c5c839f7-1806-463d-b63a-bd7e1384f203depends_on_disabled_cells§runtime Hpublished_object_keysdepends_on_skipped_cells§errored$1b15efa9-c331-46bf-93db-f96dee026fe2queued¤logsrunning¦outputbodymsgUndefVarError: `make_random_policy` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#1b15efa9-c331-46bf-93db-f96dee026fe2source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#1b15efa9-c331-46bf-93db-f96dee026fe2functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassignee const tabular_mountaincar_πrandlast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$1b15efa9-c331-46bf-93db-f96dee026fe2depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$72f575ee-d656-4af6-bf78-aab42bf1debdqueued¤logsrunning¦outputbody_<div class="markdown"><h5>Solving Mountain Car Tabular Problem with Value Iteration</h5>
</div>mimetext/htmlrootassigneelast_run_timestampA6Dϰpersist_js_state·has_pluto_hook_features§cell_id$72f575ee-d656-4af6-bf78-aab42bf1debddepends_on_disabled_cells§runtime Lpublished_object_keysdepends_on_skipped_cells§errored$2c620fe4-2f62-40f8-a666-8dced1e0b84aqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#2c620fe4-2f62-40f8-a666-8dced1e0b84asource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#2c620fe4-2f62-40f8-a666-8dced1e0b84afunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6˰persist_js_state·has_pluto_hook_features§cell_id$2c620fe4-2f62-40f8-a666-8dced1e0b84adepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8queued¤logsrunning¦outputbodymsgقUndefVarError: `v̂_mountain_car` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#bd1f42e5-94cc-4aef-b82a-9bffd1c951d8source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#bd1f42e5-94cc-4aef-b82a-9bffd1c951d8functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Qpersist_js_state·has_pluto_hook_features§cell_id$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$b8c031ca-7995-4501-a1e3-df3f34e5f0daqueued¤logsrunning¦outputbody<div class="markdown"><h2>10.3 Average Reward: A New Problem Setting for Continuing Tasks</h2>
<p>We now introduce an alternative to the discount setting for solving continuing problems &#40;MDPs without a terminal state&#41;.  The average-reward setting is more commonly used in the classical theory of dynamic programming.  The purpose of introducing the average-reward is because discounting is problematic with function approximation in a way it was not problematic for tabular problems.  </p>
<p>In the average-reward setting the quality of a policy <span class="tex">$\pi$</span> is defined as the average rate of reward, or simply <em>average reward</em>, while following that policy, which we denote as <span class="tex">$r&#40;\pi&#41;$</span>:</p>
<p class="tex">$$\begin&#123;flalign&#125;
r&#40;\pi&#41; &amp;\doteq \lim_&#123;h \rightarrow \infty&#125; \frac&#123;1&#125;&#123;h&#125;\sum_&#123;t&#61;1&#125;^h \mathbb&#123;E&#125;&#91;R_t \mid S_0,A_&#123;0:t-1&#125; \sim \pi&#93; \tag&#123;10.6&#125;\\
&amp;&#61; \lim_&#123;h \rightarrow \infty&#125; \mathbb&#123;E&#125; &#91;R_t \mid S_0,A_&#123;0:t-1&#125; \sim \pi&#93; \tag&#123;10.7&#125;\\
&amp;&#61; \sum_s \mu_\pi&#40;s&#41;\sum_a\pi&#40;a \vert s&#41; \sum_&#123;s^\prime,r&#125; p&#40;s^\prime,r \vert s, a&#41;r
\end&#123;flalign&#125;$$</p>
<p>where the expectations are conditioned on the initial state, <span class="tex">$S_0$</span>, and on the subsequent actions, <span class="tex">$A_0, A_1, \dots,A_&#123;t-1&#125;$</span>, being taken according to <span class="tex">$\pi$</span>. The second and third equations hold if the state-state distribution <span class="tex">$\mu_\pi&#40;s&#41; \doteq \lim_&#123;t\rightarrow \infty&#125; \Pr \&#123;S_t &#61; s \mid A_&#123;0:t-1&#125; \sim \pi \&#125;$</span>, exists and is independent of <span class="tex">$S_0$</span>, in other words, if the MDP is <em>ergodic</em>. In an ergodic MDP, the starting state and any early decision made by the agent can only have a temporary effect; in the long run the expectation of being in a state depends on the policy and the MDP transition probabilities.  Ergodicity is sufficient but not necessary to guarantee the existence of the limit in &#40;10.6&#41;.</p>
<p>In this setting, we consider all policies that obtain the maximum value of <span class="tex">$r&#40;\pi&#41;$</span> or the <em>reward rate</em> to be optimal.  Note that the steady state distribution <span class="tex">$\mu_\pi$</span> is the special distribution under which, if you select actions according to <span class="tex">$\pi$</span>, you remain in the same distribution.  That is, for which </p>
<p class="tex">$$\sum_s \mu_\pi&#40;s&#41; \sum_a \pi&#40;a\vert s&#41;p&#40;s^\prime \vert s, a&#41; &#61; \mu_\pi&#40;s^\prime&#41; \tag&#123;10.8&#125;$$</p>
<p>In the average-reward setting, returns are defined in terms of differences between rewards and the average reward: </p>
<p class="tex">$$G_t \doteq R_&#123;t&#43;1&#125; - r&#40;\pi&#41; &#43; R_&#123;t&#43;2&#125; - r&#40;\pi&#41; &#43; R_&#123;t&#43;3&#125; - r&#40;\pi&#41; &#43; \cdots \tag&#123;10.9&#125;$$</p>
<p>This is known as the <em>differential</em> return, and th corresponding value functions are known as <em>differential</em> value functions.  Differential value functions are defined in terms of the new return just as conventional value functions were defined in terms of the discounted return; thus we will use the same notation, <span class="tex">$v_\pi &#40;s&#41; \doteq \mathbb&#123;E&#125;_\pi&#91;G_t \vert S_t &#61; s&#93;$</span> and <span class="tex">$q_\pi &#40;s, a&#41; \doteq \mathbb&#123;E&#125;_\pi&#91;G_t \vert S_t &#61; s, A_t &#61; a&#93;$</span> &#40;similarly for <span class="tex">$v_*$</span> and <span class="tex">$q_*$</span>&#41;, for differential value functions.  Differential value functions also have Bellman equations, just slightly different from those we have seen earlier.  We simply remove all <span class="tex">$\gamma$</span>s and replace all rewards by the difference between the reward and the true average reward:</p>
<p class="tex">$$\begin&#123;flalign&#125;
&amp;v_\pi&#40;s&#41; &#61; \sum_a \pi&#40;a\vert s&#41; \sum_&#123;r, s^\prime&#125;p&#40;s^\prime, r \vert s, a&#41; \left &#91; r - r&#40;\pi&#41; &#43; v_\pi&#40;s^\prime&#41; \right &#93; \\
&amp;q_\pi&#40;s, a&#41; &#61; \sum_&#123;r, s^\prime&#125;p&#40;s^\prime, r \vert s, a&#41; \left &#91; r - r&#40;\pi&#41; &#43; \sum_&#123;a^\prime&#125; \pi&#40;a^\prime \vert s^\prime&#41; q_\pi&#40;s^\prime, a^\prime&#41; \right &#93; \\
&amp;v_* &#61; \max_a \sum_&#123;r, s^\prime&#125;p&#40;s^\prime, r \vert s, a&#41; \left &#91; r - r&#40;\pi&#41; &#43; v_*&#40;s^\prime&#41; \right &#93; \\
&amp;q_* &#61; \sum_&#123;r, s^\prime&#125;p&#40;s^\prime, r \vert s, a&#41; \left &#91; r - \max_&#123;\pi&#125;r&#40;\pi&#41; &#43; \max_a q_\pi&#40;s^\prime, a^\prime&#41; \right &#93; \\
\end&#123;flalign&#125;$$</p>
<p>There is also a differential form of the two TD errors:</p>
<p class="tex">$$\delta_t \doteq R_&#123;t&#43;1&#125; - \bar&#123;R&#125;_t&#43; \hat v &#40;S_&#123;t&#43;1&#125;, \mathbf&#123;w&#125;_t&#41; - \hat v&#40;S_t, \mathbf&#123;w&#125;_t&#41; \tag&#123;10.10&#125;$$</p>
<p>and</p>
<p class="tex">$$\delta_t \doteq R_&#123;t&#43;1&#125; - \bar&#123;R&#125;_t&#43; \hat q &#40;S_&#123;t&#43;1&#125;, A_&#123;t&#43;1&#125;, \mathbf&#123;w&#125;_t&#41; - \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_t&#41; \tag&#123;10.11&#125;$$</p>
<p>where <span class="tex">$\bar&#123;R&#125;_t$</span> is an estimate at time <span class="tex">$t$</span> of the average reward <span class="tex">$r&#40;\pi&#41;$</span>.  With these alternate definitions, most of our algorithms and many theoretical results carry through to the average_reward setting without any change.  </p>
<p>For example, an average reward version of semi-gradient Sarsa could be defined just as in &#40;10.2&#41; except with the differential version of the TD error.  That is by</p>
<p class="tex">$$\mathbf&#123;w&#125;_&#123;t&#43;1&#125; \doteq \mathbf&#123;w&#125;_t &#43; \alpha \delta_t \nabla \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_t&#41;$$</p>
<p>with <span class="tex">$\delta_t$</span> given by &#40;10.11&#41;.  See a full implementation below.  One limitation of this algorithm is that it does not converge to the differential values but to the differential values plut an arbitrary offset.  Notice that the Bellman equations and TD errors given above are unaffected if all the values are shifted by the same amount.  Thus, the offset may not matter in practice.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6F?persist_js_state·has_pluto_hook_features§cell_id$b8c031ca-7995-4501-a1e3-df3f34e5f0dadepends_on_disabled_cells§runtime -published_object_keysdepends_on_skipped_cells§errored$014339eb-5b23-4ac5-a551-8eeb2238366fqueued¤logsrunning¦outputbody5access_control_step (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA6⬰persist_js_state·has_pluto_hook_features§cell_id$014339eb-5b23-4ac5-a551-8eeb2238366fdepends_on_disabled_cells§runtime %lpublished_object_keysdepends_on_skipped_cells§errored$49249ac1-8964-4afc-89f2-3cd4d4322cc2queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 10.1</em></h3>
<p>We have not explicitely considered or given pseudocode for any Monte Carlo methods in this chapter.  What would they be like?  Why is it reasonable not to give pseudocode for them?  How would they perform on the Mountain Car task?</p>
</blockquote>
<p>Monte Carlo methods require an episode to terminate prior to updating any action value estimates.  After the final reward is retrieved then all the action value pairs visited along the trajectory can be updated and the policy can be updated prior to starting the next episode.  For tasks such as the Mountain Car task where a random policy will likely never terminate, such a method will never be able to complete a single episode worth of updates.  We saw in earlier chapters with the racetrack and gridworld examples that for some environments a bootstrap method is the only suitable one given this possibility of an episode never terminating.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6E~persist_js_state·has_pluto_hook_features§cell_id$49249ac1-8964-4afc-89f2-3cd4d4322cc2depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$1a5acfb0-3b35-41b1-98f8-ffce941c587fqueued¤logsrunning¦outputbodyX<div class="markdown"><h4>Mountain Car Linear Approximation with Tile Coding</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA6D persist_js_state·has_pluto_hook_features§cell_id$1a5acfb0-3b35-41b1-98f8-ffce941c587fdepends_on_disabled_cells§runtime 1published_object_keysdepends_on_skipped_cells§errored$7bc49107-9de5-4985-8750-979f36b3aa81queued¤logsrunning¦outputbody1π_mountain_car2 (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6Rkpersist_js_state·has_pluto_hook_features§cell_id$7bc49107-9de5-4985-8750-979f36b3aa81depends_on_disabled_cells§runtime %published_object_keysdepends_on_skipped_cellsçerrored$4d392303-4681-4ea1-8dcc-e002a78ea0a1queued¤logsrunning¦outputbody<div class="markdown"><h3>Policy Improvement</h3>
<p>The purpose of the value function lies in the <em>Policy Improvement Theorem</em> which provides a way to iteratively improve a given policy towards the optimal policy.  Consider a policy <span class="tex">$\pi&#40;s&#41;$</span> and its associated value functions <span class="tex">$v_\pi&#40;s&#41;$</span> and <span class="tex">$q_\pi&#40;s, a&#41;$</span>.  Now consider a new policy <span class="tex">$\pi^\prime&#40;s&#41;$</span> that would select a different action <span class="tex">$a^\prime$</span> at state <span class="tex">$s$</span> than the original policy <span class="tex">$\pi$</span> such that <span class="tex">$q_\pi&#40;s, a^\prime&#41; \geq v_\pi&#40;s&#41;$</span>.  The theorem proves that if the former is true, then <span class="tex">$v_&#123;\pi^\prime&#125;&#40;s&#41; \geq v_\pi&#40;s&#41; \forall s \in \mathcal&#123;S&#125;$</span>.  In other words, the new policy is superior to the old one since it has a higher value value at every state.  There is also an easy way to construct a policy which meets the necessary criteria of the policy improvement theorem:</p>
<p class="tex">$$\begin&#123;flalign&#125;
\pi^\prime&#40;s&#41; &amp;\doteq \mathrm&#123;argmax&#125;_a q_\pi&#40;s, a&#41; \\
&amp; &#61; \mathrm&#123;argmax&#125;_a \mathbb&#123;E&#125; &#91;R_&#123;t&#43;1&#125; &#43; \gamma v_\pi&#40;S_&#123;t&#43;1&#125;&#41; \mid S_t &#61; s, A_t &#61; a&#93; \\
&amp; &#61; \mathrm&#123;argmax&#125;_a \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; &#91;r &#43; \gamma v_\pi&#40;s^\prime&#41;&#93; \\
\end&#123;flalign&#125;$$</p>
<p>If we have the state-action value function <span class="tex">$q_\pi&#40;s, a&#41;$</span>, then the construction is trivial.  If we only have <span class="tex">$v_\pi&#40;s&#41;$</span>, then we must also have the probability transition function for the environment in order to reconstruct the state-action values.  In the absence of <span class="tex">$p$</span> we must rely on <span class="tex">$q_\pi$</span>.  Consider some future policy such that <span class="tex">$\pi&#40;s&#41; &#61; \mathrm&#123;argmax&#125;_a q_\pi&#40;s, a&#41; \: \forall s$</span>.  In this case, the updated policy will be identical to the original policy and the process will have converged.  The policy at convergence will also be the optimal policy <span class="tex">$\pi_*$</span> whose value functions fulfill the following properties:</p>
<p class="tex">$$\begin&#123;flalign&#125;
v_*&#40;s&#41; &amp;\doteq \max_\pi v_\pi&#40;s&#41; \: \forall \: s \in \mathcal&#123;S&#125; \tag&#123;3.15&#125; \\
&amp;&#61; \max_&#123;a \in \mathcal&#123;A&#125;&#40;s&#41;&#125; q_&#123;*&#125;&#40;s, a&#41; \: \forall \: s \in \mathcal&#123;S&#125; \tag&#123;meaning of optimal&#125;\\
&amp;&#61; \max_&#123;a \in \mathcal&#123;A&#125;&#40;s&#41;&#125; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; \left &#91; r &#43; γ v_* &#40;s^\prime&#41; \right &#93; \quad \forall s \in \mathcal&#123;S&#125; \tag&#123;Used by Value Iteration when p is available&#125;\\
q_*&#40;s, a&#41; &amp;\doteq \max_\pi q_\pi&#40;s, a&#41; \: \forall \: s \in \mathcal&#123;S&#125; \text&#123; and &#125; a \in \mathcal&#123;A&#125;&#40;s&#41; \tag&#123;3.16&#125; \\
&amp;&#61;\mathbb&#123;E&#125; \left &#91; R_&#123;t&#43;1&#125; &#43; \gamma v_* &#40;S_&#123;t&#43;1&#125;&#41; \mid S_t &#61; s, A_t &#61; a \right &#93; \tag&#123;3.17&#125; \\
&amp;&#61; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; \left &#91; r &#43; γ v_* &#40;s^\prime&#41; \right &#93; \tag&#123;exp value def &#40;3.21&#41;&#125; \\
&amp;&#61; \sum_&#123;s^\prime, r&#125; p&#40;s^\prime, r \vert s, a&#41; \left &#91; r &#43; γ \max_&#123;a^\prime&#125; q_*&#40;s^\prime, a^\prime&#41; \right &#93; \tag&#123;Used by Q Value Iteration when p is available&#125; \\
&amp;&#61; \mathbb&#123;E&#125; \left &#91; R_t &#43; γ \max_&#123;a^\prime&#125; q_*&#40;s^\prime, a^\prime&#41; \mid S_t &#61; s, A_t &#61; a \right &#93; \tag&#123;Used by Q Learning when p is not available&#125; \\
\end&#123;flalign&#125;$$</p>
<p>The policy improvement theorem suggests an approach where we initialize a random policy, find its value function, and then derive an improved policy until the process has converged.  If we have the probability transition function, we can use dynamic programming to calculate the value function for a policy as well as the improved policy.  Repeating this process until convergence is called <em>Policy Iteration</em>.  Alternatively, we can use the properties of the optimal value function without explicitely considering a sequence of policies.  That is only possible when the probability transition function is known and is called <em>Value Iteration</em>.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6A persist_js_state·has_pluto_hook_features§cell_id$4d392303-4681-4ea1-8dcc-e002a78ea0a1depends_on_disabled_cells§runtime 	published_object_keysdepends_on_skipped_cells§errored$d3ba78fa-f032-4bb9-9359-ef3bcff2252dqueued¤logsrunning¦outputbodyDmountaincar_fcann_differential_test (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$d3ba78fa-f032-4bb9-9359-ef3bcff2252ddepends_on_disabled_cells§runtime )逵published_object_keysdepends_on_skipped_cellsçerrored$742100ba-c38e-4840-8988-40990039b527queued¤logsrunning¦outputbody9setup_mountain_car_tiles (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6`persist_js_state·has_pluto_hook_features§cell_id$742100ba-c38e-4840-8988-40990039b527depends_on_disabled_cells§runtime Jpublished_object_keysdepends_on_skipped_cellsçerrored$2f0d0a71-c65b-4aa0-a493-e7cdccd901ebqueued¤logsrunning¦outputbody8plot_mountaincar_values (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$2f0d0a71-c65b-4aa0-a493-e7cdccd901ebdepends_on_disabled_cells§runtime 6>published_object_keysdepends_on_skipped_cellsçerrored$a3cf270b-b309-44f0-9972-bd84228bcf17queued¤logsrunning¦outputbody	/<div class="markdown"><h3>Finding the Optimal Policy</h3>
<p>Depending on the nature of the problem and the available information, different techniques are available.  Below is a summary of the conditions and available techniques for different scenarios starting with the ideal case where all information is available.</p>
<h4>Idealized Tabular Case</h4>
<h5>Problem conditions</h5>
<ul>
<li><p>All states and actions can be enumerated: <span class="tex">$\mathcal&#123;S&#125; &#61; \&#123;s_1, s_2, \cdots, s_n\&#125;$</span> and <span class="tex">$\mathcal&#123;A&#125; &#61; \&#123;a_1, a_2, \cdots, a_m\&#125;$</span></p>
</li>
<li><p><span class="tex">$p&#40;s^\prime, r \vert s, a&#41;$</span> is available for all states and actions</p>
</li>
</ul>
<p>In order to verify that we have the correct value function or the optimal one, we need to confirm the conditions for every state or state-action pair.  In short we require <span class="tex">$p&#40;s^\prime, r \vert s, a&#41; \: \forall s, a$</span> which also implies the ability to check all the state action pairs.  If this is possible, then the problem is <em>tabular</em> since we can tabulate all of the necessary values.  It is only in this best case scenario that we can definitively verify the correct solution.</p>
<h5>Solution Techniques</h5>
<ul>
<li><p>Value Iteration</p>
<ul>
<li><p>initialize a list of state values: <span class="tex">$&#91;v_1, v_2, \cdots, v_n&#93;$</span>, one for each state</p>
</li>
<li><p>perform the following update accross all states until the values converge: <span class="tex">$v_i &#61; \max_&#123;a \in \mathcal&#123;A&#125;&#125; \sum_&#123;s_j, r&#125; p&#40;s_j, r \vert s_i, a&#41; \left &#91; r &#43; γ v_j \right &#93;$</span></p>
</li>
</ul>
</li>
<li><p>Policy Iteration</p>
<ul>
<li><p>initialize a random policy <span class="tex">$\pi$</span> &#40;probability distribution over actions for each state, could be a matrix&#41;</p>
</li>
<li><p>initialize a list of state values: <span class="tex">$&#91;v_1, v_2, \cdots, v_n&#93;$</span>, one for each state</p>
</li>
<li><p>repeat the following until the values converge</p>
<ul>
<li><p>use dynamic programming policy evaulation to update the state values</p>
</li>
<li><p>update the policy to be greedy with respect to the value function</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>mimetext/htmlrootassigneelast_run_timestampA6Apersist_js_state·has_pluto_hook_features§cell_id$a3cf270b-b309-44f0-9972-bd84228bcf17depends_on_disabled_cells§runtime npublished_object_keysdepends_on_skipped_cells§errored$b9125c5b-01d6-451e-84b5-a419e38425b5queued¤logsrunning¦outputbody6π_mountain_car_fcann (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6%persist_js_state·has_pluto_hook_features§cell_id$b9125c5b-01d6-451e-84b5-a419e38425b5depends_on_disabled_cells§runtime gpublished_object_keysdepends_on_skipped_cellsçerrored$9d65285f-d49e-40ce-acea-1f565bcd4108queued¤logsrunning¦outputbodymsgUndefVarError: `TabularDeterministicTransition` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_short,make_tabular_mountaincar(N::Int64, M::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#12f5065b-5bed-4d03-a0f0-72a942492394#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#12f5065b-5bed-4d03-a0f0-72a942492394source_packageMaincall,make_tabular_mountaincar(N::Int64, M::Int64)linfo_typeCore.MethodInstanceline!fileZChapter_10_On_policy_Control_with_Approximation.jl#==#12f5065b-5bed-4d03-a0f0-72a942492394funcmake_tabular_mountaincarparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#9d65285f-d49e-40ce-acea-1f565bcd4108source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#9d65285f-d49e-40ce-acea-1f565bcd4108functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6tpersist_js_state·has_pluto_hook_features§cell_id$9d65285f-d49e-40ce-acea-1f565bcd4108depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$57a6510f-bd42-4d1d-a550-d1442f79569fqueued¤logsrunning¦outputbody_<div class="markdown"><h3><em>Semi-gradient Dynamic Programming Implementation</em></h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6C'persist_js_state·has_pluto_hook_features§cell_id$57a6510f-bd42-4d1d-a550-d1442f79569fdepends_on_disabled_cells§runtime Zpublished_object_keysdepends_on_skipped_cells§errored$b0761704-5447-4e64-8270-708d9dccef60queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDPTransitionDistribution` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b0761704-5447-4e64-8270-708d9dccef60source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b0761704-5447-4e64-8270-708d9dccef60functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Apersist_js_state·has_pluto_hook_features§cell_id$b0761704-5447-4e64-8270-708d9dccef60depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$a6c5ec28-b2d5-4893-a118-95c1318d1f7fqueued¤logsrunning¦outputbodyC<div class="markdown"><blockquote>
<h3><em>Exercise 10.6</em></h3>
<p>Suppose there is an MDP that under any policy produces the deterministic sequence of rewards &#43;1, 0, &#43;1, 0, &#43;1, 0, . . . going on forever. Technically, this violates ergodicity; there is no stationary limiting distribution <span class="tex">$μ_\pi$</span> and the limit &#40;10.7&#41; does not exist. Nevertheless, the average reward &#40;10.6&#41; is well defined. What is it? Now consider two states in this MDP. From A, the reward sequence is exactly as described above, starting with a &#43;1, whereas, from B, the reward sequence starts with a 0 and then continues with &#43;1, 0, &#43;1, 0, . . .. We would like to compute the differential values of A and B. Unfortunately, the differential return &#40;10.9&#41; is not well defined when starting from these states as the implicit limit does not exist. To repair this, one could alternatively define the differential value of a state as <span class="tex">$v_\pi &#40;s&#41; \doteq \lim_&#123;\gamma \rightarrow 1&#125; \lim_&#123;h \rightarrow \infty&#125; \sum_&#123;t&#61;0&#125;^h \gamma^t \left &#40; \mathbb&#123;E_\pi&#125; &#91;R_&#123;t&#43;1&#125;|S_0&#61;s&#93;-r&#40;\pi&#41;  \right &#41;$</span>.  Under this definition what are the differential values of states A and B?</p>
</blockquote>
</div>mimetext/htmlrootassigneelast_run_timestampA6G:persist_js_state·has_pluto_hook_features§cell_id$a6c5ec28-b2d5-4893-a118-95c1318d1f7fdepends_on_disabled_cells§runtime c0Lpublished_object_keysdepends_on_skipped_cells§errored$f1edb500-fbd1-4c03-b033-53860dfa452dqueued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 10.7</em></h3>
<p>Consider a Markov reward process consisting of a ring of three states A, B, and C, with state transitions going deterministically around the ring.  A reward of &#43;1 is received upon arrival in A and otherwise the reward is 0.  What are the differential values of the three states, using &#40;10.13&#41;</p>
</blockquote>
<p>From 10.13 we have </p>
<p class="tex">$$v_\pi &#40;s&#41; \doteq \lim_&#123;\gamma \rightarrow 1&#125; \lim_&#123;h \rightarrow \infty&#125; \sum_&#123;t&#61;0&#125;^h \gamma^t \left &#40; \mathbb&#123;E_\pi&#125; &#91;R_&#123;t&#43;1&#125;|S_0&#61;s&#93;-r&#40;\pi&#41;  \right &#41;$$</p>
<p>The average reward per step is <span class="tex">$\frac&#123;1&#125;&#123;3&#125;$</span> so we can apply the same method used in exercise 10.6 where the elements inside the parentheses of the sum are: <span class="tex">$\frac&#123;2&#125;&#123;3&#125;$</span> for <span class="tex">$C \rightarrow A$</span> and <span class="tex">$-\frac&#123;1&#125;&#123;3&#125;$</span> for the other two.  Starting in state A we transition twice and then on the third arrive in state A leading to the following mean corrected values of <span class="tex">$-\frac&#123;1&#125;&#123;3&#125;$</span>, <span class="tex">$-\frac&#123;1&#125;&#123;3&#125;$</span>, and <span class="tex">$\frac&#123;2&#125;&#123;3&#125;$</span>.  The other states will have these values cyclically permuted leading to the following infinite sums:</p>
<p>For state A: <span class="tex">$-\frac&#123;1&#125;&#123;3&#125; - \frac&#123;1&#125;&#123;3&#125;\gamma &#43; \frac&#123;2&#125;&#123;3&#125;\gamma^2 - \frac&#123;1&#125;&#123;3&#125;\gamma^3 - \frac&#123;1&#125;&#123;3&#125;\gamma^4 &#43; \cdots$</span></p>
<p>For state B: <span class="tex">$-\frac&#123;1&#125;&#123;3&#125; &#43; \frac&#123;2&#125;&#123;3&#125;\gamma - \frac&#123;1&#125;&#123;3&#125;\gamma^2 - \frac&#123;1&#125;&#123;3&#125;\gamma^3 &#43; \frac&#123;2&#125;&#123;3&#125;\gamma^4 &#43; \cdots$</span></p>
<p>For state C: <span class="tex">$\frac&#123;2&#125;&#123;3&#125; - \frac&#123;1&#125;&#123;3&#125;\gamma - \frac&#123;1&#125;&#123;3&#125; \gamma^2 &#43; \frac&#123;2&#125;&#123;3&#125;\gamma^3 &#43; \cdots &#61; 3 \times &#40;2 - \gamma - \gamma^2 &#43; 2\gamma^3 &#43; \cdots&#41;$</span></p>
<p>Comparing these sequences we have:</p>
<p class="tex">$$\gamma \times v&#40;A&#41; &#61; v&#40;C&#41; - \frac&#123;2&#125;&#123;3&#125; \implies v&#40;A&#41; &#61; \frac&#123;v&#40;C&#41; - \frac&#123;2&#125;&#123;3&#125;&#125;&#123;\gamma&#125;$$</p>
<p class="tex">$$\gamma \times v&#40;B&#41; &#61; v&#40;A&#41; &#43; \frac&#123;1&#125;&#123;3&#125; \implies v&#40;A&#41; &#61; \gamma \times v&#40;B&#41; - \frac&#123;1&#125;&#123;3&#125;$$</p>
<p>so</p>
<p class="tex">$$\frac&#123;v&#40;C&#41; - \frac&#123;2&#125;&#123;3&#125;&#125;&#123;\gamma&#125; &#61; \gamma \times v&#40;B&#41; - \frac&#123;1&#125;&#123;3&#125; \implies v&#40;C&#41; &#61; \gamma \left &#40; \gamma \times v&#40;B&#41; - \frac&#123;1&#125;&#123;3&#125; \right &#41; &#43; \frac&#123;2&#125;&#123;3&#125;$$</p>
<p>also </p>
<p class="tex">$$\gamma \times v&#40;C&#41; &#61; v&#40;B&#41; &#43; \frac&#123;1&#125;&#123;3&#125; \implies v&#40;C&#41; &#61; \frac&#123;v&#40;B&#41; &#43; \frac&#123;1&#125;&#123;3&#125;&#125;&#123;\gamma&#125;$$</p>
<p>Equation the two sides for <span class="tex">$v&#40;C&#41;$</span> that only contain <span class="tex">$v&#40;B&#41;$</span> terms we have:</p>
<p class="tex">$$\frac&#123;v&#40;B&#41; &#43; \frac&#123;1&#125;&#123;3&#125;&#125;&#123;\gamma&#125; &#61; \gamma \left &#40; \gamma \times v&#40;B&#41; - \frac&#123;1&#125;&#123;3&#125; \right &#41; &#43; \frac&#123;2&#125;&#123;3&#125;$$</p>
<p class="tex">$$v&#40;B&#41; &#61; \gamma \left &#40; \gamma \left &#40; \gamma \times v&#40;B&#41; - \frac&#123;1&#125;&#123;3&#125; \right &#41; &#43; \frac&#123;2&#125;&#123;3&#125; \right &#41; - \frac&#123;1&#125;&#123;3&#125; &#61; \gamma^3 v&#40;B&#41; - \gamma^2 \frac&#123;1&#125;&#123;3&#125; &#43; \gamma\frac&#123;2&#125;&#123;3&#125; - \frac&#123;1&#125;&#123;3&#125;$$</p>
<p class="tex">$$v&#40;B&#41; \left &#40; 1 - \gamma^3 \right &#41; &#61; - \gamma^2 \frac&#123;1&#125;&#123;3&#125; &#43; \gamma\frac&#123;2&#125;&#123;3&#125; - \frac&#123;1&#125;&#123;3&#125; \implies v&#40;B&#41; &#61; \frac&#123;- \gamma^2 \frac&#123;1&#125;&#123;3&#125; &#43; \gamma\frac&#123;2&#125;&#123;3&#125; - \frac&#123;1&#125;&#123;3&#125;&#125;&#123;1 - \gamma^3&#125;$$</p>
<p class="tex">$$v&#40;B&#41; &#61; -\frac&#123;1&#125;&#123;3&#125; \frac&#123;\gamma^2 - 2\gamma &#43; 1&#125;&#123;1 - \gamma^3&#125; &#61; -\frac&#123;1&#125;&#123;3&#125; \frac&#123;&#40;\gamma - 1&#41;^2&#125;&#123;-&#40;\gamma - 1&#41;&#40;\gamma^2 &#43; \gamma &#43; 1&#41;&#125; &#61; \frac&#123;1&#125;&#123;3&#125; \frac&#123;\gamma - 1&#125;&#123;\gamma^2 &#43; \gamma &#43; 1&#125;$$</p>
<p>Therefore, </p>
<p class="tex">$$\begin&#123;flalign&#125;
\lim_&#123;\gamma \rightarrow 1&#125; v&#40;B&#41; &amp;&#61; \frac&#123;1&#125;&#123;3&#125; \frac&#123;1 - 1&#125;&#123;3&#125; &#61; 0 \\
\lim_&#123;\gamma \rightarrow 1&#125; v&#40;A&#41; &amp;&#61; \gamma \times 0 - \frac&#123;1&#125;&#123;3&#125; &#61; -\frac&#123;1&#125;&#123;3&#125; \\
&#36;\lim_&#123;\gamma \rightarrow 1&#125; v&#40;C&#41; &amp;&#61;  \frac&#123;0 &#43; \frac&#123;1&#125;&#123;3&#125;&#125;&#123;\gamma&#125; &#61; \frac&#123;1&#125;&#123;3&#125;
\end&#123;flalign&#125;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6G9persist_js_state·has_pluto_hook_features§cell_id$f1edb500-fbd1-4c03-b033-53860dfa452ddepends_on_disabled_cells§runtime #published_object_keysdepends_on_skipped_cells§errored$96548352-cd4d-4448-8312-ed10057f4359queued¤logsrunning¦outputbody4update_parameters! (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA6Tpersist_js_state·has_pluto_hook_features§cell_id$96548352-cd4d-4448-8312-ed10057f4359depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$ed1bd92c-8cc7-457f-9692-a10a9487c953queued¤logsrunning¦outputbodyٴ<style>
	main {
		margin: 0 auto;
		max-width: min(1600px, 90%);
		padding-left: max(10px, 5%);
		padding-right: max(10px, 5%);
		font-size: max(10px, min(24px, 2vw));
	}
</style>
mimetext/htmlrootassigneelast_run_timestampA6Ipersist_js_state·has_pluto_hook_features§cell_id$ed1bd92c-8cc7-457f-9692-a10a9487c953depends_on_disabled_cells§runtime xpublished_object_keysdepends_on_skipped_cellsçerrored$c9759bd9-ec9b-47a1-9080-a7fc332be565queued¤logsrunning¦outputbodyGdifferential_semi_gradient_q_learning! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6_=persist_js_state·has_pluto_hook_features§cell_id$c9759bd9-ec9b-47a1-9080-a7fc332be565depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$953907cd-9926-4478-99b3-da7068118c22queued¤logsrunning¦outputbodyLgradient_monte_carlo_action_episode_update! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6Lpersist_js_state·has_pluto_hook_features§cell_id$953907cd-9926-4478-99b3-da7068118c22depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$278a26ac-c48f-4e18-93bb-706a4634c8c0queued¤logsrunning¦outputbody<div class="markdown"><p>Two options to represent parameters for use with action-values is to simply have a unique set of parameters for each action each of which matches the size of the state representation vector.  Using this technique means we do not need to encode the action space into the representation.  The parameters could be represented by a vector of vectors or a matrix in which each column is assigned to an action.  Below are the update rules for both of these cases.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Chpersist_js_state·has_pluto_hook_features§cell_id$278a26ac-c48f-4e18-93bb-706a4634c8c0depends_on_disabled_cells§runtime +˵published_object_keysdepends_on_skipped_cells§errored$8b7e1031-9864-439c-86eb-11aa08f53b90queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#8b7e1031-9864-439c-86eb-11aa08f53b90source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#8b7e1031-9864-439c-86eb-11aa08f53b90functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Ypersist_js_state·has_pluto_hook_features§cell_id$8b7e1031-9864-439c-86eb-11aa08f53b90depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$d577b393-4b40-4c90-9993-4ffbcbd9df6dqueued¤logsrunning¦outputbodyprefixFloat32elements-1.0text/plain0.0text/plain1.0text/plaintypeArrayprefix_shortobjectid6e918b9b045291d6mime!application/vnd.pluto.tree+objectrootassigneeconst mountain_car_actionslast_run_timestampA6Z persist_js_state·has_pluto_hook_features§cell_id$d577b393-4b40-4c90-9993-4ffbcbd9df6ddepends_on_disabled_cells§runtime ĵpublished_object_keysdepends_on_skipped_cells§errored$5fdbce61-ca25-45e0-b07d-94adf7138446queued¤logsrunning¦outputbodymsg٨UndefVarError: `mountain_car_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_short~mountaincar_fcann_test(max_steps::Int64, α::Float32, ϵ::Float32; num_layers::Int64, layer_size::Int64, kwargs::@Kwargs{…})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#c11aa069-93c2-435a-8f0e-353ced9633b6#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#c11aa069-93c2-435a-8f0e-353ced9633b6source_packageMaincallmountaincar_fcann_test(max_steps::Int64, α::Float32, ϵ::Float32; num_layers::Int64, layer_size::Int64, kwargs::@Kwargs{compute_value::typeof(compute_sarsa_value), λ::Float32, c::Float32, dropout::Float32})linfo_typeCore.MethodInstanceline
fileZChapter_10_On_policy_Control_with_Approximation.jl#==#c11aa069-93c2-435a-8f0e-353ced9633b6func#mountaincar_fcann_test#66parent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#5fdbce61-ca25-45e0-b07d-94adf7138446source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#5fdbce61-ca25-45e0-b07d-94adf7138446func##function_wrapped_cell#514parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneemountain_car_fcannlast_run_timestampA6jpersist_js_state·has_pluto_hook_features§cell_id$5fdbce61-ca25-45e0-b07d-94adf7138446depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$49e43d51-05d6-415b-a685-76e50904c5bcqueued¤logsrunning¦outputbody>mountaincar_differential_test (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6Hpersist_js_state·has_pluto_hook_features§cell_id$49e43d51-05d6-415b-a685-76e50904c5bcdepends_on_disabled_cells§runtime  _published_object_keysdepends_on_skipped_cellsçerrored$0f958535-6b18-46de-a1ba-81f64c217ee0queued¤logsrunning¦outputbody5mountaincar_fcann_dp (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6{݇persist_js_state·has_pluto_hook_features§cell_id$0f958535-6b18-46de-a1ba-81f64c217ee0depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cellsçerrored$44d43dbf-fe32-438e-b89d-c677bbc35893queued¤logsrunning¦outputbody<div class="markdown"><p>In order to use &#40;10.6&#41;: <span class="tex">$r&#40;\pi&#41; \doteq \lim_&#123;h \rightarrow \infty&#125; \frac&#123;1&#125;&#123;h&#125; \sum_&#123;t &#61; 1&#125;^h \mathbb&#123;E&#125; &#91;R_t \mid S_0, A_&#123;0:t-1&#125; \sim \pi&#93;$</span> we need to compute <span class="tex">$\mathbb&#123;E&#125; &#91;R_t \mid S_0, A_&#123;0:t-1&#125; \sim \pi&#93;$</span>.  In this case, we are told that regardless of the policy, the reward sequence will be &#43;1, 0, &#43;1, 0, ....  We can therefore replace the expected values in the equation with this sequence since the rewards at each time step are known with 100&#37; probability.</p>
<p>the average reward can be computed as <span class="tex">$r&#40;\pi&#41; &#61; \lim_&#123;h \rightarrow \infty&#125; \frac&#123;1&#125;&#123;2h&#125;\sum_&#123;t&#61;1&#125;^h &#40;-1&#41;^&#123;t&#43;1&#125; &#43; 1 &#61; \lim_&#123;h \rightarrow \infty&#125; \frac&#123;h&#125;&#123;2h&#125; &#43; \frac&#123;1&#125;&#123;2h&#125; \sum_&#123;t&#61;1&#125;^h &#40;-1&#41;^&#123;t&#43;1&#125;$</span></p>
<p>The sum left in the expression is <span class="tex">$1 - 1 &#43; 1 - 1 \cdots$</span> which is 1 for even h and 0 for odd h.  Either way, when divided by <span class="tex">$2h$</span> that term goes to 0 leaving only the term <span class="tex">$\frac&#123;h&#125;&#123;2h&#125; &#61; \frac&#123;1&#125;&#123;2&#125;$</span> so <span class="tex">$r&#40;\pi&#41; &#61; \frac&#123;1&#125;&#123;2&#125;$</span></p>
<p>To compute the differential value function for state A and B, consider the alternative definition above using the fact that <span class="tex">$r&#40;\pi&#41; &#61; 0.5$</span>.  </p>
<p>For state A, each parenthetical term in the sum will be: <span class="tex">$1 - 0.5, 0 - 0.5, 1 - 0.5, 0 - 0.5, \dots &#61; 0.5, -0.5, 0.5, -0.5, \dots$</span></p>
<p>For state B, each parenthetical term in the sum will be: <span class="tex">$0 - 0.5, 1 - 0.5, 0 - 0.5, 1 - 0.5, \dots &#61; -0.5, 0.5, -0.5, 0.5, \dots$</span></p>
<p class="tex">$$\begin&#123;flalign&#125;
v_\pi &#40;A&#41; &amp;&#61; \lim_&#123;\gamma \rightarrow 1&#125; \lim_&#123;h \rightarrow \infty&#125; 0.5 - 0.5\gamma &#43; 0.5 \gamma^2 - 0.5\gamma^3 &#43; \cdots \\
&amp;&#61;0.5\lim_&#123;\gamma \rightarrow 1&#125; \lim_&#123;h \rightarrow \infty&#125;\sum_&#123;t&#61;0&#125;^h &#40;-\gamma&#41;^t \\
&amp;&#61;0.5\lim_&#123;\gamma \rightarrow 1&#125;\frac&#123;1&#125;&#123;\gamma &#43;1 &#125; &#61; 0.25
\end&#123;flalign&#125;$$</p>
<p class="tex">$$\begin&#123;flalign&#125;
v_\pi &#40;B&#41; &amp;&#61; \lim_&#123;\gamma \rightarrow 1&#125; \lim_&#123;h \rightarrow \infty&#125; -0.5 &#43; 0.5\gamma - 0.5 \gamma^2 &#43; 0.5\gamma^3 &#43; \cdots \\
&amp;&#61;-0.5\lim_&#123;\gamma \rightarrow 1&#125; \lim_&#123;h \rightarrow \infty&#125;\sum_&#123;t&#61;0&#125;^h &#40;-\gamma&#41;^t \\
&amp;&#61;-0.5\lim_&#123;\gamma \rightarrow 1&#125;\frac&#123;1&#125;&#123;\gamma &#43;1 &#125; &#61; -0.25
\end&#123;flalign&#125;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Gcpersist_js_state·has_pluto_hook_features§cell_id$44d43dbf-fe32-438e-b89d-c677bbc35893depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$b3658e4d-ee8e-45cd-906a-06dd512a6921queued¤logsrunning¦outputbodymsgَUndefVarError: `mountaincar_fcann_dp_results` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b3658e4d-ee8e-45cd-906a-06dd512a6921source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b3658e4d-ee8e-45cd-906a-06dd512a6921functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Npersist_js_state·has_pluto_hook_features§cell_id$b3658e4d-ee8e-45cd-906a-06dd512a6921depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$00e7783f-7f17-4944-a085-ea87509cd75aqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#00e7783f-7f17-4944-a085-ea87509cd75asource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#00e7783f-7f17-4944-a085-ea87509cd75afunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6/|Npersist_js_state·has_pluto_hook_features§cell_id$00e7783f-7f17-4944-a085-ea87509cd75adepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$5be866c3-0fb2-4d1f-9c31-b85aba332905queued¤logsrunning¦outputbody:semi_gradient_q_learning! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6òpersist_js_state·has_pluto_hook_features§cell_id$5be866c3-0fb2-4d1f-9c31-b85aba332905depends_on_disabled_cells§runtime  published_object_keysdepends_on_skipped_cells§errored$e5ad765a-341f-4f11-9ae8-37d81cb349d2queued¤logsrunning¦outputbodymsg UndefVarError: `StateMDPTransitionSampler` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#e5ad765a-341f-4f11-9ae8-37d81cb349d2source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#e5ad765a-341f-4f11-9ae8-37d81cb349d2functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassignee*const mountain_car_differential_transitionlast_run_timestampA6n?persist_js_state·has_pluto_hook_features§cell_id$e5ad765a-341f-4f11-9ae8-37d81cb349d2depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$8befede5-378a-447a-96bd-edcd9d2ce98bqueued¤logsrunning¦outputbody	<div class="markdown"><p>We can use these to create a sampling transition function, although it will be deterministic.  The positions and velocities are still defined by two real numbers so the state space is unbounded and we cannot use a tabular method.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Dpersist_js_state·has_pluto_hook_features§cell_id$8befede5-378a-447a-96bd-edcd9d2ce98bdepends_on_disabled_cells§runtime {published_object_keysdepends_on_skipped_cells§errored$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667queued¤logsrunning¦outputbodymsgٵUndefVarError: `mountain_car_differential_mdp` not defined in `Main.var"workspace#5"`
Suggestion: add an appropriate import or assignment. This global was declared but not assigned.stacktracecall_short٘mountaincar_fcann_differential_test(max_steps::Int64, α::Float32, β::Float32, ϵ::Float32; num_layers::Int64, layer_size::Int64, kwargs::@Kwargs{…})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#d3ba78fa-f032-4bb9-9359-ef3bcff2252d#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#d3ba78fa-f032-4bb9-9359-ef3bcff2252dsource_packageMaincallmountaincar_fcann_differential_test(max_steps::Int64, α::Float32, β::Float32, ϵ::Float32; num_layers::Int64, layer_size::Int64, kwargs::@Kwargs{compute_value::typeof(compute_q_learning_value)})linfo_typeCore.MethodInstanceline
fileZChapter_10_On_policy_Control_with_Approximation.jl#==#d3ba78fa-f032-4bb9-9359-ef3bcff2252dfunc'#mountaincar_fcann_differential_test#79parent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#ae5c5377-8b44-4c82-a63c-d2cb8a0d6667source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#ae5c5377-8b44-4c82-a63c-d2cb8a0d6667func##function_wrapped_cell#562parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Xpersist_js_state·has_pluto_hook_features§cell_id$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867fqueued¤logsrunning¦outputbody.update_input! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6&אpersist_js_state·has_pluto_hook_features§cell_id$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867fdepends_on_disabled_cells§runtime ypublished_object_keysdepends_on_skipped_cells§errored$065b2626-01f1-443f-8be4-3036003a2772queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#065b2626-01f1-443f-8be4-3036003a2772source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#065b2626-01f1-443f-8be4-3036003a2772functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6A3persist_js_state·has_pluto_hook_features§cell_id$065b2626-01f1-443f-8be4-3036003a2772depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$57ea3538-33be-4673-b914-8191d35426a9queued¤logsrunning¦outputbodymsgUndefVarError: `value_iteration_v` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#57ea3538-33be-4673-b914-8191d35426a9source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#57ea3538-33be-4673-b914-8191d35426a9functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassignee!const mountaincar_value_iterationlast_run_timestampA68persist_js_state·has_pluto_hook_features§cell_id$57ea3538-33be-4673-b914-8191d35426a9depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adbqueued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 10.8</em></h3>
<p>The pseudocode in the box on page 251 updates <span class="tex">$\bar R_t$</span> using <span class="tex">$\delta_t$</span> as an error rather than simply <span class="tex">$R_&#123;t&#43;1&#125; - \bar R_t$</span>.  Both errors work, but using <span class="tex">$\delta_t$</span> is better.  To see why, consider the ring MRP of three states from Exercise 10.7.  The estimate of the average reward should tend towards its true value of <span class="tex">$\frac&#123;1&#125;&#123;3&#125;$</span>.  Suppose it was already there and was held stuck there.  What would the sequence of <span class="tex">$R_&#123;t&#43;1&#125; - \bar R_t$</span> errors be?  What would the sequence of <span class="tex">$\delta_t$</span> errors be &#40;using Equation 10.10&#41;?  Which error sequence would produce a more stable estimate of the average reward if the estimate were allowed to change in response to the errors? Why?</p>
</blockquote>
<p>The sequence of <span class="tex">$R_&#123;t&#43;1&#125; - \bar R_t$</span> would be given by the cyclical sequence of rewards.  Let&#39;s assume we start the sequence at state A.  Then our reward sequence will be 0, 0, 1, 0, 0, 1... so the error sequence will be <span class="tex">$-\frac&#123;1&#125;&#123;3&#125;$</span>, <span class="tex">$-\frac&#123;1&#125;&#123;3&#125;$</span>, <span class="tex">$\frac&#123;2&#125;&#123;3&#125;$</span>,...  If we update the average error estimate using these corrections it would remain centered at the correct value but fluctuate up and down with each correction.</p>
<p>In order to calculate <span class="tex">$\delta_t$</span> we must use the definition given by 10.10:</p>
<p class="tex">$$\delta_t &#61; R_&#123;t&#43;1&#125; - \bar R_t &#43; \hat v&#40;S_&#123;t&#43;1&#125;, \mathbf&#123;w&#125;_t&#41; - \hat v&#40;S_t, \mathbf&#123;w&#125;_t&#41;$$</p>
<p>This equation requires us to have value estimates for each state which we can assume have converged to the true values as we have for the average reward estimate: <span class="tex">$\hat v&#40;A&#41; &#61; -\frac&#123;1&#125;&#123;3&#125;$</span>, <span class="tex">$\hat v&#40;B&#41; &#61; 0$</span>, and <span class="tex">$\hat v&#40;C&#41; &#61; \frac&#123;1&#125;&#123;3&#125;$</span>.  Starting at state A, <span class="tex">$\delta_t &#61; 0 - \frac&#123;1&#125;&#123;3&#125; &#43; 0 - -\frac&#123;1&#125;&#123;3&#125; &#61; 0$</span>.  For the following state we have <span class="tex">$0 - \frac&#123;1&#125;&#123;3&#125; &#43; \frac&#123;1&#125;&#123;3&#125; &#61; 0$</span>.  Finally we have <span class="tex">$1 - \frac&#123;1&#125;&#123;3&#125; &#43; -\frac&#123;1&#125;&#123;3&#125; - \frac&#123;1&#125;&#123;3&#125; &#61; 0$</span>.  So if we use the TD error to update our average reward estimate, at equilibrium all the values will remain unchanged.  Using <span class="tex">$\delta$</span> provides a lower variance estimator than simply using the reward.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Gpersist_js_state·has_pluto_hook_features§cell_id$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adbdepends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$425fe768-c7bb-4d3e-87e6-47fa052ba612queued¤logsrunning¦outputbodymsgنUndefVarError: `episode_steps2_fcann` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#425fe768-c7bb-4d3e-87e6-47fa052ba612source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#425fe768-c7bb-4d3e-87e6-47fa052ba612functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6ߘpersist_js_state·has_pluto_hook_features§cell_id$425fe768-c7bb-4d3e-87e6-47fa052ba612depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$06834750-cc3a-468a-b0c2-81349c288a33queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#06834750-cc3a-468a-b0c2-81349c288a33source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#06834750-cc3a-468a-b0c2-81349c288a33functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA60jpersist_js_state·has_pluto_hook_features§cell_id$06834750-cc3a-468a-b0c2-81349c288a33depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$1054cfa3-9f58-4a93-a318-c2d21cf23220queued¤logsrunning¦outputbody=show_mountaincar_trajectory (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA6Lpersist_js_state·has_pluto_hook_features§cell_id$1054cfa3-9f58-4a93-a318-c2d21cf23220depends_on_disabled_cells§runtime h'published_object_keysdepends_on_skipped_cellsçerrored$8ed6f8fd-8574-4d5a-9964-ce8a32629c6fqueued¤logsrunning¦outputbody=compute_expected_sarsa_value (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6'аpersist_js_state·has_pluto_hook_features§cell_id$8ed6f8fd-8574-4d5a-9964-ce8a32629c6fdepends_on_disabled_cells§runtime 	published_object_keysdepends_on_skipped_cells§errored$f9abf433-8ce3-4520-9b47-f17f8f07b4cbqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDPTransitionDistribution` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#f9abf433-8ce3-4520-9b47-f17f8f07b4cbsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#f9abf433-8ce3-4520-9b47-f17f8f07b4cbfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassignee*const mountain_car_transition_distributionlast_run_timestampA6x6persist_js_state·has_pluto_hook_features§cell_id$f9abf433-8ce3-4520-9b47-f17f8f07b4cbdepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$59ec5223-f23f-4f32-9e5f-8a08e450da85queued¤logsrunning¦outputbody<div class="markdown"><h2>10.2 Semi-gradient <em>n</em>-step Sarsa</h2>
<p>We can obtain an <span class="tex">$n$</span>-step version of semi-gradient Sarsa by using an <span class="tex">$n$</span>-step return as the update target for the semi-gradient Sarsa update equation &#40;10.1&#41;.  The <span class="tex">$n$</span>-step return immediately generalizes from its tabular form &#40;7.4&#41; to a function approximation form: </p>
<p class="tex">$$G_&#123;t:t&#43;n&#125; \doteq R_&#123;t&#43;1&#125; &#43; \gamma R_&#123;t&#43;2&#125; &#43; \cdots &#43; \gamma^&#123;n-1&#125;R_&#123;t&#43;n&#125; &#43; \gamma^n \hat q&#40;S_&#123;t&#43;n&#125;, A_&#123;t&#43;n&#125;, \mathbf&#123;w&#125;_&#123;t&#43;n-1&#125;&#41;, \quad t&#43;n \lt T \tag&#123;10.4&#125;$$</p>
<p>with <span class="tex">$G_&#123;t:t&#43;n&#125; \doteq G_t$</span> if <span class="tex">$t&#43;n \geq T$</span>, as usual.  The <span class="tex">$n$</span>-step update equation is</p>
<p class="tex">$$\mathbf&#123;w&#125;_&#123;t&#43;n&#125; \doteq \mathbf&#123;w&#125;_&#123;t&#43;n-1&#125; &#43; \alpha \left &#91; G_&#123;t:t&#43;n&#125; - \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_&#123;t&#43;n-1&#125;&#41; \right &#93; \nabla \hat q&#40;S_t, A_t, \mathbf&#123;w&#125;_&#123;t&#43;n-1&#125;&#41;, \quad 0 \leq t \lt T \tag&#123;10.5&#125;$$</p>
<p>As we have seen before, performance is often best with an <span class="tex">$n$</span> that is some intermediate value between the 1-step sarsa method and Monte Carlo; however, we will not create a full implementation of this algorithm here as it will be replaced by semi-gradient Sarsa&#40;<span class="tex">$\lambda$</span>&#41; in Chapter 12 which is a much more efficient version of the same concept.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6EcVpersist_js_state·has_pluto_hook_features§cell_id$59ec5223-f23f-4f32-9e5f-8a08e450da85depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$0c7f5742-6c51-4c6a-b67f-217163935ba5queued¤logsrunning¦outputbody<div class="markdown"><blockquote>
<h3><em>Exercise 10.5</em></h3>
<p>What equations are needed &#40;beyond 10.10&#41; to specify the differential version of TD&#40;0&#41;?</p>
</blockquote>
<p>10.10 includes a reward estimate at time t, <span class="tex">$\bar R_t$</span>, which also needs to be updated.  The TD error represents the newly observed reward the was experienced in excess of the estimated average so the update equation should move <span class="tex">$\bar R$</span> in the direction of the TD error.  After each step, the following updates should occur.</p>
<p class="tex">$$\begin&#123;flalign&#125;
\delta &amp;\leftarrow R - \bar R &#43; \hat v&#40;S^\prime, \mathbf&#123;w&#125;&#41; - \hat v&#40;S, \mathbf&#123;w&#125;&#41; \\
\bar R &amp;\leftarrow \bar R &#43; \beta \delta \\
\mathbf&#123;w&#125; &amp;\leftarrow \mathbf&#123;w&#125; &#43; \alpha \delta \nabla \hat v&#40;S, \mathbf&#123;w&#125;&#41; \\
S &amp; \leftarrow S^\prime \\
\end&#123;flalign&#125;$$</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Fpersist_js_state·has_pluto_hook_features§cell_id$0c7f5742-6c51-4c6a-b67f-217163935ba5depends_on_disabled_cells§runtime >published_object_keysdepends_on_skipped_cells§errored$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efcqueued¤logsrunning¦outputbody5fill_action_values! (generic function with 2 methods)mimetext/plainrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efcdepends_on_disabled_cells§runtime ,published_object_keysdepends_on_skipped_cells§errored$9fb5dace-a799-4424-bcb3-8542e508dd4bqueued¤logsrunning¦outputbodymimetext/plainrootassigneelast_run_timestampA6lpersist_js_state·has_pluto_hook_features§cell_id$9fb5dace-a799-4424-bcb3-8542e508dd4bdepends_on_disabled_cells§runtime9۵published_object_keysdepends_on_skipped_cellsçerrored$c1388562-0708-4a6a-acfe-927413dab5d2queued¤logsrunning¦outputbodymsgفUndefVarError: `episode_rewards` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#c1388562-0708-4a6a-acfe-927413dab5d2source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#c1388562-0708-4a6a-acfe-927413dab5d2functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$c1388562-0708-4a6a-acfe-927413dab5d2depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3queued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shortIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93source_packageMaincallIshow_mountaincar_trajectory(π::Function, max_steps::Int64, name::String)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cc9197e0-f5bd-4742-bea3-b54e0b8e3b93funcshow_mountaincar_trajectoryparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3func##function_wrapped_cell#434parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6S}Jpersist_js_state·has_pluto_hook_features§cell_id$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$6cea9e69-bf8c-4079-9884-663a728d7b08queued¤logsrunning¦outputbody2<div class="markdown"><h1>Dependencies</h1>
</div>mimetext/htmlrootassigneelast_run_timestampA6Hlpersist_js_state·has_pluto_hook_features§cell_id$6cea9e69-bf8c-4079-9884-663a728d7b08depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$b0cc6ff8-7296-461c-9db7-e52fa518e2e2queued¤logsrunning¦outputbody6mountaincar_dist_test (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6hpersist_js_state·has_pluto_hook_features§cell_id$b0cc6ff8-7296-461c-9db7-e52fa518e2e2depends_on_disabled_cells§runtime ",?published_object_keysdepends_on_skipped_cellsçerrored$30ab21ba-3f5b-46a8-8b8c-753f2755d419queued¤logsrunning¦outputbodymsgكUndefVarError: `tile_coding_setup` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shortCsetup_mountain_car_tiles(tile_size::Tuple{…}, num_tilings::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527source_packageMaincallPsetup_mountain_car_tiles(tile_size::Tuple{Float32, Float32}, num_tilings::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527funcsetup_mountain_car_tilesparent_moduleMain.var"workspace#5"from_ccall_shortxmountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4source_packageMaincallxmountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, kwargs::@Kwargs{})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4func#mountaincar_test#92parent_moduleMain.var"workspace#5"from_ccall_short?mountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4source_packageMaincall?mountaincar_test(max_episodes::Int64, α::Float32, ϵ::Float32)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#7c5fb569-81f0-4b70-ae95-1fce0c51b6f4funcmountaincar_testparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#30ab21ba-3f5b-46a8-8b8c-753f2755d419source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#30ab21ba-3f5b-46a8-8b8c-753f2755d419func##function_wrapped_cell#598parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6ܰpersist_js_state·has_pluto_hook_features§cell_id$30ab21ba-3f5b-46a8-8b8c-753f2755d419depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$1478745a-634d-4f31-8a70-b74f0e536201queued¤logsrunning¦outputbody<div class="markdown"><p>Part of the Sarsa algorithm requires us to identify the maximizing action.  These functions update a vector of action-values using the parameters and state representation.  By computing all of the action values at once, the maximum can be identified, and these functions compute all the action values more efficiently than using the above function for each action individually.</p>
</div>mimetext/htmlrootassigneelast_run_timestampA6Cpersist_js_state·has_pluto_hook_features§cell_id$1478745a-634d-4f31-8a70-b74f0e536201depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$b07460f1-0461-4f63-b145-c4e1818a497equeued¤logsrunning¦outputbody2mountain_car_step (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6epersist_js_state·has_pluto_hook_features§cell_id$b07460f1-0461-4f63-b145-c4e1818a497edepends_on_disabled_cells§runtime 㞵published_object_keysdepends_on_skipped_cells§errored$a9b74949-9392-4048-bcb6-5fd48c1d9b98queued¤logsrunning¦outputbodyR<div class="markdown"><h3>Example 10.2: An Access-Control Queuing Task</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6Gסpersist_js_state·has_pluto_hook_features§cell_id$a9b74949-9392-4048-bcb6-5fd48c1d9b98depends_on_disabled_cells§runtime {published_object_keysdepends_on_skipped_cells§errored$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0queued¤logsrunning¦outputbodyKdifferential_semi_gradient_expected_sarsa! (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6cpersist_js_state·has_pluto_hook_features§cell_id$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$12f5065b-5bed-4d03-a0f0-72a942492394queued¤logsrunning¦outputbody9make_tabular_mountaincar (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6{Spersist_js_state·has_pluto_hook_features§cell_id$12f5065b-5bed-4d03-a0f0-72a942492394depends_on_disabled_cells§runtime u1published_object_keysdepends_on_skipped_cells§errored$4afbb723-340b-4d85-9115-027a0ff8dfadqueued¤logsrunning¦outputbodymsgقUndefVarError: `q̂_mountain_car` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#4afbb723-340b-4d85-9115-027a0ff8dfadsource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#4afbb723-340b-4d85-9115-027a0ff8dfadfunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6Dpersist_js_state·has_pluto_hook_features§cell_id$4afbb723-340b-4d85-9115-027a0ff8dfaddepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$00399548-b21c-43b5-90e2-30656ab1541equeued¤logsrunning¦outputbodymsgَUndefVarError: `mountaincar_fcann_dp_results` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#00399548-b21c-43b5-90e2-30656ab1541esource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#00399548-b21c-43b5-90e2-30656ab1541efunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6?persist_js_state·has_pluto_hook_features§cell_id$00399548-b21c-43b5-90e2-30656ab1541edepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$c75dc51c-cbff-48b1-b0fd-108828929b51queued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#c75dc51c-cbff-48b1-b0fd-108828929b51source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#c75dc51c-cbff-48b1-b0fd-108828929b51functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6{İpersist_js_state·has_pluto_hook_features§cell_id$c75dc51c-cbff-48b1-b0fd-108828929b51depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$7a47a518-dfc7-4310-a0b5-6f0d151c8263queued¤logsrunning¦outputbodyU<div class="markdown"><h3>Neural Network Mountain Car Semi-gradient Sarsa</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6E=persist_js_state·has_pluto_hook_features§cell_id$7a47a518-dfc7-4310-a0b5-6f0d151c8263depends_on_disabled_cells§runtime published_object_keysdepends_on_skipped_cells§errored$a22e5d34-4b8d-479c-985c-d6abd41a6c80queued¤logsrunning¦outputbodyE<div class="markdown"><h3>Example 10.1: Mountain Car Task</h3>
</div>mimetext/htmlrootassigneelast_run_timestampA6Cpersist_js_state·has_pluto_hook_features§cell_id$a22e5d34-4b8d-479c-985c-d6abd41a6c80depends_on_disabled_cells§runtime Lpublished_object_keysdepends_on_skipped_cells§errored$b990ba67-42c8-4ab9-943d-085392204fddqueued¤logsrunning¦outputbodyE<div class="markdown"><h4>Defining Car State and Dynamics</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA6Dİpersist_js_state·has_pluto_hook_features§cell_id$b990ba67-42c8-4ab9-943d-085392204fdddepends_on_disabled_cells§runtime ޵published_object_keysdepends_on_skipped_cells§errored$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4queued¤logsrunning¦outputbody1mountaincar_test (generic function with 1 method)mimetext/plainrootassigneelast_run_timestampA6Npersist_js_state·has_pluto_hook_features§cell_id$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4depends_on_disabled_cells§runtime Ǭpublished_object_keysdepends_on_skipped_cellsçerrored$0e3e506d-1959-47fd-8da9-b3dfd294be67queued¤logsrunning¦outputbodymsgكUndefVarError: `q̂_mountain_car2` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#0e3e506d-1959-47fd-8da9-b3dfd294be67source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#0e3e506d-1959-47fd-8da9-b3dfd294be67functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6V~persist_js_state·has_pluto_hook_features§cell_id$0e3e506d-1959-47fd-8da9-b3dfd294be67depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$af97f222-08d1-4200-a10b-8da178182175queued¤logsrunning¦outputbody9<div class="markdown"><h4>Dynamic Programming</h4>
</div>mimetext/htmlrootassigneelast_run_timestampA6D1persist_js_state·has_pluto_hook_features§cell_id$af97f222-08d1-4200-a10b-8da178182175depends_on_disabled_cells§runtime Opublished_object_keysdepends_on_skipped_cells§errored$b5273dfa-2262-487a-856b-441f007bd163queued¤logsrunning¦outputbodymsgUndefVarError: `runepisode` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktrace call_short(::var"#32#33")(i::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b5273dfa-2262-487a-856b-441f007bd163#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b5273dfa-2262-487a-856b-441f007bd163source_packageMaincall(::var"#32#33")(i::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b5273dfa-2262-487a-856b-441f007bd163func#32parent_moduleMain.var"workspace#5"from_ccall_shortnextinlinedãurlpath=/home/runner/.julia/packages/Transducers/fnznF/src/library.jlsource_packagecallnextlinfo_typeNothingline6filelibrary.jlfuncnextparent_modulefrom_ccall_shortnextinlinedãurlpath:/home/runner/.julia/packages/Transducers/fnznF/src/core.jlsource_packagecallnextlinfo_typeNothinglinefilecore.jlfuncnextparent_modulefrom_ccall_shortmacro expansioninlinedãurlpath:/home/runner/.julia/packages/Transducers/fnznF/src/core.jlsource_packagecallmacro expansionlinfo_typeNothingline̵filecore.jlfuncmacro expansionparent_modulefrom_ccall_short_foldl_arrayinlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecall_foldl_arraylinfo_typeNothingline̻fileprocesses.jlfunc_foldl_arrayparent_modulefrom_ccall_short__foldl__inlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecall__foldl__linfo_typeNothingline̶fileprocesses.jlfunc__foldl__parent_modulefrom_ccall_shortfoldl_basecaseinlinedãurlpath?/home/runner/.julia/packages/Transducers/fnznF/src/processes.jlsource_packagecallfoldl_basecaselinfo_typeNothinglineifileprocesses.jlfuncfoldl_basecaseparent_modulefrom_ccall_short{_reduce_basecase(rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlLfile:///home/runner/.julia/packages/Transducers/fnznF/src/threading_utils.jlpathE/home/runner/.julia/packages/Transducers/fnznF/src/threading_utils.jlsource_packageTransducerscall_reduce_basecase(rf::Transducers.Reduction{Transducers.Map{var"#32#33"}, Transducers.BottomRF{Transducers.Completing{typeof(+)}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline:filethreading_utils.jlfunc_reduce_basecaseparent_moduleTransducersfrom_ccall_shortٚ_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscall_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{Transducers.Map{var"#32#33"}, Transducers.BottomRF{Transducers.Completing{typeof(+)}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline̋filereduce.jlfunc_reduceparent_moduleTransducersfrom_ccall_shortٚ_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{…}, init::Transducers.InitOf{…}, reducible::Transducers.SizedReducible{…})inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscall_reduce(ctx::Transducers.CancellableDACContext, rf::Transducers.Reduction{Transducers.Map{var"#32#33"}, Transducers.BottomRF{Transducers.Completing{typeof(+)}}}, init::Transducers.InitOf{Transducers.DefaultInitOf}, reducible::Transducers.SizedReducible{UnitRange{Int64}, Int64})linfo_typeCore.MethodInstanceline̔filereduce.jlfunc_reduceparent_moduleTransducersfrom_ccall_short_transduce_assoc_nocompleteinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecall_transduce_assoc_nocompletelinfo_typeNothinglinẽfilereduce.jlfunc_transduce_assoc_nocompleteparent_modulefrom_ccall_shorttransduce_assoc(xform::Transducers.Map{…}, step::Transducers.Completing{…}, init::Transducers.InitOf{…}, coll0::UnitRange{…}; simd::Val{…}, basesize::Nothing, stoppable::Nothing, nestlevel::Nothing)inlined£urlCfile:///home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packageTransducerscalltransduce_assoc(xform::Transducers.Map{var"#32#33"}, step::Transducers.Completing{typeof(+)}, init::Transducers.InitOf{Transducers.DefaultInitOf}, coll0::UnitRange{Int64}; simd::Val{false}, basesize::Nothing, stoppable::Nothing, nestlevel::Nothing)linfo_typeCore.MethodInstancelinelfilereduce.jlfunc#transduce_assoc#253parent_moduleTransducersfrom_ccall_shorttransduce_associnlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecalltransduce_assoclinfo_typeNothinglineTfilereduce.jlfunctransduce_assocparent_modulefrom_ccall_shortfoldxtinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecallfoldxtlinfo_typeNothinglinefilereduce.jlfuncfoldxtparent_modulefrom_ccall_shortfoldxtinlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecallfoldxtlinfo_typeNothinglinefilereduce.jlfuncfoldxtparent_modulefrom_ccall_short#264inlinedãurlpath</home/runner/.julia/packages/Transducers/fnznF/src/reduce.jlsource_packagecall#264linfo_typeNothinglinefilereduce.jlfunc#264parent_modulefrom_ccall_shortC|>(x::Transducers.Eduction{…}, f::Transducers.var"#264#265"{…})inlined£urlghttps://github.com/JuliaLang/julia/tree/8f5b7ca12ad48c6d740e058312fc8cf2bbe67848/base/operators.jl#L926path./operators.jlsource_packageMaincall|>(x::Transducers.Eduction{Transducers.Reduction{Transducers.Map{var"#32#33"}, Transducers.BottomRF{Transducers.Completing{typeof(BangBang.push!!)}}}, UnitRange{Int64}}, f::Transducers.var"#264#265"{@Kwargs{}, typeof(+)})linfo_typeCore.MethodInstancelinefileoperators.jlfunc|>parent_moduleBasefrom_ccall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b5273dfa-2262-487a-856b-441f007bd163source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b5273dfa-2262-487a-856b-441f007bd163functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6հpersist_js_state·has_pluto_hook_features§cell_id$b5273dfa-2262-487a-856b-441f007bd163depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$b5409b69-a254-4355-b2b9-99394eceb2f7queued¤logsrunning¦outputbodymsgكUndefVarError: `π_mountain_car_q` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b5409b69-a254-4355-b2b9-99394eceb2f7source_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b5409b69-a254-4355-b2b9-99394eceb2f7functop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6>yJpersist_js_state·has_pluto_hook_features§cell_id$b5409b69-a254-4355-b2b9-99394eceb2f7depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerrored$b9ebd6bb-90a1-4945-85ed-023206e2420aqueued¤logsrunning¦outputbodymsgUndefVarError: `StateMDP` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.
Hint: a global variable of this name may be made accessible by importing TabularRL in the current active module Mainstacktracecall_shorttop-level scopeinlined£urlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b9ebd6bb-90a1-4945-85ed-023206e2420asource_packagecalltop-level scopelinfo_typeCore.CodeInfolinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b9ebd6bb-90a1-4945-85ed-023206e2420afunctop-level scopeparent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6persist_js_state·has_pluto_hook_features§cell_id$b9ebd6bb-90a1-4945-85ed-023206e2420adepends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cells§errored$d0cf3806-05c6-4a50-94c8-55c9042d51b7queued¤logsrunning¦outputbodymsgكUndefVarError: `tile_coding_setup` not defined in `Main.var"workspace#5"`
Suggestion: check for spelling errors or missing imports.stacktracecall_shortCsetup_mountain_car_tiles(tile_size::Tuple{…}, num_tilings::Int64)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527source_packageMaincallPsetup_mountain_car_tiles(tile_size::Tuple{Float32, Float32}, num_tilings::Int64)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#742100ba-c38e-4840-8988-40990039b527funcsetup_mountain_car_tilesparent_moduleMain.var"workspace#5"from_ccall_shortُmountaincar_dist_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, max_steps::Int64, kwargs::@Kwargs{})inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b0cc6ff8-7296-461c-9db7-e52fa518e2e2#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b0cc6ff8-7296-461c-9db7-e52fa518e2e2source_packageMaincallُmountaincar_dist_test(max_episodes::Int64, α::Float32, ϵ::Float32; num_tiles::Int64, num_tilings::Int64, max_steps::Int64, kwargs::@Kwargs{})linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b0cc6ff8-7296-461c-9db7-e52fa518e2e2func#mountaincar_dist_test#63parent_moduleMain.var"workspace#5"from_ccall_shortDmountaincar_dist_test(max_episodes::Int64, α::Float32, ϵ::Float32)inlined£urlhttps://github.com/jekyllstein/RL-Deploy-Test/tree/cccdbd59a290bd4aaf6a8c0e27aad843d2b4b2f3//Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b0cc6ff8-7296-461c-9db7-e52fa518e2e2#L1pathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#b0cc6ff8-7296-461c-9db7-e52fa518e2e2source_packageMaincallDmountaincar_dist_test(max_episodes::Int64, α::Float32, ϵ::Float32)linfo_typeCore.MethodInstancelinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#b0cc6ff8-7296-461c-9db7-e52fa518e2e2funcmountaincar_dist_testparent_moduleMain.var"workspace#5"from_ccall_shorttop-level scopeinlinedãurlpathٕ/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jl#==#d0cf3806-05c6-4a50-94c8-55c9042d51b7source_packagecalltop-level scopelinfo_typeNothinglinefileZChapter_10_On_policy_Control_with_Approximation.jl#==#d0cf3806-05c6-4a50-94c8-55c9042d51b7func##function_wrapped_cell#454parent_modulefrom_c¤mime'application/vnd.pluto.stacktrace+objectrootassigneelast_run_timestampA6kʎpersist_js_state·has_pluto_hook_features§cell_id$d0cf3806-05c6-4a50-94c8-55c9042d51b7depends_on_disabled_cells§runtimepublished_object_keysdepends_on_skipped_cellsçerroredñcell_dependencies $f68952bd-4c0b-4331-a09c-5b118c8fa5a9precedence_heuristic	cell_id$f68952bd-4c0b-4331-a09c-5b118c8fa5a9downstream_cells_map'state_aggregation_action_gradient_setup$62839b2a-398a-4445-87d1-b15ff2acc1d1upstream_cells_mapRealget_action_value$4271151d-d5a6-4a29-96c3-f2102b142b95update_parameters!$5f8b0254-88f4-4d19-ade1-8e7c40941b43$96548352-cd4d-4448-8312-ed10057f4359update_action_values!$5534526a-d790-4379-98b0-8e4ee981fd9fFunctionVector$9df1a18d-137c-4ea5-8d15-05697f7bbf07precedence_heuristic	cell_id$9df1a18d-137c-4ea5-8d15-05697f7bbf07downstream_cells_mapupstream_cells_map@md_strgetindex$c11aa069-93c2-435a-8f0e-353ced9633b6precedence_heuristic	cell_id$c11aa069-93c2-435a-8f0e-353ced9633b6downstream_cells_mapmountaincar_fcann_test$5fdbce61-ca25-45e0-b07d-94adf7138446upstream_cells_maprun_fcann_semi_gradient_sarsa$39b0f100-a7e7-4633-b296-ccc87a5a35abmountain_car_mdp$1e9c537a-a731-4b81-8f6a-cb658b52c5bezerosIntegerVector-Float32/NTuple*fill$7812e801-70fd-4331-ad0a-fad02c1a399fprecedence_heuristic	cell_id$7812e801-70fd-4331-ad0a-fad02c1a399fdownstream_cells_mapsemi_gradient_expected_sarsa!upstream_cells_mapcompute_expected_sarsa_value$8ed6f8fd-8574-4d5a-9964-ce8a32629c6fsemi_gradient_sarsa!$991492f4-7dfc-43aa-ab6c-a6b1f3e38225$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18precedence_heuristic	cell_id$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18downstream_cells_mapupstream_cells_map@md_strgetindex$dae59fd9-0397-4307-afd8-bafb6f0bfa52precedence_heuristic	cell_id$dae59fd9-0397-4307-afd8-bafb6f0bfa52downstream_cells_mapupstream_cells_map:nsamples$e86bc86f-9909-458d-b86d-0a4ac4b9d43d/|>+foldxtmountain_car_mdp$1e9c537a-a731-4b81-8f6a-cb658b52c5beMaprunepisode$c678846c-aaff-4266-8b2c-07a3a92445efprecedence_heuristic	cell_id$c678846c-aaff-4266-8b2c-07a3a92445efdownstream_cells_mapfcann_action_gradient_setup$39b0f100-a7e7-4633-b296-ccc87a5a35ab$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0$c75dc51c-cbff-48b1-b0fd-108828929b51upstream_cells_map update_nn_parameters!typemin!>FCANN.zeroParams!islessStateMDPlength<FCANN.predict!eachindexdeepcopyVectorFloat32/FCANN.form_tanh_grads:FCANNzerosonessizeupdate_input!$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867fIntegerFunctionFCANN.initializeparams_saxeendInt64+*$528533f7-68f1-4d19-9a37-6d4d0d7c38e2precedence_heuristic	cell_id$528533f7-68f1-4d19-9a37-6d4d0d7c38e2downstream_cells_mapconstant_params$d42bb733-07e2-4932-aab4-09229ff67492upstream_cells_map @md_strCore:PlutoUI$9fb5dace-a799-4424-bcb3-8542e508dd4b|>Base.get@bind=>SliderBasePlutoRunnerPlutoRunner.create_bondconfirmCore.applicablePlutoUI.combineSelectgetindex$cafb20b4-a2bd-46a9-9660-b0ace84d6e4cprecedence_heuristic	cell_id$cafb20b4-a2bd-46a9-9660-b0ace84d6e4cdownstream_cells_mapinitialize_car_state$ac80958a-73ec-4342-b553-b33df6612a50$f9abf433-8ce3-4520-9b47-f17f8f07b4cb$1e9c537a-a731-4b81-8f6a-cb658b52c5be$5b2ffd90-ead0-42ce-999a-584ed8995910$12f5065b-5bed-4d03-a0f0-72a942492394$e5ad765a-341f-4f11-9ae8-37d81cb349d2$bc1d7cce-c0f4-47a8-b674-8acb82491c7fupstream_cells_map-Float32*rand$66d6a4b0-ddf8-4781-b3b4-20f02b25199aprecedence_heuristic	cell_id$66d6a4b0-ddf8-4781-b3b4-20f02b25199adownstream_cells_mapupstream_cells_mapshow_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220policy_num$e2cd69c5-eda7-4897-9e64-0adf940d4d96mountaincar_policy_iteration$3c300a2b-4139-4df0-906b-4cae3592cc2btabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108$b0265b93-ae5f-48f2-a9fd-44fd6115164bprecedence_heuristic	cell_id$b0265b93-ae5f-48f2-a9fd-44fd6115164bdownstream_cells_mapupstream_cells_map@md_strgetindex$57659c52-de1b-46e6-a863-8eeec0cee601precedence_heuristic	cell_id$57659c52-de1b-46e6-a863-8eeec0cee601downstream_cells_mapπ_optimal_value_iteration$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3upstream_cells_mapmountaincar_value_iteration$57ea3538-33be-4673-b914-8191d35426a9sample_action:&assign_state_index_tabular_mountaincar$9d65285f-d49e-40ce-acea-1f565bcd4108view$a9fdb1fd-3f62-4e1c-9157-c4eee6215261precedence_heuristic	cell_id$a9fdb1fd-3f62-4e1c-9157-c4eee6215261downstream_cells_map!differential_semi_gradient_sarsa!$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0$c9759bd9-ec9b-47a1-9080-a7fc332be565$065b2626-01f1-443f-8be4-3036003a2772$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0$b4af8d87-a6e5-4e09-92b4-b07757f58f7fupstream_cells_map zeroTupleonecompute_sarsa_value$fc0b88f3-fbf9-450d-b770-b34357ffad49StateMDPlengthsample_actionVectoreachindexReal/zerosrandIntegerFunction<=Int64push!-+*make_ϵ_greedy_policy!$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93precedence_heuristic	cell_id$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93downstream_cells_mapshow_mountaincar_trajectory$d42bb733-07e2-4932-aab4-09229ff67492$864450b9-1319-4426-961f-ee6df93463d8$99e3ec39-24f0-43d6-b6fd-9910b738ce2c$a97e3b12-b7a5-4f88-bdb9-c3158203e0ff$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3$66d6a4b0-ddf8-4781-b3b4-20f02b25199a$78087a57-33a0-4581-81de-926476090931$f2201afe-8952-4dde-9e39-02beeb920f6f$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0$1e224a46-91ef-4a5f-ae35-ef4062147f2d$5cbaeb8e-bc02-47c9-87b4-57df554cea9d$b5409b69-a254-4355-b2b9-99394eceb2f7$ab4cb3db-3a2d-4145-826b-b1001114eeff$b191d3f9-cf25-4fb4-8f5a-8da86e96e125$954848db-6dcc-4666-90f8-b5a900203242upstream_cells_map@md_strsummountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dmountain_car_mdp$1e9c537a-a731-4b81-8f6a-cb658b52c5beIntegerFunctionMarkdown.parsescatterplotMarkdownLayoutrunepisodegetindex$e86bc86f-9909-458d-b86d-0a4ac4b9d43dprecedence_heuristic	cell_id$e86bc86f-9909-458d-b86d-0a4ac4b9d43ddownstream_cells_mapnsamples$b5273dfa-2262-487a-856b-441f007bd163$dae59fd9-0397-4307-afd8-bafb6f0bfa52upstream_cells_mapCore:|>Base.get@bindBasePlutoRunnerPlutoRunner.create_bondNumberFieldconfirmCore.applicable$bc1d7cce-c0f4-47a8-b674-8acb82491c7fprecedence_heuristic	cell_id$bc1d7cce-c0f4-47a8-b674-8acb82491c7fdownstream_cells_mapmountain_car_differential_mdp$49e43d51-05d6-415b-a685-76e50904c5bc$d3ba78fa-f032-4bb9-9359-ef3bcff2252dupstream_cells_mapmountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dinitialize_car_state$cafb20b4-a2bd-46a9-9660-b0ace84d6e4c==$mountain_car_differential_transition$e5ad765a-341f-4f11-9ae8-37d81cb349d2StateMDP$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2precedence_heuristic	cell_id$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2downstream_cells_mapmountaincar_velocities$c799ffe4-f4af-487d-b557-8b50d13632b7$58a0b622-1b51-4b42-a416-24109ae41a90upstream_cells_maptabular_mountaincar_args$33ea5f09-3a1f-476d-875a-1f3635a40295LinRange$c12070a9-df63-4b25-99e6-26ff876af1b4precedence_heuristic	cell_id$c12070a9-df63-4b25-99e6-26ff876af1b4downstream_cells_map"update_mountaincar_feature_vector!$0f958535-6b18-46de-a1ba-81f64c217ee0upstream_cells_map-Float32/NTuple*Vector$991492f4-7dfc-43aa-ab6c-a6b1f3e38225precedence_heuristic	cell_id$991492f4-7dfc-43aa-ab6c-a6b1f3e38225downstream_cells_mapsemi_gradient_sarsa!$2c620fe4-2f62-40f8-a666-8dced1e0b84a$39b0f100-a7e7-4633-b296-ccc87a5a35ab$7812e801-70fd-4331-ad0a-fad02c1a399f$5be866c3-0fb2-4d1f-9c31-b85aba332905upstream_cells_map zeroTuple>islessonecompute_sarsa_value$fc0b88f3-fbf9-450d-b770-b34357ffad49StateMDPlengthsample_action<eachindexVectorReal/^zerosrandIntegerFunctiontypemax<=Int64push!-+*make_ϵ_greedy_policy!$28e0d632-0df3-4a5b-85c4-571c845ff827precedence_heuristic	cell_id$28e0d632-0df3-4a5b-85c4-571c845ff827downstream_cells_mapmountain_car_action_names$d42bb733-07e2-4932-aab4-09229ff67492upstream_cells_map$b191d3f9-cf25-4fb4-8f5a-8da86e96e125precedence_heuristic	cell_id$b191d3f9-cf25-4fb4-8f5a-8da86e96e125downstream_cells_mapupstream_cells_mapshow_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220π_mountain_car2_fcann$b094bf9f-bb97-4f23-acdc-f39411a07fb9$e338be2b-05f1-43f4-a194-45ffd710777eprecedence_heuristic	cell_id$e338be2b-05f1-43f4-a194-45ffd710777edownstream_cells_mapaccelerate_mountaincar_π$e48af9f4-0b47-4a45-b0ad-8f53b094e712outupstream_cells_maplength:Float32zerostabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108$224b4bec-9ec5-434d-a950-f5974cd786d0precedence_heuristic	cell_id$224b4bec-9ec5-434d-a950-f5974cd786d0downstream_cells_mapupstream_cells_map@md_strgetindex$8752c98d-fac1-4b3b-b20b-70acc0677fcbprecedence_heuristic	cell_id$8752c98d-fac1-4b3b-b20b-70acc0677fcbdownstream_cells_mapupstream_cells_map@md_strgetindex$dd472c0f-7b43-4abe-ada9-9dc8004a18cbprecedence_heuristic	cell_id$dd472c0f-7b43-4abe-ada9-9dc8004a18cbdownstream_cells_mapadd_elementsupstream_cells_mapHTMLHypertextLiteral.BypassHypertextLiteral.ResultHypertextLiteral$9fb5dace-a799-4424-bcb3-8542e508dd4bAbstractStringHypertextLiteral.content@htl$ab4cb3db-3a2d-4145-826b-b1001114eeffprecedence_heuristic	cell_id$ab4cb3db-3a2d-4145-826b-b1001114eeffdownstream_cells_mapupstream_cells_mapshow_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220π_mountain_car2$7bc49107-9de5-4985-8750-979f36b3aa81$1410db13-4b73-4a87-af34-30a5232af4baprecedence_heuristic	cell_id$1410db13-4b73-4a87-af34-30a5232af4badownstream_cells_mapcompute_q_learning_value$5be866c3-0fb2-4d1f-9c31-b85aba332905$cbac1927-b087-4c4c-98ae-6aa5f0b824ad$c9759bd9-ec9b-47a1-9080-a7fc332be565$db189316-e880-4cc8-9070-ccfe2b4fc545$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667upstream_cells_mapRealmaximumIntegerVector$eb28458f-b222-4f8e-9a5b-8203d3997f7bprecedence_heuristic	cell_id$eb28458f-b222-4f8e-9a5b-8203d3997f7bdownstream_cells_mapmountain_car_differential_step$e5ad765a-341f-4f11-9ae8-37d81cb349d2upstream_cells_mapInt64-mountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dFloat32Tuple+clamp*==cos$a97e3b12-b7a5-4f88-bdb9-c3158203e0ffprecedence_heuristic	cell_id$a97e3b12-b7a5-4f88-bdb9-c3158203e0ffdownstream_cells_mapupstream_cells_mapmountaincar_value_iteration$57ea3538-33be-4673-b914-8191d35426a9show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220tabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6aprecedence_heuristic	cell_id$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6adownstream_cells_mapupstream_cells_mapsmooth_error$c85033e1-3ee6-42ad-9ef0-144ce6238ce4scatter-plotmountain_car_fcann$5fdbce61-ca25-45e0-b07d-94adf7138446Layout$1e224a46-91ef-4a5f-ae35-ef4062147f2dprecedence_heuristic	cell_id$1e224a46-91ef-4a5f-ae35-ef4062147f2ddownstream_cells_mapupstream_cells_mapshow_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220mountaincar_fcann_dp_results$ee59176e-24b6-4213-8f8e-759a70bc1d5e$5b2ffd90-ead0-42ce-999a-584ed8995910precedence_heuristic	cell_id$5b2ffd90-ead0-42ce-999a-584ed8995910downstream_cells_mapmountain_car_dist_mdp$b0cc6ff8-7296-461c-9db7-e52fa518e2e2$0f958535-6b18-46de-a1ba-81f64c217ee0upstream_cells_mapmountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6d$mountain_car_transition_distribution$f9abf433-8ce3-4520-9b47-f17f8f07b4cbinitialize_car_state$cafb20b4-a2bd-46a9-9660-b0ace84d6e4c==StateMDP$62839b2a-398a-4445-87d1-b15ff2acc1d1precedence_heuristic	cell_id$62839b2a-398a-4445-87d1-b15ff2acc1d1downstream_cells_mapcreate_access_control_task$b4af8d87-a6e5-4e09-92b4-b07757f58f7fupstream_cells_map Reject$fbf1c64f-1979-4384-a8c6-dc7875174d1faccess_control_step$014339eb-5b23-4ac5-a551-8eeb2238366f:randIntegerStateMDPVector'state_aggregation_action_gradient_setup$f68952bd-4c0b-4331-a09c-5b118c8fa5a9Int64lengthAccept$fbf1c64f-1979-4384-a8c6-dc7875174d1fStateMDPTransitionSamplerFloat32AccessControlState$e7372e2b-a2db-4a93-9efc-f75aa74c197blog2+*$8d096d0d-8fea-421a-aa33-82269d3fe7e2precedence_heuristic	cell_id$8d096d0d-8fea-421a-aa33-82269d3fe7e2downstream_cells_mapupstream_cells_map@md_strgetindex$39b0f100-a7e7-4633-b296-ccc87a5a35abprecedence_heuristic	cell_id$39b0f100-a7e7-4633-b296-ccc87a5a35abdownstream_cells_maprun_fcann_semi_gradient_sarsa$c11aa069-93c2-435a-8f0e-353ced9633b6upstream_cells_maplengthVectorFunctionFloat32zerosInfsemi_gradient_sarsa!$991492f4-7dfc-43aa-ab6c-a6b1f3e38225fcann_action_gradient_setup$c678846c-aaff-4266-8b2c-07a3a92445efIntegerStateMDP$1a82ae95-3c3e-4281-bc1d-9eb19bf50286precedence_heuristic	cell_id$1a82ae95-3c3e-4281-bc1d-9eb19bf50286downstream_cells_mapfigure_10_2$ddcb50be-5287-47f8-89f9-58c026a6b151upstream_cells_map:|>mountaincar_test$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4mapscatter-/plot+foldxtMapLayout$99e3ec39-24f0-43d6-b6fd-9910b738ce2cprecedence_heuristic	cell_id$99e3ec39-24f0-43d6-b6fd-9910b738ce2cdownstream_cells_mapupstream_cells_maptabular_mountaincar_args$33ea5f09-3a1f-476d-875a-1f3635a40295show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220tabular_policies$e48af9f4-0b47-4a45-b0ad-8f53b094e712tabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108$f11787a1-57f8-4077-8d60-bc760ece7cc6precedence_heuristic	cell_id$f11787a1-57f8-4077-8d60-bc760ece7cc6downstream_cells_mapcalculate_action_value$b9ebd6bb-90a1-4945-85ed-023206e2420aupstream_cells_map zeropopisless@inboundsnothingVector<Base.simd_indexdoteachindexSparseVector@simdMatrixRealAbstractVectorjulia.simdloopIntegerBaseBase.simd_outer_rangeInt64Base.simd_inner_length+*$fc3e0577-45aa-4bba-a275-fa7a352fc5ccprecedence_heuristic	cell_id$fc3e0577-45aa-4bba-a275-fa7a352fc5ccdownstream_cells_mapupstream_cells_mapplot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548mountain_car_fcann$5fdbce61-ca25-45e0-b07d-94adf7138446$98a5d65e-4253-4523-a74e-99d03be03b89precedence_heuristic	cell_id$98a5d65e-4253-4523-a74e-99d03be03b89downstream_cells_mapupstream_cells_map@md_strgetindex$4271151d-d5a6-4a29-96c3-f2102b142b95precedence_heuristic	cell_id$4271151d-d5a6-4a29-96c3-f2102b142b95downstream_cells_mapget_action_value$f68952bd-4c0b-4331-a09c-5b118c8fa5a9upstream_cells_mapRealMatrixIntegerVector$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94precedence_heuristic	cell_id$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94downstream_cells_maprun_linear_semi_gradient_dp$b0cc6ff8-7296-461c-9db7-e52fa518e2e2upstream_cells_map zerosemi_gradient_dp!$b0761704-5447-4e64-8270-708d9dccef60AbstractVector!zerosIntegerStateMDPNamedTuplesample_actionlinear_features_gradient_setupeachindexRealFunctionlength+make_greedy_policy!*$3f7484b3-272d-410d-92b1-ca13e5d7a8b7precedence_heuristiccell_id$3f7484b3-272d-410d-92b1-ca13e5d7a8b7downstream_cells_mapupstream_cells_map@raw_str@__DIR__CapturedExceptionPlutoDevMacros.@frompackage$1a7ba296-52ca-4069-85fa-792d08d77b0eprecedence_heuristic	cell_id$1a7ba296-52ca-4069-85fa-792d08d77b0edownstream_cells_mapupstream_cells_map@md_strgetindex$39eada35-8c3e-4ddc-8df9-7cf9f120928dprecedence_heuristic	cell_id$39eada35-8c3e-4ddc-8df9-7cf9f120928ddownstream_cells_mapupstream_cells_map@md_strgetindex$b55d50a4-b039-4240-b434-42f7b724d24dprecedence_heuristic	cell_id$b55d50a4-b039-4240-b434-42f7b724d24ddownstream_cells_mapupstream_cells_mapplot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548mc_test$0714a1cf-9288-4f1e-ba72-d82608704d69$41c626c7-908d-4ff6-9730-4ad0b8c3cc25precedence_heuristic	cell_id$41c626c7-908d-4ff6-9730-4ad0b8c3cc25downstream_cells_mapupstream_cells_mapfigure_10_5$546a775e-d3c9-4693-9f64-d4c47a84fb9f$1e9c537a-a731-4b81-8f6a-cb658b52c5beprecedence_heuristic	cell_id$1e9c537a-a731-4b81-8f6a-cb658b52c5bedownstream_cells_mapmountain_car_mdp$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$b5273dfa-2262-487a-856b-441f007bd163$dae59fd9-0397-4307-afd8-bafb6f0bfa52$742100ba-c38e-4840-8988-40990039b527$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4$c11aa069-93c2-435a-8f0e-353ced9633b6$0714a1cf-9288-4f1e-ba72-d82608704d69upstream_cells_mapmountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dmountain_car_transition$ac80958a-73ec-4342-b553-b33df6612a50initialize_car_state$cafb20b4-a2bd-46a9-9660-b0ace84d6e4c==StateMDP$13e477f0-dc15-46cb-9691-c04a1b4c83c8precedence_heuristic	cell_id$13e477f0-dc15-46cb-9691-c04a1b4c83c8downstream_cells_map.gradient_monte_carlo_action_policy_estimation!upstream_cells_map$gradient_monte_carlo_episode_update!:TupleviewoneIntegerStateMDPRealFunctionreward_historyrunepisode!push!/runepisode+gradient_monte_carlo_action_episode_update!$953907cd-9926-4478-99b3-da7068118c22$47710ddd-79d9-464d-b5dd-27180f2d6b31precedence_heuristic	cell_id$47710ddd-79d9-464d-b5dd-27180f2d6b31downstream_cells_mapupstream_cells_map@md_strgetindex$14fe2253-cf2c-4159-a360-1e65f1c82b09precedence_heuristic	cell_id$14fe2253-cf2c-4159-a360-1e65f1c82b09downstream_cells_mapupstream_cells_map@md_strgetindex$5c920177-8e46-49c9-9b95-1a657fdcae4eprecedence_heuristic	cell_id$5c920177-8e46-49c9-9b95-1a657fdcae4edownstream_cells_mapupstream_cells_mapsmooth_error$c85033e1-3ee6-42ad-9ef0-144ce6238ce4scatter-plotepisode_rewards_dp$d0cf3806-05c6-4a50-94c8-55c9042d51b7Layout$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0precedence_heuristic	cell_id$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0downstream_cells_map*run_fcann_differential_semi_gradient_sarsa$d3ba78fa-f032-4bb9-9359-ef3bcff2252dupstream_cells_mapVectorFunctionlengthFloat32!differential_semi_gradient_sarsa!$a9fdb1fd-3f62-4e1c-9157-c4eee6215261zerosfcann_action_gradient_setup$c678846c-aaff-4266-8b2c-07a3a92445efIntegerStateMDP$3c300a2b-4139-4df0-906b-4cae3592cc2bprecedence_heuristic	cell_id$3c300a2b-4139-4df0-906b-4cae3592cc2bdownstream_cells_mapmountaincar_policy_iteration$e2cd69c5-eda7-4897-9e64-0adf940d4d96$66d6a4b0-ddf8-4781-b3b4-20f02b25199a$78087a57-33a0-4581-81de-926476090931$58a0b622-1b51-4b42-a416-24109ae41a90$5bc2eda5-5f4c-4165-9afb-16920f30b0c5upstream_cells_mappolicy_iteration_vtabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bdprecedence_heuristic	cell_id$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bddownstream_cells_mapplot_mountaincar_action_values$c799ffe4-f4af-487d-b557-8b50d13632b7$58a0b622-1b51-4b42-a416-24109ae41a90$4afbb723-340b-4d85-9115-027a0ff8dfad$fc3e0577-45aa-4bba-a275-fa7a352fc5cc$f9ee13e8-7406-4fba-9a30-1e2714bd7cfc$0e3e506d-1959-47fd-8da9-b3dfd294be67$c44dd6c6-8213-49fb-8d33-ba8f2c766b2e$b55d50a4-b039-4240-b434-42f7b724d24dupstream_cells_map :hcatHypertextLiteral.BypasszerosreduceHypertextLiteral.contentsize@htlfindmaxlengtheachindexenumerateFloat32plotHypertextLiteral$9fb5dace-a799-4424-bcb3-8542e508dd4bheatmapHypertextLiteral.ResultMatrixLayout$fbf1c64f-1979-4384-a8c6-dc7875174d1fprecedence_heuristic	cell_id$fbf1c64f-1979-4384-a8c6-dc7875174d1fdownstream_cells_mapReject$014339eb-5b23-4ac5-a551-8eeb2238366f$62839b2a-398a-4445-87d1-b15ff2acc1d1Accept$014339eb-5b23-4ac5-a551-8eeb2238366f$62839b2a-398a-4445-87d1-b15ff2acc1d1AccessControlAction$fbf1c64f-1979-4384-a8c6-dc7875174d1fupstream_cells_mapAccessControlAction$fbf1c64f-1979-4384-a8c6-dc7875174d1f$0714a1cf-9288-4f1e-ba72-d82608704d69precedence_heuristic	cell_id$0714a1cf-9288-4f1e-ba72-d82608704d69downstream_cells_mapmc_test$b76551e0-c027-4682-b5ae-bba7ea2b987a$954848db-6dcc-4666-90f8-b5a900203242$b55d50a4-b039-4240-b434-42f7b724d24dupstream_cells_map/'run_linear_gradient_monte_carlo_control$17d11fea-883b-4ddb-bec2-c4ad491b39ddmountain_car_mdp$1e9c537a-a731-4b81-8f6a-cb658b52c5besetup_mountain_car_tiles$742100ba-c38e-4840-8988-40990039b527$f7410fe7-e3d8-4047-8fa7-f076476e9d3aprecedence_heuristic	cell_id$f7410fe7-e3d8-4047-8fa7-f076476e9d3adownstream_cells_mapupstream_cells_map@md_strgetindex$864450b9-1319-4426-961f-ee6df93463d8precedence_heuristic	cell_id$864450b9-1319-4426-961f-ee6df93463d8downstream_cells_mapupstream_cells_map:show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220rand_nsteps$afee7bc9-aff0-4c71-a227-9845cb23d4e9rand$662759be-282c-460b-adc3-8595475b53c2precedence_heuristic	cell_id$662759be-282c-460b-adc3-8595475b53c2downstream_cells_mapupstream_cells_map@md_strgetindex$f5e32900-6eb6-4b61-916d-893c0bcaf214precedence_heuristic	cell_id$f5e32900-6eb6-4b61-916d-893c0bcaf214downstream_cells_mapupstream_cells_mapTableOfContents$e1abf8c7-06b8-4cd5-b557-1d187004bdf1precedence_heuristic	cell_id$e1abf8c7-06b8-4cd5-b557-1d187004bdf1downstream_cells_mapupstream_cells_map@md_strgetindex$b76551e0-c027-4682-b5ae-bba7ea2b987aprecedence_heuristic	cell_id$b76551e0-c027-4682-b5ae-bba7ea2b987adownstream_cells_mapupstream_cells_mapsmooth_error$c85033e1-3ee6-42ad-9ef0-144ce6238ce4mc_test$0714a1cf-9288-4f1e-ba72-d82608704d69plotLayout$d8d5db17-d89c-47db-b258-6ad1635478b7precedence_heuristic	cell_id$d8d5db17-d89c-47db-b258-6ad1635478b7downstream_cells_mapplot_mountaincar_action_values$c799ffe4-f4af-487d-b557-8b50d13632b7$58a0b622-1b51-4b42-a416-24109ae41a90$4afbb723-340b-4d85-9115-027a0ff8dfad$fc3e0577-45aa-4bba-a275-fa7a352fc5cc$f9ee13e8-7406-4fba-9a30-1e2714bd7cfc$0e3e506d-1959-47fd-8da9-b3dfd294be67$c44dd6c6-8213-49fb-8d33-ba8f2c766b2e$b55d50a4-b039-4240-b434-42f7b724d24dupstream_cells_map≈:zerosfindmaxVectorlengthenumerateFloat32/heatmapplotMatrixLayout$78087a57-33a0-4581-81de-926476090931precedence_heuristic	cell_id$78087a57-33a0-4581-81de-926476090931downstream_cells_mapupstream_cells_mapsample_action:show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220policy_num$e2cd69c5-eda7-4897-9e64-0adf940d4d96viewmountaincar_policy_iteration$3c300a2b-4139-4df0-906b-4cae3592cc2b&assign_state_index_tabular_mountaincar$9d65285f-d49e-40ce-acea-1f565bcd4108$69fb26ed-763e-44ad-9b70-193e5a1a09b9precedence_heuristiccell_id$69fb26ed-763e-44ad-9b70-193e5a1a09b9downstream_cells_mapStatisticsTransducersLinearAlgebraPlutoDevMacrosRandomupstream_cells_map$35d59eae-77fd-11ef-2790-35dd5a834060precedence_heuristic	cell_id$35d59eae-77fd-11ef-2790-35dd5a834060downstream_cells_mapupstream_cells_map@md_strgetindex$5f8b0254-88f4-4d19-ade1-8e7c40941b43precedence_heuristic	cell_id$5f8b0254-88f4-4d19-ade1-8e7c40941b43downstream_cells_mapupdate_parameters!$b9ebd6bb-90a1-4945-85ed-023206e2420a$f68952bd-4c0b-4331-a09c-5b118c8fa5a9upstream_cells_map zeropopisless@inboundsnothingVector<Base.simd_indexeachindexRealSparseVector@simdMatrixAbstractVectorjulia.simdloopIntegerBaseBase.simd_outer_rangeInt64Base.simd_inner_length+*$546a775e-d3c9-4693-9f64-d4c47a84fb9fprecedence_heuristic	cell_id$546a775e-d3c9-4693-9f64-d4c47a84fb9fdownstream_cells_mapfigure_10_5$41c626c7-908d-4ff6-9730-4ad0b8c3cc25upstream_cells_map @md_str%run_access_control_differential_sarsa$b4af8d87-a6e5-4e09-92b4-b07757f58f7fBitArray>islessFloat64<scatterFloat32heatmapmeanroundgetindex:|>zerosend-plot+undefLayout$6351304f-50ac-4755-86e1-cd4680f2d803precedence_heuristic	cell_id$6351304f-50ac-4755-86e1-cd4680f2d803downstream_cells_mapupstream_cells_map@md_strgetindex$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6precedence_heuristic	cell_id$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6downstream_cells_mapupstream_cells_map@md_strgetindex$bc220d14-97fd-486d-9880-6908135fe036precedence_heuristic	cell_id$bc220d14-97fd-486d-9880-6908135fe036downstream_cells_mapupstream_cells_map@md_strgetindex$e48af9f4-0b47-4a45-b0ad-8f53b094e712precedence_heuristic	cell_id$e48af9f4-0b47-4a45-b0ad-8f53b094e712downstream_cells_maptabular_policies$99e3ec39-24f0-43d6-b6fd-9910b738ce2cupstream_cells_maptabular_mountaincar_πrand$1b15efa9-c331-46bf-93db-f96dee026fe2accelerate_mountaincar_π$e338be2b-05f1-43f4-a194-45ffd710777e$5534526a-d790-4379-98b0-8e4ee981fd9fprecedence_heuristic	cell_id$5534526a-d790-4379-98b0-8e4ee981fd9fdownstream_cells_mapupdate_action_values!$f68952bd-4c0b-4331-a09c-5b118c8fa5a9upstream_cells_map zerotypemin!>popisless@inboundsnothingVector<Base.simd_indexeachindexReal@simdMatrixjulia.simdloopIntegerBaseBase.simd_outer_rangeBase.simd_inner_length+*$ca970333-fa08-412c-b89d-491e70f0ac79precedence_heuristic	cell_id$ca970333-fa08-412c-b89d-491e70f0ac79downstream_cells_mapupstream_cells_map@md_strgetindex$db189316-e880-4cc8-9070-ccfe2b4fc545precedence_heuristic	cell_id$db189316-e880-4cc8-9070-ccfe2b4fc545downstream_cells_mapepisode_steps2$4775126e-4374-49be-b25f-4597401f3642episode_rewards2q̂_mountain_car2$7bc49107-9de5-4985-8750-979f36b3aa81$0e3e506d-1959-47fd-8da9-b3dfd294be67average_step_reward$4775126e-4374-49be-b25f-4597401f3642upstream_cells_map/compute_q_learning_value$1410db13-4b73-4a87-af34-30a5232af4bamountaincar_differential_test$49e43d51-05d6-415b-a685-76e50904c5bc$ddcb50be-5287-47f8-89f9-58c026a6b151precedence_heuristic	cell_id$ddcb50be-5287-47f8-89f9-58c026a6b151downstream_cells_mapupstream_cells_mapfigure_10_2$1a82ae95-3c3e-4281-bc1d-9eb19bf50286$e7bf61d7-c362-433d-9b83-6537d308c255precedence_heuristic	cell_id$e7bf61d7-c362-433d-9b83-6537d308c255downstream_cells_mapupstream_cells_map@md_strgetindex$69a06405-57cd-42e5-96b1-5cc77d74aa03precedence_heuristic	cell_id$69a06405-57cd-42e5-96b1-5cc77d74aa03downstream_cells_mapupstream_cells_map@md_strgetindex$c44dd6c6-8213-49fb-8d33-ba8f2c766b2eprecedence_heuristic	cell_id$c44dd6c6-8213-49fb-8d33-ba8f2c766b2edownstream_cells_mapupstream_cells_mapplot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548q̂_mountain_car2_fcann$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667$ac80958a-73ec-4342-b553-b33df6612a50precedence_heuristic	cell_id$ac80958a-73ec-4342-b553-b33df6612a50downstream_cells_mapmountain_car_transition$1e9c537a-a731-4b81-8f6a-cb658b52c5beupstream_cells_mapmountain_car_step$b07460f1-0461-4f63-b145-c4e1818a497eStateMDPTransitionSamplerinitialize_car_state$cafb20b4-a2bd-46a9-9660-b0ace84d6e4c$09088eee-4cb3-40ac-b127-658ce1332fbaprecedence_heuristic	cell_id$09088eee-4cb3-40ac-b127-658ce1332fbadownstream_cells_mapupstream_cells_mapepisode_rewards_q$cbac1927-b087-4c4c-98ae-6aa5f0b824adsmooth_error$c85033e1-3ee6-42ad-9ef0-144ce6238ce4scatter-plotLayout$33ea5f09-3a1f-476d-875a-1f3635a40295precedence_heuristic	cell_id$33ea5f09-3a1f-476d-875a-1f3635a40295downstream_cells_maptabular_mountaincar_args$1d417a66-205f-4883-b49c-a6fc900af4ce$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2$9d65285f-d49e-40ce-acea-1f565bcd4108$99e3ec39-24f0-43d6-b6fd-9910b738ce2cupstream_cells_map @md_strCore:PlutoUI$9fb5dace-a799-4424-bcb3-8542e508dd4b|>Base.get@bind=>BasePlutoRunnerPlutoRunner.create_bondNumberFieldconfirmCore.applicablePlutoUI.combineSelectgetindex$318b398a-d8f2-4f39-a45d-fd9023961bf8precedence_heuristiccell_id$318b398a-d8f2-4f39-a45d-fd9023961bf8downstream_cells_mapupstream_cells_mapjoinpath@__DIR__include$be77b538-d106-4ca0-a974-289415588c47precedence_heuristic	cell_id$be77b538-d106-4ca0-a974-289415588c47downstream_cells_mapupstream_cells_map@md_strgetindex$5bc2eda5-5f4c-4165-9afb-16920f30b0c5precedence_heuristic	cell_id$5bc2eda5-5f4c-4165-9afb-16920f30b0c5downstream_cells_mapπ_optimal_policy_iterationupstream_cells_mapsample_action:&assign_state_index_tabular_mountaincar$9d65285f-d49e-40ce-acea-1f565bcd4108viewmountaincar_policy_iteration$3c300a2b-4139-4df0-906b-4cae3592cc2bend$f9ee13e8-7406-4fba-9a30-1e2714bd7cfcprecedence_heuristic	cell_id$f9ee13e8-7406-4fba-9a30-1e2714bd7cfcdownstream_cells_mapupstream_cells_mapplot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548q̂_mountain_car_q$cbac1927-b087-4c4c-98ae-6aa5f0b824ad$afee7bc9-aff0-4c71-a227-9845cb23d4e9precedence_heuristic	cell_id$afee7bc9-aff0-4c71-a227-9845cb23d4e9downstream_cells_maprand_nsteps$864450b9-1319-4426-961f-ee6df93463d8upstream_cells_map@md_strCore:Base.get@bindSliderBasePlutoRunnerPlutoRunner.create_bondconfirmCore.applicablegetindex$4775126e-4374-49be-b25f-4597401f3642precedence_heuristic	cell_id$4775126e-4374-49be-b25f-4597401f3642downstream_cells_mapupstream_cells_mapepisode_steps2$db189316-e880-4cc8-9070-ccfe2b4fc545:-scatterplotattrviewLayoutaverage_step_reward$db189316-e880-4cc8-9070-ccfe2b4fc545end$d291541d-ddba-4b71-a4eb-37fef758b71bprecedence_heuristic	cell_id$d291541d-ddba-4b71-a4eb-37fef758b71bdownstream_cells_mapupstream_cells_map@md_strgetindex$e2cd69c5-eda7-4897-9e64-0adf940d4d96precedence_heuristic	cell_id$e2cd69c5-eda7-4897-9e64-0adf940d4d96downstream_cells_mappolicy_num$66d6a4b0-ddf8-4781-b3b4-20f02b25199a$78087a57-33a0-4581-81de-926476090931$58a0b622-1b51-4b42-a416-24109ae41a90upstream_cells_mapCoreBasePlutoRunner.create_bondPlutoRunnereachindexCore.applicable@bindBase.getmountaincar_policy_iteration$3c300a2b-4139-4df0-906b-4cae3592cc2bSelect$cbac1927-b087-4c4c-98ae-6aa5f0b824adprecedence_heuristic	cell_id$cbac1927-b087-4c4c-98ae-6aa5f0b824addownstream_cells_mapepisode_rewards_q$09088eee-4cb3-40ac-b127-658ce1332fbaπ_mountain_car_q$b5409b69-a254-4355-b2b9-99394eceb2f7q̂_mountain_car_q$f9ee13e8-7406-4fba-9a30-1e2714bd7cfcepisode_steps_qupstream_cells_mapmountaincar_test$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4/compute_q_learning_value$1410db13-4b73-4a87-af34-30a5232af4ba$ee59176e-24b6-4213-8f8e-759a70bc1d5eprecedence_heuristic	cell_id$ee59176e-24b6-4213-8f8e-759a70bc1d5edownstream_cells_mapmountaincar_fcann_dp_results$b3658e4d-ee8e-45cd-906a-06dd512a6921$1e224a46-91ef-4a5f-ae35-ef4062147f2d$00399548-b21c-43b5-90e2-30656ab1541eupstream_cells_mapmountaincar_fcann_dp$0f958535-6b18-46de-a1ba-81f64c217ee0$54b92594-04b8-4a8a-82c2-773b4a24680dprecedence_heuristic	cell_id$54b92594-04b8-4a8a-82c2-773b4a24680ddownstream_cells_mapupstream_cells_map@md_strgetindex$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0precedence_heuristic	cell_id$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0downstream_cells_mapupstream_cells_mapshow_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220π_greedy_dp$d0cf3806-05c6-4a50-94c8-55c9042d51b7$c316c5d3-f484-4e8e-bd56-be1e236d96bcprecedence_heuristic	cell_id$c316c5d3-f484-4e8e-bd56-be1e236d96bcdownstream_cells_mapupstream_cells_map@md_strgetindex$f2201afe-8952-4dde-9e39-02beeb920f6fprecedence_heuristic	cell_id$f2201afe-8952-4dde-9e39-02beeb920f6fdownstream_cells_mapupstream_cells_mapπ_mountain_car$30ab21ba-3f5b-46a8-8b8c-753f2755d419show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220$31fb07d2-1c34-44ec-b932-a598e78ec8dcprecedence_heuristic	cell_id$31fb07d2-1c34-44ec-b932-a598e78ec8dcdownstream_cells_mapupstream_cells_map@md_strgetindex$5db29488-a150-42ee-aedb-380a3a4fd548precedence_heuristic	cell_id$5db29488-a150-42ee-aedb-380a3a4fd548downstream_cells_mapplot_mountaincar_action_values$c799ffe4-f4af-487d-b557-8b50d13632b7$58a0b622-1b51-4b42-a416-24109ae41a90$4afbb723-340b-4d85-9115-027a0ff8dfad$fc3e0577-45aa-4bba-a275-fa7a352fc5cc$f9ee13e8-7406-4fba-9a30-1e2714bd7cfc$0e3e506d-1959-47fd-8da9-b3dfd294be67$c44dd6c6-8213-49fb-8d33-ba8f2c766b2e$b55d50a4-b039-4240-b434-42f7b724d24dupstream_cells_mapenumeratemountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dFloat32plotheatmapzerosLinRangeLayout$39c63495-36c3-4e62-b8fb-36865f2c6243precedence_heuristic	cell_id$39c63495-36c3-4e62-b8fb-36865f2c6243downstream_cells_mapupstream_cells_map@md_strgetindex$d42bb733-07e2-4932-aab4-09229ff67492precedence_heuristic	cell_id$d42bb733-07e2-4932-aab4-09229ff67492downstream_cells_mapupstream_cells_mapconstant_params$528533f7-68f1-4d19-9a37-6d4d0d7c38e2show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220mountain_car_action_names$28e0d632-0df3-4a5b-85c4-571c845ff827$58a0b622-1b51-4b42-a416-24109ae41a90precedence_heuristic	cell_id$58a0b622-1b51-4b42-a416-24109ae41a90downstream_cells_mapupstream_cells_mapmountaincar_velocities$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2plot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548policy_num$e2cd69c5-eda7-4897-9e64-0adf940d4d96mountaincar_policy_iteration$3c300a2b-4139-4df0-906b-4cae3592cc2btabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108mountaincar_positions$1d417a66-205f-4883-b49c-a6fc900af4ce$954848db-6dcc-4666-90f8-b5a900203242precedence_heuristic	cell_id$954848db-6dcc-4666-90f8-b5a900203242downstream_cells_mapupstream_cells_mapshow_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220mc_test$0714a1cf-9288-4f1e-ba72-d82608704d69mc_test.π_ϵ_greedy$df07524f-b3fe-4a66-98ac-8f80df66bcffprecedence_heuristic	cell_id$df07524f-b3fe-4a66-98ac-8f80df66bcffdownstream_cells_mapmountain_car_dist_step$f9abf433-8ce3-4520-9b47-f17f8f07b4cbupstream_cells_mapInt64mountain_car_step$b07460f1-0461-4f63-b145-c4e1818a497eFloat32Tuple$c85033e1-3ee6-42ad-9ef0-144ce6238ce4precedence_heuristic	cell_id$c85033e1-3ee6-42ad-9ef0-144ce6238ce4downstream_cells_mapsmooth_error$5c920177-8e46-49c9-9b95-1a657fdcae4e$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6a$09088eee-4cb3-40ac-b127-658ce1332fba$b76551e0-c027-4682-b5ae-bba7ea2b987aupstream_cells_maplength:-+mean$f6e08689-040f-4565-9dfb-e9a65d1c1f18precedence_heuristic	cell_id$f6e08689-040f-4565-9dfb-e9a65d1c1f18downstream_cells_mapupstream_cells_map@md_strgetindex$e7372e2b-a2db-4a93-9efc-f75aa74c197bprecedence_heuristic	cell_id$e7372e2b-a2db-4a93-9efc-f75aa74c197bdownstream_cells_mapAccessControlState$014339eb-5b23-4ac5-a551-8eeb2238366f$62839b2a-398a-4445-87d1-b15ff2acc1d1$b4af8d87-a6e5-4e09-92b4-b07757f58f7fupstream_cells_mapInt64Float32$dc2cffeb-9adf-4956-afa3-ac82af377c59precedence_heuristic	cell_id$dc2cffeb-9adf-4956-afa3-ac82af377c59downstream_cells_mapupstream_cells_map@md_strgetindex$fc0b88f3-fbf9-450d-b770-b34357ffad49precedence_heuristic	cell_id$fc0b88f3-fbf9-450d-b770-b34357ffad49downstream_cells_mapcompute_sarsa_value$991492f4-7dfc-43aa-ab6c-a6b1f3e38225$8b7e1031-9864-439c-86eb-11aa08f53b90$5fdbce61-ca25-45e0-b07d-94adf7138446$a9fdb1fd-3f62-4e1c-9157-c4eee6215261upstream_cells_mapRealIntegerVector$50f6ff51-d81b-4e97-9f8a-0daf03af7192precedence_heuristic	cell_id$50f6ff51-d81b-4e97-9f8a-0daf03af7192downstream_cells_mapupstream_cells_map@md_strgetindex$5cbaeb8e-bc02-47c9-87b4-57df554cea9dprecedence_heuristic	cell_id$5cbaeb8e-bc02-47c9-87b4-57df554cea9ddownstream_cells_mapupstream_cells_mapπ_mountain_car_fcann$b9125c5b-01d6-451e-84b5-a419e38425b5show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220$b094bf9f-bb97-4f23-acdc-f39411a07fb9precedence_heuristic	cell_id$b094bf9f-bb97-4f23-acdc-f39411a07fb9downstream_cells_mapπ_mountain_car2_fcann$b191d3f9-cf25-4fb4-8f5a-8da86e96e125upstream_cells_map<argmax:eachindexmountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dislessq̂_mountain_car2_fcann$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667rand$1d417a66-205f-4883-b49c-a6fc900af4ceprecedence_heuristic	cell_id$1d417a66-205f-4883-b49c-a6fc900af4cedownstream_cells_mapmountaincar_positions$c799ffe4-f4af-487d-b557-8b50d13632b7$58a0b622-1b51-4b42-a416-24109ae41a90upstream_cells_maptabular_mountaincar_args$33ea5f09-3a1f-476d-875a-1f3635a40295LinRange$17d11fea-883b-4ddb-bec2-c4ad491b39ddprecedence_heuristic	cell_id$17d11fea-883b-4ddb-bec2-c4ad491b39dddownstream_cells_map'run_linear_gradient_monte_carlo_control$0714a1cf-9288-4f1e-ba72-d82608704d69upstream_cells_map:AbstractVectorzerosislessaction_valuesrandIntegerStateMDPReal<Functioneachindexlength%linear_features_action_gradient_setup$b9ebd6bb-90a1-4945-85ed-023206e2420agradient_monte_carlo_control!$06834750-cc3a-468a-b0c2-81349c288a33$b4af8d87-a6e5-4e09-92b4-b07757f58f7fprecedence_heuristic	cell_id$b4af8d87-a6e5-4e09-92b4-b07757f58f7fdownstream_cells_map%run_access_control_differential_sarsa$546a775e-d3c9-4693-9f64-d4c47a84fb9fupstream_cells_mapcreate_access_control_task$62839b2a-398a-4445-87d1-b15ff2acc1d1Int64lengtheachindexFloat32AccessControlState$e7372e2b-a2db-4a93-9efc-f75aa74c197bzeros!differential_semi_gradient_sarsa!$a9fdb1fd-3f62-4e1c-9157-c4eee6215261Real$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5bprecedence_heuristic	cell_id$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5bdownstream_cells_mapupstream_cells_map@md_strgetindex$c799ffe4-f4af-487d-b557-8b50d13632b7precedence_heuristic	cell_id$c799ffe4-f4af-487d-b557-8b50d13632b7downstream_cells_mapupstream_cells_mapmountaincar_value_iteration$57ea3538-33be-4673-b914-8191d35426a9mountaincar_velocities$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2plot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548tabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108mountaincar_positions$1d417a66-205f-4883-b49c-a6fc900af4ce$0e66a941-1ec1-4d3b-b064-e5f25cc93bafprecedence_heuristic	cell_id$0e66a941-1ec1-4d3b-b064-e5f25cc93bafdownstream_cells_mapupstream_cells_map@md_strgetindex$c5c839f7-1806-463d-b63a-bd7e1384f203precedence_heuristic	cell_id$c5c839f7-1806-463d-b63a-bd7e1384f203downstream_cells_mapupstream_cells_map@md_strgetindex$1b15efa9-c331-46bf-93db-f96dee026fe2precedence_heuristic	cell_id$1b15efa9-c331-46bf-93db-f96dee026fe2downstream_cells_maptabular_mountaincar_πrand$e48af9f4-0b47-4a45-b0ad-8f53b094e712upstream_cells_mapmake_random_policytabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108$72f575ee-d656-4af6-bf78-aab42bf1debdprecedence_heuristic	cell_id$72f575ee-d656-4af6-bf78-aab42bf1debddownstream_cells_mapupstream_cells_map@md_strgetindex$2c620fe4-2f62-40f8-a666-8dced1e0b84aprecedence_heuristic	cell_id$2c620fe4-2f62-40f8-a666-8dced1e0b84adownstream_cells_maprun_linear_semi_gradient_sarsa$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4upstream_cells_map:AbstractVectorzerossemi_gradient_sarsa!$991492f4-7dfc-43aa-ab6c-a6b1f3e38225findmaxIntegerStateMDPNamedTupleRealFunctionlength%linear_features_action_gradient_setup$b9ebd6bb-90a1-4945-85ed-023206e2420a$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8precedence_heuristic	cell_id$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8downstream_cells_mapupstream_cells_mapv̂_mountain_car$d0cf3806-05c6-4a50-94c8-55c9042d51b7π_greedy_dp$d0cf3806-05c6-4a50-94c8-55c9042d51b7plot_mountaincar_values$2f0d0a71-c65b-4aa0-a493-e7cdccd901eb$b8c031ca-7995-4501-a1e3-df3f34e5f0daprecedence_heuristic	cell_id$b8c031ca-7995-4501-a1e3-df3f34e5f0dadownstream_cells_mapupstream_cells_map@md_strgetindex$014339eb-5b23-4ac5-a551-8eeb2238366fprecedence_heuristic	cell_id$014339eb-5b23-4ac5-a551-8eeb2238366fdownstream_cells_mapaccess_control_step$62839b2a-398a-4445-87d1-b15ff2acc1d1upstream_cells_mapReject$fbf1c64f-1979-4384-a8c6-dc7875174d1f:sumislessrandIntegerVector<-Accept$fbf1c64f-1979-4384-a8c6-dc7875174d1fFloat32AccessControlState$e7372e2b-a2db-4a93-9efc-f75aa74c197b==$49249ac1-8964-4afc-89f2-3cd4d4322cc2precedence_heuristic	cell_id$49249ac1-8964-4afc-89f2-3cd4d4322cc2downstream_cells_mapupstream_cells_map@md_strgetindex$1a5acfb0-3b35-41b1-98f8-ffce941c587fprecedence_heuristic	cell_id$1a5acfb0-3b35-41b1-98f8-ffce941c587fdownstream_cells_mapupstream_cells_map@md_strgetindex$7bc49107-9de5-4985-8750-979f36b3aa81precedence_heuristic	cell_id$7bc49107-9de5-4985-8750-979f36b3aa81downstream_cells_mapπ_mountain_car2$ab4cb3db-3a2d-4145-826b-b1001114eeffupstream_cells_mapargmaxq̂_mountain_car2$db189316-e880-4cc8-9070-ccfe2b4fc545eachindexmountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6d$4d392303-4681-4ea1-8dcc-e002a78ea0a1precedence_heuristic	cell_id$4d392303-4681-4ea1-8dcc-e002a78ea0a1downstream_cells_mapupstream_cells_map@md_strgetindex$d3ba78fa-f032-4bb9-9359-ef3bcff2252dprecedence_heuristic	cell_id$d3ba78fa-f032-4bb9-9359-ef3bcff2252ddownstream_cells_map#mountaincar_fcann_differential_test$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667upstream_cells_mapzerosIntegerVector*run_fcann_differential_semi_gradient_sarsa$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0-Float32/mountain_car_differential_mdp$bc1d7cce-c0f4-47a8-b674-8acb82491c7fNTuple*fill$742100ba-c38e-4840-8988-40990039b527precedence_heuristic	cell_id$742100ba-c38e-4840-8988-40990039b527downstream_cells_mapsetup_mountain_car_tiles$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4$b0cc6ff8-7296-461c-9db7-e52fa518e2e2$49e43d51-05d6-415b-a685-76e50904c5bc$0714a1cf-9288-4f1e-ba72-d82608704d69upstream_cells_maptile_coding_setupFloat32mountain_car_mdp$1e9c537a-a731-4b81-8f6a-cb658b52c5beNTupleInteger$2f0d0a71-c65b-4aa0-a493-e7cdccd901ebprecedence_heuristic	cell_id$2f0d0a71-c65b-4aa0-a493-e7cdccd901ebdownstream_cells_mapplot_mountaincar_values$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8$b3658e4d-ee8e-45cd-906a-06dd512a6921upstream_cells_mapenumerateFloat32plotheatmapzerosLinRangeLayout$a3cf270b-b309-44f0-9972-bd84228bcf17precedence_heuristic	cell_id$a3cf270b-b309-44f0-9972-bd84228bcf17downstream_cells_mapupstream_cells_map@md_strgetindex$b9125c5b-01d6-451e-84b5-a419e38425b5precedence_heuristic	cell_id$b9125c5b-01d6-451e-84b5-a419e38425b5downstream_cells_mapπ_mountain_car_fcann$5cbaeb8e-bc02-47c9-87b4-57df554cea9dupstream_cells_mapargmaxeachindexmountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6d!mountain_car_fcann.value_functionmountain_car_fcann$5fdbce61-ca25-45e0-b07d-94adf7138446$9d65285f-d49e-40ce-acea-1f565bcd4108precedence_heuristic	cell_id$9d65285f-d49e-40ce-acea-1f565bcd4108downstream_cells_map&assign_state_index_tabular_mountaincar$57659c52-de1b-46e6-a863-8eeec0cee601$78087a57-33a0-4581-81de-926476090931$5bc2eda5-5f4c-4165-9afb-16920f30b0c5tabular_mountaincar_mdp$1b15efa9-c331-46bf-93db-f96dee026fe2$e338be2b-05f1-43f4-a194-45ffd710777e$99e3ec39-24f0-43d6-b6fd-9910b738ce2c$57ea3538-33be-4673-b914-8191d35426a9$a97e3b12-b7a5-4f88-bdb9-c3158203e0ff$c799ffe4-f4af-487d-b557-8b50d13632b7$3c300a2b-4139-4df0-906b-4cae3592cc2b$66d6a4b0-ddf8-4781-b3b4-20f02b25199a$58a0b622-1b51-4b42-a416-24109ae41a90upstream_cells_mapmake_tabular_mountaincar$12f5065b-5bed-4d03-a0f0-72a942492394tabular_mountaincar_args$33ea5f09-3a1f-476d-875a-1f3635a40295$57a6510f-bd42-4d1d-a550-d1442f79569fprecedence_heuristic	cell_id$57a6510f-bd42-4d1d-a550-d1442f79569fdownstream_cells_mapupstream_cells_map@md_strgetindex$b0761704-5447-4e64-8270-708d9dccef60precedence_heuristic	cell_id$b0761704-5447-4e64-8270-708d9dccef60downstream_cells_mapsemi_gradient_dp!$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94$00e7783f-7f17-4944-a085-ea87509cd75aupstream_cells_map zerotypemin!Tuple>islessoneStateMDPTransitionDistributionStateMDPlengthsample_action<eachindexVectorReal/^zerosrandIntegerFunctiontypemax<=Int64push!-+*make_ϵ_greedy_policy!$a6c5ec28-b2d5-4893-a118-95c1318d1f7fprecedence_heuristic	cell_id$a6c5ec28-b2d5-4893-a118-95c1318d1f7fdownstream_cells_mapupstream_cells_map@md_strgetindex$f1edb500-fbd1-4c03-b033-53860dfa452dprecedence_heuristic	cell_id$f1edb500-fbd1-4c03-b033-53860dfa452ddownstream_cells_mapupstream_cells_map@md_strgetindex$96548352-cd4d-4448-8312-ed10057f4359precedence_heuristic	cell_id$96548352-cd4d-4448-8312-ed10057f4359downstream_cells_mapupdate_parameters!$b9ebd6bb-90a1-4945-85ed-023206e2420a$f68952bd-4c0b-4331-a09c-5b118c8fa5a9upstream_cells_mapRealnothing-Matrix+*IntegerVector$ed1bd92c-8cc7-457f-9692-a10a9487c953precedence_heuristic	cell_id$ed1bd92c-8cc7-457f-9692-a10a9487c953downstream_cells_mapupstream_cells_mapBaseBase.Docs.HTML@html_str$c9759bd9-ec9b-47a1-9080-a7fc332be565precedence_heuristic	cell_id$c9759bd9-ec9b-47a1-9080-a7fc332be565downstream_cells_map&differential_semi_gradient_q_learning!upstream_cells_map!differential_semi_gradient_sarsa!$a9fdb1fd-3f62-4e1c-9157-c4eee6215261compute_q_learning_value$1410db13-4b73-4a87-af34-30a5232af4ba$953907cd-9926-4478-99b3-da7068118c22precedence_heuristic	cell_id$953907cd-9926-4478-99b3-da7068118c22downstream_cells_map+gradient_monte_carlo_action_episode_update!$13e477f0-dc15-46cb-9691-c04a1b4c83c8$06834750-cc3a-468a-b0c2-81349c288a33upstream_cells_maplengthzero:AbstractVector+*FunctionReal$278a26ac-c48f-4e18-93bb-706a4634c8c0precedence_heuristic	cell_id$278a26ac-c48f-4e18-93bb-706a4634c8c0downstream_cells_mapupstream_cells_map@md_strgetindex$8b7e1031-9864-439c-86eb-11aa08f53b90precedence_heuristic	cell_id$8b7e1031-9864-439c-86eb-11aa08f53b90downstream_cells_mapsemi_gradient_double_sarsa!upstream_cells_map zeroTupleislessonecompute_sarsa_value$fc0b88f3-fbf9-450d-b770-b34357ffad49StateMDPlengthsample_action<eachindexVectorReal/^zerosrandIntegerFunction<=Int64push!-+*make_ϵ_greedy_policy!$d577b393-4b40-4c90-9993-4ffbcbd9df6dprecedence_heuristic	cell_id$d577b393-4b40-4c90-9993-4ffbcbd9df6ddownstream_cells_mapmountain_car_actions$b07460f1-0461-4f63-b145-c4e1818a497e$1e9c537a-a731-4b81-8f6a-cb658b52c5be$5b2ffd90-ead0-42ce-999a-584ed8995910$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$12f5065b-5bed-4d03-a0f0-72a942492394$1054cfa3-9f58-4a93-a318-c2d21cf23220$5db29488-a150-42ee-aedb-380a3a4fd548$b9125c5b-01d6-451e-84b5-a419e38425b5$eb28458f-b222-4f8e-9a5b-8203d3997f7b$bc1d7cce-c0f4-47a8-b674-8acb82491c7f$7bc49107-9de5-4985-8750-979f36b3aa81$b094bf9f-bb97-4f23-acdc-f39411a07fb9upstream_cells_map$5fdbce61-ca25-45e0-b07d-94adf7138446precedence_heuristic	cell_id$5fdbce61-ca25-45e0-b07d-94adf7138446downstream_cells_mapmountain_car_fcann$b9125c5b-01d6-451e-84b5-a419e38425b5$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6a$fc3e0577-45aa-4bba-a275-fa7a352fc5ccupstream_cells_mapmountaincar_fcann_test$c11aa069-93c2-435a-8f0e-353ced9633b6compute_sarsa_value$fc0b88f3-fbf9-450d-b770-b34357ffad49$49e43d51-05d6-415b-a685-76e50904c5bcprecedence_heuristic	cell_id$49e43d51-05d6-415b-a685-76e50904c5bcdownstream_cells_mapmountaincar_differential_test$db189316-e880-4cc8-9070-ccfe2b4fc545upstream_cells_maplengthInt64mountain_car_differential_mdp$bc1d7cce-c0f4-47a8-b674-8acb82491c7fFloat32/zeros+run_linear_differential_semi_gradient_sarsa$065b2626-01f1-443f-8be4-3036003a2772setup_mountain_car_tiles$742100ba-c38e-4840-8988-40990039b527Integertypemax$0f958535-6b18-46de-a1ba-81f64c217ee0precedence_heuristic	cell_id$0f958535-6b18-46de-a1ba-81f64c217ee0downstream_cells_mapmountaincar_fcann_dp$ee59176e-24b6-4213-8f8e-759a70bc1d5eupstream_cells_mapInt64run_fcann_semi_gradient_dp$00e7783f-7f17-4944-a085-ea87509cd75amountain_car_dist_mdp$5b2ffd90-ead0-42ce-999a-584ed8995910Float32zeros"update_mountaincar_feature_vector!$c12070a9-df63-4b25-99e6-26ff876af1b4Integertypemax$44d43dbf-fe32-438e-b89d-c677bbc35893precedence_heuristic	cell_id$44d43dbf-fe32-438e-b89d-c677bbc35893downstream_cells_mapupstream_cells_map@md_strgetindex$b3658e4d-ee8e-45cd-906a-06dd512a6921precedence_heuristic	cell_id$b3658e4d-ee8e-45cd-906a-06dd512a6921downstream_cells_mapupstream_cells_mapmountaincar_fcann_dp_results$ee59176e-24b6-4213-8f8e-759a70bc1d5eplot_mountaincar_values$2f0d0a71-c65b-4aa0-a493-e7cdccd901eb$00e7783f-7f17-4944-a085-ea87509cd75aprecedence_heuristic	cell_id$00e7783f-7f17-4944-a085-ea87509cd75adownstream_cells_maprun_fcann_semi_gradient_dp$0f958535-6b18-46de-a1ba-81f64c217ee0upstream_cells_map fcann_gradient_setupzerosemi_gradient_dp!$b0761704-5447-4e64-8270-708d9dccef60AbstractVector!zerosInfIntegerStateMDPVectorsample_actionInt64eachindexRealFunctionlength+make_greedy_policy!*$5be866c3-0fb2-4d1f-9c31-b85aba332905precedence_heuristic	cell_id$5be866c3-0fb2-4d1f-9c31-b85aba332905downstream_cells_mapsemi_gradient_q_learning!upstream_cells_mapsemi_gradient_sarsa!$991492f4-7dfc-43aa-ab6c-a6b1f3e38225compute_q_learning_value$1410db13-4b73-4a87-af34-30a5232af4ba$e5ad765a-341f-4f11-9ae8-37d81cb349d2precedence_heuristic	cell_id$e5ad765a-341f-4f11-9ae8-37d81cb349d2downstream_cells_map$mountain_car_differential_transition$bc1d7cce-c0f4-47a8-b674-8acb82491c7fupstream_cells_mapStateMDPTransitionSamplerinitialize_car_state$cafb20b4-a2bd-46a9-9660-b0ace84d6e4cmountain_car_differential_step$eb28458f-b222-4f8e-9a5b-8203d3997f7b$8befede5-378a-447a-96bd-edcd9d2ce98bprecedence_heuristic	cell_id$8befede5-378a-447a-96bd-edcd9d2ce98bdownstream_cells_mapupstream_cells_map@md_strgetindex$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667precedence_heuristic	cell_id$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667downstream_cells_mapepisode_rewards2_fcannaverage_step_reward_fcannq̂_mountain_car2_fcann$b094bf9f-bb97-4f23-acdc-f39411a07fb9$c44dd6c6-8213-49fb-8d33-ba8f2c766b2eepisode_steps2_fcann$425fe768-c7bb-4d3e-87e6-47fa052ba612upstream_cells_mapcompute_q_learning_value$1410db13-4b73-4a87-af34-30a5232af4ba#mountaincar_fcann_differential_test$d3ba78fa-f032-4bb9-9359-ef3bcff2252d$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867fprecedence_heuristic	cell_id$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867fdownstream_cells_mapupdate_input!$c678846c-aaff-4266-8b2c-07a3a92445efupstream_cells_maplength:eachindexFloat32Matrix+sizeIntegerVector$065b2626-01f1-443f-8be4-3036003a2772precedence_heuristic	cell_id$065b2626-01f1-443f-8be4-3036003a2772downstream_cells_map+run_linear_differential_semi_gradient_sarsa$49e43d51-05d6-415b-a685-76e50904c5bcupstream_cells_map:AbstractVector!differential_semi_gradient_sarsa!$a9fdb1fd-3f62-4e1c-9157-c4eee6215261zerosIntegerStateMDPNamedTupleRealFunctionlength%linear_features_action_gradient_setup$b9ebd6bb-90a1-4945-85ed-023206e2420a$57ea3538-33be-4673-b914-8191d35426a9precedence_heuristic	cell_id$57ea3538-33be-4673-b914-8191d35426a9downstream_cells_mapmountaincar_value_iteration$57659c52-de1b-46e6-a863-8eeec0cee601$a97e3b12-b7a5-4f88-bdb9-c3158203e0ff$c799ffe4-f4af-487d-b557-8b50d13632b7upstream_cells_maptabular_mountaincar_mdp$9d65285f-d49e-40ce-acea-1f565bcd4108value_iteration_v$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adbprecedence_heuristic	cell_id$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adbdownstream_cells_mapupstream_cells_map@md_strgetindex$425fe768-c7bb-4d3e-87e6-47fa052ba612precedence_heuristic	cell_id$425fe768-c7bb-4d3e-87e6-47fa052ba612downstream_cells_mapupstream_cells_map:-scatterfindlastiszeroplot!episode_steps2_fcann$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667Layout$06834750-cc3a-468a-b0c2-81349c288a33precedence_heuristic	cell_id$06834750-cc3a-468a-b0c2-81349c288a33downstream_cells_mapgradient_monte_carlo_control!$17d11fea-883b-4ddb-bec2-c4ad491b39dd$c75dc51c-cbff-48b1-b0fd-108828929b51upstream_cells_map sum!Tupleislessviewone'Base.CoreLogging.Base.fixup_stdlib_pathStateMDPBase.CoreLogging.!<lengtheachindexrunepisode!Real/@infoBase.invokelatestrunepisode+gradient_monte_carlo_action_episode_update!$953907cd-9926-4478-99b3-da7068118c22Base.CoreLogging.invokelatestBase.CoreLogging.===:zeros#___this_pluto_module_namerandIntegerFunctionBasepush!Base.CoreLogging.isaBase.CoreLogging.>=$1054cfa3-9f58-4a93-a318-c2d21cf23220precedence_heuristic	cell_id$1054cfa3-9f58-4a93-a318-c2d21cf23220downstream_cells_mapshow_mountaincar_trajectory$d42bb733-07e2-4932-aab4-09229ff67492$864450b9-1319-4426-961f-ee6df93463d8$99e3ec39-24f0-43d6-b6fd-9910b738ce2c$a97e3b12-b7a5-4f88-bdb9-c3158203e0ff$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3$66d6a4b0-ddf8-4781-b3b4-20f02b25199a$78087a57-33a0-4581-81de-926476090931$f2201afe-8952-4dde-9e39-02beeb920f6f$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0$1e224a46-91ef-4a5f-ae35-ef4062147f2d$5cbaeb8e-bc02-47c9-87b4-57df554cea9d$b5409b69-a254-4355-b2b9-99394eceb2f7$ab4cb3db-3a2d-4145-826b-b1001114eeff$b191d3f9-cf25-4fb4-8f5a-8da86e96e125$954848db-6dcc-4666-90f8-b5a900203242upstream_cells_map@md_strsummountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dIntegerRealMarkdown.parsescatterplotMatrixMarkdownLayoutrunepisodegetindex$8ed6f8fd-8574-4d5a-9964-ce8a32629c6fprecedence_heuristic	cell_id$8ed6f8fd-8574-4d5a-9964-ce8a32629c6fdownstream_cells_mapcompute_expected_sarsa_value$7812e801-70fd-4331-ad0a-fad02c1a399f$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0upstream_cells_mapRealdotIntegerVector$f9abf433-8ce3-4520-9b47-f17f8f07b4cbprecedence_heuristic	cell_id$f9abf433-8ce3-4520-9b47-f17f8f07b4cbdownstream_cells_map$mountain_car_transition_distribution$5b2ffd90-ead0-42ce-999a-584ed8995910upstream_cells_mapmountain_car_dist_step$df07524f-b3fe-4a66-98ac-8f80df66bcffinitialize_car_state$cafb20b4-a2bd-46a9-9660-b0ace84d6e4cStateMDPTransitionDistribution$59ec5223-f23f-4f32-9e5f-8a08e450da85precedence_heuristic	cell_id$59ec5223-f23f-4f32-9e5f-8a08e450da85downstream_cells_mapupstream_cells_map@md_strgetindex$0c7f5742-6c51-4c6a-b67f-217163935ba5precedence_heuristic	cell_id$0c7f5742-6c51-4c6a-b67f-217163935ba5downstream_cells_mapupstream_cells_map@md_strgetindex$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efcprecedence_heuristic	cell_id$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efcdownstream_cells_mapfill_action_values!$b9ebd6bb-90a1-4945-85ed-023206e2420aupstream_cells_mapAbstractVectormul!pop@inboundsadjointVectorRealdoteachindexMatrixconj$9fb5dace-a799-4424-bcb3-8542e508dd4bprecedence_heuristiccell_id$9fb5dace-a799-4424-bcb3-8542e508dd4bdownstream_cells_mapPlutoUI$528533f7-68f1-4d19-9a37-6d4d0d7c38e2$33ea5f09-3a1f-476d-875a-1f3635a40295HypertextLiteral$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$dd472c0f-7b43-4abe-ada9-9dc8004a18cbPlutoProfileBenchmarkToolsPlutoPlotlyLaTeXStringsupstream_cells_map$c1388562-0708-4a6a-acfe-927413dab5d2precedence_heuristic	cell_id$c1388562-0708-4a6a-acfe-927413dab5d2downstream_cells_mapupstream_cells_map-scatterplotLayoutepisode_rewards$30ab21ba-3f5b-46a8-8b8c-753f2755d419$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3precedence_heuristic	cell_id$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3downstream_cells_mapupstream_cells_mapπ_optimal_value_iteration$57659c52-de1b-46e6-a863-8eeec0cee601show_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220$6cea9e69-bf8c-4079-9884-663a728d7b08precedence_heuristic	cell_id$6cea9e69-bf8c-4079-9884-663a728d7b08downstream_cells_mapupstream_cells_map@md_strgetindex$b0cc6ff8-7296-461c-9db7-e52fa518e2e2precedence_heuristic	cell_id$b0cc6ff8-7296-461c-9db7-e52fa518e2e2downstream_cells_mapmountaincar_dist_test$d0cf3806-05c6-4a50-94c8-55c9042d51b7upstream_cells_maplengthInt64typemaxmountain_car_dist_mdp$5b2ffd90-ead0-42ce-999a-584ed8995910Float32/zerossetup_mountain_car_tiles$742100ba-c38e-4840-8988-40990039b527Integerrun_linear_semi_gradient_dp$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94$30ab21ba-3f5b-46a8-8b8c-753f2755d419precedence_heuristic	cell_id$30ab21ba-3f5b-46a8-8b8c-753f2755d419downstream_cells_mapepisode_stepsπ_mountain_car$f2201afe-8952-4dde-9e39-02beeb920f6fepisode_rewards$c1388562-0708-4a6a-acfe-927413dab5d2q̂_mountain_car$4afbb723-340b-4d85-9115-027a0ff8dfadupstream_cells_mapmountaincar_test$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4/$1478745a-634d-4f31-8a70-b74f0e536201precedence_heuristic	cell_id$1478745a-634d-4f31-8a70-b74f0e536201downstream_cells_mapupstream_cells_map@md_strgetindex$b07460f1-0461-4f63-b145-c4e1818a497eprecedence_heuristic	cell_id$b07460f1-0461-4f63-b145-c4e1818a497edownstream_cells_mapmountain_car_step$df07524f-b3fe-4a66-98ac-8f80df66bcff$ac80958a-73ec-4342-b553-b33df6612a50$12f5065b-5bed-4d03-a0f0-72a942492394upstream_cells_mapInt64-mountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dFloat32Tuple+clamp*==cos$a9b74949-9392-4048-bcb6-5fd48c1d9b98precedence_heuristic	cell_id$a9b74949-9392-4048-bcb6-5fd48c1d9b98downstream_cells_mapupstream_cells_map@md_strgetindex$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0precedence_heuristic	cell_id$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0downstream_cells_map*differential_semi_gradient_expected_sarsa!upstream_cells_mapcompute_expected_sarsa_value$8ed6f8fd-8574-4d5a-9964-ce8a32629c6f!differential_semi_gradient_sarsa!$a9fdb1fd-3f62-4e1c-9157-c4eee6215261$12f5065b-5bed-4d03-a0f0-72a942492394precedence_heuristic	cell_id$12f5065b-5bed-4d03-a0f0-72a942492394downstream_cells_mapmake_tabular_mountaincar$9d65285f-d49e-40ce-acea-1f565bcd4108upstream_cells_map :mountain_car_step$b07460f1-0461-4f63-b145-c4e1818a497esearchsortedfirstLinRangemountain_car_actions$d577b393-4b40-4c90-9993-4ffbcbd9df6dinitialize_car_state$cafb20b4-a2bd-46a9-9660-b0ace84d6e4czeroslengthInt64-enumerateFloat32TabularDeterministicTransition^+*==TabularMDP$4afbb723-340b-4d85-9115-027a0ff8dfadprecedence_heuristic	cell_id$4afbb723-340b-4d85-9115-027a0ff8dfaddownstream_cells_mapupstream_cells_mapplot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548q̂_mountain_car$30ab21ba-3f5b-46a8-8b8c-753f2755d419$00399548-b21c-43b5-90e2-30656ab1541eprecedence_heuristic	cell_id$00399548-b21c-43b5-90e2-30656ab1541edownstream_cells_mapupstream_cells_map-scatterplotmountaincar_fcann_dp_results$ee59176e-24b6-4213-8f8e-759a70bc1d5eLayout$c75dc51c-cbff-48b1-b0fd-108828929b51precedence_heuristic	cell_id$c75dc51c-cbff-48b1-b0fd-108828929b51downstream_cells_map&run_fcann_gradient_monte_carlo_controlupstream_cells_map AbstractVectorInfzerosislessrandIntegerStateMDPVector<Int64eachindexRealFunctionFloat32lengthgradient_monte_carlo_control!$06834750-cc3a-468a-b0c2-81349c288a33fcann_action_gradient_setup$c678846c-aaff-4266-8b2c-07a3a92445ef$7a47a518-dfc7-4310-a0b5-6f0d151c8263precedence_heuristic	cell_id$7a47a518-dfc7-4310-a0b5-6f0d151c8263downstream_cells_mapupstream_cells_map@md_strgetindex$a22e5d34-4b8d-479c-985c-d6abd41a6c80precedence_heuristic	cell_id$a22e5d34-4b8d-479c-985c-d6abd41a6c80downstream_cells_mapupstream_cells_map@md_strgetindex$b990ba67-42c8-4ab9-943d-085392204fddprecedence_heuristic	cell_id$b990ba67-42c8-4ab9-943d-085392204fdddownstream_cells_mapupstream_cells_map@md_strgetindex$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4precedence_heuristic	cell_id$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4downstream_cells_mapmountaincar_test$30ab21ba-3f5b-46a8-8b8c-753f2755d419$1a82ae95-3c3e-4281-bc1d-9eb19bf50286$cbac1927-b087-4c4c-98ae-6aa5f0b824adupstream_cells_maplengthInt64run_linear_semi_gradient_sarsa$2c620fe4-2f62-40f8-a666-8dced1e0b84aFloat32/mountain_car_mdp$1e9c537a-a731-4b81-8f6a-cb658b52c5bezerossetup_mountain_car_tiles$742100ba-c38e-4840-8988-40990039b527Integertypemax$0e3e506d-1959-47fd-8da9-b3dfd294be67precedence_heuristic	cell_id$0e3e506d-1959-47fd-8da9-b3dfd294be67downstream_cells_mapupstream_cells_mapq̂_mountain_car2$db189316-e880-4cc8-9070-ccfe2b4fc545plot_mountaincar_action_values$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$5db29488-a150-42ee-aedb-380a3a4fd548$af97f222-08d1-4200-a10b-8da178182175precedence_heuristic	cell_id$af97f222-08d1-4200-a10b-8da178182175downstream_cells_mapupstream_cells_map@md_strgetindex$b5273dfa-2262-487a-856b-441f007bd163precedence_heuristic	cell_id$b5273dfa-2262-487a-856b-441f007bd163downstream_cells_mapupstream_cells_map:nsamples$e86bc86f-9909-458d-b86d-0a4ac4b9d43d/|>+foldxtmountain_car_mdp$1e9c537a-a731-4b81-8f6a-cb658b52c5be==runepisodeMap$b5409b69-a254-4355-b2b9-99394eceb2f7precedence_heuristic	cell_id$b5409b69-a254-4355-b2b9-99394eceb2f7downstream_cells_mapupstream_cells_mapπ_mountain_car_q$cbac1927-b087-4c4c-98ae-6aa5f0b824adshow_mountaincar_trajectory$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$1054cfa3-9f58-4a93-a318-c2d21cf23220$b9ebd6bb-90a1-4945-85ed-023206e2420aprecedence_heuristic	cell_id$b9ebd6bb-90a1-4945-85ed-023206e2420adownstream_cells_map%linear_features_action_gradient_setup$2c620fe4-2f62-40f8-a666-8dced1e0b84a$065b2626-01f1-443f-8be4-3036003a2772$17d11fea-883b-4ddb-bec2-c4ad491b39ddupstream_cells_map calculate_action_value$f11787a1-57f8-4077-8d60-bc760ece7cc6AbstractVectoriszeroAbstractArrayfindmaxIntegerStateMDPnothingVectorRealcopy-Functionfill_action_values!$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efcupdate_parameters!$5f8b0254-88f4-4d19-ade1-8e7c40941b43$96548352-cd4d-4448-8312-ed10057f4359UnionStateMRP$d0cf3806-05c6-4a50-94c8-55c9042d51b7precedence_heuristic	cell_id$d0cf3806-05c6-4a50-94c8-55c9042d51b7downstream_cells_mapv̂_mountain_car$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8π_greedy_dp$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0episode_rewards_dp$5c920177-8e46-49c9-9b95-1a657fdcae4eepisode_steps_dpupstream_cells_map/mountaincar_dist_test$b0cc6ff8-7296-461c-9db7-e52fa518e2e2cell_execution_order $69fb26ed-763e-44ad-9b70-193e5a1a09b9$3f7484b3-272d-410d-92b1-ca13e5d7a8b7$9fb5dace-a799-4424-bcb3-8542e508dd4b$318b398a-d8f2-4f39-a45d-fd9023961bf8$35d59eae-77fd-11ef-2790-35dd5a834060$b0265b93-ae5f-48f2-a9fd-44fd6115164b$47710ddd-79d9-464d-b5dd-27180f2d6b31$4d392303-4681-4ea1-8dcc-e002a78ea0a1$a3cf270b-b309-44f0-9972-bd84228bcf17$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18$14fe2253-cf2c-4159-a360-1e65f1c82b09$6351304f-50ac-4755-86e1-cd4680f2d803$e7bf61d7-c362-433d-9b83-6537d308c255$fc0b88f3-fbf9-450d-b770-b34357ffad49$991492f4-7dfc-43aa-ab6c-a6b1f3e38225$8b7e1031-9864-439c-86eb-11aa08f53b90$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6$57a6510f-bd42-4d1d-a550-d1442f79569f$b0761704-5447-4e64-8270-708d9dccef60$54b92594-04b8-4a8a-82c2-773b4a24680d$278a26ac-c48f-4e18-93bb-706a4634c8c0$5f8b0254-88f4-4d19-ade1-8e7c40941b43$c5c839f7-1806-463d-b63a-bd7e1384f203$f11787a1-57f8-4077-8d60-bc760ece7cc6$1478745a-634d-4f31-8a70-b74f0e536201$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efc$dc2cffeb-9adf-4956-afa3-ac82af377c59$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94$8d096d0d-8fea-421a-aa33-82269d3fe7e2$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867f$c678846c-aaff-4266-8b2c-07a3a92445ef$39b0f100-a7e7-4633-b296-ccc87a5a35ab$00e7783f-7f17-4944-a085-ea87509cd75a$a22e5d34-4b8d-479c-985c-d6abd41a6c80$b990ba67-42c8-4ab9-943d-085392204fdd$cafb20b4-a2bd-46a9-9660-b0ace84d6e4c$d577b393-4b40-4c90-9993-4ffbcbd9df6d$b07460f1-0461-4f63-b145-c4e1818a497e$df07524f-b3fe-4a66-98ac-8f80df66bcff$28e0d632-0df3-4a5b-85c4-571c845ff827$8befede5-378a-447a-96bd-edcd9d2ce98b$ac80958a-73ec-4342-b553-b33df6612a50$f9abf433-8ce3-4520-9b47-f17f8f07b4cb$1e9c537a-a731-4b81-8f6a-cb658b52c5be$5b2ffd90-ead0-42ce-999a-584ed8995910$f6e08689-040f-4565-9dfb-e9a65d1c1f18$528533f7-68f1-4d19-9a37-6d4d0d7c38e2$afee7bc9-aff0-4c71-a227-9845cb23d4e9$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$ca970333-fa08-412c-b89d-491e70f0ac79$e86bc86f-9909-458d-b86d-0a4ac4b9d43d$b5273dfa-2262-487a-856b-441f007bd163$dae59fd9-0397-4307-afd8-bafb6f0bfa52$d291541d-ddba-4b71-a4eb-37fef758b71b$12f5065b-5bed-4d03-a0f0-72a942492394$39c63495-36c3-4e62-b8fb-36865f2c6243$33ea5f09-3a1f-476d-875a-1f3635a40295$1d417a66-205f-4883-b49c-a6fc900af4ce$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2$9d65285f-d49e-40ce-acea-1f565bcd4108$1b15efa9-c331-46bf-93db-f96dee026fe2$e338be2b-05f1-43f4-a194-45ffd710777e$e48af9f4-0b47-4a45-b0ad-8f53b094e712$72f575ee-d656-4af6-bf78-aab42bf1debd$57ea3538-33be-4673-b914-8191d35426a9$57659c52-de1b-46e6-a863-8eeec0cee601$be77b538-d106-4ca0-a974-289415588c47$3c300a2b-4139-4df0-906b-4cae3592cc2b$e2cd69c5-eda7-4897-9e64-0adf940d4d96$5bc2eda5-5f4c-4165-9afb-16920f30b0c5$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$1054cfa3-9f58-4a93-a318-c2d21cf23220$d42bb733-07e2-4932-aab4-09229ff67492$864450b9-1319-4426-961f-ee6df93463d8$99e3ec39-24f0-43d6-b6fd-9910b738ce2c$a97e3b12-b7a5-4f88-bdb9-c3158203e0ff$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3$66d6a4b0-ddf8-4781-b3b4-20f02b25199a$78087a57-33a0-4581-81de-926476090931$1a5acfb0-3b35-41b1-98f8-ffce941c587f$742100ba-c38e-4840-8988-40990039b527$af97f222-08d1-4200-a10b-8da178182175$224b4bec-9ec5-434d-a950-f5974cd786d0$b0cc6ff8-7296-461c-9db7-e52fa518e2e2$d0cf3806-05c6-4a50-94c8-55c9042d51b7$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0$31fb07d2-1c34-44ec-b932-a598e78ec8dc$c12070a9-df63-4b25-99e6-26ff876af1b4$0f958535-6b18-46de-a1ba-81f64c217ee0$ee59176e-24b6-4213-8f8e-759a70bc1d5e$1e224a46-91ef-4a5f-ae35-ef4062147f2d$00399548-b21c-43b5-90e2-30656ab1541e$5db29488-a150-42ee-aedb-380a3a4fd548$c799ffe4-f4af-487d-b557-8b50d13632b7$58a0b622-1b51-4b42-a416-24109ae41a90$2f0d0a71-c65b-4aa0-a493-e7cdccd901eb$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8$b3658e4d-ee8e-45cd-906a-06dd512a6921$7a47a518-dfc7-4310-a0b5-6f0d151c8263$c11aa069-93c2-435a-8f0e-353ced9633b6$5fdbce61-ca25-45e0-b07d-94adf7138446$b9125c5b-01d6-451e-84b5-a419e38425b5$fc3e0577-45aa-4bba-a275-fa7a352fc5cc$5cbaeb8e-bc02-47c9-87b4-57df554cea9d$59ec5223-f23f-4f32-9e5f-8a08e450da85$49249ac1-8964-4afc-89f2-3cd4d4322cc2$e1abf8c7-06b8-4cd5-b557-1d187004bdf1$98a5d65e-4253-4523-a74e-99d03be03b89$8ed6f8fd-8574-4d5a-9964-ce8a32629c6f$1410db13-4b73-4a87-af34-30a5232af4ba$7812e801-70fd-4331-ad0a-fad02c1a399f$5be866c3-0fb2-4d1f-9c31-b85aba332905$f7410fe7-e3d8-4047-8fa7-f076476e9d3a$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5b$b8c031ca-7995-4501-a1e3-df3f34e5f0da$69a06405-57cd-42e5-96b1-5cc77d74aa03$a9fdb1fd-3f62-4e1c-9157-c4eee6215261$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0$c9759bd9-ec9b-47a1-9080-a7fc332be565$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0$1a7ba296-52ca-4069-85fa-792d08d77b0e$eb28458f-b222-4f8e-9a5b-8203d3997f7b$e5ad765a-341f-4f11-9ae8-37d81cb349d2$bc1d7cce-c0f4-47a8-b674-8acb82491c7f$d3ba78fa-f032-4bb9-9359-ef3bcff2252d$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667$b094bf9f-bb97-4f23-acdc-f39411a07fb9$425fe768-c7bb-4d3e-87e6-47fa052ba612$b191d3f9-cf25-4fb4-8f5a-8da86e96e125$c44dd6c6-8213-49fb-8d33-ba8f2c766b2e$9df1a18d-137c-4ea5-8d15-05697f7bbf07$0c7f5742-6c51-4c6a-b67f-217163935ba5$a6c5ec28-b2d5-4893-a118-95c1318d1f7f$44d43dbf-fe32-438e-b89d-c677bbc35893$f1edb500-fbd1-4c03-b033-53860dfa452d$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adb$a9b74949-9392-4048-bcb6-5fd48c1d9b98$fbf1c64f-1979-4384-a8c6-dc7875174d1f$e7372e2b-a2db-4a93-9efc-f75aa74c197b$014339eb-5b23-4ac5-a551-8eeb2238366f$96548352-cd4d-4448-8312-ed10057f4359$b9ebd6bb-90a1-4945-85ed-023206e2420a$2c620fe4-2f62-40f8-a666-8dced1e0b84a$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4$30ab21ba-3f5b-46a8-8b8c-753f2755d419$4afbb723-340b-4d85-9115-027a0ff8dfad$f2201afe-8952-4dde-9e39-02beeb920f6f$c1388562-0708-4a6a-acfe-927413dab5d2$1a82ae95-3c3e-4281-bc1d-9eb19bf50286$ddcb50be-5287-47f8-89f9-58c026a6b151$cbac1927-b087-4c4c-98ae-6aa5f0b824ad$b5409b69-a254-4355-b2b9-99394eceb2f7$f9ee13e8-7406-4fba-9a30-1e2714bd7cfc$065b2626-01f1-443f-8be4-3036003a2772$49e43d51-05d6-415b-a685-76e50904c5bc$db189316-e880-4cc8-9070-ccfe2b4fc545$7bc49107-9de5-4985-8750-979f36b3aa81$ab4cb3db-3a2d-4145-826b-b1001114eeff$0e3e506d-1959-47fd-8da9-b3dfd294be67$4775126e-4374-49be-b25f-4597401f3642$4271151d-d5a6-4a29-96c3-f2102b142b95$5534526a-d790-4379-98b0-8e4ee981fd9f$f68952bd-4c0b-4331-a09c-5b118c8fa5a9$62839b2a-398a-4445-87d1-b15ff2acc1d1$b4af8d87-a6e5-4e09-92b4-b07757f58f7f$546a775e-d3c9-4693-9f64-d4c47a84fb9f$41c626c7-908d-4ff6-9730-4ad0b8c3cc25$662759be-282c-460b-adc3-8595475b53c2$0e66a941-1ec1-4d3b-b064-e5f25cc93baf$c316c5d3-f484-4e8e-bd56-be1e236d96bc$bc220d14-97fd-486d-9880-6908135fe036$39eada35-8c3e-4ddc-8df9-7cf9f120928d$8752c98d-fac1-4b3b-b20b-70acc0677fcb$50f6ff51-d81b-4e97-9f8a-0daf03af7192$953907cd-9926-4478-99b3-da7068118c22$13e477f0-dc15-46cb-9691-c04a1b4c83c8$06834750-cc3a-468a-b0c2-81349c288a33$c85033e1-3ee6-42ad-9ef0-144ce6238ce4$5c920177-8e46-49c9-9b95-1a657fdcae4e$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6a$09088eee-4cb3-40ac-b127-658ce1332fba$17d11fea-883b-4ddb-bec2-c4ad491b39dd$0714a1cf-9288-4f1e-ba72-d82608704d69$b76551e0-c027-4682-b5ae-bba7ea2b987a$954848db-6dcc-4666-90f8-b5a900203242$b55d50a4-b039-4240-b434-42f7b724d24d$c75dc51c-cbff-48b1-b0fd-108828929b51$6cea9e69-bf8c-4079-9884-663a728d7b08$f5e32900-6eb6-4b61-916d-893c0bcaf214$ed1bd92c-8cc7-457f-9692-a10a9487c953$dd472c0f-7b43-4abe-ada9-9dc8004a18cblast_hot_reload_time        shortpath2Chapter_10_On_policy_Control_with_Approximation.jlprocess_statusreadypathm/home/runner/work/RL-Deploy-Test/RL-Deploy-Test/Chapter-10/Chapter_10_On_policy_Control_with_Approximation.jlpluto_versionv0.19.47last_save_timeA6*X֪cell_order $35d59eae-77fd-11ef-2790-35dd5a834060$b0265b93-ae5f-48f2-a9fd-44fd6115164b$47710ddd-79d9-464d-b5dd-27180f2d6b31$4d392303-4681-4ea1-8dcc-e002a78ea0a1$a3cf270b-b309-44f0-9972-bd84228bcf17$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18$14fe2253-cf2c-4159-a360-1e65f1c82b09$6351304f-50ac-4755-86e1-cd4680f2d803$e7bf61d7-c362-433d-9b83-6537d308c255$fc0b88f3-fbf9-450d-b770-b34357ffad49$991492f4-7dfc-43aa-ab6c-a6b1f3e38225$8b7e1031-9864-439c-86eb-11aa08f53b90$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6$57a6510f-bd42-4d1d-a550-d1442f79569f$b0761704-5447-4e64-8270-708d9dccef60$54b92594-04b8-4a8a-82c2-773b4a24680d$278a26ac-c48f-4e18-93bb-706a4634c8c0$5f8b0254-88f4-4d19-ade1-8e7c40941b43$c5c839f7-1806-463d-b63a-bd7e1384f203$f11787a1-57f8-4077-8d60-bc760ece7cc6$1478745a-634d-4f31-8a70-b74f0e536201$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efc$dc2cffeb-9adf-4956-afa3-ac82af377c59$b9ebd6bb-90a1-4945-85ed-023206e2420a$2c620fe4-2f62-40f8-a666-8dced1e0b84a$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94$8d096d0d-8fea-421a-aa33-82269d3fe7e2$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867f$c678846c-aaff-4266-8b2c-07a3a92445ef$39b0f100-a7e7-4633-b296-ccc87a5a35ab$00e7783f-7f17-4944-a085-ea87509cd75a$a22e5d34-4b8d-479c-985c-d6abd41a6c80$b990ba67-42c8-4ab9-943d-085392204fdd$cafb20b4-a2bd-46a9-9660-b0ace84d6e4c$b07460f1-0461-4f63-b145-c4e1818a497e$df07524f-b3fe-4a66-98ac-8f80df66bcff$d577b393-4b40-4c90-9993-4ffbcbd9df6d$28e0d632-0df3-4a5b-85c4-571c845ff827$8befede5-378a-447a-96bd-edcd9d2ce98b$ac80958a-73ec-4342-b553-b33df6612a50$f9abf433-8ce3-4520-9b47-f17f8f07b4cb$1e9c537a-a731-4b81-8f6a-cb658b52c5be$5b2ffd90-ead0-42ce-999a-584ed8995910$f6e08689-040f-4565-9dfb-e9a65d1c1f18$528533f7-68f1-4d19-9a37-6d4d0d7c38e2$d42bb733-07e2-4932-aab4-09229ff67492$afee7bc9-aff0-4c71-a227-9845cb23d4e9$864450b9-1319-4426-961f-ee6df93463d8$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93$ca970333-fa08-412c-b89d-491e70f0ac79$e86bc86f-9909-458d-b86d-0a4ac4b9d43d$b5273dfa-2262-487a-856b-441f007bd163$dae59fd9-0397-4307-afd8-bafb6f0bfa52$d291541d-ddba-4b71-a4eb-37fef758b71b$12f5065b-5bed-4d03-a0f0-72a942492394$1d417a66-205f-4883-b49c-a6fc900af4ce$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2$9d65285f-d49e-40ce-acea-1f565bcd4108$1b15efa9-c331-46bf-93db-f96dee026fe2$e338be2b-05f1-43f4-a194-45ffd710777e$e48af9f4-0b47-4a45-b0ad-8f53b094e712$39c63495-36c3-4e62-b8fb-36865f2c6243$33ea5f09-3a1f-476d-875a-1f3635a40295$99e3ec39-24f0-43d6-b6fd-9910b738ce2c$72f575ee-d656-4af6-bf78-aab42bf1debd$57ea3538-33be-4673-b914-8191d35426a9$57659c52-de1b-46e6-a863-8eeec0cee601$a97e3b12-b7a5-4f88-bdb9-c3158203e0ff$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3$c799ffe4-f4af-487d-b557-8b50d13632b7$be77b538-d106-4ca0-a974-289415588c47$3c300a2b-4139-4df0-906b-4cae3592cc2b$e2cd69c5-eda7-4897-9e64-0adf940d4d96$66d6a4b0-ddf8-4781-b3b4-20f02b25199a$78087a57-33a0-4581-81de-926476090931$58a0b622-1b51-4b42-a416-24109ae41a90$5bc2eda5-5f4c-4165-9afb-16920f30b0c5$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bd$d8d5db17-d89c-47db-b258-6ad1635478b7$1054cfa3-9f58-4a93-a318-c2d21cf23220$1a5acfb0-3b35-41b1-98f8-ffce941c587f$742100ba-c38e-4840-8988-40990039b527$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4$30ab21ba-3f5b-46a8-8b8c-753f2755d419$4afbb723-340b-4d85-9115-027a0ff8dfad$f2201afe-8952-4dde-9e39-02beeb920f6f$c1388562-0708-4a6a-acfe-927413dab5d2$ddcb50be-5287-47f8-89f9-58c026a6b151$af97f222-08d1-4200-a10b-8da178182175$224b4bec-9ec5-434d-a950-f5974cd786d0$b0cc6ff8-7296-461c-9db7-e52fa518e2e2$d0cf3806-05c6-4a50-94c8-55c9042d51b7$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0$5c920177-8e46-49c9-9b95-1a657fdcae4e$31fb07d2-1c34-44ec-b932-a598e78ec8dc$c12070a9-df63-4b25-99e6-26ff876af1b4$0f958535-6b18-46de-a1ba-81f64c217ee0$ee59176e-24b6-4213-8f8e-759a70bc1d5e$b3658e4d-ee8e-45cd-906a-06dd512a6921$1e224a46-91ef-4a5f-ae35-ef4062147f2d$00399548-b21c-43b5-90e2-30656ab1541e$1a82ae95-3c3e-4281-bc1d-9eb19bf50286$5db29488-a150-42ee-aedb-380a3a4fd548$2f0d0a71-c65b-4aa0-a493-e7cdccd901eb$7a47a518-dfc7-4310-a0b5-6f0d151c8263$c11aa069-93c2-435a-8f0e-353ced9633b6$5fdbce61-ca25-45e0-b07d-94adf7138446$b9125c5b-01d6-451e-84b5-a419e38425b5$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6a$fc3e0577-45aa-4bba-a275-fa7a352fc5cc$5cbaeb8e-bc02-47c9-87b4-57df554cea9d$59ec5223-f23f-4f32-9e5f-8a08e450da85$49249ac1-8964-4afc-89f2-3cd4d4322cc2$e1abf8c7-06b8-4cd5-b557-1d187004bdf1$98a5d65e-4253-4523-a74e-99d03be03b89$8ed6f8fd-8574-4d5a-9964-ce8a32629c6f$1410db13-4b73-4a87-af34-30a5232af4ba$7812e801-70fd-4331-ad0a-fad02c1a399f$5be866c3-0fb2-4d1f-9c31-b85aba332905$f7410fe7-e3d8-4047-8fa7-f076476e9d3a$cbac1927-b087-4c4c-98ae-6aa5f0b824ad$b5409b69-a254-4355-b2b9-99394eceb2f7$f9ee13e8-7406-4fba-9a30-1e2714bd7cfc$09088eee-4cb3-40ac-b127-658ce1332fba$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5b$b8c031ca-7995-4501-a1e3-df3f34e5f0da$69a06405-57cd-42e5-96b1-5cc77d74aa03$a9fdb1fd-3f62-4e1c-9157-c4eee6215261$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0$c9759bd9-ec9b-47a1-9080-a7fc332be565$065b2626-01f1-443f-8be4-3036003a2772$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0$1a7ba296-52ca-4069-85fa-792d08d77b0e$eb28458f-b222-4f8e-9a5b-8203d3997f7b$e5ad765a-341f-4f11-9ae8-37d81cb349d2$bc1d7cce-c0f4-47a8-b674-8acb82491c7f$49e43d51-05d6-415b-a685-76e50904c5bc$db189316-e880-4cc8-9070-ccfe2b4fc545$7bc49107-9de5-4985-8750-979f36b3aa81$ab4cb3db-3a2d-4145-826b-b1001114eeff$0e3e506d-1959-47fd-8da9-b3dfd294be67$4775126e-4374-49be-b25f-4597401f3642$b094bf9f-bb97-4f23-acdc-f39411a07fb9$d3ba78fa-f032-4bb9-9359-ef3bcff2252d$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667$425fe768-c7bb-4d3e-87e6-47fa052ba612$b191d3f9-cf25-4fb4-8f5a-8da86e96e125$c44dd6c6-8213-49fb-8d33-ba8f2c766b2e$9df1a18d-137c-4ea5-8d15-05697f7bbf07$0c7f5742-6c51-4c6a-b67f-217163935ba5$a6c5ec28-b2d5-4893-a118-95c1318d1f7f$44d43dbf-fe32-438e-b89d-c677bbc35893$f1edb500-fbd1-4c03-b033-53860dfa452d$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adb$a9b74949-9392-4048-bcb6-5fd48c1d9b98$fbf1c64f-1979-4384-a8c6-dc7875174d1f$e7372e2b-a2db-4a93-9efc-f75aa74c197b$014339eb-5b23-4ac5-a551-8eeb2238366f$62839b2a-398a-4445-87d1-b15ff2acc1d1$96548352-cd4d-4448-8312-ed10057f4359$4271151d-d5a6-4a29-96c3-f2102b142b95$5534526a-d790-4379-98b0-8e4ee981fd9f$f68952bd-4c0b-4331-a09c-5b118c8fa5a9$b4af8d87-a6e5-4e09-92b4-b07757f58f7f$41c626c7-908d-4ff6-9730-4ad0b8c3cc25$546a775e-d3c9-4693-9f64-d4c47a84fb9f$662759be-282c-460b-adc3-8595475b53c2$0e66a941-1ec1-4d3b-b064-e5f25cc93baf$c316c5d3-f484-4e8e-bd56-be1e236d96bc$bc220d14-97fd-486d-9880-6908135fe036$39eada35-8c3e-4ddc-8df9-7cf9f120928d$8752c98d-fac1-4b3b-b20b-70acc0677fcb$50f6ff51-d81b-4e97-9f8a-0daf03af7192$953907cd-9926-4478-99b3-da7068118c22$13e477f0-dc15-46cb-9691-c04a1b4c83c8$06834750-cc3a-468a-b0c2-81349c288a33$0714a1cf-9288-4f1e-ba72-d82608704d69$c85033e1-3ee6-42ad-9ef0-144ce6238ce4$b76551e0-c027-4682-b5ae-bba7ea2b987a$954848db-6dcc-4666-90f8-b5a900203242$b55d50a4-b039-4240-b434-42f7b724d24d$17d11fea-883b-4ddb-bec2-c4ad491b39dd$c75dc51c-cbff-48b1-b0fd-108828929b51$6cea9e69-bf8c-4079-9884-663a728d7b08$69fb26ed-763e-44ad-9b70-193e5a1a09b9$3f7484b3-272d-410d-92b1-ca13e5d7a8b7$318b398a-d8f2-4f39-a45d-fd9023961bf8$9fb5dace-a799-4424-bcb3-8542e508dd4b$f5e32900-6eb6-4b61-916d-893c0bcaf214$ed1bd92c-8cc7-457f-9692-a10a9487c953$dd472c0f-7b43-4abe-ada9-9dc8004a18cbpublished_objectsnbpkginstall_time_ns   ^instantiatedòinstalled_versionsStatistics1.11.1Transducers0.4.84PlutoUI0.7.60RandomstdlibBenchmarkTools1.5.0LinearAlgebrastdlibPlutoDevMacros0.9.0PlutoProfile0.4.0HypertextLiteral0.9.5LaTeXStrings1.3.1PlutoPlotly0.5.0terminal_outputsStatistics@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`Transducers@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`PlutoUI@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`Random@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`BenchmarkTools@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`LinearAlgebra@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`PlutoProfile@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`LaTeXStrings@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`ApproximationUtils@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`nbpkg_sync@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`PlutoDevMacros@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`HypertextLiteral@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`PlutoPlotly@
[0m[1mInstantiating...[22m
[90m===[39m

[0m[1mResolving...[22m
[90m===[39m
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Project.toml`
[32m[1m  No Changes[22m[39m to `/tmp/jl_PWP9T2/Manifest.toml`

[0m[1mPrecompiling...[22m
[90m===[39m
[32m[1m  Activating[22m[39m project at `/tmp/jl_PWP9T2`enabled÷restart_recommended_msgrestart_required_msgbusy_packageswaiting_for_permission,waiting_for_permission_but_probably_disabled«cell_inputs $f68952bd-4c0b-4331-a09c-5b118c8fa5a9cell_id$f68952bd-4c0b-4331-a09c-5b118c8fa5a9code4function state_aggregation_action_gradient_setup(assign_state_group::Function)
	function update_params!(parameters, s, i_a, g::T, α::T) where {T<:Real}
		i_s = assign_state_group(s)
		update_parameters!(parameters, i_s, i_a, g, α)
	end

	q̂(s, i_a, parameters) = get_action_value(assign_state_group(s), i_a, parameters)
	q̂(action_values::Vector{T}, s, parameters) where T<:Real = update_action_values!(action_values, assign_state_group(s), parameters)
		
	return (value_function = q̂, value_args = (), parameter_update = update_params!, update_args = ())
endmetadatashow_logsèdisabled®skip_as_script«code_folded$9df1a18d-137c-4ea5-8d15-05697f7bbf07cell_id$9df1a18d-137c-4ea5-8d15-05697f7bbf07codemd"""
> ### *Exercise 10.4* 
> Give pseudocode for a differential version of semi-gradient Q-learning.

Given the pseudocode for semi-gradient Sarsa, make the following changes:

$\vdots$

Initialize S

Loop for each step of episode:

Choose A from S using ϵ-greedy policy
Take action A, observe R, S'

$\delta \leftarrow R - \bar R + \max_a \hat q(S^\prime, a, \mathbf{w}) - \hat q(S, A, \mathbf{w})$

$\vdots$
$S \leftarrow S^\prime$

See implementation above
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c11aa069-93c2-435a-8f0e-353ced9633b6cell_id$c11aa069-93c2-435a-8f0e-353ced9633b6codefunction mountaincar_fcann_test(max_steps::Integer, α::Float32, ϵ::Float32; num_layers = 3, layer_size = 2, kwargs...)
	feature_vector = zeros(Float32, 2)
	function update_feature_vector!(v::Vector{Float32}, s::NTuple{2, Float32})
		x1 = 3.45f0*(((s[1] - 1.2f0) / 1.7f0) - 0.5f0)
		x2 = 1.725f0*s[2] / 0.07f0
		v[1] = x1
		v[2] = x2
	end
	layers = fill(layer_size, num_layers)
	run_fcann_semi_gradient_sarsa(mountain_car_mdp, 1f0, 100, max_steps, feature_vector, update_feature_vector!, layers; α = α, ϵ = ϵ, kwargs...)
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$7812e801-70fd-4331-ad0a-fad02c1a399fcell_id$7812e801-70fd-4331-ad0a-fad02c1a399fcodeوsemi_gradient_expected_sarsa!(args...; kwargs...) = semi_gradient_sarsa!(args...; kwargs..., compute_value=compute_expected_sarsa_value)metadatashow_logsèdisabled®skip_as_script«code_folded$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18cell_id$2f685ee2-6ad8-4bb1-b326-e5de7c15eb18codemd"""
#### Sampling Tabular Case
##### Problem conditions
- All states and actions can be enumerated: $\mathcal{S} = \{s_1, s_2, \cdots, s_n\}$ and $\mathcal{A} = \{a_1, a_2, \cdots, a_m\}$
-  $p(s^\prime, r \vert s, a)$ is not available
- Observations from the environment can be collected: $S_t, A_t \implies R_{t+1}, S_{t+1}$

##### Solution Techniques
In the absence of $p$, we cannot use value iteration which is the only technique that circumvents the need for a policy.  So we must use some form of policy iteration.  It turns out that as long as we continue to update both the policy and the value function, neither need to converge to the correct values at any intermediate step.  The idea behind *Generalized Policy Iteration* is to maintain a value estimate for a given policy and update the policy periodically prior to knowing whether or not the value function has converged.  This interval could be as short as a single time step or as it takes to converge.  For episodic tasks, using a single episode of samples to update the value function followed by the policy is a natural choice.  For continuing tasks, one or more steps can be used in place of an episode.  All of the techniques will have the following in common:
- A list of state-action value estimates: $q = [q_{1, 1}, q_{1, 2}, \cdots, q_{1, m}, \cdots q_{n, m}]$, one for each state-action pair initialized to some value
- An initial random policy $\pi$ (probability distribution over actions for each state, could be a matrix)
- State-action values will be updated by averaging together samples which are unbiased estimates of $q_\pi(s, a)$

The primary difference between the techniques will be which equation is used to calculate the sample values.

- Monte Carlo Control: uses samples of the expected value in the definition of $q_\pi(s, a) = \mathbb{E}_\pi [G_t \vert S_t = s, A_t = a]$
  - repeat the following for a set number of episodes
    - Collect a trajectory under the policy $\pi$: $S_0 \overset{\pi}{\rightarrow} A_0 \rightarrow R_1, S_1 \overset{\pi}{\rightarrow} A_1 \rightarrow R_2, S_2 \overset{\pi}{\rightarrow} A_2 \rightarrow \cdots\rightarrow R_T, S_T$
    - Use the reward sequence to compute an unbiased estimate of $\mathbb{E}_\pi[G_t] = \mathbb{E}[q_\pi(S_t, A_t)]$
    - Update the existing value for each state-action pair $S_t, A_t$ observed in the episode using the estimate (can use any number of averaging techniques)
    - Update $\pi$ to select greedy actions with respect to the state-action value estimates and random actions occassionally (this is required to ensure visits to all state-action pairs and convergence of the expected values)

- Sarsa/Expected Sarsa: uses samples of the expected value in the Bellman equation for $q_\pi(s, a) = \mathbb{E} [R_{t+1} + \gamma\sum_{a^\prime} \pi(a^\prime \vert s^\prime) q_\pi(s^\prime, a^\prime) \mid S_t = s, A_t = a]$
  - initialize a state $S_0$
  - repeat the following for a set number of steps
    - Use $\pi$ to select an action $A_t$
    - Sample from the environment $R_{t+1}, S_{t+1}$
    - Calculate an unbiased estimate for $q_\pi(S_t, A_t)$ using $R_{t+1} + \gamma\sum_{a^\prime} \pi(a^\prime \vert s^\prime) q(S_{t+1}, a^\prime)$ OR use $\pi$ to select the next action $A_{t+1}$ and use $R_{t+1} + \gamma q(S_{t+1}, A_{t+1})$
    - Use some averaging method to update the estimated state-action value for $S_t, A_t$
    - Update $\pi$ to select greedy actions with respect to the state-action value estimates and random actions occassionally (this is required to ensure visits to all state-action pairs and convergence of the expected values)

- Q-learning: uses samples of the expected value in the Bellman optimality equation for $q_*(s, a) = \mathbb{E} \left [ R_t + γ \max_{a^\prime} q_*(s^\prime, a^\prime) \mid S_t = s, A_t = a \right ]$
  - initialize a state $S_0$
  - repeat the following for a set number of steps
    - Use $\pi$ to select an action $A_t$
    - Sample from the environment $R_{t+1}, S_{t+1}$
    - Calculate an unbiased estimate for $q_*(S_t, A_t)$ using $R_{t+1} + \gamma \max_{a^\prime} q(S_{t+1}, a^\prime)$
    - Use some averaging method ot update the state-action value for $S_t, A_t$
    - Update $\pi$ to select greedy actions with respect to the state-action value estimates and random actions occassionally (this is required to ensure visits to all state-action pairs and convergence of the expected values)

Note that technically, Monte Carlo Control and Sarsa find the optimal $\epsilon$-greedy policy and value function; however in practice $\epsilon$ can be reduced over time to arbitrarily approach the true optimal policy.  Q-learning, on the other hand can work even if the policy is never updated since the value update does not depend at all on the policy.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$dae59fd9-0397-4307-afd8-bafb6f0bfa52cell_id$dae59fd9-0397-4307-afd8-bafb6f0bfa52codef(1:nsamples |> Map(i -> runepisode(mountain_car_mdp; max_steps = 100_000)[5]) |> foldxt(+)) / nsamplesmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$c678846c-aaff-4266-8b2c-07a3a92445efcell_id$c678846c-aaff-4266-8b2c-07a3a92445efcodefunction fcann_action_gradient_setup(mdp::StateMDP, layers::Vector{Int64}, feature_vector::Vector{Float32}, update_feature_vector!::Function; kwargs...)
	s0 = mdp.initialize_state()
	num_actions = length(mdp.actions)
	input_layer_size = length(feature_vector)
	update_feature_vector!(feature_vector, s0)
	θ, β = FCANN.initializeparams_saxe(input_layer_size, layers, num_actions, 1; use_μP = true)

	∇θ = deepcopy(θ)
	∇β = deepcopy(β)
	∇tanh_z = FCANN.form_tanh_grads(layers, 1)

	function setup_training(batch_size::Integer)
		activations = [zeros(Float32, batch_size, l) for l in [layers; num_actions]]
		δs = deepcopy(activations)
		onesvec = zeros(Float32, batch_size)
		return (activations, δs, onesvec)
	end

	(activations, δs, onesvec) = setup_training(1)

	input = zeros(Float32, 1, input_layer_size)
	output = zeros(Float32, 1, num_actions)
	scales = ones(Float32, length(layers)+1)
	for i in 2:length(scales)
		scales[i] /= size(θ[i], 2)
	end
	mT = deepcopy(θ)
	vT = deepcopy(θ)
	# θ_est = deepcopy(θ)
	# θ_avg = deepcopy(θ)
	mB = deepcopy(β)
	vB = deepcopy(β)
	# β_est = deepcopy(β)
	# β_avg = deepcopy(β)
	FCANN.zeroParams!(mT, vT)
	FCANN.zeroParams!(vT, vB)
	# function update_parameters!(parameters, s, i_a::Integer, g::Float32, α::Float32, gradients, state_representation::Vector{Float32}, input, output, ∇tanh_z, activations, δs, onesvec, scales)
	# 	update_feature_vector!(state_representation, s)
	# 	NonTabularRL.update_input!(input, state_representation, 1)
	# 	FCANN.predict!(parameters[1], parameters[2], input, activations, 1)
	# 	for i in 1:num_actions
	# 		output[1, i] = activations[end][1, i]
	# 	end
	# 	output[1, i_a] = g
	# 	NonTabularRL.update_nn_parameters!(parameters[1], parameters[2], layers, gradients[1], gradients[2], input, output, ∇tanh_z, activations, δs, onesvec, α, scales; kwargs...)
	# end

	function update_parameters!(parameters, s, i_a::Integer, g::Float32, α::Float32, gradients, state_representation::Vector{Float32}, input, output, ∇tanh_z, activations, δs, onesvec, scales, mT, mB, vT, vB)
		update_feature_vector!(state_representation, s)
		update_input!(input, state_representation, 1)
		for i in 1:num_actions
			output[1, i] = activations[end][1, i]
		end
		output[1, i_a] = g
		update_nn_parameters!(parameters[1], parameters[2], layers, gradients[1], gradients[2], input, output, ∇tanh_z, activations, δs, onesvec, α, scales, mT, mB, vT, vB, 10000)
	end

	function q̂(s, i_a::Integer, parameters, state_representation, input, activations) 
		update_feature_vector!(state_representation, s)
		update_input!(input, state_representation, 1)
		FCANN.predict!(parameters[1], parameters[2], input, activations, 1)
		return activations[end][1, i_a]
	end

	function q̂(action_values::Vector{Float32}, s, parameters, state_representation, input, activations) 
		update_feature_vector!(state_representation, s)
		update_input!(input, state_representation, 1)
		FCANN.predict!(parameters[1], parameters[2], input, activations, 1)
		best_action = 1
		best_value = typemin(Float32)
		for i_a in eachindex(action_values)
			q = activations[end][1, i_a]
			newmax = q > best_value
			best_action = !newmax*best_action + newmax*i_a
			best_value = !newmax*best_value + newmax*q
			action_values[i_a] = q
		end
		return (best_value, best_action)
	end

	# update_args = ((∇θ, ∇β), feature_vector, input, output, ∇tanh_z, activations, δs, onesvec, scales)
	update_args = ((∇θ, ∇β), feature_vector, input, output, ∇tanh_z, activations, δs, onesvec, scales, mT, mB, vT, vB)
	
	return (value_function = q̂, value_args = (feature_vector, input, activations), parameter_update = update_parameters!, update_args = update_args, parameters = (θ, β))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$528533f7-68f1-4d19-9a37-6d4d0d7c38e2cell_id$528533f7-68f1-4d19-9a37-6d4d0d7c38e2code@bind constant_params PlutoUI.combine() do Child
	md"""
	Number of Steps: $(Child(:nsteps, Slider(1:1000, default = 200, show_value=true)))
	
	Select Constant Action: $(Child(:action, Select([1 => "Decelerate", 2 => "Nothing", 3 => "Accelerate"])))
	"""
end |> confirmmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$cafb20b4-a2bd-46a9-9660-b0ace84d6e4ccell_id$cafb20b4-a2bd-46a9-9660-b0ace84d6e4ccodebfunction initialize_car_state()
	a = rand(Float32) * 0.2f0
	x = a - 0.6f0
	ẋ = 0f0
	(x, ẋ)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$66d6a4b0-ddf8-4781-b3b4-20f02b25199acell_id$66d6a4b0-ddf8-4781-b3b4-20f02b25199acodeٍshow_mountaincar_trajectory(tabular_mountaincar_mdp, mountaincar_policy_iteration[1][policy_num], 500, "Policy Iteration Number $policy_num")metadatashow_logsèdisabled®skip_as_script«code_folded$b0265b93-ae5f-48f2-a9fd-44fd6115164bcell_id$b0265b93-ae5f-48f2-a9fd-44fd6115164bcodemd"""
## Solving the Control Problem

### Goal: Maximizing $G_t$
For a given MDP problem with a state space $\mathcal{S}$ and action space $\mathcal{A}$, there exists some optimal policy $\pi_*$ for which taking actions under that policy will result in a higher expected discounted reward sum than any other policy.  In short:

$\mathbb{E}_{\pi_*}[G_t \vert S_t = s] \ge \mathbb{E}_{\pi}[G_t \vert S_t = s] \quad \forall s,\pi$ where $G_t \doteq \sum_{k=0}^\infty \gamma^k R_{t+k+1} \text{ or } \sum_{k = t+1} ^ T \gamma^{k-t-1}R_k$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$57659c52-de1b-46e6-a863-8eeec0cee601cell_id$57659c52-de1b-46e6-a863-8eeec0cee601codeٍπ_optimal_value_iteration(s) = sample_action(view(mountaincar_value_iteration.optimal_policy, :, assign_state_index_tabular_mountaincar(s)))metadatashow_logsèdisabled®skip_as_script«code_folded$a9fdb1fd-3f62-4e1c-9157-c4eee6215261cell_id$a9fdb1fd-3f62-4e1c-9157-c4eee6215261codeCfunction differential_semi_gradient_sarsa!(parameters, mdp::StateMDP{T, S, A, P, F1, F2, F3}, max_episodes::Integer, max_steps::Integer, estimate_value::Function, estimate_args::Tuple, update_parameters!::Function, update_args::Tuple; α = one(T)/10, β = one(T)/100, ϵ = one(T) / 10, compute_value = compute_sarsa_value, kwargs...) where {T<:Real, S, A, P, F1, F2, F3}
	s = mdp.initialize_state()
	i_a = rand(eachindex(mdp.actions))
	ep = 1
	step = 1
	R̄ = zero(T)
	ō = zero(T)
	epreward = zero(T)
	episode_rewards = zeros(T, max_episodes)
	episode_steps = zeros(Int64, max_episodes)
	action_values = zeros(T, length(mdp.actions))
	average_step_reward = Vector{T}()
	policy = zeros(T, length(mdp.actions))
	while (ep <= max_episodes) && (step <= max_steps)
		(r, s′) = mdp.ptf(s, i_a)
		estimate_value(action_values, s, parameters, estimate_args...)
		q̂ = action_values[i_a]
		U_t = r - R̄
		epreward += r
		if mdp.isterm(s′)
			s′ = mdp.initialize_state()
			episode_rewards[ep] = epreward
			episode_steps[ep] = step
			epreward = zero(T)
			ep += 1
		end
		estimate_value(action_values, s′, parameters, estimate_args...)
		policy .= action_values
		make_ϵ_greedy_policy!(policy; ϵ = ϵ)
		i_a′ = sample_action(policy)
		q̂′ = compute_value(action_values, policy, i_a′)
		U_t += q̂′
		δ = U_t - q̂
		ō += β * (one(T) - ō)
		R̄ += (β/ō)*δ
		# R̄ += β*δ
		push!(average_step_reward, R̄)
		update_parameters!(parameters, s, i_a, U_t, α, update_args...)
		s = s′
		i_a = i_a′
		step += 1
	end
	return episode_rewards, episode_steps, average_step_reward
endmetadatashow_logsèdisabled®skip_as_script«code_folded$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93cell_id$cc9197e0-f5bd-4742-bea3-b54e0b8e3b93codeNfunction show_mountaincar_trajectory(π::Function, max_steps::Integer, name)
	states, actions, rewards, sterm, nsteps = runepisode(mountain_car_mdp; π = π, max_steps = max_steps)
	positions = [s[1] for s in states]
	velocities = [s[2] for s in states]
	tr1 = scatter(x = positions, y = velocities, mode = "markers", showlegend = false)
	tr2 = scatter(y = positions, showlegend = false)
	tr3 = scatter(y = [mountain_car_actions[i] for i in actions], showlegend = false)
	p1 = plot(tr1, Layout(xaxis_title = "position", yaxis_title = "velocity", xaxis_range = [-1.2, 0.5], yaxis_range = [-0.07, 0.07]))
	p2 = plot(tr2, Layout(xaxis_title = "time", yaxis_title = "position"))
	p3 = plot(tr3, Layout(xaxis_title = "time", yaxis_title = "action"))
	mdname = Markdown.parse(name)
	md"""
	$mdname
	Total Reward: $(sum(rewards))
	$([p1 p2 p3])
	"""
endmetadatashow_logsèdisabled®skip_as_script«code_folded$e86bc86f-9909-458d-b86d-0a4ac4b9d43dcell_id$e86bc86f-9909-458d-b86d-0a4ac4b9d43dcode@@bind nsamples NumberField(1:100_000, default = 1000) |> confirmmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$bc1d7cce-c0f4-47a8-b674-8acb82491c7fcell_id$bc1d7cce-c0f4-47a8-b674-8acb82491c7fcodeٔconst mountain_car_differential_mdp = StateMDP(mountain_car_actions, mountain_car_differential_transition, initialize_car_state, s -> s[1] == 0.5f0)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2cell_id$7e8c89aa-8a5e-4ff4-afd2-df8f5c77b5b2codebconst mountaincar_velocities = LinRange(-0.07f0, 0.07f0, tabular_mountaincar_args.num_velocities) metadatashow_logsèdisabled®skip_as_script«code_folded$c12070a9-df63-4b25-99e6-26ff876af1b4cell_id$c12070a9-df63-4b25-99e6-26ff876af1b4codeټfunction update_mountaincar_feature_vector!(v::Vector{Float32}, s::NTuple{2, Float32})
	x1 = 3.45f0*(((s[1] - 1.2f0) / 1.7f0) - 0.5f0)
	x2 = 1.725f0*s[2] / 0.07f0
	v[1] = x1
	v[2] = x2
endmetadatashow_logsèdisabled®skip_as_script«code_folded$991492f4-7dfc-43aa-ab6c-a6b1f3e38225cell_id$991492f4-7dfc-43aa-ab6c-a6b1f3e38225codefunction semi_gradient_sarsa!(parameters::P, mdp::StateMDP, γ::T, max_episodes::Integer, max_steps::Integer, estimate_value::Function, estimate_args::Tuple, update_parameters!::Function, update_args::Tuple; α = one(T)/10, ϵ = one(T) / 10, compute_value = compute_sarsa_value, nn_momentum = false, α_decay = one(T), decay_step = typemax(Int64), kwargs...) where {P, T<:Real}
	s = mdp.initialize_state()
	i_a = rand(eachindex(mdp.actions))
	ep = 1
	step = 1
	epreward = zero(T)
	episode_rewards = Vector{T}()
	episode_steps = Vector{Int64}()
	action_values = zeros(T, length(mdp.actions))
	policy = zeros(T, length(mdp.actions))
	decay = one(T)
	while (ep <= max_episodes) && (step <= max_steps)
		(r, s′) = mdp.ptf(s, i_a)
		epreward += r
		if mdp.isterm(s′)
			U_t = r
			s′ = mdp.initialize_state()
			i_a′ = rand(eachindex(mdp.actions))
			push!(episode_rewards, epreward)
			push!(episode_steps, step)
			epreward = zero(T)
			ep += 1
		else
			estimate_value(action_values, s′, parameters, estimate_args...)
			policy .= action_values
			make_ϵ_greedy_policy!(policy; ϵ = ϵ)
			i_a′ = sample_action(policy)
			q̂ = compute_value(action_values, policy, i_a′)
			U_t = r + γ*q̂
		end
		learning_rate = nn_momentum ? T(1 - 0.999^step) : one(T)
		if step > decay_step
			decay *= α_decay
		end
		update_parameters!(parameters, s, i_a, U_t, α * learning_rate * decay, update_args...)
		s = s′
		i_a = i_a′
		step += 1
	end
	return episode_rewards, episode_steps
endmetadatashow_logsèdisabled®skip_as_script«code_folded$28e0d632-0df3-4a5b-85c4-571c845ff827cell_id$28e0d632-0df3-4a5b-85c4-571c845ff827codeIconst mountain_car_action_names = ["Decelerate", "Nothing", "Accelerate"]metadatashow_logsèdisabled®skip_as_script«code_folded$b191d3f9-cf25-4fb4-8f5a-8da86e96e125cell_id$b191d3f9-cf25-4fb4-8f5a-8da86e96e125codedshow_mountaincar_trajectory(π_mountain_car2_fcann, 1_000, "Differential Q-learning Learned Policy")metadatashow_logsèdisabled®skip_as_script«code_folded$e338be2b-05f1-43f4-a194-45ffd710777ecell_id$e338be2b-05f1-43f4-a194-45ffd710777ecodeكconst accelerate_mountaincar_π = begin
	out = zeros(Float32, 3, length(tabular_mountaincar_mdp.states))
	out[3, :] .= 1f0
	out
endmetadatashow_logsèdisabled®skip_as_script«code_folded$224b4bec-9ec5-434d-a950-f5974cd786d0cell_id$224b4bec-9ec5-434d-a950-f5974cd786d0codemd"""
##### Linear Tile Coding

Since we are only learning the value function, the same tiling setup will have fewer parameters than the action value techniques.  Empirically, more tilings are necessary to learn a state value function that can approach the optimal policy.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$8752c98d-fac1-4b3b-b20b-70acc0677fcbcell_id$8752c98d-fac1-4b3b-b20b-70acc0677fcbcodemd"""
> ### *Exercise 10.9* 
> In the differential semi-gradient n-step Sarsa algorithm, the step-size parameter on the average reward, $\beta$, needs to be quite small so that $\bar R$ becomes a good long-term estimate of the average reward. Unfortunately, $\bar R$ will then be biased by its initial value for many steps, which may make learning inefficient. Alternatively, one could use a sample average of the observed rewards for $\bar R$. That would initially adapt rapidly but in the long run would also adapt slowly. As the policy slowly changed, $\bar R$ would also change; the potential for such long-term nonstationarity makes sample-average methods ill-suited. In fact, the step-size parameter on the average reward is a perfect place to use the unbiased constant-step-size trick from Exercise 2.7. Describe the specific changes needed to the boxed algorithm for differential semi-gradient n-step Sarsa to use this trick.

At the start initialize $\bar o = 0$ and select $\lambda > 0$ small instead of $\beta$. 

Within the loop under the $\tau \geq 0$ line, add two lines; one to update $\bar o$ and one to calculate the update rate for the average reward: 

Line 1: $\bar o \leftarrow \bar o + \lambda (1 - \bar o)$

Line 2: $\beta = \lambda / \bar o$

As steps progress $\beta$ will approach $\lambda$ but early on will take on much larger values as $\bar o$ starts close to 0 and approaches 1.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$dd472c0f-7b43-4abe-ada9-9dc8004a18cbcell_id$dd472c0f-7b43-4abe-ada9-9dc8004a18cbcodebegin
function add_elements(a, b)
	@htl("""
	$a
	$b
	""")
end
add_elements(a::HTML, b::HTML) = add_elements(a.content, b.content)
add_elements(a::HTML, b::AbstractString) = add_elements(a.content, b)
add_elements(a::AbstractString, b::HTML) = add_elements(a, b.content)
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$ab4cb3db-3a2d-4145-826b-b1001114eeffcell_id$ab4cb3db-3a2d-4145-826b-b1001114eeffcode^show_mountaincar_trajectory(π_mountain_car2, 1_000, "Differential Q-learning Learned Policy")metadatashow_logsèdisabled®skip_as_script«code_folded$1410db13-4b73-4a87-af34-30a5232af4bacell_id$1410db13-4b73-4a87-af34-30a5232af4bacodezcompute_q_learning_value(action_values::Vector{T}, policy::Vector{T}, i_a::Integer) where T<:Real = maximum(action_values)metadatashow_logsèdisabled®skip_as_script«code_folded$eb28458f-b222-4f8e-9a5b-8203d3997f7bcell_id$eb28458f-b222-4f8e-9a5b-8203d3997f7bcodeZfunction mountain_car_differential_step(s::Tuple{Float32, Float32}, i_a::Int64)
	a = mountain_car_actions[i_a]
	ẋ′ = clamp(s[2] + 0.001f0*a - 0.0025f0*cos(3*s[1]), -0.07f0, 0.07f0)
	x′ = clamp(s[1] + ẋ′, -1.2f0, 0.5f0)
	x′ == -1.2f0 && return (0f0, (x′, 0f0))
	s′ = (x′, ẋ′)
	r = Float32(x′ == 0.5f0)
	return (r, s′)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$a97e3b12-b7a5-4f88-bdb9-c3158203e0ffcell_id$a97e3b12-b7a5-4f88-bdb9-c3158203e0ffcodeٕshow_mountaincar_trajectory(tabular_mountaincar_mdp, mountaincar_value_iteration.optimal_policy, 1000, "Tabular Mountain Car Value Iteration Policy")metadatashow_logsèdisabled®skip_as_script«code_folded$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6acell_id$4ccb8a52-c6af-445d-a39e-d4d9b10c0d6acodebplot(scatter(y = -smooth_error(mountain_car_fcann.reward_history, 1)), Layout(yaxis_type = "log"))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$1e224a46-91ef-4a5f-ae35-ef4062147f2dcell_id$1e224a46-91ef-4a5f-ae35-ef4062147f2dcode_show_mountaincar_trajectory(mountaincar_fcann_dp_results.π_greedy, 1_000, "DP Learned Policy")metadatashow_logsèdisabled®skip_as_scriptëcode_folded$5b2ffd90-ead0-42ce-999a-584ed8995910cell_id$5b2ffd90-ead0-42ce-999a-584ed8995910codeٌconst mountain_car_dist_mdp = StateMDP(mountain_car_actions, mountain_car_transition_distribution, initialize_car_state, s -> s[1] == 0.5f0)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$62839b2a-398a-4445-87d1-b15ff2acc1d1cell_id$62839b2a-398a-4445-87d1-b15ff2acc1d1codefunction create_access_control_task(num_servers::Integer, priority_payments::Vector{Float32})
	actions = [Accept(), Reject()]

	initialize_state() = AccessControlState(num_servers, rand(priority_payments))

	transition = StateMDPTransitionSampler((s, i_a) -> access_control_step(s, actions[i_a], num_servers, priority_payments), initialize_state())
	mdp = StateMDP(actions, transition, initialize_state, s -> false)
	states =  [AccessControlState(n, p) for n in 0:num_servers for p in priority_payments]
	assign_group(s::AccessControlState) = s.num_free_servers + 1 + (num_servers+1)*Int64(log2(s.top_priority))
	(mdp = mdp, gradient_setup = state_aggregation_action_gradient_setup(assign_group), num_groups = (num_servers+1) * length(priority_payments))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$8d096d0d-8fea-421a-aa33-82269d3fe7e2cell_id$8d096d0d-8fea-421a-aa33-82269d3fe7e2codeGmd"""
### *Action-Value Implementation of Non-Linear Approximation*
"""metadatashow_logsèdisabled®skip_as_script«code_folded$39b0f100-a7e7-4633-b296-ccc87a5a35abcell_id$39b0f100-a7e7-4633-b296-ccc87a5a35abcode!function run_fcann_semi_gradient_sarsa(mdp::StateMDP, γ::Float32, max_episodes::Integer, max_steps::Integer, state_representation::Vector{Float32}, update_state_representation!::Function, layers::Vector{T}; λ = 0f0, c = Inf, dropout = 0f0, kwargs...) where T<:Integer
	setup = fcann_action_gradient_setup(mdp, layers, state_representation, update_state_representation!; λ = λ, c = c, dropout = dropout)
	num_actions = length(mdp.actions)
	episode_rewards, episode_steps = semi_gradient_sarsa!(setup.parameters, mdp, γ, max_episodes, max_steps, setup.value_function, setup.value_args, setup.parameter_update, setup.update_args; nn_momentum = true, kwargs...)
	q̂(s, i_a) = setup.value_function(s, i_a, setup.parameters, setup.value_args...)
	action_values = zeros(Float32, num_actions)
	q̂(s) = setup.value_function(action_values, s, setup.parameters, setup.value_args...)
	π_greedy(s) = q̂(s)[2]
	return (value_function = q̂, π_greedy = π_greedy, reward_history = episode_rewards, step_history = episode_steps, parameters = setup.parameters)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$1a82ae95-3c3e-4281-bc1d-9eb19bf50286cell_id$1a82ae95-3c3e-4281-bc1d-9eb19bf50286codefunction figure_10_2(;α_list = [0.1f0, 0.2f0, 0.5f0], num_episodes = 50, ϵ = 0.05f0)
	traces = map(α_list) do α
		scatter(y = 1:100 |> Map(_ -> mountaincar_test(num_episodes, α/8, ϵ; num_tiles = 12, num_tilings = 8).reward_history) |> foldxt((a, b) -> a .+ b) |> v -> -v ./ 100, name = "α = $α/8")
	end
	plot(traces, Layout(xaxis_title = "Episode", yaxis_title = "Steps per episode<br>averaged over 100 runs", yaxis_type = "log"))
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$99e3ec39-24f0-43d6-b6fd-9910b738ce2ccell_id$99e3ec39-24f0-43d6-b6fd-9910b738ce2ccodeِshow_mountaincar_trajectory(tabular_mountaincar_mdp, tabular_policies[tabular_mountaincar_args.policy], 1000, "Tabular Mountain Car Trajectory")metadatashow_logsèdisabled®skip_as_script«code_folded$f11787a1-57f8-4077-8d60-bc760ece7cc6cell_id$f11787a1-57f8-4077-8d60-bc760ece7cc6codebegin
	calculate_action_value(state_representation::AbstractVector{T}, i_a::Integer, parameters::Vector{Vector{T}}) where T<:Real = dot(state_representation, parameters[i_a])

	function calculate_action_value(state_representation::AbstractVector{T}, i_a::Integer, parameters::Matrix{T}) where T<:Real 
		q = zero(T)
		@inbounds @simd for i in eachindex(state_representation)
			q += state_representation[i]*parameters[i, i_a]
		end
		return q
	end

	function calculate_action_value(state_representation::SparseVector{T, Int64}, i_a::Integer, parameters::Matrix{T}) where T<:Real 
		q = zero(T)
		@inbounds @simd for i in state_representation.nzind
			q += state_representation[i]*parameters[i, i_a]
		end
		return q
	end
end	metadatashow_logsèdisabled®skip_as_script«code_folded$fc3e0577-45aa-4bba-a275-fa7a352fc5cccell_id$fc3e0577-45aa-4bba-a275-fa7a352fc5cccodeKplot_mountaincar_action_values(mountain_car_fcann.value_function, 200, 200)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$98a5d65e-4253-4523-a74e-99d03be03b89cell_id$98a5d65e-4253-4523-a74e-99d03be03b89codeYmd"""
### *Semi-gradient Expected Sarsa Implementation*

Since we already update the policy and action values in the sarsa algorithm, the only difference in expected sarsa is to compute the action-value using the entire policy distribution instead of just the sampled action.  Similarly for Q-learning we would only select the maximum value.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$4271151d-d5a6-4a29-96c3-f2102b142b95cell_id$4271151d-d5a6-4a29-96c3-f2102b142b95codebegin
	get_action_value(i_s::Integer, i_a::Integer, parameters::Vector{Vector{T}}) where T<:Real = parameters[i_a][i_s]
	get_action_value(i_s::Integer, i_a::Integer, parameters::Matrix{T}) where T<:Real = parameters[i_s, i_a]
endmetadatashow_logsèdisabled®skip_as_script«code_folded$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94cell_id$56b0d69b-b7c3-4365-9b02-e0d5e8a85f94codefunction run_linear_semi_gradient_dp(mdp::StateMDP, γ::T, max_episodes::Integer, max_steps::Integer, state_representation::AbstractVector{T}, update_state_representation!::Function; setup_kwargs = NamedTuple(), kwargs...) where T<:Real
	setup = linear_features_gradient_setup(mdp, state_representation, update_state_representation!; setup_kwargs...)
	l = length(state_representation)
	num_actions = length(mdp.actions)
	parameters = zeros(T, l)
	episode_rewards, episode_steps = semi_gradient_dp!(parameters, mdp, γ, max_episodes, max_steps, setup.value_function, setup.value_args, setup.parameter_update, setup.update_args; kwargs...)
	v̂(s) = setup.value_function(s, parameters, setup.value_args...)
	function π_greedy(s)
		action_values = zeros(T, num_actions)
		for i_a in eachindex(action_values)
			(rewards, states, probabilities) = mdp.ptf.step(s, i_a)
			q = zero(T) 
			for i in eachindex(probabilities)
				v̂′ = !mdp.isterm(states[i])*v̂(states[i])
				q += probabilities[i]*(rewards[i] + γ*v̂′)
			end
			action_values[i_a] = q
		end
		make_greedy_policy!(action_values)
		i_a = sample_action(action_values)
	end
	return (value_function = v̂, π_greedy = π_greedy, reward_history = episode_rewards, step_history = episode_steps)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$3f7484b3-272d-410d-92b1-ca13e5d7a8b7cell_id$3f7484b3-272d-410d-92b1-ca13e5d7a8b7codepPlutoDevMacros.@frompackage @raw_str(joinpath(@__DIR__, "..", "ApproximationUtils.jl")) using ApproximationUtilsmetadatashow_logs¨disabled®skip_as_script«code_folded$1a7ba296-52ca-4069-85fa-792d08d77b0ecell_id$1a7ba296-52ca-4069-85fa-792d08d77b0ecodemd"""
### Example: Differential Sarsa and Q-learning with Mountain Car Task

In order to apply differential learning to the mountain car task, we need to change the rewards per step.  Previously, the rewards were assigned in a manner appropriate for learning with a discount rate of 1.  The reward of -1 per episode step ensures that policies that finish the task faster have a higher reward.  In the average reward setting, every policy would have an average reward per step of -1 making the task ill posed.  Instead, we can assign a reward of 1 for finishing to the right and 0 at all other steps.  These rewards would produce an ill posed task for $\gamma = 1$ but are perfectly fine for the average reward setting.  Now our learning procedure should find a policy that produces the highest average reward $\frac{1}{\text{num steps}}$ which is maximized when the number of steps to finish an episode is minimized.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$39eada35-8c3e-4ddc-8df9-7cf9f120928dcell_id$39eada35-8c3e-4ddc-8df9-7cf9f120928dcode;md"""
## 10.5 Differential Semi-gradient *n*-step Sarsa
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b55d50a4-b039-4240-b434-42f7b724d24dcell_id$b55d50a4-b039-4240-b434-42f7b724d24dcode@plot_mountaincar_action_values(mc_test.value_function, 100, 100)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$41c626c7-908d-4ff6-9730-4ad0b8c3cc25cell_id$41c626c7-908d-4ff6-9730-4ad0b8c3cc25codefigure_10_5()metadatashow_logsèdisabled®skip_as_script«code_folded$1e9c537a-a731-4b81-8f6a-cb658b52c5becell_id$1e9c537a-a731-4b81-8f6a-cb658b52c5becodezconst mountain_car_mdp = StateMDP(mountain_car_actions, mountain_car_transition, initialize_car_state, s -> s[1] == 0.5f0)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$13e477f0-dc15-46cb-9691-c04a1b4c83c8cell_id$13e477f0-dc15-46cb-9691-c04a1b4c83c8codeGfunction gradient_monte_carlo_action_policy_estimation!(parameters, mdp::StateMDP, π::Function, γ::T, num_episodes::Integer, update_parameters!::Function, update_args::Tuple; α = one(T)/10, epkwargs...) where {T<:Real}
	(states, actions, rewards, sterm, nsteps) = runepisode(mdp; π = π, epkwargs...)
	gradient_monte_carlo_action_episode_update!(parameters, update_parameters!, states, actions, rewards, γ, α, update_args...)
	step_history = [nsteps]
	for ep in 2:num_episodes
		(states, actions, rewards, sterm, nsteps) = runepisode!((states, actions, rewards), mdp; π = π, epkwargs...)
		gradient_monte_carlo_episode_update!(parameters, update_parameters!, view(states, 1:nsteps), view(actions:1:nsteps), view(rewards, 1:nsteps), γ, α, update_args...)
		push!(step_history, nsteps)
	end
	return step_history, reward_history
endmetadatashow_logsèdisabled®skip_as_script«code_folded$47710ddd-79d9-464d-b5dd-27180f2d6b31cell_id$47710ddd-79d9-464d-b5dd-27180f2d6b31code	md"""
### Defining the Value Function

Since we are interested in maximizing the expected value of $G_t$, it is useful to define functions which calculate this expected value given a state or state action pair
Below is the definition of the two types of value functions as well as derived expressions that are used in solution or approximation techniques.  The Bellman equation as well as other definitions are used to derive all of the useful expressions for the value function.

#### State Value Function
$\begin{flalign}
v_\pi(s) &\doteq \mathbb{E}_\pi [G_t \mid S_t = s] \tag{Used in Monte Carlo Estimation}\\
&= \sum_a \pi(a \vert s) \mathbb{E}_\pi [G_{t} \mid S_t = s, A_t = a] \tag{exp value def} \\
&= \sum_a \pi(a \vert s) q_\pi(s, a) \tag{by definition of q} \\
&= \sum_a \pi(a \vert s) \sum_{s^\prime, r} p(s^\prime, r \vert s, a) [r + \gamma v_\pi(s^\prime)] \tag{Used in Dynamic Programming when p is available} \\
&= \mathbb{E}_\pi [R_{t+1} + \gamma v_\pi(S_{t+1}) \mid S_t = s] \tag{Used in TD(0) when p is not available}\\
\end{flalign}$

#### State-Action Value Function
$\begin{flalign}
q_\pi(s, a) &\doteq \mathbb{E}_\pi[G_t \mid S_t=s,A_t=a] \tag{Used in Monte Carlo Estimation} \\
& = \mathbb{E}_\pi \left [ R_{t+1} + \gamma G_{t+1} \mid S_t = s, A_t = a \right ] \tag{by (3.9)} \\
& = \sum_{s^\prime, r} p(s^\prime, r \vert s, a) \mathbb{E}_\pi \left [ r + \gamma G_{t+1} \mid S_{t+1} = s^\prime \right ] \tag{exp value def}\\
& = \sum_{s^\prime, r} p(s^\prime, r \vert s, a) [r + \gamma v_\pi(s^\prime)] \tag{by definition of v (4.6)} \\
& = \sum_{s^\prime, r} p(s^\prime, r \vert s, a) [r + \gamma\sum_{a^\prime} \pi(a^\prime \vert s^\prime) q_\pi(s^\prime, a^\prime)] \tag{Used in Dynamic Programming when p is available} \\
& = \mathbb{E} [R_{t+1} + \gamma\sum_{a^\prime} \pi(a^\prime \vert s^\prime) q_\pi(s^\prime, a^\prime) \mid S_t = s, A_t = a] \tag{Used in Expected Sarsa when p is not available} \\
\end{flalign}$

The optimal policy $\pi_*$ will have a value function $v_{\pi_*}(s)$ $q_{\pi_*}(s, a)$ whose values are greather than or equal to any other value function at every state or state action pair.  In short

$v_{\pi_*}(s) \geq v_\pi(s) \forall s \in \mathcal{S} \quad \text{and} \quad q_{\pi_*}(s, a) \geq q_\pi(s, a) \forall s \in \mathcal{S}, \forall a \in \mathcal{A}$ 
"""metadatashow_logsèdisabled®skip_as_script«code_folded$14fe2253-cf2c-4159-a360-1e65f1c82b09cell_id$14fe2253-cf2c-4159-a360-1e65f1c82b09codemd"""
#### Distributional Non-Tabular Case

##### Problem conditions
- All actions can be enumerated: $\mathcal{A} = \{a_1, a_2, \cdots, a_m\}$ but the state space is either infinite or too large to practically count
-  $p(s^\prime, r \vert s, a)$ is available

Previously we considered value estimates in the form of a list.  Since that list is now uncountably large, a different approach, that of approximation, is needed to estimate the value function.  The approximation function must rely on a countable, limited set of information such as a list of parameters $\mathbf{w}$ or a memory of past observations.  Either way, that limited set of information must be used to generalize value estimates accross any state that is encountered.  By construction, this function cannot guarantee that a change to one state value does not affect another, thus the previous goal of optimizing all of the state values is no longer possible.  In order to even define success in this case, a new objective is needed.  Consider the caes of a parameterized function $\hat v(s, \mathbf{w})$ whose goal is to estimate the true value function of a policy $v_\pi(s)$.  One natural objective is to find the parameters that minimize the squared error this function has with the true value function under the distribution of states visited under that policy.  This objective is called the *value error*:

$\overline{\text{VE}}(\mathbf{w}) \doteq \sum_{s \in S} \mu(s)[v_\pi(s) - \hat v(s, \mathbf{w})]^2$

In Chapter 9, we used stochastic gradient descent to derive an update rule for the parameters in the case of knowning the true value function:

$$\begin{flalign}
\mathbf{w}_{t+1} & \doteq \mathbf{w}_t - \frac{1}{2} \alpha \nabla [v_\pi(S_t) - \hat v(S_t, \mathbf{w}_t)]^2 \\
& = \mathbf{w}_t + \alpha[v_\pi(S_t) - \hat v(S_t, \mathbf{w}_t)]\nabla\hat v(S_t, \mathbf{w}_t)
\end{flalign}$$

Since we do not know the true value function, we can sample unbiased estimates of it using the methods already described above.  Then the solution techniques would mirror those in the tabular case with the value updates simply replaced with parameter updates using the same sample estimate.

##### Solution Techniques

Since $p$ is available, we can use state value estimates to compute state-action value estimates.  Consider the estimate Bellman optimality equation for state values:

$v_* =  \max_{a \in \mathcal{A}(s)} \sum_{s^\prime, r} p(s^\prime, r \vert s, a) \left [ r + γ v_* (s^\prime) \right ] \: \forall s \in \mathcal{S}$

This target value can be used in the gradient update as follows:

$\mathbf{w}_{t+1} = \mathbf{w}_t + \alpha \left [ \max_{a \in \mathcal{A}(s)} \left [ \sum_{s^\prime, r} p(s^\prime, r \vert S_t, a) \left [ r + γ \hat v(s^\prime, \mathbf{w}_t) \right ] \right ]- \hat v(S_t, \mathbf{w}_t) \right ]\nabla\hat v(S_t, \mathbf{w}_t)$

while the optimal policy can be derived as:

$\pi(s) = \mathrm{argmax}_a\sum_{s^\prime, r} p(s^\prime, r \vert s, a)( r + \gamma \hat v(s^\prime, \mathbf{w}))$

The derivation of the parameter update rule assumed that the sample estimate for $v_\pi$ did not depend on the parameters.  This assumption is violated here as it was in the semi-gradient TD methods from Chapter 9.  Nevertheless, in the linear case, this technique can converge to some bounded region around the true minimum value error.  Updating the parameters in this way is similar to value iteration which used the same target value and swept across the entire state space.  Using this method here highlights the problem with approximation and its connection to the minimum value error objective.  That objective is only defined in terms of the on policy distribution, so in order for this to converge, the states sampled must match the on-policy distribution which would be the greedy policy in this case.  So while the update rule does not explicitely reference the policy (seemingly implying like in Q-learning that we could perform these updates with any policy), the samples do need to be drawn from the on policy distribution for this to work properly.

#### Sample Non-Tabular Case
##### Problem conditions
- All actions can be enumerated: $\mathcal{A} = \{a_1, a_2, \cdots, a_m\}$ but the state space is either infinite or too large to practically count
-  $p(s^\prime, r \vert s, a)$ is not available

##### Solution Techniques
Finally, we arrive at the case considered at the beginning of Chapter 10 where we must rely on sampling from the environment in the non-tabular case.  Since $p$ is not available, we must instead estimate $\hat q_\pi(s, a)$ for a given policy and proceed with generalized policy iteration as before either with episodic or per step updates to the parameters.  The value error objective can easily be modified to consider all actions as well as states.  Since the actions are enumerable in this case, there is no need to consider the on policy distribution as the error can be minimized across all actions:

$\overline{\text{VE}}(\mathbf{w}) \doteq \sum_a \sum_{s \in S} \mu(s)[q_\pi(s, a) - \hat q(s, a, \mathbf{w})]^2$

The parameter update will look identical to that for state values with the update target replaced by the true state-action value.  The control algorithms will mirror the tabular case with the gradient update replacing the averaging update.  The techniques are defined by which target value is used:

- Semi-gradient Sarsa: $q_\pi(s, a) = \mathbb{E} [R_{t+1} + \gamma\sum_{a^\prime} \pi(a^\prime \vert s^\prime) q_\pi(s^\prime, a^\prime) \mid S_t = s, A_t = a]$
- Gradient Monte Carlo Control: $q_\pi(s, a) = \mathbb{E}_\pi[G_t \vert S_t = s, A_t = a]$
- Semi-gradient Q-learning: $q_*(s, a) = \mathbb{E} \left [ R_t + γ \max_{a^\prime} q_*(s^\prime, a^\prime) \mid S_t = s, A_t = a \right ]$

Note that genearlized policy iteration only works if the policy improvement theorem applies.  In the case of approximation, that is not the case since a policy change cannot be said to only apply to one state.  While many of these techniques can work emphirically, there is no theoretical guarantee that iterating in this manner will produce the optimal policy, even if the approximation is linear.  The only guarantee we can make in that case is that the value function will converge to one that minimizes the value error for the policy at the time.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$5c920177-8e46-49c9-9b95-1a657fdcae4ecell_id$5c920177-8e46-49c9-9b95-1a657fdcae4ecodeSplot(scatter(y = -smooth_error(episode_rewards_dp, 1)), Layout(yaxis_type = "log"))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0cell_id$b5d2776f-4b93-4eaa-8873-c1c4e610e6b0codefunction run_fcann_differential_semi_gradient_sarsa(mdp::StateMDP, max_episodes::Integer, max_steps::Integer, state_representation::Vector{Float32}, update_state_representation!::Function, layers::Vector{T}; kwargs...) where T<:Integer
	setup = fcann_action_gradient_setup(mdp, layers, state_representation, update_state_representation!)
	num_actions = length(mdp.actions)
	episode_rewards, episode_steps, average_step_reward = differential_semi_gradient_sarsa!(setup.parameters, mdp, max_episodes, max_steps, setup.value_function, setup.value_args, setup.parameter_update, setup.update_args; kwargs...)
	q̂(s, i_a) = setup.value_function(s, i_a, setup.parameters, setup.value_args...)
	action_values = zeros(Float32, num_actions)
	q̂(s) = setup.value_function(action_values, s, setup.parameters, setup.value_args...)
	return (value_function = q̂, reward_history = episode_rewards, step_history = episode_steps, average_step_reward = average_step_reward, parameters = setup.parameters)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$3c300a2b-4139-4df0-906b-4cae3592cc2bcell_id$3c300a2b-4139-4df0-906b-4cae3592cc2bcodewconst mountaincar_policy_iteration = policy_iteration_v(tabular_mountaincar_mdp, 1f0; θ = 0.001f0, max_iterations = 2)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bdcell_id$8a5d9e3d-e8ef-4cea-8cd8-6975f797d7bdcodefunction plot_mountaincar_action_values(tabular_mountaincar_mdp, value_function::Matrix{Float32}, π::Matrix{Float32}, mountaincar_positions, mountaincar_velocities)
	n = 100
	num_positions = length(mountaincar_positions)
	num_velocities = length(mountaincar_velocities)
	values = [zeros(Float32, num_positions, num_velocities) for _ in 1:size(π, 1)]
	actions = zeros(Float32, num_positions, num_velocities)
	for (i_x, x) in enumerate(mountaincar_positions)
		for (i_v, v) in enumerate(mountaincar_velocities)
			value_index = tabular_mountaincar_mdp.state_index[(x, v)]
			(pmax, i_amax) = findmax(value_function[i, value_index] for i in 1:3)
			actions[i_v, i_x] = i_amax
			# pmax ≈ 1f0/3 ? actions[i_x, i_v] = 2 : actions[i_x, i_v] = i_amax
			for i_a in 1:size(value_function, 1)
				values[i_a][i_v, i_x] = value_function[i_a, value_index]
			end
		end
	end
			
	p1 = [plot(heatmap(x = mountaincar_positions, y = mountaincar_velocities, z = values[i]) , Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Learned Value Function")) for i in eachindex(values)]
	p2 = plot(heatmap(x = mountaincar_positions, y = mountaincar_velocities, z = actions, colorscale = "rb", showscale = false), Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Greedy Policy (blue = accelerate left, <br>red = accelerate right, gray = no acceleration)"))
	# [p1; p2]
	# $(HTML(reduce(add_elements, p1)))
	@htl("""
	<div style = "display: flex;">
	
	$(reduce(hcat, p1))
	</div>
	$p2
	</div>
	""")
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$fbf1c64f-1979-4384-a8c6-dc7875174d1fcell_id$fbf1c64f-1979-4384-a8c6-dc7875174d1fcodeلbegin
	abstract type AccessControlAction end
	struct Accept <: AccessControlAction end
	struct Reject <: AccessControlAction end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$0714a1cf-9288-4f1e-ba72-d82608704d69cell_id$0714a1cf-9288-4f1e-ba72-d82608704d69codeٳmc_test = run_linear_gradient_monte_carlo_control(mountain_car_mdp, 1f0, 5_000, setup_mountain_car_tiles((1/12f0, 1/12f0), 9).args...; α = 1f-7, ϵ = 0.25f0, max_steps = 100_000)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$f7410fe7-e3d8-4047-8fa7-f076476e9d3acell_id$f7410fe7-e3d8-4047-8fa7-f076476e9d3acodeDmd"""
### Example: Semi-gradient Q-learning on Mountain Car Task
"""metadatashow_logsèdisabled®skip_as_script«code_folded$864450b9-1319-4426-961f-ee6df93463d8cell_id$864450b9-1319-4426-961f-ee6df93463d8codeeshow_mountaincar_trajectory(s -> rand(1:3), rand_nsteps, "Mountain Car Trajectory for Random Policy")metadatashow_logsèdisabled®skip_as_script«code_folded$662759be-282c-460b-adc3-8595475b53c2cell_id$662759be-282c-460b-adc3-8595475b53c2codeAmd"""
## 10.4 Deprecating the Discounted Setting

In a special case of indistinguishable states, we can only use the actions and reward sequences to analyze a continuing task.  For a policy $\pi$, the average of the discounted returns with discount factor $\gamma$ is always $\frac{r(\pi)}{1-\gamma}$.  Therefore the *ordering* of all policies is independent of the discount rate and would match the ordering we get in the average reward setting.  This derivation however depends on states being indistinguishable allowing us to match up the weights on reward sequences from different policies.

We can use discounting in approximate solution methods regardless but then $\gamma$ changes from a problem parameter to a solution method parameter.  Unfortunately, discounting algorithms with function approximation do not optimize discounted value over the on-policy distribution, and thus are not guaranteed to optimze average reward.

The root cause of the problem applying discounting with function approximation is that we have lost the policy improvement theorem which states that a policy $\pi^\prime$ is better than policy $\pi$ if $v_{\pi^\prime}(s) \geq v_\pi(s) \forall s\in \mathcal{S}$.  Under this theorem we could take a deterministic policy, choose a specific state, and find a new action at that state with a higher expected reward than the current policy.  If the policy is an approximation function that uses states represented by feature vectors, then adjusting the parameters can in general affect the actions at many states including ones that have not been encountered yet.  In fact, with approximate solution methods we cannot guarantee  policy improvement in any setting.  Later we will introduce a theoretical guarantee called the "policy-gradient theorem" but for an alternative class of algorithms based on parametrized policies.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$f5e32900-6eb6-4b61-916d-893c0bcaf214cell_id$f5e32900-6eb6-4b61-916d-893c0bcaf214codeTableOfContents()metadatashow_logsèdisabled®skip_as_scriptëcode_folded$e1abf8c7-06b8-4cd5-b557-1d187004bdf1cell_id$e1abf8c7-06b8-4cd5-b557-1d187004bdf1code,md"""
> ### *Exercise 10.2* 
> Give pseudocode for semi-gradient one-step *Expected* Sarsa for control.

Use the same pseudocode given for semi-gradient one-step Sarsa but with the following change to the weight update step in the non-terminal case:

$\mathbf{w} \leftarrow \mathbf{w} + \alpha[R + \gamma \sum_a \pi(a|S^\prime)\hat q(S^\prime, a, \mathbf{w}) - \hat q(S, A, \mathbf{w}) ] \nabla \hat q(S, A, \mathbf{w})$

where $\pi$ is the currently used policy which is $\epsilon$ greedy with respect to $\hat q$.  See complete implementation below. 
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b76551e0-c027-4682-b5ae-bba7ea2b987acell_id$b76551e0-c027-4682-b5ae-bba7ea2b987acodeHplot(smooth_error(mc_test.step_history, 10), Layout(yaxis_type = "log"))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$d8d5db17-d89c-47db-b258-6ad1635478b7cell_id$d8d5db17-d89c-47db-b258-6ad1635478b7codefunction plot_mountaincar_action_values(tabular_mountaincar_mdp, value_function::Vector{Float32}, π::Matrix{Float32}, mountaincar_positions, mountaincar_velocities)
	n = 100
	num_positions = length(mountaincar_positions)
	num_velocities = length(mountaincar_velocities)
	values = zeros(Float32, num_positions, num_velocities)
	actions = zeros(Float32, num_positions, num_velocities)
	for (i_x, x) in enumerate(mountaincar_positions)
		for (i_v, v) in enumerate(mountaincar_velocities)
			value_index = tabular_mountaincar_mdp.state_index[(x, v)]
			values[i_v, i_x] = value_function[value_index]
			(pmax, i_amax) = findmax(π[i, value_index] for i in 1:3)
			pmax ≈ 1f0/3 ? actions[i_v, i_x] = 2 : actions[i_v, i_x] = i_amax
		end
	end
			
	p1 = plot(heatmap(x = mountaincar_positions, y = mountaincar_velocities, z = values), Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Learned Value Function"))
	p2 = plot(heatmap(x = mountaincar_positions, y = mountaincar_velocities, z = actions, colorscale = "rb", showscale = false), Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Policy (blue = accelerate left, <br>red = accelerate right, gray = no acceleration)"))
	[p1 p2]
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$78087a57-33a0-4581-81de-926476090931cell_id$78087a57-33a0-4581-81de-926476090931codeshow_mountaincar_trajectory(s -> sample_action(view(mountaincar_policy_iteration[1][policy_num], :, assign_state_index_tabular_mountaincar(s))), 500, "Policy Iteration Number $policy_num on True MDP")metadatashow_logsèdisabled®skip_as_script«code_folded$69fb26ed-763e-44ad-9b70-193e5a1a09b9cell_id$69fb26ed-763e-44ad-9b70-193e5a1a09b9codeDusing PlutoDevMacros, Random, Statistics, LinearAlgebra, Transducersmetadatashow_logsèdisabled®skip_as_script«code_folded$35d59eae-77fd-11ef-2790-35dd5a834060cell_id$35d59eae-77fd-11ef-2790-35dd5a834060code<md"""
# Chapter 10: On-policy Control with Approximation
"""metadatashow_logsèdisabled®skip_as_script«code_folded$5f8b0254-88f4-4d19-ade1-8e7c40941b43cell_id$5f8b0254-88f4-4d19-ade1-8e7c40941b43code6begin
	function update_parameters!(parameters::Vector{Vector{T}}, state_representation::SparseVector{T, Int64}, i_a::Integer, α::T, δ::T) where T<:Real
		x = α*δ
		for i in eachindex(state_representation.nzind)
			parameters[i_a][state_representation.nzind[i]] += x .* state_representation.nzval[i]
		end
	end

	function update_parameters!(parameters::Matrix{T}, state_representation::SparseVector{T, Int64}, i_a::Integer, α::T, δ::T) where T<:Real
		x = α*δ
		for i in eachindex(state_representation.nzind)
			parameters[state_representation.nzind[i], i_a] += x .* state_representation.nzval[i]
		end
	end

	update_parameters!(parameters::Vector{Vector{T}}, state_representation::AbstractVector{T}, i_a::Integer, α::T, δ::T) where T<:Real = (parameters[i_a] .+= α .* δ .* state_representation)

	function update_parameters!(parameters::Matrix{T}, state_representation::AbstractVector{T}, i_a::Integer, α::T, δ::T) where T<:Real 
		@inbounds @simd for i in eachindex(state_representation)
			parameters[i, i_a] += α .* δ .* state_representation[i]
		end
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$546a775e-d3c9-4693-9f64-d4c47a84fb9fcell_id$546a775e-d3c9-4693-9f64-d4c47a84fb9fcode6function figure_10_5(;numsteps = 2_000_000, α = 0.01f0, β = 0.01f0, ϵ = 0.1f0)
	access_control_output = run_access_control_differential_sarsa(numsteps; β = β, α = α, ϵ = ϵ)
	policy_output = BitArray(undef, (4, 10))
	priorities = [8, 4, 2, 1]
	actions = [true, false]
	value_function_outputs = [zeros(Float32, 11) for _ in 1:4]
	for num_free_servers in 0:10
		for priority in 1:4
			v, i_a = access_control_output.value_function(num_free_servers, priorities[priority])
			value_function_outputs[priority][num_free_servers+1] = v
			if num_free_servers > 0
				policy_output[priority, num_free_servers] = actions[i_a]
			end
		end
	end
	policy_trace = heatmap(x = 1:10, y = 1:4, z = Float32.(policy_output), colorscale="Greys", showscale = false)
	value_traces = [scatter(x = 0:10, y = value_function_outputs[i], name = "priority $(priorities[i])") for i in 1:4]
	p1 = plot(policy_trace, Layout(yaxis_tickvals = 1:4, yaxis_ticktext = priorities, xaxis_ticktext = 1:10, xaxis_tickvals = 1:10, xaxis_title = "Number of free servers", yaxis_title = "Priority", title = "Policy (black=reject, white=accept)"))
	p2 = plot(value_traces, Layout(xaxis_title = "Number of free servers", yaxis_title = "Differential value of best action", title = "Value Function"))

	md"""
	Figure 10.5

	The policy and value function found by differential semi-gradient one-step Sarsa on the access-control queuing task after 2 million steps.  The value learned for $\bar R$ was about $(access_control_output.steprewards[end-10000:end] |> mean |> Float64 |> x -> round(x, sigdigits = 3))
	$([p1 p2])
	"""
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$6351304f-50ac-4755-86e1-cd4680f2d803cell_id$6351304f-50ac-4755-86e1-cd4680f2d803codemd"""
## 10.1 Episodic Semi-gradient Control

It is straightforward to extend the semi-gradient prediction methods in Chapter 9 to action values.  We simply consider examples of the form $S_t, A_t \rightarrow U_t$ where $U_t$ is any of the previously described update targets such as the Monte Carlo Return ($G_t$).  The new gradient-decent update for action-value prediction is:

$\mathbf{w}_{t+1} \doteq \alpha \left [ U_t - \hat q(S_t, A_t, \mathbf{w}_t) \right ] \nabla \hat q(S_t, A_t, \mathbf{w}_t)$

For example, the one-step Sarsa update is:

$\mathbf{w}_{t+1} \doteq \alpha \left [ R_{t+1} + \gamma \hat q(S_{t+1}, A_{t+1}, \mathbf{w}_t) - \hat q(S_t, A_t, \mathbf{w}_t) \right ] \nabla \hat q(S_t, A_t, \mathbf{w}_t)$

If the action set is discrete, then at the next state $S_{t+1}$ we can compute $\hat q(S_{t+1}, a, \mathbf{w}_t)$ for every action and then find the greedy action $A^*_{t+1} = \text{argmax}_a\hat q(S_{t+1}, a, \mathbf{w}_t)$.  Policy improvement is then done by changing the estimation policy to a soft approximation of the greedy policy such as the $\epsilon$-greedy policy.  Actions are selected according to this same policy.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6cell_id$05e2fff5-4871-4468-a00e-9c1b7ba0ffc6codemd"""
### Semi-gradient Dynamic Programming

Typically, to solve the control problem we require action-value estimates.  Even in the non-tabular case; however, we may have access to the transition distribution of an MDP.  A simple example of this is a deterministic problem in which there may be an uncountable number of states, but the transition dynamics are known exactly.  In this case, one can reconstruct the action values from the state values as follows:

$\hat q(s, a) = \sum_{s^\prime, r}p(s^\prime, r \vert s, a)\left (r + \gamma \hat v(s^\prime) \right ) = \sum_{s^\prime}p(s^\prime \vert s, a) \left[ r(s^\prime, s, a) + \gamma \hat v(s^\prime) \right ]$

In the case of a deterministic problem there is only one transition state $s^\prime = t(s, a)$ where $t$ is the deterministic mapping function.  Then the formula simplifies to $\hat q(s, a) = r(s, a) + \hat v(t(s, a))$.  We can update the parameters $\mathbf{w}$ for some value function $\hat v(s, \mathbf{w})$ using the techniques in Chapter 9.  Then, to derive the greedy policy, we can use 

$\pi(s) = \text{argmax}_a \left [ r(s, a) + \gamma \sum_{s^\prime}p(s^\prime \vert s, a) \hat v(s^\prime) \right ]$

From tabular dynamic programming, we have the following update rule for the optimal state value function:

$v_*(s) = \max_a \sum_{s^\prime}p(s^\prime \vert s, a) \left[ r(s^\prime, s, a) + \gamma v_*(s^\prime) \right ]$

If the right side expression uses the approximate value function, then it is available to use as an update target instead of the usual Sarsa one.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$bc220d14-97fd-486d-9880-6908135fe036cell_id$bc220d14-97fd-486d-9880-6908135fe036codemd"""
The reason why the left policy can be better if $\gamma < 0.5$ in the original example is because it has a higher value in each state considered.  Consider $\gamma = 0.25$.  The left policy has the following approximate discounted value estimates for top, left, right: 

1.0667, 0.2667, 2.2667. 

Meanwhile the right policy has the corresponding values of: 

0.533, 0.133, 2.133.

Each value is smaller for the right policy.  However when we calculate the average value calculated over the long term distribution of states, the left policy averages the first two values while the right policy averages the first and third values because in the long run we expect the left policy to only exist in the top and left state while the right policy will exist in the top and right state.  Because the right state has such a high value for both policies but only the right policy includes it in the average it makes its entire objective estimate higher.  However, we can see that in the event of being in the right state, it is still a higher value expectation following the left policy in this case.  The decision to average based on the final distribution results in a policy ordering that doesn't match with what we know to be the optimal policy from the policy improvement theorem over finite states.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e48af9f4-0b47-4a45-b0ad-8f53b094e712cell_id$e48af9f4-0b47-4a45-b0ad-8f53b094e712codePconst tabular_policies = [tabular_mountaincar_πrand, accelerate_mountaincar_π]metadatashow_logsèdisabled®skip_as_script«code_folded$5534526a-d790-4379-98b0-8e4ee981fd9fcell_id$5534526a-d790-4379-98b0-8e4ee981fd9fcode=begin
	function update_action_values!(action_values::Vector{T}, i_s::Integer, parameters::Vector{Vector{T}}) where T<:Real
		maxvalue = typemin(T)
		maxindex = 1
		@inbounds @simd for i_a in eachindex(action_values)
			q = parameters[i_a][i_s]
			action_values[i_a] = q
			newmax = q > maxvalue
			maxvalue = newmax*q + !newmax*maxvalue
			maxindex = newmax*i_a + !newmax*maxindex
		end
		return maxvalue, maxindex
	end
	function update_action_values!(action_values::Vector{T}, i_s::Integer, parameters::Matrix{T}) where T<:Real
		maxvalue = typemin(T)
		maxindex = 1
		@inbounds @simd for i_a in eachindex(action_values)
			q = parameters[i_s, i_a]
			action_values[i_a] = q
			newmax = q > maxvalue
			maxvalue = newmax*q + !newmax*maxvalue
			maxindex = newmax*i_a + !newmax*maxindex
		end
		return maxvalue, maxindex
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$ca970333-fa08-412c-b89d-491e70f0ac79cell_id$ca970333-fa08-412c-b89d-491e70f0ac79code9md"""
#### Typical Episode Length under Random Policy
"""metadatashow_logsèdisabled®skip_as_script«code_folded$db189316-e880-4cc8-9070-ccfe2b4fc545cell_id$db189316-e880-4cc8-9070-ccfe2b4fc545codeٸ(q̂_mountain_car2, episode_rewards2, episode_steps2, average_step_reward) = mountaincar_differential_test(100, 0.0008f0/8, 0.00001f0, 0.33f0; compute_value = compute_q_learning_value)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$ddcb50be-5287-47f8-89f9-58c026a6b151cell_id$ddcb50be-5287-47f8-89f9-58c026a6b151codefigure_10_2()metadatashow_logsèdisabled®skip_as_scriptëcode_folded$e7bf61d7-c362-433d-9b83-6537d308c255cell_id$e7bf61d7-c362-433d-9b83-6537d308c255codemd"""
### *Semi-gradient Sarsa Implementation*

Below is an implementation of Semi-gradient Sarsa in a similar style to the algorithms in Chapter 9.  This function updates the provided parameters using the `update_parameters!` function and also requires an `estimate_value` function.  The linear function approximation version of this simplifies the required arguments greatly, needing only a state representation update function.  
"""metadatashow_logsèdisabled®skip_as_script«code_folded$69a06405-57cd-42e5-96b1-5cc77d74aa03cell_id$69a06405-57cd-42e5-96b1-5cc77d74aa03code?md"""
### *Differential Semi-gradient Sarsa Implementation*
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c44dd6c6-8213-49fb-8d33-ba8f2c766b2ecell_id$c44dd6c6-8213-49fb-8d33-ba8f2c766b2ecodeAplot_mountaincar_action_values(q̂_mountain_car2_fcann, 500, 500)metadatashow_logsèdisabled®skip_as_script«code_folded$ac80958a-73ec-4342-b553-b33df6612a50cell_id$ac80958a-73ec-4342-b553-b33df6612a50codedconst mountain_car_transition = StateMDPTransitionSampler(mountain_car_step, initialize_car_state())metadatashow_logsèdisabled®skip_as_script«code_folded$09088eee-4cb3-40ac-b127-658ce1332fbacell_id$09088eee-4cb3-40ac-b127-658ce1332fbacodeٍplot(scatter(y = -smooth_error(episode_rewards_q, 10)), Layout(yaxis_type = "log", xaxis_title = "Episode", yaxis_title = "Number of Steps"))metadatashow_logsèdisabled®skip_as_script«code_folded$33ea5f09-3a1f-476d-875a-1f3635a40295cell_id$33ea5f09-3a1f-476d-875a-1f3635a40295codeY@bind tabular_mountaincar_args PlutoUI.combine() do Child
	md"""
	Policy View Selection: $(Child(:policy, Select([1 => "Random", 2 => "Accelerate Only"])))
	Number of Positions: $(Child(:num_positions, NumberField(1:10000, default = 500)))
	Number of Velocities: $(Child(:num_velocities, NumberField(1:10000, default = 500)))
	"""
end |> confirmmetadatashow_logsèdisabled®skip_as_script«code_folded$318b398a-d8f2-4f39-a45d-fd9023961bf8cell_id$318b398a-d8f2-4f39-a45d-fd9023961bf8codefinclude(joinpath(@__DIR__, "..", "Chapter-9", "Chapter_9_On-policy_Prediction_with_Approximation.jl"))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$be77b538-d106-4ca0-a974-289415588c47cell_id$be77b538-d106-4ca0-a974-289415588c47codeJmd"""
##### Solving Mountain Car Tabular Problem with Policy Iteration
"""metadatashow_logsèdisabled®skip_as_script«code_folded$5bc2eda5-5f4c-4165-9afb-16920f30b0c5cell_id$5bc2eda5-5f4c-4165-9afb-16920f30b0c5codeوπ_optimal_policy_iteration(s) = sample_action(view(mountaincar_policy_iteration[1][end], :, assign_state_index_tabular_mountaincar(s)))metadatashow_logsèdisabled®skip_as_script«code_folded$f9ee13e8-7406-4fba-9a30-1e2714bd7cfccell_id$f9ee13e8-7406-4fba-9a30-1e2714bd7cfccode<plot_mountaincar_action_values(q̂_mountain_car_q, 500, 500)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$afee7bc9-aff0-4c71-a227-9845cb23d4e9cell_id$afee7bc9-aff0-4c71-a227-9845cb23d4e9codefmd"""Number of Steps: $(@bind rand_nsteps confirm(Slider(1:1_000, default = 200, show_value=true)))"""metadatashow_logsèdisabled®skip_as_scriptëcode_folded$4775126e-4374-49be-b25f-4597401f3642cell_id$4775126e-4374-49be-b25f-4597401f3642codeplot([scatter(y = view(average_step_reward, episode_steps2[2:end]), name = "Average Steps Reward"), scatter(y = (episode_steps2[2:end] .- episode_steps2[1:end-1])[:], name = "Steps Per Episode", yaxis = "y2")], Layout(yaxis2 = attr(overlaying = "y", side = "right")))metadatashow_logsèdisabled®skip_as_script«code_folded$d291541d-ddba-4b71-a4eb-37fef758b71bcell_id$d291541d-ddba-4b71-a4eb-37fef758b71bcodemd"""
#### Tabular Version of Mountain Car

If we discretize the positions and velocities then we can transform this into a tabular problem.  The number of states will be NxM where N and M are the number of distinct values for position and velocity respectively.  As N and M approach infinity this problem will approach the original MDP, so we can study the limiting behavior of the optimal policy and value function using tabular methods that are guaranteed to converge.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e2cd69c5-eda7-4897-9e64-0adf940d4d96cell_id$e2cd69c5-eda7-4897-9e64-0adf940d4d96codeC@bind policy_num Select(eachindex(mountaincar_policy_iteration[1]))metadatashow_logsèdisabled®skip_as_script«code_folded$cbac1927-b087-4c4c-98ae-6aa5f0b824adcell_id$cbac1927-b087-4c4c-98ae-6aa5f0b824adcode٢(q̂_mountain_car_q, π_mountain_car_q, episode_rewards_q, episode_steps_q) = mountaincar_test(1_000, 0.002f0/8, 0.25f0; compute_value = compute_q_learning_value)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$ee59176e-24b6-4213-8f8e-759a70bc1d5ecell_id$ee59176e-24b6-4213-8f8e-759a70bc1d5ecodefmountaincar_fcann_dp_results = mountaincar_fcann_dp(100, 1f-5, 0.1f0; layers = [16, 16, 16], c = 10f0)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$54b92594-04b8-4a8a-82c2-773b4a24680dcell_id$54b92594-04b8-4a8a-82c2-773b4a24680dcodemd"""
### *Action-Value Implementation of Linear Approximation*

If we update the techniques from Chapter 9 to accomodate action-value estimates, then all of the linear techniques explored there can be used for these control algorihtms.  Previously, we only considered state value estimates, but we can adapt all of those techniques to action values in the linear case quite easily.  The main difference is that the action index needs to be included as an argument to the parameter update function.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0cell_id$7d21c4cd-ab79-4f40-9b8b-f637b3efcab0codeEshow_mountaincar_trajectory(π_greedy_dp, 1_000, "DP Learned Policy")metadatashow_logsèdisabled®skip_as_scriptëcode_folded$c316c5d3-f484-4e8e-bd56-be1e236d96bccell_id$c316c5d3-f484-4e8e-bd56-be1e236d96bccode
md"""
Applying the derivation of discount independence to the MDP in exercise 3.22 who's optimal policy depends on $\gamma$

$J(\pi) = \sum_s \mu_\pi(s)v_\pi^\gamma(s)$

Consider $\pi_{left}$: $J(\pi_{left})=0.5 \times (1 + 0 + \gamma^2 + 0 + \gamma^4 + 0 + \cdots) + 0.5 \times(0 + \gamma + 0 + \gamma^3 + 0 + \gamma^5 + \cdots)$
$J(\pi_{left}) = 0.5 \times (1 + \gamma + \gamma^2 + \gamma^3 + \gamma^4 + \gamma^5 + \cdots)$

Consider $\pi_{right}$: $J(\pi_{right})=0.5 \times (0 + 2\gamma + 0 + 2\gamma^3 + 0 + \cdots) + 0.5 \times(2 + 0 + 2\gamma^2 + 0 + 2\gamma^4 + \cdots)$
$J(\pi_{right}) = 0.5 \times 2 \times (1 + \gamma + \gamma^2 + \gamma^3 + \gamma^4 + \gamma^5 + \cdots)$

So both average reward values have the same factor for the discount rate and thus the right policy appears better since the average reward value is higher.  Previously, we had calculated that a discount rate less than 0.5 made the left policy favorable since the reward was obtained sooner going left vs right.  In the original problem we can consider the value of the top state for both left and right policies:
$v_{\pi_{left}} (top) = 1 + 0 + \gamma^2 + 0 + \gamma^4 + \cdots = 1 + \gamma^2 + \gamma^4 + \cdots$
$v_{\pi_{right}} (top) = 0 + 2\gamma + 0 + 2\gamma^3 + \cdots = 2 \times (\gamma + \gamma^3 + \cdots) = 2\gamma(v_{\pi_{left}}(top))$

Clearly for $\gamma > 0.5$ the right policy is better.

Similarly, we can consider the value of the left state for both left and right policies:
$v_{\pi_{left}} (left) = 0 + \gamma + 0 + \gamma^3 + \cdots = \gamma + \gamma^3 + \cdots$
$v_{\pi_{right}} (left) = 0 + 0 + 2\gamma^2 + 0  + 2\gamma^4 + \cdots = 2 \times (\gamma^2 + \gamma^4 + \cdots) = 2\gamma(v_{\pi_{left}}(left))$

Again, for $\gamma > 0.5$ the right policy is better.

And finally for the right state:
$v_{\pi_{left}} (right) = 2 + \gamma + 0 + \gamma^3 + 0 + \gamma^5 \cdots = 2+\gamma(1 + \gamma^2 + \gamma^4 + \cdots)=2 + \frac{\gamma}{1-\gamma^2}$ 
$= \frac{2(1-\gamma^2) + \gamma}{1-\gamma^2} = \frac{2 - 2\gamma^2 + \gamma}{1-\gamma^2}$
$v_{\pi_{right}} (right) = 2 + 0 + 2\gamma^2 + 0 + 2\gamma^4 +  \cdots = 2 \times (1+\gamma^2 + \gamma^4 + \cdots) = \frac{2}{1-\gamma^2}$

$\frac{v_{\pi_{left}} (right)}{v_{\pi_{right}} (right)}=\frac{2 - 2\gamma^2 + \gamma}{2}$

For $\gamma=0$ this quantity is 1 meaning the policies are equal and for $\gamma=1$ this quantity is 0.5 meaning that the right policy is better.  At $\gamma=0.5$ the quantity is $\frac{2 - 0.5 + 0.5}{2}=\frac{2}{2}=1$ meaning they are equal.  The maximum value occurs at $2\gamma = 0.5 \implies \gamma = 0.25$ with a ratio value of $\frac{2 - 0.125 + 0.25}{2}=\frac{2.125}{2}=1.0625$ meaning that the left policy is slightly better or equal from $0 \leq \gamma \leq 0.5$ and worse at $\gamma > 0.5$ which matches the earlier states.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$f2201afe-8952-4dde-9e39-02beeb920f6fcell_id$f2201afe-8952-4dde-9e39-02beeb920f6fcodeKshow_mountaincar_trajectory(π_mountain_car, 1_000, "Sarsa Learned Policy")metadatashow_logsèdisabled®skip_as_scriptëcode_folded$31fb07d2-1c34-44ec-b932-a598e78ec8dccell_id$31fb07d2-1c34-44ec-b932-a598e78ec8dccodemd"""
#### Non-linear Neural Network

Compared to tile coding, the feature vector for non-linear learning will simply be two values: one for the position and another for the velocity.  Both values will be scaled so the mean value is 0 and the variance is approximately 1.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$5db29488-a150-42ee-aedb-380a3a4fd548cell_id$5db29488-a150-42ee-aedb-380a3a4fd548code!function plot_mountaincar_action_values(q̂_mountain_car, n1, n2)
	xvals = LinRange(-1.2f0, 0.5f0, n1)
	vvals = LinRange(-0.07f0, 0.07f0, n2)
	values = zeros(Float32, n1, n2)
	actions = zeros(Float32, n1, n2)
	for (i, x) in enumerate(xvals)
		for (j, v) in enumerate(vvals)
			(q̂, i_a) = q̂_mountain_car((x, v))
			values[j, i] = q̂
			actions[j, i] = mountain_car_actions[i_a]
		end
	end
	p1 = plot(heatmap(x = xvals, y = vvals, z = values), Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Learned Value Function"))
	p2 = plot(heatmap(x = xvals, y = vvals, z = actions, colorscale = "rb", showscale = false), Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Policy (blue = accelerate left, <br>red = accelerate right, gray = no acceleration)"))
	[p1 p2]
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$39c63495-36c3-4e62-b8fb-36865f2c6243cell_id$39c63495-36c3-4e62-b8fb-36865f2c6243code<md"""
##### Visualizing Policies in Tabular Mountain Car
"""metadatashow_logsèdisabled®skip_as_script«code_folded$d42bb733-07e2-4932-aab4-09229ff67492cell_id$d42bb733-07e2-4932-aab4-09229ff67492codeٰshow_mountaincar_trajectory(s -> constant_params.action, constant_params.nsteps, "Mountain Car Trajectory for $(mountain_car_action_names[constant_params.action]) only Policy")metadatashow_logsèdisabled®skip_as_script«code_folded$58a0b622-1b51-4b42-a416-24109ae41a90cell_id$58a0b622-1b51-4b42-a416-24109ae41a90codeplot_mountaincar_action_values(tabular_mountaincar_mdp, mountaincar_policy_iteration[2][policy_num], mountaincar_policy_iteration[1][policy_num], mountaincar_positions, mountaincar_velocities)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$954848db-6dcc-4666-90f8-b5a900203242cell_id$954848db-6dcc-4666-90f8-b5a900203242code]show_mountaincar_trajectory(s -> mc_test.π_ϵ_greedy(s, 0.25f0), 10000, "MC Learned Policy")metadatashow_logsèdisabled®skip_as_script«code_folded$df07524f-b3fe-4a66-98ac-8f80df66bcffcell_id$df07524f-b3fe-4a66-98ac-8f80df66bcffcodeوfunction mountain_car_dist_step(s::Tuple{Float32, Float32}, i_a::Int64)
	(r, s′) = mountain_car_step(s, i_a)
	([r], [s′], [1f0])
endmetadatashow_logsèdisabled®skip_as_script«code_folded$c85033e1-3ee6-42ad-9ef0-144ce6238ce4cell_id$c85033e1-3ee6-42ad-9ef0-144ce6238ce4codesfunction smooth_error(error_history, n)
	l = length(error_history)
	[mean(error_history[i-n:i]) for i in n+1:l]
endmetadatashow_logsèdisabled®skip_as_script«code_folded$f6e08689-040f-4565-9dfb-e9a65d1c1f18cell_id$f6e08689-040f-4565-9dfb-e9a65d1c1f18code'md"""
#### Visualizing Trajectories
"""metadatashow_logsèdisabled®skip_as_script«code_folded$e7372e2b-a2db-4a93-9efc-f75aa74c197bcell_id$e7372e2b-a2db-4a93-9efc-f75aa74c197bcodeMstruct AccessControlState
	num_free_servers::Int64
	top_priority::Float32
endmetadatashow_logsèdisabled®skip_as_script«code_folded$dc2cffeb-9adf-4956-afa3-ac82af377c59cell_id$dc2cffeb-9adf-4956-afa3-ac82af377c59codemd"""
Finally we can create the action-value function and parameter update for the generic linear case.  If a vector of action values is provided as the first argument to the value function, that vector will be updated with all of the action values for a given state.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$fc0b88f3-fbf9-450d-b770-b34357ffad49cell_id$fc0b88f3-fbf9-450d-b770-b34357ffad49codeqcompute_sarsa_value(action_values::Vector{T}, policy::Vector{T}, i_a::Integer) where T<:Real = action_values[i_a]metadatashow_logsèdisabled®skip_as_script«code_folded$50f6ff51-d81b-4e97-9f8a-0daf03af7192cell_id$50f6ff51-d81b-4e97-9f8a-0daf03af7192code)md"""
## Monte Carlo Gradient Control
"""metadatashow_logsèdisabled®skip_as_script«code_folded$5cbaeb8e-bc02-47c9-87b4-57df554cea9dcell_id$5cbaeb8e-bc02-47c9-87b4-57df554cea9dcodeQshow_mountaincar_trajectory(π_mountain_car_fcann, 1_000, "Sarsa Learned Policy")metadatashow_logsèdisabled®skip_as_scriptëcode_folded$b094bf9f-bb97-4f23-acdc-f39411a07fb9cell_id$b094bf9f-bb97-4f23-acdc-f39411a07fb9codeهπ_mountain_car2_fcann(s) = rand() < 0.05 ? rand(1:3) : argmax(i_a -> q̂_mountain_car2_fcann(s, i_a), eachindex(mountain_car_actions))metadatashow_logsèdisabled®skip_as_script«code_folded$1d417a66-205f-4883-b49c-a6fc900af4cecell_id$1d417a66-205f-4883-b49c-a6fc900af4cecode^const mountaincar_positions = LinRange(-1.2f0, 0.5f0, tabular_mountaincar_args.num_positions) metadatashow_logsèdisabled®skip_as_script«code_folded$17d11fea-883b-4ddb-bec2-c4ad491b39ddcell_id$17d11fea-883b-4ddb-bec2-c4ad491b39ddcodefunction run_linear_gradient_monte_carlo_control(mdp::StateMDP, γ::T, num_episodes::Integer, state_representation::AbstractVector{T}, update_state_representation!::Function; kwargs...) where T<:Real
	setup = linear_features_action_gradient_setup(mdp, state_representation, update_state_representation!)
	parameters = [zeros(T, length(state_representation)) for _ in 1:length(mdp.actions)]
	step_history, reward_history = gradient_monte_carlo_control!(parameters, mdp, γ, num_episodes, setup...; kwargs...)
	q̂(s) = setup.value_function(action_values, s, parameters, setup.value_args...)
	action_values = zeros(T, length(mdp.actions))
	π_greedy(s) = setup.value_function(action_values, s, parameters, setup.value_args...)[2]
	π_ϵ_greedy(s, ϵ) = rand() < ϵ ? rand(eachindex(mdp.actions)) : setup.value_function(action_values, s, parameters, setup.value_args...)[2]
	return (value_function = q̂, π_greedy = π_greedy, π_ϵ_greedy = π_ϵ_greedy, step_history = step_history, reward_history = reward_history)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$b4af8d87-a6e5-4e09-92b4-b07757f58f7fcell_id$b4af8d87-a6e5-4e09-92b4-b07757f58f7fcodefunction run_access_control_differential_sarsa(max_steps::Int64; num_servers = 10, priority_payments = [1f0, 2f0, 4f0, 8f0], kwargs...)
	(mdp, gradient_setup, num_groups) = create_access_control_task(num_servers, priority_payments)
	parameters = [zeros(Float32, num_groups) for _ in eachindex(mdp.actions)]
	state_representation = zeros(Float32, num_groups)
	(_, _, steprewards) = differential_semi_gradient_sarsa!(parameters, mdp, 1, max_steps, gradient_setup...; kwargs...)
	action_values = zeros(Float32, length(mdp.actions))
	v̂(num_free_servers::Int64, priority::Real) = gradient_setup.value_function(action_values, AccessControlState(num_free_servers, Float32(priority)), parameters)

	(value_function = v̂, mdp = mdp, parameters = parameters, steprewards = steprewards)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5bcell_id$d6ad1ff1-8fbf-4799-8b1b-ae1e3ce88c5bcodecmd"""
> ### *Exercise 10.3* 
> Why do the results shown in Figure 10.4 have higher standard errors at large *n* than at small *n*?

At large n more of the reward function comes from the actual trajectory observed during a run.  Since random actions are taken initially there will be more spread in the observed reward estimates than with 1 step bootstrapping which is more dependent on the initialization of the action value function.  If ties are broken randomly then you would select random actions for the first n-steps of bootstrapping thus experience more spread in the early trajectories for higher n.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c799ffe4-f4af-487d-b557-8b50d13632b7cell_id$c799ffe4-f4af-487d-b557-8b50d13632b7codeٻplot_mountaincar_action_values(tabular_mountaincar_mdp, mountaincar_value_iteration.final_value, mountaincar_value_iteration.optimal_policy, mountaincar_positions, mountaincar_velocities)metadatashow_logsèdisabled®skip_as_script«code_folded$0e66a941-1ec1-4d3b-b064-e5f25cc93bafcell_id$0e66a941-1ec1-4d3b-b064-e5f25cc93bafcode%md"""
### Connection to Chapter 3
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c5c839f7-1806-463d-b63a-bd7e1384f203cell_id$c5c839f7-1806-463d-b63a-bd7e1384f203codemd"""
The action value calculation also depends on how parameters are represented.  Either a dot product is used by extracting the appropriate parameter vector, or the parameter matrix needs to be iterated over the appropriate column
"""metadatashow_logsèdisabled®skip_as_script«code_folded$1b15efa9-c331-46bf-93db-f96dee026fe2cell_id$1b15efa9-c331-46bf-93db-f96dee026fe2codeNconst tabular_mountaincar_πrand = make_random_policy(tabular_mountaincar_mdp)metadatashow_logsèdisabled®skip_as_script«code_folded$72f575ee-d656-4af6-bf78-aab42bf1debdcell_id$72f575ee-d656-4af6-bf78-aab42bf1debdcodeImd"""
##### Solving Mountain Car Tabular Problem with Value Iteration
"""metadatashow_logsèdisabled®skip_as_script«code_folded$2c620fe4-2f62-40f8-a666-8dced1e0b84acell_id$2c620fe4-2f62-40f8-a666-8dced1e0b84acodeQfunction run_linear_semi_gradient_sarsa(mdp::StateMDP, γ::T, max_episodes::Integer, max_steps::Integer, state_representation::AbstractVector{T}, update_state_representation!::Function; setup_kwargs = NamedTuple(), kwargs...) where T<:Real
	setup = linear_features_action_gradient_setup(mdp, state_representation, update_state_representation!; setup_kwargs...)
	l = length(state_representation)
	num_actions = length(mdp.actions)
	# parameters = zeros(T, l, num_actions)
	parameters = [zeros(T, l) for _ in 1:num_actions]
	episode_rewards, episode_steps = semi_gradient_sarsa!(parameters, mdp, γ, max_episodes, max_steps, setup.value_function, setup.value_args, setup.parameter_update, setup.update_args; kwargs...)
	q̂(s, i_a) = setup.value_function(s, i_a, parameters, setup.value_args...)
	function q̂(s)
		action_values = zeros(T, num_actions)
		setup.value_function(action_values, s, parameters, setup.value_args...)
		findmax(action_values)
	end

	π_greedy(s) = q̂(s)[2]
	
	return (value_function = q̂, π_greedy = π_greedy, reward_history = episode_rewards, step_history = episode_steps)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8cell_id$bd1f42e5-94cc-4aef-b82a-9bffd1c951d8code7plot_mountaincar_values(v̂_mountain_car, π_greedy_dp)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$b8c031ca-7995-4501-a1e3-df3f34e5f0dacell_id$b8c031ca-7995-4501-a1e3-df3f34e5f0dacodemd"""
## 10.3 Average Reward: A New Problem Setting for Continuing Tasks

We now introduce an alternative to the discount setting for solving continuing problems (MDPs without a terminal state).  The average-reward setting is more commonly used in the classical theory of dynamic programming.  The purpose of introducing the average-reward is because discounting is problematic with function approximation in a way it was not problematic for tabular problems.  

In the average-reward setting the quality of a policy $\pi$ is defined as the average rate of reward, or simply *average reward*, while following that policy, which we denote as $r(\pi)$:

$\begin{flalign}
r(\pi) &\doteq \lim_{h \rightarrow \infty} \frac{1}{h}\sum_{t=1}^h \mathbb{E}[R_t \mid S_0,A_{0:t-1} \sim \pi] \tag{10.6}\\
&= \lim_{h \rightarrow \infty} \mathbb{E} [R_t \mid S_0,A_{0:t-1} \sim \pi] \tag{10.7}\\
&= \sum_s \mu_\pi(s)\sum_a\pi(a \vert s) \sum_{s^\prime,r} p(s^\prime,r \vert s, a)r
\end{flalign}$

where the expectations are conditioned on the initial state, $S_0$, and on the subsequent actions, $A_0, A_1, \dots,A_{t-1}$, being taken according to $\pi$. The second and third equations hold if the state-state distribution $\mu_\pi(s) \doteq \lim_{t\rightarrow \infty} \Pr \{S_t = s \mid A_{0:t-1} \sim \pi \}$, exists and is independent of $S_0$, in other words, if the MDP is *ergodic*. In an ergodic MDP, the starting state and any early decision made by the agent can only have a temporary effect; in the long run the expectation of being in a state depends on the policy and the MDP transition probabilities.  Ergodicity is sufficient but not necessary to guarantee the existence of the limit in (10.6).

In this setting, we consider all policies that obtain the maximum value of $r(\pi)$ or the *reward rate* to be optimal.  Note that the steady state distribution $\mu_\pi$ is the special distribution under which, if you select actions according to $\pi$, you remain in the same distribution.  That is, for which 

$\sum_s \mu_\pi(s) \sum_a \pi(a\vert s)p(s^\prime \vert s, a) = \mu_\pi(s^\prime) \tag{10.8}$

In the average-reward setting, returns are defined in terms of differences between rewards and the average reward: 

$G_t \doteq R_{t+1} - r(\pi) + R_{t+2} - r(\pi) + R_{t+3} - r(\pi) + \cdots \tag{10.9}$

This is known as the *differential* return, and th corresponding value functions are known as *differential* value functions.  Differential value functions are defined in terms of the new return just as conventional value functions were defined in terms of the discounted return; thus we will use the same notation, $v_\pi (s) \doteq \mathbb{E}_\pi[G_t \vert S_t = s]$ and $q_\pi (s, a) \doteq \mathbb{E}_\pi[G_t \vert S_t = s, A_t = a]$ (similarly for $v_*$ and $q_*$), for differential value functions.  Differential value functions also have Bellman equations, just slightly different from those we have seen earlier.  We simply remove all $\gamma$s and replace all rewards by the difference between the reward and the true average reward:

$\begin{flalign}
&v_\pi(s) = \sum_a \pi(a\vert s) \sum_{r, s^\prime}p(s^\prime, r \vert s, a) \left [ r - r(\pi) + v_\pi(s^\prime) \right ] \\
&q_\pi(s, a) = \sum_{r, s^\prime}p(s^\prime, r \vert s, a) \left [ r - r(\pi) + \sum_{a^\prime} \pi(a^\prime \vert s^\prime) q_\pi(s^\prime, a^\prime) \right ] \\
&v_* = \max_a \sum_{r, s^\prime}p(s^\prime, r \vert s, a) \left [ r - r(\pi) + v_*(s^\prime) \right ] \\
&q_* = \sum_{r, s^\prime}p(s^\prime, r \vert s, a) \left [ r - \max_{\pi}r(\pi) + \max_a q_\pi(s^\prime, a^\prime) \right ] \\
\end{flalign}$

There is also a differential form of the two TD errors:

$\delta_t \doteq R_{t+1} - \bar{R}_t+ \hat v (S_{t+1}, \mathbf{w}_t) - \hat v(S_t, \mathbf{w}_t) \tag{10.10}$

and

$\delta_t \doteq R_{t+1} - \bar{R}_t+ \hat q (S_{t+1}, A_{t+1}, \mathbf{w}_t) - \hat q(S_t, A_t, \mathbf{w}_t) \tag{10.11}$

where $\bar{R}_t$ is an estimate at time $t$ of the average reward $r(\pi)$.  With these alternate definitions, most of our algorithms and many theoretical results carry through to the average_reward setting without any change.  

For example, an average reward version of semi-gradient Sarsa could be defined just as in (10.2) except with the differential version of the TD error.  That is by

$\mathbf{w}_{t+1} \doteq \mathbf{w}_t + \alpha \delta_t \nabla \hat q(S_t, A_t, \mathbf{w}_t)$

with $\delta_t$ given by (10.11).  See a full implementation below.  One limitation of this algorithm is that it does not converge to the differential values but to the differential values plut an arbitrary offset.  Notice that the Bellman equations and TD errors given above are unaffected if all the values are shifted by the same amount.  Thus, the offset may not matter in practice.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$014339eb-5b23-4ac5-a551-8eeb2238366fcell_id$014339eb-5b23-4ac5-a551-8eeb2238366fcode}begin 
	function access_control_step(s::AccessControlState, ::Reject, num_servers::Integer, priority_payments::Vector{Float32})
		occupied_servers = num_servers - s.num_free_servers
		freed_servers = sum(_ -> Float32(rand() < 0.06), 1:occupied_servers; init = 0f0)
		new_occupied_servers = occupied_servers - freed_servers
		new_free_servers = num_servers - new_occupied_servers
		new_priority = rand(priority_payments)
		(0f0, AccessControlState(new_free_servers, new_priority))
	end

	function access_control_step(s::AccessControlState, ::Accept, num_servers::Integer, priority_payments::Vector{Float32})
		occupied_servers = num_servers - s.num_free_servers
		(r_reject, s′) = access_control_step(s, Reject(), num_servers, priority_payments)
		s.num_free_servers == 0 && return (r_reject, s′)
		(s.top_priority, AccessControlState(s′.num_free_servers - 1, s′.top_priority))
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$49249ac1-8964-4afc-89f2-3cd4d4322cc2cell_id$49249ac1-8964-4afc-89f2-3cd4d4322cc2codemd"""
> ### *Exercise 10.1* 
> We have not explicitely considered or given pseudocode for any Monte Carlo methods in this chapter.  What would they be like?  Why is it reasonable not to give pseudocode for them?  How would they perform on the Mountain Car task?

Monte Carlo methods require an episode to terminate prior to updating any action value estimates.  After the final reward is retrieved then all the action value pairs visited along the trajectory can be updated and the policy can be updated prior to starting the next episode.  For tasks such as the Mountain Car task where a random policy will likely never terminate, such a method will never be able to complete a single episode worth of updates.  We saw in earlier chapters with the racetrack and gridworld examples that for some environments a bootstrap method is the only suitable one given this possibility of an episode never terminating.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$1a5acfb0-3b35-41b1-98f8-ffce941c587fcell_id$1a5acfb0-3b35-41b1-98f8-ffce941c587fcodeAmd"""
#### Mountain Car Linear Approximation with Tile Coding
"""metadatashow_logsèdisabled®skip_as_script«code_folded$7bc49107-9de5-4985-8750-979f36b3aa81cell_id$7bc49107-9de5-4985-8750-979f36b3aa81code_π_mountain_car2(s) = argmax(i_a -> q̂_mountain_car2(s, i_a), eachindex(mountain_car_actions))metadatashow_logsèdisabled®skip_as_script«code_folded$4d392303-4681-4ea1-8dcc-e002a78ea0a1cell_id$4d392303-4681-4ea1-8dcc-e002a78ea0a1codeemd"""
### Policy Improvement
The purpose of the value function lies in the *Policy Improvement Theorem* which provides a way to iteratively improve a given policy towards the optimal policy.  Consider a policy $\pi(s)$ and its associated value functions $v_\pi(s)$ and $q_\pi(s, a)$.  Now consider a new policy $\pi^\prime(s)$ that would select a different action $a^\prime$ at state $s$ than the original policy $\pi$ such that $q_\pi(s, a^\prime) \geq v_\pi(s)$.  The theorem proves that if the former is true, then $v_{\pi^\prime}(s) \geq v_\pi(s) \forall s \in \mathcal{S}$.  In other words, the new policy is superior to the old one since it has a higher value value at every state.  There is also an easy way to construct a policy which meets the necessary criteria of the policy improvement theorem:

$\begin{flalign}
\pi^\prime(s) &\doteq \mathrm{argmax}_a q_\pi(s, a) \\
& = \mathrm{argmax}_a \mathbb{E} [R_{t+1} + \gamma v_\pi(S_{t+1}) \mid S_t = s, A_t = a] \\
& = \mathrm{argmax}_a \sum_{s^\prime, r} p(s^\prime, r \vert s, a) [r + \gamma v_\pi(s^\prime)] \\
\end{flalign}$

If we have the state-action value function $q_\pi(s, a)$, then the construction is trivial.  If we only have $v_\pi(s)$, then we must also have the probability transition function for the environment in order to reconstruct the state-action values.  In the absence of $p$ we must rely on $q_\pi$.  Consider some future policy such that $\pi(s) = \mathrm{argmax}_a q_\pi(s, a) \: \forall s$.  In this case, the updated policy will be identical to the original policy and the process will have converged.  The policy at convergence will also be the optimal policy $\pi_*$ whose value functions fulfill the following properties:

$\begin{flalign}
v_*(s) &\doteq \max_\pi v_\pi(s) \: \forall \: s \in \mathcal{S} \tag{3.15} \\
&= \max_{a \in \mathcal{A}(s)} q_{*}(s, a) \: \forall \: s \in \mathcal{S} \tag{meaning of optimal}\\
&= \max_{a \in \mathcal{A}(s)} \sum_{s^\prime, r} p(s^\prime, r \vert s, a) \left [ r + γ v_* (s^\prime) \right ] \quad \forall s \in \mathcal{S} \tag{Used by Value Iteration when p is available}\\
q_*(s, a) &\doteq \max_\pi q_\pi(s, a) \: \forall \: s \in \mathcal{S} \text{ and } a \in \mathcal{A}(s) \tag{3.16} \\
&=\mathbb{E} \left [ R_{t+1} + \gamma v_* (S_{t+1}) \mid S_t = s, A_t = a \right ] \tag{3.17} \\
&= \sum_{s^\prime, r} p(s^\prime, r \vert s, a) \left [ r + γ v_* (s^\prime) \right ] \tag{exp value def (3.21)} \\
&= \sum_{s^\prime, r} p(s^\prime, r \vert s, a) \left [ r + γ \max_{a^\prime} q_*(s^\prime, a^\prime) \right ] \tag{Used by Q Value Iteration when p is available} \\
&= \mathbb{E} \left [ R_t + γ \max_{a^\prime} q_*(s^\prime, a^\prime) \mid S_t = s, A_t = a \right ] \tag{Used by Q Learning when p is not available} \\
\end{flalign}$

The policy improvement theorem suggests an approach where we initialize a random policy, find its value function, and then derive an improved policy until the process has converged.  If we have the probability transition function, we can use dynamic programming to calculate the value function for a policy as well as the improved policy.  Repeating this process until convergence is called *Policy Iteration*.  Alternatively, we can use the properties of the optimal value function without explicitely considering a sequence of policies.  That is only possible when the probability transition function is known and is called *Value Iteration*.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$d3ba78fa-f032-4bb9-9359-ef3bcff2252dcell_id$d3ba78fa-f032-4bb9-9359-ef3bcff2252dcodeJfunction mountaincar_fcann_differential_test(max_steps::Integer, α::Float32, β::Float32, ϵ::Float32; num_layers = 3, layer_size = 2, kwargs...)
	feature_vector = zeros(Float32, 2)
	function update_feature_vector!(v::Vector{Float32}, s::NTuple{2, Float32})
		x1 = 3.45f0*(((s[1] - 1.2f0) / 1.7f0) - 0.5f0)
		x2 = 1.725f0*s[2] / 0.07f0
		v[1] = x1
		v[2] = x2
	end
	layers = fill(layer_size, num_layers)
	run_fcann_differential_semi_gradient_sarsa(mountain_car_differential_mdp, 1000, max_steps, feature_vector, update_feature_vector!, layers; α = α, β = β, ϵ = ϵ, kwargs...)
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$742100ba-c38e-4840-8988-40990039b527cell_id$742100ba-c38e-4840-8988-40990039b527codeٷsetup_mountain_car_tiles(tile_size::NTuple{2, Float32}, num_tilings::Integer) = tile_coding_setup(mountain_car_mdp, (-1.2f0, 0.5f0), (-0.07f0, 0.07f0), tile_size, num_tilings, (1, 3))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$2f0d0a71-c65b-4aa0-a493-e7cdccd901ebcell_id$2f0d0a71-c65b-4aa0-a493-e7cdccd901ebcodefunction plot_mountaincar_values(v̂_mountain_car, π; n1 = 100, n2 = 100)
	xvals = LinRange(-1.2f0, 0.5f0, n1)
	vvals = LinRange(-0.07f0, 0.07f0, n2)
	values = zeros(Float32, n1, n2)
	actions = zeros(Float32, n1, n2)
	for (i, x) in enumerate(xvals)
		for (j, v) in enumerate(vvals)
			v̂ = v̂_mountain_car((x, v))
			values[j, i] = v̂
			actions[j, i] = π((x, v))
		end
	end
	p1 = plot(heatmap(x = xvals, y = vvals, z = values), Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Learned Value Function"))
	p2 = plot(heatmap(x = xvals, y = vvals, z = actions, colorscale = "rb", showscale = false), Layout(xaxis_title = "position", yaxis_title = "velocity", title = "Policy (blue = accelerate left, <br>red = accelerate right, gray = no acceleration)"))
	[p1 p2]
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$a3cf270b-b309-44f0-9972-bd84228bcf17cell_id$a3cf270b-b309-44f0-9972-bd84228bcf17codemd"""
### Finding the Optimal Policy
Depending on the nature of the problem and the available information, different techniques are available.  Below is a summary of the conditions and available techniques for different scenarios starting with the ideal case where all information is available.

#### Idealized Tabular Case
##### Problem conditions
- All states and actions can be enumerated: $\mathcal{S} = \{s_1, s_2, \cdots, s_n\}$ and $\mathcal{A} = \{a_1, a_2, \cdots, a_m\}$
-  $p(s^\prime, r \vert s, a)$ is available for all states and actions

In order to verify that we have the correct value function or the optimal one, we need to confirm the conditions for every state or state-action pair.  In short we require $p(s^\prime, r \vert s, a) \: \forall s, a$ which also implies the ability to check all the state action pairs.  If this is possible, then the problem is *tabular* since we can tabulate all of the necessary values.  It is only in this best case scenario that we can definitively verify the correct solution.

##### Solution Techniques
- Value Iteration
  - initialize a list of state values: $[v_1, v_2, \cdots, v_n]$, one for each state
  - perform the following update accross all states until the values converge: $v_i = \max_{a \in \mathcal{A}} \sum_{s_j, r} p(s_j, r \vert s_i, a) \left [ r + γ v_j \right ]$
- Policy Iteration
  - initialize a random policy $\pi$ (probability distribution over actions for each state, could be a matrix)
  - initialize a list of state values: $[v_1, v_2, \cdots, v_n]$, one for each state
  - repeat the following until the values converge
    - use dynamic programming policy evaulation to update the state values
    - update the policy to be greedy with respect to the value function
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b9125c5b-01d6-451e-84b5-a419e38425b5cell_id$b9125c5b-01d6-451e-84b5-a419e38425b5codetπ_mountain_car_fcann(s) = argmax(i_a -> mountain_car_fcann.value_function(s, i_a), eachindex(mountain_car_actions))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$9d65285f-d49e-40ce-acea-1f565bcd4108cell_id$9d65285f-d49e-40ce-acea-1f565bcd4108codeٳconst (tabular_mountaincar_mdp, assign_state_index_tabular_mountaincar) = make_tabular_mountaincar(tabular_mountaincar_args.num_positions, tabular_mountaincar_args.num_velocities)metadatashow_logsèdisabled®skip_as_script«code_folded$57a6510f-bd42-4d1d-a550-d1442f79569fcell_id$57a6510f-bd42-4d1d-a550-d1442f79569fcode@md"""
### *Semi-gradient Dynamic Programming Implementation*
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b0761704-5447-4e64-8270-708d9dccef60cell_id$b0761704-5447-4e64-8270-708d9dccef60coderfunction semi_gradient_dp!(parameters, mdp::StateMDP{T, S, A, P, F1, F2, F3}, γ::T, max_episodes::Integer, max_steps::Integer, estimate_value::Function, estimate_args::Tuple, update_parameters!::Function, update_args::Tuple; α = one(T)/10, ϵ = one(T) / 10, nn_momentum = false, α_decay = one(T), decay_step = typemax(Int64), kwargs...) where {T<:Real, S, A, P<:StateMDPTransitionDistribution, F1<:Function, F2<:Function, F3<:Function}
	s = mdp.initialize_state()
	i_a = rand(eachindex(mdp.actions))
	ep = 1
	step = 1
	epreward = zero(T)
	episode_rewards = Vector{T}()
	episode_steps = Vector{Int64}()
	action_values = zeros(T, length(mdp.actions))
	policy = zeros(T, length(mdp.actions))
	decay = one(T)
	while (ep <= max_episodes) && (step <= max_steps)
		maxq = typemin(T)
		#computes q and finds maximizing action value, this is effectively trajectory sampling in the case of approximation where we stay close to the optimal policy
		for i_a in eachindex(action_values)
			(rewards, states, probabilities) = mdp.ptf.step(s, i_a)
			v′ = zero(T) 
			r_avg = zero(T)
			for i in eachindex(probabilities)
				v′ += probabilities[i]*(!mdp.isterm(states[i])*estimate_value(states[i], parameters, estimate_args...))
				r_avg += probabilities[i]*rewards[i]
			end
			q = r_avg + γ*v′
			action_values[i_a] = q
			if q > maxq
				maxq = q
			end
		end
		
		learning_rate = nn_momentum ? T(1 - 0.999^step) : one(T)
		update_parameters!(parameters, s, maxq, α * learning_rate * decay, update_args...)

		make_ϵ_greedy_policy!(action_values; ϵ = ϵ)
		i_a = sample_action(action_values)
		(r, s) = mdp.ptf(s, i_a)
		epreward += r
		
		if mdp.isterm(s)
			s = mdp.initialize_state()
			push!(episode_rewards, epreward)
			push!(episode_steps, step)
			epreward = zero(T)
			ep += 1
		end
		
		if step > decay_step
			decay *= α_decay
		end
		step += 1
	end
	return episode_rewards, episode_steps
endmetadatashow_logsèdisabled®skip_as_script«code_folded$a6c5ec28-b2d5-4893-a118-95c1318d1f7fcell_id$a6c5ec28-b2d5-4893-a118-95c1318d1f7fcodeGmd"""
> ### *Exercise 10.6* 
> Suppose there is an MDP that under any policy produces the deterministic sequence of rewards +1, 0, +1, 0, +1, 0, . . . going on forever. Technically, this violates ergodicity; there is no stationary limiting distribution $μ_\pi$ and the limit (10.7) does not exist. Nevertheless, the average reward (10.6) is well defined. What is it? Now consider two states in this MDP. From A, the reward sequence is exactly as described above, starting with a +1, whereas, from B, the reward sequence starts with a 0 and then continues with +1, 0, +1, 0, . . .. We would like to compute the differential values of A and B. Unfortunately, the differential return (10.9) is not well defined when starting from these states as the implicit limit does not exist. To repair this, one could alternatively define the differential value of a state as $v_\pi (s) \doteq \lim_{\gamma \rightarrow 1} \lim_{h \rightarrow \infty} \sum_{t=0}^h \gamma^t \left ( \mathbb{E_\pi} [R_{t+1}|S_0=s]-r(\pi)  \right )$.  Under this definition what are the differential values of states A and B?
"""metadatashow_logsèdisabled®skip_as_script«code_folded$f1edb500-fbd1-4c03-b033-53860dfa452dcell_id$f1edb500-fbd1-4c03-b033-53860dfa452dcodemd"""
> ### *Exercise 10.7* 
> Consider a Markov reward process consisting of a ring of three states A, B, and C, with state transitions going deterministically around the ring.  A reward of +1 is received upon arrival in A and otherwise the reward is 0.  What are the differential values of the three states, using (10.13)

From 10.13 we have 

$v_\pi (s) \doteq \lim_{\gamma \rightarrow 1} \lim_{h \rightarrow \infty} \sum_{t=0}^h \gamma^t \left ( \mathbb{E_\pi} [R_{t+1}|S_0=s]-r(\pi)  \right )$

The average reward per step is $\frac{1}{3}$ so we can apply the same method used in exercise 10.6 where the elements inside the parentheses of the sum are: $\frac{2}{3}$ for $C \rightarrow A$ and $-\frac{1}{3}$ for the other two.  Starting in state A we transition twice and then on the third arrive in state A leading to the following mean corrected values of $-\frac{1}{3}$, $-\frac{1}{3}$, and $\frac{2}{3}$.  The other states will have these values cyclically permuted leading to the following infinite sums:

For state A:
$-\frac{1}{3} - \frac{1}{3}\gamma + \frac{2}{3}\gamma^2 - \frac{1}{3}\gamma^3 - \frac{1}{3}\gamma^4 + \cdots$

For state B:
$-\frac{1}{3} + \frac{2}{3}\gamma - \frac{1}{3}\gamma^2 - \frac{1}{3}\gamma^3 + \frac{2}{3}\gamma^4 + \cdots$

For state C:
$\frac{2}{3} - \frac{1}{3}\gamma - \frac{1}{3} \gamma^2 + \frac{2}{3}\gamma^3 + \cdots = 3 \times (2 - \gamma - \gamma^2 + 2\gamma^3 + \cdots)$

Comparing these sequences we have:

$\gamma \times v(A) = v(C) - \frac{2}{3} \implies v(A) = \frac{v(C) - \frac{2}{3}}{\gamma}$
$\gamma \times v(B) = v(A) + \frac{1}{3} \implies v(A) = \gamma \times v(B) - \frac{1}{3}$

so

$\frac{v(C) - \frac{2}{3}}{\gamma} = \gamma \times v(B) - \frac{1}{3} \implies v(C) = \gamma \left ( \gamma \times v(B) - \frac{1}{3} \right ) + \frac{2}{3}$

also 

$\gamma \times v(C) = v(B) + \frac{1}{3} \implies v(C) = \frac{v(B) + \frac{1}{3}}{\gamma}$

Equation the two sides for $v(C)$ that only contain $v(B)$ terms we have:

$\frac{v(B) + \frac{1}{3}}{\gamma} = \gamma \left ( \gamma \times v(B) - \frac{1}{3} \right ) + \frac{2}{3}$

$v(B) = \gamma \left ( \gamma \left ( \gamma \times v(B) - \frac{1}{3} \right ) + \frac{2}{3} \right ) - \frac{1}{3} = \gamma^3 v(B) - \gamma^2 \frac{1}{3} + \gamma\frac{2}{3} - \frac{1}{3}$

$v(B) \left ( 1 - \gamma^3 \right ) = - \gamma^2 \frac{1}{3} + \gamma\frac{2}{3} - \frac{1}{3} \implies v(B) = \frac{- \gamma^2 \frac{1}{3} + \gamma\frac{2}{3} - \frac{1}{3}}{1 - \gamma^3}$

$v(B) = -\frac{1}{3} \frac{\gamma^2 - 2\gamma + 1}{1 - \gamma^3} = -\frac{1}{3} \frac{(\gamma - 1)^2}{-(\gamma - 1)(\gamma^2 + \gamma + 1)} = \frac{1}{3} \frac{\gamma - 1}{\gamma^2 + \gamma + 1}$

Therefore, 

$\begin{flalign}
\lim_{\gamma \rightarrow 1} v(B) &= \frac{1}{3} \frac{1 - 1}{3} = 0 \\
\lim_{\gamma \rightarrow 1} v(A) &= \gamma \times 0 - \frac{1}{3} = -\frac{1}{3} \\
$\lim_{\gamma \rightarrow 1} v(C) &=  \frac{0 + \frac{1}{3}}{\gamma} = \frac{1}{3}
\end{flalign}$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$96548352-cd4d-4448-8312-ed10057f4359cell_id$96548352-cd4d-4448-8312-ed10057f4359codebegin
	function update_parameters!(parameters::Vector{Vector{T}}, i_s::Integer, i_a::Integer, g::T, α::T) where {T<:Real}
		q̂ = parameters[i_a][i_s]
		δ = (g - q̂)
		parameters[i_a][i_s] += α*δ
		return nothing
	end
	function update_parameters!(parameters::Matrix{T}, i_s::Integer, i_a::Integer, g::T, α::T) where {T<:Real}
		q̂ = parameters[i_s, i_a]
		δ = (g - q̂)
		parameters[i_s, i_a] += α*δ
		return nothing
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$ed1bd92c-8cc7-457f-9692-a10a9487c953cell_id$ed1bd92c-8cc7-457f-9692-a10a9487c953codeٿhtml"""
<style>
	main {
		margin: 0 auto;
		max-width: min(1600px, 90%);
		padding-left: max(10px, 5%);
		padding-right: max(10px, 5%);
		font-size: max(10px, min(24px, 2vw));
	}
</style>
"""metadatashow_logsèdisabled®skip_as_scriptëcode_folded$c9759bd9-ec9b-47a1-9080-a7fc332be565cell_id$c9759bd9-ec9b-47a1-9080-a7fc332be565codeٚdifferential_semi_gradient_q_learning!(args...; kwargs...) = differential_semi_gradient_sarsa!(args...; kwargs..., compute_value=compute_q_learning_value)metadatashow_logsèdisabled®skip_as_script«code_folded$953907cd-9926-4478-99b3-da7068118c22cell_id$953907cd-9926-4478-99b3-da7068118c22codefunction gradient_monte_carlo_action_episode_update!(parameters, update_parameters!::Function, states::AbstractVector{S}, actions::AbstractVector{A}, rewards::AbstractVector{T}, γ::T, α::T, update_args...) where {T<:Real, S, A}
	g = zero(T)
	l = length(states)
	for i in l:-1:1
		s = states[i]
		i_a = actions[i]
		g = γ * g + rewards[i]
		update_parameters!(parameters, s, i_a, g, α, update_args...)
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$278a26ac-c48f-4e18-93bb-706a4634c8c0cell_id$278a26ac-c48f-4e18-93bb-706a4634c8c0codemd"""
Two options to represent parameters for use with action-values is to simply have a unique set of parameters for each action each of which matches the size of the state representation vector.  Using this technique means we do not need to encode the action space into the representation.  The parameters could be represented by a vector of vectors or a matrix in which each column is assigned to an action.  Below are the update rules for both of these cases.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$8b7e1031-9864-439c-86eb-11aa08f53b90cell_id$8b7e1031-9864-439c-86eb-11aa08f53b90codefunction semi_gradient_double_sarsa!(parameters1::P, parameters2::P, mdp::StateMDP, γ::T, max_episodes::Integer, max_steps::Integer, estimate_value::Function, estimate_args::Tuple, update_parameters!::Function, update_args::Tuple; α = one(T)/10, ϵ = one(T) / 10, compute_value = compute_sarsa_value, nn_decay = false, kwargs...) where {P, T<:Real}
	s = mdp.initialize_state()
	i_a = rand(eachindex(mdp.actions))
	ep = 1
	step = 1
	epreward = zero(T)
	episode_rewards = Vector{T}()
	episode_steps = Vector{Int64}()
	action_values = zeros(T, length(mdp.actions))
	policy = zeros(T, length(mdp.actions))
	while (ep <= max_episodes) && (step <= max_steps)
		(r, s′) = mdp.ptf(s, i_a)
		epreward += r
		if rand() < 0.5
			update_params = parameters1
			select_params = parameters2
		end
		if mdp.isterm(s′)
			U_t = r
			s′ = mdp.initialize_state()
			i_a′ = rand(eachindex(mdp.actions))
			push!(episode_rewards, epreward)
			push!(episode_steps, step)
			epreward = zero(T)
			ep += 1
		else
			estimate_value(action_values, s′, select_params, estimate_args...)
			policy .= action_values
			make_ϵ_greedy_policy!(policy; ϵ = ϵ)
			i_a′ = sample_action(policy)
			estimate_value(action_values, s′, update_params, estimate_args...)
			q̂ = compute_value(action_values, policy, i_a′)
			U_t = r + γ*q̂
		end
		learning_rate = nn_decay ? T(1 - 0.999^step) : one(T)
		update_parameters!(update_params, s, i_a, U_t, α * learning_rate, update_args...)
		s = s′
		i_a = i_a′
		step += 1
	end
	return episode_rewards, episode_steps
endmetadatashow_logsèdisabled®skip_as_script«code_folded$d577b393-4b40-4c90-9993-4ffbcbd9df6dcell_id$d577b393-4b40-4c90-9993-4ffbcbd9df6dcode-const mountain_car_actions = [-1f0, 0f0, 1f0]metadatashow_logsèdisabled®skip_as_script«code_folded$5fdbce61-ca25-45e0-b07d-94adf7138446cell_id$5fdbce61-ca25-45e0-b07d-94adf7138446codeٰmountain_car_fcann = mountaincar_fcann_test(1_000_000, 8f-7, 0.05f0; num_layers = 3, layer_size = 16, compute_value = compute_sarsa_value, λ = 0f-4, c = 10f0, dropout = 0.0f0)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$49e43d51-05d6-415b-a685-76e50904c5bccell_id$49e43d51-05d6-415b-a685-76e50904c5bccodefunction mountaincar_differential_test(max_episodes::Integer, α::Float32, β::Float32, ϵ::Float32; num_tiles = 12, num_tilings = 8, kwargs...)
	setup = setup_mountain_car_tiles((1f0/num_tiles, 1f0/num_tiles), num_tilings)
	v = setup.args.feature_vector
	run_linear_differential_semi_gradient_sarsa(mountain_car_differential_mdp, max_episodes, typemax(Int64), zeros(Float32, length(v)), setup.args.feature_vector_update; α = α, β = β, ϵ = ϵ, kwargs...)
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$0f958535-6b18-46de-a1ba-81f64c217ee0cell_id$0f958535-6b18-46de-a1ba-81f64c217ee0code7function mountaincar_fcann_dp(max_episodes::Integer, α::Float32, ϵ::Float32; layers = [4, 4], max_steps = typemax(Int64), kwargs...)
	run_fcann_semi_gradient_dp(mountain_car_dist_mdp, 1f0, max_episodes, max_steps, zeros(Float32, 2), update_mountaincar_feature_vector!, layers; α = α, ϵ = ϵ, kwargs...)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$44d43dbf-fe32-438e-b89d-c677bbc35893cell_id$44d43dbf-fe32-438e-b89d-c677bbc35893codemd"""
In order to use (10.6): $r(\pi) \doteq \lim_{h \rightarrow \infty} \frac{1}{h} \sum_{t = 1}^h \mathbb{E} [R_t \mid S_0, A_{0:t-1} \sim \pi]$ we need to compute $\mathbb{E} [R_t \mid S_0, A_{0:t-1} \sim \pi]$.  In this case, we are told that regardless of the policy, the reward sequence will be +1, 0, +1, 0, ....  We can therefore replace the expected values in the equation with this sequence since the rewards at each time step are known with 100% probability.

the average reward can be computed as $r(\pi) = \lim_{h \rightarrow \infty} \frac{1}{2h}\sum_{t=1}^h (-1)^{t+1} + 1 = \lim_{h \rightarrow \infty} \frac{h}{2h} + \frac{1}{2h} \sum_{t=1}^h (-1)^{t+1}$

The sum left in the expression is $1 - 1 + 1 - 1 \cdots$ which is 1 for even h and 0 for odd h.  Either way, when divided by $2h$ that term goes to 0 leaving only the term $\frac{h}{2h} = \frac{1}{2}$ so $r(\pi) = \frac{1}{2}$

To compute the differential value function for state A and B, consider the alternative definition above using the fact that $r(\pi) = 0.5$.  

For state A, each parenthetical term in the sum will be: $1 - 0.5, 0 - 0.5, 1 - 0.5, 0 - 0.5, \dots = 0.5, -0.5, 0.5, -0.5, \dots$

For state B, each parenthetical term in the sum will be: $0 - 0.5, 1 - 0.5, 0 - 0.5, 1 - 0.5, \dots = -0.5, 0.5, -0.5, 0.5, \dots$

$\begin{flalign}
v_\pi (A) &= \lim_{\gamma \rightarrow 1} \lim_{h \rightarrow \infty} 0.5 - 0.5\gamma + 0.5 \gamma^2 - 0.5\gamma^3 + \cdots \\
&=0.5\lim_{\gamma \rightarrow 1} \lim_{h \rightarrow \infty}\sum_{t=0}^h (-\gamma)^t \\
&=0.5\lim_{\gamma \rightarrow 1}\frac{1}{\gamma +1 } = 0.25
\end{flalign}$

$\begin{flalign}
v_\pi (B) &= \lim_{\gamma \rightarrow 1} \lim_{h \rightarrow \infty} -0.5 + 0.5\gamma - 0.5 \gamma^2 + 0.5\gamma^3 + \cdots \\
&=-0.5\lim_{\gamma \rightarrow 1} \lim_{h \rightarrow \infty}\sum_{t=0}^h (-\gamma)^t \\
&=-0.5\lim_{\gamma \rightarrow 1}\frac{1}{\gamma +1 } = -0.25
\end{flalign}$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b3658e4d-ee8e-45cd-906a-06dd512a6921cell_id$b3658e4d-ee8e-45cd-906a-06dd512a6921codeـplot_mountaincar_values(mountaincar_fcann_dp_results.value_function, mountaincar_fcann_dp_results.π_greedy; n1 = 100, n2 = 100)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$00e7783f-7f17-4944-a085-ea87509cd75acell_id$00e7783f-7f17-4944-a085-ea87509cd75acodefunction run_fcann_semi_gradient_dp(mdp::StateMDP, γ::T, max_episodes::Integer, max_steps::Integer, state_representation::AbstractVector{T}, update_state_representation!::Function, layers::Vector{Int64}; λ = 0f0, c = Inf, dropout = 0f0, kwargs...) where T<:Real
	setup = fcann_gradient_setup(mdp, layers, state_representation, update_state_representation!; λ = λ, c = c, dropout = dropout)
	l = length(state_representation)
	num_actions = length(mdp.actions)
	episode_rewards, episode_steps = semi_gradient_dp!(setup.parameters, mdp, γ, max_episodes, max_steps, setup.value_function, setup.value_args, setup.parameter_update, setup.update_args; kwargs...)
	v̂(s) = setup.value_function(s, setup.parameters, setup.value_args...)
	function π_greedy(s)
		action_values = zeros(T, num_actions)
		for i_a in eachindex(action_values)
			(rewards, states, probabilities) = mdp.ptf.step(s, i_a)
			q = zero(T) 
			for i in eachindex(probabilities)
				v̂′ = !mdp.isterm(states[i])*v̂(states[i])
				q += probabilities[i]*(rewards[i] + γ*v̂′)
			end
			action_values[i_a] = q
		end
		make_greedy_policy!(action_values)
		i_a = sample_action(action_values)
	end
	return (value_function = v̂, π_greedy = π_greedy, reward_history = episode_rewards, step_history = episode_steps)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$5be866c3-0fb2-4d1f-9c31-b85aba332905cell_id$5be866c3-0fb2-4d1f-9c31-b85aba332905codeـsemi_gradient_q_learning!(args...; kwargs...) = semi_gradient_sarsa!(args...; kwargs..., compute_value=compute_q_learning_value)metadatashow_logsèdisabled®skip_as_script«code_folded$e5ad765a-341f-4f11-9ae8-37d81cb349d2cell_id$e5ad765a-341f-4f11-9ae8-37d81cb349d2code~const mountain_car_differential_transition = StateMDPTransitionSampler(mountain_car_differential_step, initialize_car_state())metadatashow_logsèdisabled®skip_as_scriptëcode_folded$8befede5-378a-447a-96bd-edcd9d2ce98bcell_id$8befede5-378a-447a-96bd-edcd9d2ce98bcodemd"""
We can use these to create a sampling transition function, although it will be deterministic.  The positions and velocities are still defined by two real numbers so the state space is unbounded and we cannot use a tabular method.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667cell_id$ae5c5377-8b44-4c82-a63c-d2cb8a0d6667code(q̂_mountain_car2_fcann, episode_rewards2_fcann, episode_steps2_fcann, average_step_reward_fcann) = mountaincar_fcann_differential_test(1_000_000, 1f-4, 0.001f0, 0.5f0; num_layers = 3, layer_size = 8, compute_value = compute_q_learning_value)metadatashow_logsèdisabled®skip_as_script«code_folded$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867fcell_id$f58cd0a2-8c82-46b2-bb8f-00f6aa1d867fcode5function update_input!(input::Matrix{Float32}, feature_vector::Vector{Float32}, i_a::Integer, num::Integer)
	l1 = length(feature_vector)
	l2 = size(input, 2)
	for i in eachindex(feature_vector)
		input[num, i] = feature_vector[i]
	end
	for i in l1+1:l2
		input[num, i] = 0f0
	end
	input[num, l1+i_a] = 1f0
endmetadatashow_logsèdisabled®skip_as_script«code_folded$065b2626-01f1-443f-8be4-3036003a2772cell_id$065b2626-01f1-443f-8be4-3036003a2772codeDfunction run_linear_differential_semi_gradient_sarsa(mdp::StateMDP, max_episodes::Integer, max_steps::Integer, state_representation::AbstractVector{T}, update_state_representation!::Function; setup_kwargs = NamedTuple(), kwargs...) where T<:Real
	setup = linear_features_action_gradient_setup(mdp, state_representation, update_state_representation!; setup_kwargs...)
	l = length(state_representation)
	num_actions = length(mdp.actions)
	# parameters = zeros(T, l, num_actions)
	parameters = [zeros(T, l) for _ in 1:num_actions]
	episode_rewards, episode_steps, average_step_reward = differential_semi_gradient_sarsa!(parameters, mdp, max_episodes, max_steps, setup.value_function, setup.value_args, setup.parameter_update, setup.update_args; kwargs...)
	q̂(s, i_a) = setup.value_function(s, i_a, parameters, setup.value_args...)
	action_values = zeros(T, num_actions)
	q̂(s) = setup.value_function(action_values, s, parameters, setup.value_args...)
	return (value_function = q̂, reward_history = episode_rewards, step_history = episode_steps, average_step_reward = average_step_reward)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$57ea3538-33be-4673-b914-8191d35426a9cell_id$57ea3538-33be-4673-b914-8191d35426a9codeiconst mountaincar_value_iteration = value_iteration_v(tabular_mountaincar_mdp, 1f0; save_history = false)metadatashow_logsèdisabled®skip_as_script«code_folded$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adbcell_id$2d7679ad-a9b3-448b-a4bc-7e5b9bce6adbcodemd"""
> ### *Exercise 10.8* 
> The pseudocode in the box on page 251 updates $\bar R_t$ using $\delta_t$ as an error rather than simply $R_{t+1} - \bar R_t$.  Both errors work, but using $\delta_t$ is better.  To see why, consider the ring MRP of three states from Exercise 10.7.  The estimate of the average reward should tend towards its true value of $\frac{1}{3}$.  Suppose it was already there and was held stuck there.  What would the sequence of $R_{t+1} - \bar R_t$ errors be?  What would the sequence of $\delta_t$ errors be (using Equation 10.10)?  Which error sequence would produce a more stable estimate of the average reward if the estimate were allowed to change in response to the errors? Why?

The sequence of $R_{t+1} - \bar R_t$ would be given by the cyclical sequence of rewards.  Let's assume we start the sequence at state A.  Then our reward sequence will be 0, 0, 1, 0, 0, 1... so the error sequence will be $-\frac{1}{3}$, $-\frac{1}{3}$, $\frac{2}{3}$,...  If we update the average error estimate using these corrections it would remain centered at the correct value but fluctuate up and down with each correction.

In order to calculate $\delta_t$ we must use the definition given by 10.10:

$\delta_t = R_{t+1} - \bar R_t + \hat v(S_{t+1}, \mathbf{w}_t) - \hat v(S_t, \mathbf{w}_t)$

This equation requires us to have value estimates for each state which we can assume have converged to the true values as we have for the average reward estimate: $\hat v(A) = -\frac{1}{3}$, $\hat v(B) = 0$, and $\hat v(C) = \frac{1}{3}$.  Starting at state A, $\delta_t = 0 - \frac{1}{3} + 0 - -\frac{1}{3} = 0$.  For the following state we have $0 - \frac{1}{3} + \frac{1}{3} = 0$.  Finally we have $1 - \frac{1}{3} + -\frac{1}{3} - \frac{1}{3} = 0$.  So if we use the TD error to update our average reward estimate, at equilibrium all the values will remain unchanged.  Using $\delta$ provides a lower variance estimator than simply using the reward.

"""metadatashow_logsèdisabled®skip_as_script«code_folded$425fe768-c7bb-4d3e-87e6-47fa052ba612cell_id$425fe768-c7bb-4d3e-87e6-47fa052ba612codeٷplot(scatter(y = (episode_steps2_fcann[2:findlast(!iszero, episode_steps2_fcann)] .- episode_steps2_fcann[1:findlast(!iszero, episode_steps2_fcann) - 1])), Layout(yaxis_type = "log"))metadatashow_logsèdisabled®skip_as_script«code_folded$06834750-cc3a-468a-b0c2-81349c288a33cell_id$06834750-cc3a-468a-b0c2-81349c288a33codefunction gradient_monte_carlo_control!(parameters, mdp::StateMDP, γ::T, num_episodes::Integer, value_function::Function, value_args::Tuple, update_parameters!::Function, update_args::Tuple; α = one(T)/10, ϵ = one(T)/10, suppress_warning = false, epkwargs...) where {T<:Real}
	action_values = zeros(T, length(mdp.actions))
	function π_ϵ_greedy(s)
		rand() < ϵ && return rand(eachindex(mdp.actions)) 
		value_function(action_values, s, parameters, value_args...)[2]
	end
	(states, actions, rewards, sterm, nsteps) = runepisode(mdp; epkwargs...)
	gradient_monte_carlo_action_episode_update!(parameters, update_parameters!, states, actions, rewards, γ, α, update_args...)
	if !suppress_warning && !mdp.isterm(sterm) 
		@info "Warning: Episode 1 did not conclude in $nsteps steps"
	end
	step_history = [nsteps]
	reward_history = [sum(rewards)]
	for ep in 2:num_episodes
		(states, actions, rewards, sterm, nsteps) = runepisode!((states, actions, rewards), mdp; π = π_ϵ_greedy, epkwargs...)
		gradient_monte_carlo_action_episode_update!(parameters, update_parameters!, view(states, 1:nsteps), view(actions, 1:nsteps), view(rewards, 1:nsteps), γ, α, update_args...)
		if !suppress_warning && !mdp.isterm(sterm) 
			@info "Warning: Episode $ep did not conclude in $nsteps steps"
		end
		push!(step_history, nsteps)
		push!(reward_history, sum(rewards[i] for i in 1:nsteps))
	end
	return step_history, reward_history
endmetadatashow_logsèdisabled®skip_as_script«code_folded$1054cfa3-9f58-4a93-a318-c2d21cf23220cell_id$1054cfa3-9f58-4a93-a318-c2d21cf23220codefunction show_mountaincar_trajectory(tabular_mountaincar_mdp, π::Matrix{T}, max_steps::Integer, name) where T<:Real
	state_indices, actions, rewards, sterm, nsteps = runepisode(tabular_mountaincar_mdp; π = π, max_steps = max_steps)
	states = [tabular_mountaincar_mdp.states[i_s] for i_s in state_indices]
	positions = [s[1] for s in states]
	velocities = [s[2] for s in states]
	tr1 = scatter(x = positions, y = velocities, mode = "markers", showlegend = false)
	tr2 = scatter(y = positions, showlegend = false)
	tr3 = scatter(y = [mountain_car_actions[i] for i in actions], showlegend = false)
	p1 = plot(tr1, Layout(xaxis_title = "position", yaxis_title = "velocity", xaxis_range = [-1.2, 0.5], yaxis_range = [-0.07, 0.07]))
	p2 = plot(tr2, Layout(xaxis_title = "time", yaxis_title = "position"))
	p3 = plot(tr3, Layout(xaxis_title = "time", yaxis_title = "action"))
	mdname = Markdown.parse(name)
	md"""
	$mdname
	Total Reward: $(sum(rewards))
	$([p1 p2 p3])
	"""
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$8ed6f8fd-8574-4d5a-9964-ce8a32629c6fcell_id$8ed6f8fd-8574-4d5a-9964-ce8a32629c6fcodeقcompute_expected_sarsa_value(action_values::Vector{T}, policy::Vector{T}, i_a::Integer) where T<:Real = dot(action_values, policy)metadatashow_logsèdisabled®skip_as_script«code_folded$f9abf433-8ce3-4520-9b47-f17f8f07b4cbcell_id$f9abf433-8ce3-4520-9b47-f17f8f07b4cbcode{const mountain_car_transition_distribution = StateMDPTransitionDistribution(mountain_car_dist_step, initialize_car_state())metadatashow_logsèdisabled®skip_as_script«code_folded$59ec5223-f23f-4f32-9e5f-8a08e450da85cell_id$59ec5223-f23f-4f32-9e5f-8a08e450da85codeTmd"""
## 10.2 Semi-gradient *n*-step Sarsa

We can obtain an $n$-step version of semi-gradient Sarsa by using an $n$-step return as the update target for the semi-gradient Sarsa update equation (10.1).  The $n$-step return immediately generalizes from its tabular form (7.4) to a function approximation form: 

$G_{t:t+n} \doteq R_{t+1} + \gamma R_{t+2} + \cdots + \gamma^{n-1}R_{t+n} + \gamma^n \hat q(S_{t+n}, A_{t+n}, \mathbf{w}_{t+n-1}), \quad t+n \lt T \tag{10.4}$

with $G_{t:t+n} \doteq G_t$ if $t+n \geq T$, as usual.  The $n$-step update equation is

$\mathbf{w}_{t+n} \doteq \mathbf{w}_{t+n-1} + \alpha \left [ G_{t:t+n} - \hat q(S_t, A_t, \mathbf{w}_{t+n-1}) \right ] \nabla \hat q(S_t, A_t, \mathbf{w}_{t+n-1}), \quad 0 \leq t \lt T \tag{10.5}$

As we have seen before, performance is often best with an $n$ that is some intermediate value between the 1-step sarsa method and Monte Carlo; however, we will not create a full implementation of this algorithm here as it will be replaced by semi-gradient Sarsa($\lambda$) in Chapter 12 which is a much more efficient version of the same concept.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$0c7f5742-6c51-4c6a-b67f-217163935ba5cell_id$0c7f5742-6c51-4c6a-b67f-217163935ba5codemd"""
> ### *Exercise 10.5* 
> What equations are needed (beyond 10.10) to specify the differential version of TD(0)?

10.10 includes a reward estimate at time t, $\bar R_t$, which also needs to be updated.  The TD error represents the newly observed reward the was experienced in excess of the estimated average so the update equation should move $\bar R$ in the direction of the TD error.  After each step, the following updates should occur.

$\begin{flalign}
\delta &\leftarrow R - \bar R + \hat v(S^\prime, \mathbf{w}) - \hat v(S, \mathbf{w}) \\
\bar R &\leftarrow \bar R + \beta \delta \\
\mathbf{w} &\leftarrow \mathbf{w} + \alpha \delta \nabla \hat v(S, \mathbf{w}) \\
S & \leftarrow S^\prime \\
\end{flalign}$
"""metadatashow_logsèdisabled®skip_as_script«code_folded$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efccell_id$c697e0b6-d3e4-4f5f-96e9-b9486c9d7efccodebegin
	fill_action_values!(action_values::Vector{T}, state_representation::AbstractVector{T}, parameters::Matrix{T}) where T<:Real = mul!(action_values, parameters', state_representation)

	function fill_action_values!(action_values::Vector{T}, state_representation::AbstractVector{T}, parameters::Vector{Vector{T}}) where T<:Real 
		@inbounds for i in eachindex(action_values)
			action_values[i] = dot(state_representation, parameters[i])
		end
	end
endmetadatashow_logsèdisabled®skip_as_script«code_folded$9fb5dace-a799-4424-bcb3-8542e508dd4bcell_id$9fb5dace-a799-4424-bcb3-8542e508dd4bcodeWusing PlutoUI,PlutoPlotly, PlutoProfile, BenchmarkTools, LaTeXStrings, HypertextLiteralmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$c1388562-0708-4a6a-acfe-927413dab5d2cell_id$c1388562-0708-4a6a-acfe-927413dab5d2code?plot(scatter(y = -episode_rewards), Layout(yaxis_type = "log"))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3cell_id$cbf1e5ed-8308-486e-a9b7-6cf7fb441fe3codexshow_mountaincar_trajectory(π_optimal_value_iteration, 1000, "Tabular Mountain Car Value Iteration Policy on True MDP")metadatashow_logsèdisabled®skip_as_script«code_folded$6cea9e69-bf8c-4079-9884-663a728d7b08cell_id$6cea9e69-bf8c-4079-9884-663a728d7b08codemd"""
# Dependencies
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b0cc6ff8-7296-461c-9db7-e52fa518e2e2cell_id$b0cc6ff8-7296-461c-9db7-e52fa518e2e2codefunction mountaincar_dist_test(max_episodes::Integer, α::Float32, ϵ::Float32; num_tiles = 24, num_tilings = 32, max_steps = typemax(Int64), kwargs...)
	setup = setup_mountain_car_tiles((1f0/num_tiles, 1f0/num_tiles), num_tilings)
	v = setup.args.feature_vector
	run_linear_semi_gradient_dp(mountain_car_dist_mdp, 1f0, max_episodes, max_steps, zeros(Float32, length(v)), setup.args.feature_vector_update; α = α, ϵ = ϵ, kwargs...)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$30ab21ba-3f5b-46a8-8b8c-753f2755d419cell_id$30ab21ba-3f5b-46a8-8b8c-753f2755d419codep(q̂_mountain_car, π_mountain_car, episode_rewards, episode_steps) = mountaincar_test(5000, 0.0001f0/8, 0.01f0)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$1478745a-634d-4f31-8a70-b74f0e536201cell_id$1478745a-634d-4f31-8a70-b74f0e536201codemd"""
Part of the Sarsa algorithm requires us to identify the maximizing action.  These functions update a vector of action-values using the parameters and state representation.  By computing all of the action values at once, the maximum can be identified, and these functions compute all the action values more efficiently than using the above function for each action individually.
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b07460f1-0461-4f63-b145-c4e1818a497ecell_id$b07460f1-0461-4f63-b145-c4e1818a497ecode(function mountain_car_step(s::Tuple{Float32, Float32}, i_a::Int64)
	a = mountain_car_actions[i_a]
	ẋ′ = clamp(s[2] + 0.001f0*a - 0.0025f0*cos(3*s[1]), -0.07f0, 0.07f0)
	x′ = clamp(s[1] + ẋ′, -1.2f0, 0.5f0)
	x′ == -1.2f0 && return (-1f0, (x′, 0f0))
	return (-1f0, (x′, ẋ′))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$a9b74949-9392-4048-bcb6-5fd48c1d9b98cell_id$a9b74949-9392-4048-bcb6-5fd48c1d9b98code:md"""
### Example 10.2: An Access-Control Queuing Task
"""metadatashow_logsèdisabled®skip_as_script«code_folded$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0cell_id$565c53ee-7ad5-44e2-bce5-4ff1f5f162c0code٢differential_semi_gradient_expected_sarsa!(args...; kwargs...) = differential_semi_gradient_sarsa!(args...; kwargs..., compute_value=compute_expected_sarsa_value)metadatashow_logsèdisabled®skip_as_script«code_folded$12f5065b-5bed-4d03-a0f0-72a942492394cell_id$12f5065b-5bed-4d03-a0f0-72a942492394codefunction make_tabular_mountaincar(N, M)
	x_range = (-1.2f0, 0.5f0)
	v_range = (-0.07f0, 0.07f0)
	x_vals = LinRange(x_range..., N) 
	v_vals = LinRange(v_range..., M) 
	states = [(x, v) for x in x_vals for v in v_vals]
	state_transition_map = zeros(Int64, length(mountain_car_actions), length(states))
	reward_transition_map = zeros(Float32, length(mountain_car_actions), length(states))

	#assign a state to the closest state in the list by euclidean distance
	d(x1, x2) = (x1 - x2)^2
	function bucket_state(s1)
		i_x = searchsortedfirst(x_vals, s1[1])
		i_v = searchsortedfirst(v_vals, s1[2])
		M*(i_x-1) + i_v
	end
	
	for (i_s, s) in enumerate(states)
		if s[1] == 0.5f0
			state_transition_map[:, i_s] .= i_s
			reward_transition_map[:, i_s] .= 0f0
		else
			for (i_a, a) in enumerate(mountain_car_actions)
				(r, s′) = mountain_car_step(s, i_a)
				i_s′ = bucket_state(s′)
				state_transition_map[i_a, i_s] = i_s′
				reward_transition_map[i_a, i_s] = r
			end
		end
	end

	init_state_index() = bucket_state(initialize_car_state())
	ptf = TabularDeterministicTransition(state_transition_map, reward_transition_map)
	(mdp = TabularMDP(states, mountain_car_actions, ptf, init_state_index), assign_state_index = bucket_state)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$4afbb723-340b-4d85-9115-027a0ff8dfadcell_id$4afbb723-340b-4d85-9115-027a0ff8dfadcode:plot_mountaincar_action_values(q̂_mountain_car, 500, 500)metadatashow_logsèdisabled®skip_as_scriptëcode_folded$00399548-b21c-43b5-90e2-30656ab1541ecell_id$00399548-b21c-43b5-90e2-30656ab1541ecode[plot(scatter(y = -mountaincar_fcann_dp_results.reward_history), Layout(yaxis_type = "log"))metadatashow_logsèdisabled®skip_as_scriptëcode_folded$c75dc51c-cbff-48b1-b0fd-108828929b51cell_id$c75dc51c-cbff-48b1-b0fd-108828929b51codeHfunction run_fcann_gradient_monte_carlo_control(mdp::StateMDP, γ::T, num_episodes::Integer, state_representation::AbstractVector{T}, update_state_representation!::Function, layers::Vector{Int64}; λ = 0f0, c = Inf, dropout = 0f0, kwargs...) where T<:Real
	setup = fcann_action_gradient_setup(mdp, layers, state_representation, update_state_representation!; λ = λ, c = c, dropout = dropout)
	num_actions = length(mdp.actions)
	step_history, reward_history = gradient_monte_carlo_control!(setup.parameters, mdp, γ, num_episodes, setup.value_function, setup.value_args, setup.parameter_update, setup.update_args; kwargs...)
	q̂(s, i_a) = setup.value_function(s, i_a, setup.parameters, setup.value_args...)
	action_values = zeros(Float32, num_actions)
	q̂(s) = setup.value_function(action_values, s, setup.parameters, setup.value_args...)
	π_greedy(s) = q̂(s)[2]
	π_ϵ_greedy(s, ϵ) = rand() < ϵ ? rand(eachindex(mdp.actions)) : π_greedy(s)
	return (value_function = q̂, π_greedy = π_greedy, π_ϵ_greedy = π_ϵ_greedy, step_history = step_history, reward_history = reward_history)
endmetadatashow_logsèdisabled®skip_as_script«code_folded$7a47a518-dfc7-4310-a0b5-6f0d151c8263cell_id$7a47a518-dfc7-4310-a0b5-6f0d151c8263code=md"""
### Neural Network Mountain Car Semi-gradient Sarsa
"""metadatashow_logsèdisabled®skip_as_script«code_folded$a22e5d34-4b8d-479c-985c-d6abd41a6c80cell_id$a22e5d34-4b8d-479c-985c-d6abd41a6c80code-md"""
### Example 10.1: Mountain Car Task
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b990ba67-42c8-4ab9-943d-085392204fddcell_id$b990ba67-42c8-4ab9-943d-085392204fddcode.md"""
#### Defining Car State and Dynamics
"""metadatashow_logsèdisabled®skip_as_script«code_folded$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4cell_id$7c5fb569-81f0-4b70-ae95-1fce0c51b6f4codefunction mountaincar_test(max_episodes::Integer, α::Float32, ϵ::Float32; num_tiles = 12, num_tilings = 8, kwargs...)
	setup = setup_mountain_car_tiles((1f0/num_tiles, 1f0/num_tiles), num_tilings)
	v = setup.args.feature_vector
	run_linear_semi_gradient_sarsa(mountain_car_mdp, 1f0, max_episodes, typemax(Int64), zeros(Float32, length(v)), setup.args.feature_vector_update; α = α, ϵ = ϵ, kwargs...)
endmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$0e3e506d-1959-47fd-8da9-b3dfd294be67cell_id$0e3e506d-1959-47fd-8da9-b3dfd294be67code;plot_mountaincar_action_values(q̂_mountain_car2, 500, 500)metadatashow_logsèdisabled®skip_as_script«code_folded$af97f222-08d1-4200-a10b-8da178182175cell_id$af97f222-08d1-4200-a10b-8da178182175code"md"""
#### Dynamic Programming
"""metadatashow_logsèdisabled®skip_as_script«code_folded$b5273dfa-2262-487a-856b-441f007bd163cell_id$b5273dfa-2262-487a-856b-441f007bd163codeq(1:nsamples |> Map(i -> runepisode(mountain_car_mdp; max_steps = 100_000)[5] == 100_000) |> foldxt(+)) / nsamplesmetadatashow_logsèdisabled®skip_as_scriptëcode_folded$b5409b69-a254-4355-b2b9-99394eceb2f7cell_id$b5409b69-a254-4355-b2b9-99394eceb2f7codeRshow_mountaincar_trajectory(π_mountain_car_q, 1_000, "Q-Learning Learned Policy")metadatashow_logsèdisabled®skip_as_scriptëcode_folded$b9ebd6bb-90a1-4945-85ed-023206e2420acell_id$b9ebd6bb-90a1-4945-85ed-023206e2420acodefunction linear_features_action_gradient_setup(problem::Union{StateMDP{T, S, A, P, F1, F2, F3}, StateMRP{T, S, P, F1, F2}}, state_representation::AbstractVector{T}, update_feature_vector!::Function) where {T<:Real, S, A, P, F1<:Function, F2<:Function, F3<:Function}
	s0 = problem.initialize_state()
	update_feature_vector!(state_representation, s0) #verify that feature vector update is compatible with provided state representation

	function update_params!(parameters::AbstractArray, s::S, i_a::Integer, g::T, α::T, state_representation::AbstractVector{T}) where T<:Real
		update_feature_vector!(state_representation, s)
		q̂ = calculate_action_value(state_representation, i_a, parameters)
		δ = (g - q̂)
		iszero(δ) && return nothing
		update_parameters!(parameters, state_representation, i_a, α, δ)
		return nothing
	end
	
	function q̂(s::S, i_a::Integer, parameters::AbstractArray, state_representation::AbstractVector{T}) where {T<:Real} 
		update_feature_vector!(state_representation, s)
		calculate_action_value(state_representation, i_a, parameters)
	end

	function q̂(action_values::Vector{T}, s::S, parameters::AbstractArray, state_representation::AbstractVector{T}) where {T<:Real} 
		update_feature_vector!(state_representation, s)
		fill_action_values!(action_values, state_representation, parameters)
		findmax(action_values)
	end
	
	return (value_function = q̂, value_args = (state_representation,), parameter_update = update_params!, update_args = (copy(state_representation),))
endmetadatashow_logsèdisabled®skip_as_script«code_folded$d0cf3806-05c6-4a50-94c8-55c9042d51b7cell_id$d0cf3806-05c6-4a50-94c8-55c9042d51b7codew(v̂_mountain_car, π_greedy_dp, episode_rewards_dp, episode_steps_dp) = mountaincar_dist_test(100, 0.001f0/32, 0.01f0)metadatashow_logsèdisabled®skip_as_scriptëcode_folded«notebook_id$68039796-8c6b-11ef-1217-bf750534f606in_temp_dir¨metadata