diff --git a/class01/Manifest.toml b/class01/Manifest.toml index e7e2df9..7cb5daa 100644 --- a/class01/Manifest.toml +++ b/class01/Manifest.toml @@ -797,9 +797,9 @@ version = "2.84.3+0" [[deps.GracefulPkg]] deps = ["Compat", "Pkg", "TOML"] -git-tree-sha1 = "eee0ecee0391689c354c03aadc77018ee7bb85fc" +git-tree-sha1 = "698050b04f3cc0906d0817329d6e96484bf238eb" uuid = "828d9ff0-206c-6161-646e-6576656f7244" -version = "2.2.1" +version = "2.3.0" [[deps.Graphics]] deps = ["Colors", "LinearAlgebra", "NaNMath"] @@ -843,10 +843,10 @@ uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" version = "8.5.1+0" [[deps.HiGHS]] -deps = ["HiGHS_jll", "MathOptInterface", "PrecompileTools", "SparseArrays"] -git-tree-sha1 = "2aab56d4e161be93c44fc16dfc95940996f84a12" +deps = ["HiGHS_jll", "MathOptIIS", "MathOptInterface", "PrecompileTools", "SparseArrays"] +git-tree-sha1 = "3fae2ee8d6ea22009532d5919ff592fcbcab0ad9" uuid = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" -version = "1.18.2" +version = "1.19.0" [[deps.HiGHS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Zlib_jll"] @@ -1192,9 +1192,9 @@ version = "3.1.1+0" [[deps.JuMP]] deps = ["LinearAlgebra", "MacroTools", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays"] -git-tree-sha1 = "b4da175208e462c5b380f5b4d43dc9101d12c55c" +git-tree-sha1 = "d05a696a5abaf9d1f8bce948ee53ed1533fadfdb" uuid = "4076af6c-e467-56ae-b986-b466b2749572" -version = "1.27.0" +version = "1.28.0" [deps.JuMP.extensions] JuMPDimensionalDataExt = "DimensionalData" @@ -1459,11 +1459,17 @@ git-tree-sha1 = "f7d73634acd573bf3489df1ee0d270a5d6d3a7a3" uuid = "736d6165-7244-6769-4267-6b50796e6954" version = "0.1.2" +[[deps.MathOptIIS]] +deps = ["MathOptInterface"] +git-tree-sha1 = "31d4a6353ea00603104f11384aa44dd8b7162b28" +uuid = "8c4f8055-bd93-4160-a86b-a0c04941dbff" +version = "0.1.1" + [[deps.MathOptInterface]] deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON3", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test"] -git-tree-sha1 = "1251fce78b907fe415a2f680291b67cf51360d2a" +git-tree-sha1 = "ce5a316de39941da67730ffec38e5396f7504853" uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.42.0" +version = "1.42.1" [[deps.MathTeXEngine]] deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] @@ -1767,9 +1773,9 @@ version = "0.8.21" [[deps.PlotlyJS]] deps = ["Base64", "Blink", "DelimitedFiles", "JSExpr", "JSON", "Kaleido_jll", "Markdown", "Pkg", "PlotlyBase", "PlotlyKaleido", "REPL", "Reexport", "Requires", "WebIO"] -git-tree-sha1 = "b816b0f301b074e002476159a9ada5691eebaf61" +git-tree-sha1 = "287e092914da6c91f002aafcf82a2ec065bf94a3" uuid = "f0f68f2c-4968-5e81-91da-67840de0976a" -version = "0.18.16" +version = "0.18.17" [deps.PlotlyJS.extensions] CSVExt = "CSV" @@ -1823,15 +1829,15 @@ version = "1.2.1" [[deps.PlutoTeachingTools]] deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] -git-tree-sha1 = "537c439831c0f8d37265efe850ee5c0d9c7efbe4" +git-tree-sha1 = "d0f6e09433d14161a24607268d89be104e743523" uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" -version = "0.4.1" +version = "0.4.4" [[deps.PlutoUI]] deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] -git-tree-sha1 = "ec9e63bd098c50e4ad28e7cb95ca7a4860603298" +git-tree-sha1 = "2d7662f95eafd3b6c346acdbfc11a762a2256375" uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" -version = "0.7.68" +version = "0.7.69" [[deps.PolyesterWeave]] deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] @@ -2201,9 +2207,9 @@ version = "1.2.0" [[deps.SimpleTraits]] deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.4" +version = "0.9.5" [[deps.SimpleWeightedGraphs]] deps = ["Graphs", "LinearAlgebra", "Markdown", "SparseArrays"] @@ -2222,9 +2228,9 @@ uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.1" +version = "1.2.2" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] @@ -2299,9 +2305,9 @@ version = "1.7.1" [[deps.StatsBase]] deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "b81c5035922cc89c2d9523afc6c54be512411466" +git-tree-sha1 = "2c962245732371acd51700dbb268af311bddd719" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.5" +version = "0.34.6" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] @@ -2369,10 +2375,10 @@ uuid = "19f23fe9-fdab-4a78-91af-e7b7767979c3" version = "0.2.2" [[deps.SymbolicUtils]] -deps = ["AbstractTrees", "ArrayInterface", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "ExproniconLite", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TaskLocalValues", "TermInterface", "TimerOutputs", "Unityper", "WeakValueDicts"] -git-tree-sha1 = "fa63e8f55e99aee528951ba26544403b09645979" +deps = ["AbstractTrees", "ArrayInterface", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "ExproniconLite", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TaskLocalValues", "TermInterface", "TimerOutputs", "Unityper"] +git-tree-sha1 = "cb2beb85947c0a894efa345c436edad20ecec977" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" -version = "3.29.0" +version = "3.30.0" [deps.SymbolicUtils.extensions] SymbolicUtilsLabelledArraysExt = "LabelledArrays" @@ -2384,9 +2390,9 @@ version = "3.29.0" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "LaTeXStrings", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "OffsetArrays", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "6eac6fe46d0e0f21baebc87d97dc118827737e05" +git-tree-sha1 = "6feaa0f2eb9728a6089ad81e31bf7539d41c8a30" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.48.1" +version = "6.49.0" [deps.Symbolics.extensions] SymbolicsD3TreesExt = "D3Trees" @@ -2520,9 +2526,9 @@ version = "0.4.1" [[deps.Unitful]] deps = ["Dates", "LinearAlgebra", "Random"] -git-tree-sha1 = "d2282232f8a4d71f79e85dc4dd45e5b12a6297fb" +git-tree-sha1 = "6258d453843c466d84c17a58732dda5deeb8d3af" uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "1.23.1" +version = "1.24.0" weakdeps = ["ConstructionBase", "ForwardDiff", "InverseFunctions", "Printf"] [deps.Unitful.extensions] @@ -2566,11 +2572,6 @@ git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" version = "1.24.0+0" -[[deps.WeakValueDicts]] -git-tree-sha1 = "98528c2610a5479f091d470967a25becfd83edd0" -uuid = "897b6980-f191-5a31-bcb0-bf3c4585e0c1" -version = "0.1.0" - [[deps.WebIO]] deps = ["AssetRegistry", "Base64", "Distributed", "FunctionalCollections", "JSON", "Logging", "Observables", "Pkg", "Random", "Requires", "Sockets", "UUIDs", "WebSockets", "Widgets"] git-tree-sha1 = "0eef0765186f7452e52236fa42ca8c9b3c11c6e3" diff --git a/class01/background_materials/basics_math.jl b/class01/background_materials/math_basics.jl similarity index 99% rename from class01/background_materials/basics_math.jl rename to class01/background_materials/math_basics.jl index 806bb36..7f4d100 100644 --- a/class01/background_materials/basics_math.jl +++ b/class01/background_materials/math_basics.jl @@ -7,6 +7,7 @@ using InteractiveUtils # ╔═╡ 9fffca86-aec9-4c26-bced-3edaa1af9a22 begin using Pkg; Pkg.activate("..") +Pkg.instantiate() end # ╔═╡ 00cc1e5e-f10e-4559-b9d9-8aba44eb493e diff --git a/class01/background_materials/optimization_homework.jl b/class01/background_materials/optimization_basics.jl similarity index 99% rename from class01/background_materials/optimization_homework.jl rename to class01/background_materials/optimization_basics.jl index b83001c..6e6589e 100644 --- a/class01/background_materials/optimization_homework.jl +++ b/class01/background_materials/optimization_basics.jl @@ -7,6 +7,7 @@ using InteractiveUtils # ╔═╡ 881eed45-e7f0-4785-bde8-530e378d7050 begin using Pkg; Pkg.activate("..") +Pkg.instantiate() end # ╔═╡ 9f5675a3-07df-4fb1-b683-4c5fd2a85002 diff --git a/class01/Optimization.jl b/class01/background_materials/optimization_motivation.jl similarity index 85% rename from class01/Optimization.jl rename to class01/background_materials/optimization_motivation.jl index b9360cc..ce98b92 100644 --- a/class01/Optimization.jl +++ b/class01/background_materials/optimization_motivation.jl @@ -7,7 +7,7 @@ using InteractiveUtils # ╔═╡ f0c826c7-b2e3-4dbf-b29d-37623aa4d7c6 begin import Pkg - Pkg.activate(".") + Pkg.activate("..") Pkg.status() end @@ -110,8 +110,8 @@ begin for (ri,y) in enumerate(h_cs), (ci,x) in enumerate(v_cs) global vid # skip the outer frame - if !(ri == n_rows -5 && ci == 4) - if ri <= 27 || ri >= n_rows - 3 || ci <= 6 || ci >= n_cols - 3 + if !(ri == n_rows -5 && ci ==3) + if ri <= 25 || ri >= n_rows - 4 || ci <= 8 || ci >= n_cols - 2 continue end end @@ -129,7 +129,12 @@ begin end @info "Vertices = $(nv(g)) | Edges = $(ne(g))" - add_edge!(g, 211, 212) + # add entrance + add_edge!(g, 173, 174) + + # TODO: Automate ensure connectivity + add_edge!(g, 104, 83) + add_edge!(g, 104, 105) overlay_img = overlay(img, h_cs, v_cs, verts) end @@ -167,7 +172,7 @@ begin sort(sel) end - function overlay_items(img_rgb, hcs, vcs, verts, list, start_node=211, end_node=102; dot_half = 3, fade::Float64 = 0.40, gradc=false + function overlay_items(img_rgb, hcs, vcs, verts, list, start_node=173, end_node=46; dot_half = 3, fade::Float64 = 0.40, gradc=false ) grey = RGB.(Gray.(img_rgb)) ol = map(c -> RGB((1 - fade) * c.r + fade, @@ -253,7 +258,7 @@ Date: 28 of July, 2025 # ╔═╡ 01c44cc2-68d5-11f0-2860-05c9ffbde13a md"# Decisions Decisions: A Path to optimality -Once upon a time, a boy named **Pedro Paulo** 🤵 loved **Costco** supermarket 🛒. However, everytime there, he spendt more time ⏱️ and money 💸 than needed. +Once upon a time, a boy named **Pedro Paulo** 🤵 loved shopping at his local supermarket 🛒. However, everytime there, he spendt more time ⏱️ and money 💸 than needed. Let's help Pedro out! " @@ -261,7 +266,7 @@ Let's help Pedro out! # ╔═╡ 8d0fe751-aeb1-4ad1-a076-4c7bcd863a55 md"## Problem Setting -After some investigation, we got a hold of a real Costco layout! 🎉🎉 🗺️ 🎉🎉 +After some investigation, we got a hold of the market layout! 🎉🎉 🗺️ 🎉🎉 " # ╔═╡ 9eb11624-17db-438e-86e4-77b313da268b @@ -360,7 +365,7 @@ begin end # ╔═╡ 8705f186-8af4-4f6b-bb53-c3fa46d0b8ba -function greedy_tour(list, dist; start_node=211, end_node=102) +function greedy_tour(list, dist; start_node=173, end_node=46) tour = [start_node] remaining = Set([list[1:end]; end_node]) while !isempty(remaining) @@ -430,7 +435,7 @@ question_box(md"### How to model it as an integer programing problem?") # ╔═╡ acb9d0fd-c024-44b7-b549-78875068050f begin - nverts=length(verts); nitems=length(plist);start_node=211;end_node=102; + nverts=length(verts); nitems=length(plist);start_node=173;end_node=46; md""" #### What we have: @@ -476,41 +481,16 @@ begin # BASIC SETS _V = vertices(g) _A = [(u,v) for e in edges(g) for (u,v) in ((src(e),dst(e)), (dst(e),src(e)))] - _s, _e = 211, 102 # start, end + _s, _e = 173, 46 # start, end _items = setdiff(Set(plist), [_s,_e]) K = length(_items) + 1 # units of flow we must deliver # MODEL model = Model(HiGHS.Optimizer) - @variable(model, x[_A], Bin) - @variable(model, 0 ≤ f[_A] ≤ K) - - out(v) = sum(x[(v,w)] for w in _V if (v,w) in _A) - inn(v) = sum(x[(u,v)] for u in _V if (u,v) in _A) - fout(v) = sum(f[(v,w)] for w in _V if (v,w) in _A) - finn(v) = sum(f[(u,v)] for u in _V if (u,v) in _A) - - ## degree / balance - @constraint(model, out(_s) - inn(_s) == 1) # Costco Entrance - @constraint(model, inn(_e) - out(_e) == 1) # Payment Exit - @constraint(model, [i in _items], inn(i) ≥ 1) # Pick up items - @constraint(model, [i in _items], out(i) ≥ 1) - @constraint(model, [v in setdiff(_V, [_s,_e])], inn(v) == out(v)) - - ## multi-unit single-commodity flow - @constraint(model, [a in _A], f[a] ≤ K * x[a]) # deactivate on unused arcs - - @constraint(model, fout(_s) - finn(_s) == K) # source injects K units - @constraint(model, finn(_e) - fout(_e) == 1) # _e ‘consumes’ one unit - @constraint(model, [i in _items], finn(i) - fout(i) == 1) # each item consumes 1 - @constraint(model, [v in setdiff(_V, [_s,_e] ∪ _items)], - fout(v) == finn(v)) # pure transshipment elsewhere - - ## objective - @objective(model, Min, sum(D[u,v] * x[(u,v)] for (u,v) in _A)) - - optimize!(model) + # Write your Model Here + + itinerary_answer = missing # replace missing with the optimal itinerary end # ╔═╡ 8e507678-5d40-4a44-9aac-5701cc27f8ad @@ -534,45 +514,15 @@ A[i,j] = ") -# ╔═╡ f7dc2333-d85f-44d7-bd5e-2f497a23f32b -function euler!(adj, start) - st=[start]; path=Int[] - while !isempty(st) - u = st[end] - if isempty(get(adj,u,Int[])) - push!(path, pop!(st)) - else - push!(st, pop!(adj[u])) # consume arc once - end - end - reverse(path) # ends at _e by construction -end - -# ╔═╡ 7db1a83c-0100-4b6b-a97b-a7d59520dc22 -begin - adj = Dict{Int,Vector{Int}}() - for (u,v) in _A - if value(x[(u,v)]) > 0.5 - push!(get!(adj,u,Int[]), v) - end - end - itinerary_answer = euler!(deepcopy(adj), _s) - @assert itinerary_answer[1] == _s && itinerary_answer[end] == _e - itinerary_answer -end - -# ╔═╡ 1c527fc1-f4fd-4a59-8f0b-63413b1bea56 -# itinerary_answer = missing # replace with your answer - # ╔═╡ f5faca5f-abc3-49f1-add5-385de0ddb5b7 begin if ismissing(itinerary_answer) still_missing() else length_walk = itinerary_distance(itinerary_answer, D) - if length_walk <= 312 + if length_walk <= 312 && itinerary_answer[1] == _s && itinerary_answer[end] == _e correct(md" $(round(length_walk)) meters. You have found the optimal path!") - elseif length_walk <= total_length + elseif length_walk <= total_length && itinerary_answer[1] == _s && itinerary_answer[end] == _e almost(md" $(round(length_walk)) meters. Nice you have beaten the greedy algorithm! But there is still room for improvement.") else keep_working(md" $(round(length_walk)) meters. You should at least beat the greedy algorithm. I thrust in you!") @@ -580,13 +530,26 @@ begin end end +# ╔═╡ f7dc2333-d85f-44d7-bd5e-2f497a23f32b +function euler!(adj, start) + st=[start]; path=Int[] + while !isempty(st) + u = st[end] + if isempty(get(adj,u,Int[])) + push!(path, pop!(st)) + else + push!(st, pop!(adj[u])) # consume arc once + end + end + reverse(path) # ends at _e by construction +end + # ╔═╡ 5de8429f-349d-4441-90b4-6f7caaf6b5e4 if !ismissing(itinerary_answer) overlay_items(img, h_cs, v_cs, verts, full_itinerary; gradc=true) -end - -# ╔═╡ e7cc612d-fc6a-4976-89b2-821064dc612c -still_missing() +else + still_missing() +end # ╔═╡ e04cfe19-5827-4bf2-8183-a13bad579497 md"## Now Let's get a bit crazy! @@ -620,19 +583,7 @@ begin end # ╔═╡ 6ab03a08-6cda-4f35-bd80-e0ace02b86b5 -Foldable(md"#### Can we know the position of Pedro and his cart at any given moment?", md""" - -```math -x[t+1] = x[t] + \dot{x}[t] * \Delta_t -``` -```math -\dot{x}[t] = \dot{x}[t-1] + \ddot{x} -``` - -""") - -# ╔═╡ e4baeff0-f380-4269-9818-9fc43c1f802d - +question_box(md"#### Can we know the position of Pedro and his cart at any given moment?") # ╔═╡ f31d8852-ca07-46c9-bbea-5dd8f476c25c md"## References" @@ -651,9 +602,6 @@ begin ) end -# ╔═╡ 2e57bcd7-af6a-4813-8a2a-f7a71752a2de - - # ╔═╡ Cell order: # ╟─f0c826c7-b2e3-4dbf-b29d-37623aa4d7c6 # ╟─054eb7cf-cb60-41a0-9a87-215e36dcf53d @@ -684,20 +632,15 @@ end # ╟─083ddea0-f1db-46ef-b82c-5e10499bfb9d # ╠═7c889414-b9c4-477d-8e57-79ee1518dc8c # ╟─8e507678-5d40-4a44-9aac-5701cc27f8ad -# ╠═f7dc2333-d85f-44d7-bd5e-2f497a23f32b -# ╠═7db1a83c-0100-4b6b-a97b-a7d59520dc22 -# ╠═1c527fc1-f4fd-4a59-8f0b-63413b1bea56 # ╟─f5faca5f-abc3-49f1-add5-385de0ddb5b7 +# ╟─f7dc2333-d85f-44d7-bd5e-2f497a23f32b # ╟─5de8429f-349d-4441-90b4-6f7caaf6b5e4 -# ╠═e7cc612d-fc6a-4976-89b2-821064dc612c # ╟─e04cfe19-5827-4bf2-8183-a13bad579497 # ╟─263969f2-5e0f-4d7b-9b42-eb033861e4e9 # ╟─bf94beb1-f5c9-45b0-a864-94f773a3c198 # ╟─85f6ac91-bcc7-44de-948c-5a631a82c846 # ╠═bcaf8412-964e-4d79-8db8-d69754fe4b83 # ╠═c0cdf191-5350-4738-882f-8ded20168dbb -# ╠═6ab03a08-6cda-4f35-bd80-e0ace02b86b5 -# ╠═e4baeff0-f380-4269-9818-9fc43c1f802d +# ╟─6ab03a08-6cda-4f35-bd80-e0ace02b86b5 # ╟─f31d8852-ca07-46c9-bbea-5dd8f476c25c # ╟─178c6168-b515-4220-b37f-2c31b34e045c -# ╠═2e57bcd7-af6a-4813-8a2a-f7a71752a2de diff --git a/class01/class01.md b/class01/class01.md index 9290bed..7a68712 100644 --- a/class01/class01.md +++ b/class01/class01.md @@ -64,12 +64,19 @@ julia> Pluto.run() #### Step 5: Opening an existing notebook file -To run a local notebook file that you have not opened before, then you need to enter its full path (e.g. `path/to/basics_math.jl`) into the blue box in the main menu. +To run a local notebook file that you have not opened before, then you need to enter its full path (e.g. `path/to/math_basics.jl`) into the blue box in the main menu. ### **Linear Algebra**: -We have prepared a basic (Pluto) [Linear Algebra Primer](https://learningtooptimize.github.io/LearningToControlClass/dev/class01/background_materials/basics_math.html) to help you brush up on essential concepts. This primer covers key topics such as matrix operations, eigenvalues, and eigenvectors besides other fundamental calculus concepts. It is recommended to review this primer before the first class. +We have prepared a basic (Pluto) [Linear Algebra Primer](https://learningtooptimize.github.io/LearningToControlClass/dev/class01/background_materials/math_basics.html) to help you brush up on essential concepts. This primer covers key topics such as matrix operations, eigenvalues, and eigenvectors besides other fundamental calculus concepts. It is recommended to review this primer before the first class. ### **Optimization**: We will use JuMP for some optimization tasks. If you are new to JuMP, please review the [JuMP Tutorial](https://jump.dev/JuMP.jl/stable/tutorials/getting_started/getting_started_with_JuMP/) to familiarize yourself with its syntax and capabilities. -Test your knowledge with this (Pluto) [Modeling Exercise](https://learningtooptimize.github.io/LearningToControlClass/dev/class01/background_materials/optimization_homework.html). +Test your knowledge with this (Pluto) [Modeling Exercise](https://learningtooptimize.github.io/LearningToControlClass/dev/class01/background_materials/optimization_basics.html). + +*Final 🧠*: The (Pluto) [Motivational Exercise](https://learningtooptimize.github.io/LearningToControlClass/dev/class01/background_materials/optimization_motivation.html) will test what you have learned and motivate what we will research in the course. + +## In-Class Material + +Besides the administrative topics, we will cover the structure of the problem we are trying to solve and start with the basics of how to model it. +The main (Pluto) [Class 01 Notebook](https://learningtooptimize.github.io/LearningToControlClass/dev/class01/class01_intro.html) contains the in-class material. \ No newline at end of file diff --git a/class01/Dynamics.jl b/class01/class01_intro.jl similarity index 89% rename from class01/Dynamics.jl rename to class01/class01_intro.jl index 6fe176c..f63d4da 100644 --- a/class01/Dynamics.jl +++ b/class01/class01_intro.jl @@ -20,6 +20,7 @@ end begin import Pkg Pkg.activate(".") + Pkg.instantiate() # Pkg.status() using PlutoUI using Random @@ -38,11 +39,89 @@ using ForwardDiff # ╔═╡ ec473e69-d5ec-4d6a-b868-b89dadb85705 ChooseDisplayMode() +# ╔═╡ 1f774f46-d57d-4668-8204-dc83d50d8c94 +md"# Intro - Optimal Control and Learning + +In this course, we are interested in problems with the following structure: + +```math +\begin{equation} +\!\!\!\!\!\!\!\!\min_{\substack{(\mathbf y_1,\mathbf x_1)\\\mathrm{s.t.}}} +\!\underset{% + \phantom{\substack{(\mathbf y_1,\mathbf x_1)\\\mathrm{s.t.}}}% + \!\!\!\!\!\!\!\!\!\!(\mathbf y_1,\mathbf x_1)\in\mathcal X_1(\mathbf x_0)% +}{% + \!\!\!\!f(\mathbf x_1,\mathbf y_1)% +} ++\mathbb{E}_1\Bigl[ + \quad \cdots + + \;+\;\mathbb{E}_t\Bigl[ + \min_{\substack{(\mathbf y_t,\mathbf x_t)\\\mathrm{s.t.}}} + \!\underset{% + \phantom{\substack{(\mathbf y_t,\mathbf x_t)\\\mathrm{s.t.}}}% + \!\!\!\!(\mathbf y_t,\mathbf x_t)\in\mathcal X_t(\mathbf x_{t-1},w_t)% + }{% + \!\!\!\!\!\!\!\!\!\!f(\mathbf x_t,\mathbf y_t)% + } + +\mathbb{E}_{t+1}[\cdots] +\Bigr]. +\end{equation} +``` +which minimizes a first stage cost function $f(\mathbf{x}_1, +\mathbf{y}_1)$ and the expected value of future costs over possible +values of the exogenous stochastic variable $\{w_{t}\}_{t=2}^{T} \in +\Omega$. + +Here, $\mathbf{x}_0$ is the initial system state and the +control decisions $\mathbf{y}_t$ are obtained at every period $t$ +under a feasible region defined by the incoming state +$\mathbf{x}_{t-1}$ and the realized uncertainty $w_t$. $\mathbf{E}_t$ represents the expected value over future uncertainties $\{w_{\tau}\}_{\tau=t}^{T}$. This +optimization program assumes that the system is entirely defined by +the incoming state, a common modeling choice in many frameworks (e.g., +MDPs). This is without loss of generality, +since any information can be appended in the state. The system +constraints can be generally posed as: + +```math +\begin{align} + &\mathcal{X}_t(\mathbf{x}_{t-1}, w_t)= + \begin{cases} + \mathcal{T}(\mathbf{x}_{t-1}, w_t, \mathbf{y}_t) = \mathbf{x}_t \\ + h(\mathbf{x}_t, \mathbf{y}_t) \geq 0 + \end{cases} +\end{align} +``` +" + +# ╔═╡ a0f71960-c97c-40d1-8f78-4b1860d2e0a2 +md""" +where the outgoing state of the system $\mathbf{x}_t$ is a +transformation based on the incoming state, the realized uncertainty, +and the control variables. $h(\mathbf{x}_t, \mathbf{y}_t) \geq 0$ +captures the state constraints. Markov Decision Process (MDPs) refer +to $\mathcal{T}$ as the "transition kernel" of the system. State and +control variables are restricted further by additional constraints +captured by $h(\mathbf{x}_t, \mathbf{y}_t) \geq 0$. We +consider policies that map the past information into decisions. In +period $t$, an optimal policy is given by the solution of the dynamic +equations: + +```math +\begin{align} + V_{t}(\mathbf{x}_{t-1}, w_t) = &\min_{\mathbf{x}_t, \mathbf{y}_t} \quad \! \! f(\mathbf{x}_t, \mathbf{y}_t) + \mathbf{E}[V_{t+1}(\mathbf{x}_t, w_{t+1})] \\ + & \text{ s.t. } \quad\mathbf{x}_t = \mathcal{T}(\mathbf{x}_{t-1}, w_t, \mathbf{y}_t) \nonumber \\ + & \quad \quad \quad \! \! h(\mathbf{x}_t, \mathbf{y}_t) \geq 0. \nonumber +\end{align} +``` +""" + # ╔═╡ 52005382-177b-4a11-a914-49a5ffc412a3 -md"# 101 (Continuous-Time) Dynamics -#### A Crash Course +section_outline(md"A Crash Course:",md" (Continuous-Time) Dynamics +") -General form for a smooth system: +# ╔═╡ 8ea866a6-de0f-4812-8f59-2aebec709243 +md"General form for a smooth system: ```math \dot{x} = f(x,u) \quad \text{First-Order Ordinary Differential Equation (ODE)} @@ -56,7 +135,6 @@ u \in \mathbb{R}^{m} & \text{Control} \\ \dot{x} \in \mathbb{R}^{n} & \text{Time derivative of } x \\ \end{cases} ``` - " # ╔═╡ 2be161cd-2d4c-4778-adca-d45f8ab05f98 @@ -951,7 +1029,10 @@ end # ╔═╡ Cell order: # ╟─13b12c00-6d6e-11f0-3780-a16e73360478 # ╟─ec473e69-d5ec-4d6a-b868-b89dadb85705 +# ╟─1f774f46-d57d-4668-8204-dc83d50d8c94 +# ╟─a0f71960-c97c-40d1-8f78-4b1860d2e0a2 # ╟─52005382-177b-4a11-a914-49a5ffc412a3 +# ╟─8ea866a6-de0f-4812-8f59-2aebec709243 # ╟─2be161cd-2d4c-4778-adca-d45f8ab05f98 # ╟─b452ee52-ee33-44ad-a980-6a6e90954ee1 # ╟─9f62fae9-283c-44c3-8d69-29bfa90faf29 diff --git a/class01/layout.png b/class01/layout.png index 8760d12..acf1bee 100644 Binary files a/class01/layout.png and b/class01/layout.png differ diff --git a/docs/make.jl b/docs/make.jl index 98cf4e0..272ece5 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -7,7 +7,10 @@ repo_dir = dirname(@__DIR__) build_dir = joinpath(repo_dir, "docs", "build") plutos = [ - joinpath(repo_dir, "class01", "background_materials", "basics_math.jl"), + joinpath(repo_dir, "class01", "background_materials", "math_basics.jl"), + joinpath(repo_dir, "class01", "background_materials", "optimization_basics.jl"), + joinpath(repo_dir, "class01", "background_materials", "optimization_motivation.jl"), + joinpath(repo_dir, "class01", "class01_intro.jl"), ] if !isdir(build_dir) @@ -30,7 +33,9 @@ makedocs( ), pages = [ "Home" => "index.md", - "Class 1" => ["class01/class01.md"], + "Class 1" => ["class01/class01.md", + "class01/background_materials/git_adventure_guide.md", + ], ], )