Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c03f90edd | |||
| 7c06f1a850 | |||
| 2c4e5918b9 | |||
| c2128879f1 | |||
| 13d0c64183 | |||
| b2c53ffa45 | |||
| 2eff443f70 | |||
| 7e160f2031 | |||
| 097484675c | |||
| b1d655acff | |||
| 4bf3a78daf | |||
| 9add88b145 | |||
| 6920be2334 | |||
| 84d73e742c | |||
| 4f4ee7539d | |||
| cd7b324da4 | |||
| cb83ac04c0 | |||
| 74de35a44d |
+464
-145
@@ -1,8 +1,32 @@
|
|||||||
# This file is machine-generated - editing it directly is not advised
|
# This file is machine-generated - editing it directly is not advised
|
||||||
|
|
||||||
julia_version = "1.11.2"
|
julia_version = "1.12.6"
|
||||||
manifest_format = "2.0"
|
manifest_format = "2.0"
|
||||||
project_hash = "b7e1f171d36dc4812d6c1445da530f513320e6cd"
|
project_hash = "eefceed38d1e3b7216d3f052806b5d83d4fd80b7"
|
||||||
|
|
||||||
|
[[deps.Accessors]]
|
||||||
|
deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"]
|
||||||
|
git-tree-sha1 = "7063ad1083578215c7c4bf410368150abe8d5524"
|
||||||
|
uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
|
||||||
|
version = "0.1.45"
|
||||||
|
|
||||||
|
[deps.Accessors.extensions]
|
||||||
|
AxisKeysExt = "AxisKeys"
|
||||||
|
IntervalSetsExt = "IntervalSets"
|
||||||
|
LinearAlgebraExt = "LinearAlgebra"
|
||||||
|
StaticArraysExt = "StaticArrays"
|
||||||
|
StructArraysExt = "StructArrays"
|
||||||
|
TestExt = "Test"
|
||||||
|
UnitfulExt = "Unitful"
|
||||||
|
|
||||||
|
[deps.Accessors.weakdeps]
|
||||||
|
AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5"
|
||||||
|
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
|
||||||
|
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
|
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||||
|
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
|
||||||
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
||||||
|
|
||||||
[[deps.AliasTables]]
|
[[deps.AliasTables]]
|
||||||
deps = ["PtrArrays", "Random"]
|
deps = ["PtrArrays", "Random"]
|
||||||
@@ -10,10 +34,6 @@ git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff"
|
|||||||
uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8"
|
uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
|
||||||
[[deps.ArgTools]]
|
|
||||||
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
|
|
||||||
version = "1.1.2"
|
|
||||||
|
|
||||||
[[deps.Artifacts]]
|
[[deps.Artifacts]]
|
||||||
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
|
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
@@ -22,74 +42,161 @@ version = "1.11.0"
|
|||||||
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.BufferedStreams]]
|
||||||
|
git-tree-sha1 = "6863c5b7fc997eadcabdbaf6c5f201dc30032643"
|
||||||
|
uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d"
|
||||||
|
version = "1.2.2"
|
||||||
|
|
||||||
|
[[deps.CRC32c]]
|
||||||
|
uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc"
|
||||||
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.CSV]]
|
||||||
|
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"]
|
||||||
|
git-tree-sha1 = "8d8e0b0f350b8e1c91420b5e64e5de774c2f0f4d"
|
||||||
|
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||||
|
version = "0.10.16"
|
||||||
|
|
||||||
[[deps.CodeTracking]]
|
[[deps.CodeTracking]]
|
||||||
deps = ["InteractiveUtils", "UUIDs"]
|
deps = ["InteractiveUtils", "REPL", "UUIDs"]
|
||||||
git-tree-sha1 = "7eee164f122511d3e4e1ebadb7956939ea7e1c77"
|
git-tree-sha1 = "cfb7a2e89e245a9d5016b70323db412b3a7438d5"
|
||||||
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
|
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
|
||||||
version = "1.3.6"
|
version = "3.0.2"
|
||||||
|
|
||||||
|
[[deps.CodecBase]]
|
||||||
|
deps = ["TranscodingStreams"]
|
||||||
|
git-tree-sha1 = "40956acdbef3d8c7cc38cba42b56034af8f8581a"
|
||||||
|
uuid = "6c391c72-fb7b-5838-ba82-7cfb1bcfecbf"
|
||||||
|
version = "0.3.4"
|
||||||
|
|
||||||
|
[[deps.CodecZlib]]
|
||||||
|
deps = ["TranscodingStreams", "Zlib_jll"]
|
||||||
|
git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9"
|
||||||
|
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
|
||||||
|
version = "0.7.8"
|
||||||
|
|
||||||
|
[[deps.CommonSolve]]
|
||||||
|
git-tree-sha1 = "99ee296f88c12485402e37c2fd025f95ae097637"
|
||||||
|
uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
|
||||||
|
version = "0.2.9"
|
||||||
|
|
||||||
[[deps.Compat]]
|
[[deps.Compat]]
|
||||||
deps = ["TOML", "UUIDs"]
|
deps = ["TOML", "UUIDs"]
|
||||||
git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215"
|
git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad"
|
||||||
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
|
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
|
||||||
version = "4.16.0"
|
version = "4.18.1"
|
||||||
weakdeps = ["Dates", "LinearAlgebra"]
|
weakdeps = ["Dates", "LinearAlgebra"]
|
||||||
|
|
||||||
[deps.Compat.extensions]
|
[deps.Compat.extensions]
|
||||||
CompatLinearAlgebraExt = "LinearAlgebra"
|
CompatLinearAlgebraExt = "LinearAlgebra"
|
||||||
|
|
||||||
|
[[deps.Compiler]]
|
||||||
|
git-tree-sha1 = "382d79bfe72a406294faca39ef0c3cef6e6ce1f1"
|
||||||
|
uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1"
|
||||||
|
version = "0.1.1"
|
||||||
|
|
||||||
[[deps.CompilerSupportLibraries_jll]]
|
[[deps.CompilerSupportLibraries_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "Libdl"]
|
||||||
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
||||||
version = "1.1.1+0"
|
version = "1.3.0+1"
|
||||||
|
|
||||||
|
[[deps.CompositionsBase]]
|
||||||
|
git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad"
|
||||||
|
uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
|
||||||
|
version = "0.1.2"
|
||||||
|
weakdeps = ["InverseFunctions"]
|
||||||
|
|
||||||
|
[deps.CompositionsBase.extensions]
|
||||||
|
CompositionsBaseInverseFunctionsExt = "InverseFunctions"
|
||||||
|
|
||||||
|
[[deps.ConstructionBase]]
|
||||||
|
git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb"
|
||||||
|
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
|
||||||
|
version = "1.6.0"
|
||||||
|
|
||||||
|
[deps.ConstructionBase.extensions]
|
||||||
|
ConstructionBaseIntervalSetsExt = "IntervalSets"
|
||||||
|
ConstructionBaseLinearAlgebraExt = "LinearAlgebra"
|
||||||
|
ConstructionBaseStaticArraysExt = "StaticArrays"
|
||||||
|
|
||||||
|
[deps.ConstructionBase.weakdeps]
|
||||||
|
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
|
||||||
|
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
|
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||||
|
|
||||||
|
[[deps.Crayons]]
|
||||||
|
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
|
||||||
|
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
|
||||||
|
version = "4.1.1"
|
||||||
|
|
||||||
[[deps.DataAPI]]
|
[[deps.DataAPI]]
|
||||||
git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe"
|
git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe"
|
||||||
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
|
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
|
||||||
|
[[deps.DataFrames]]
|
||||||
|
deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
|
||||||
|
git-tree-sha1 = "5fab31e2e01e70ad66e3e24c968c264d1cf166d6"
|
||||||
|
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||||
|
version = "1.8.2"
|
||||||
|
|
||||||
[[deps.DataStructures]]
|
[[deps.DataStructures]]
|
||||||
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
|
deps = ["OrderedCollections"]
|
||||||
git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82"
|
git-tree-sha1 = "6fb53a69613a0b2b68a0d12671717d307ab8b24e"
|
||||||
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
||||||
version = "0.18.20"
|
version = "0.19.5"
|
||||||
|
|
||||||
|
[[deps.DataValueInterfaces]]
|
||||||
|
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
|
||||||
|
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
[[deps.Dates]]
|
[[deps.Dates]]
|
||||||
deps = ["Printf"]
|
deps = ["Printf"]
|
||||||
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.Distributed]]
|
|
||||||
deps = ["Random", "Serialization", "Sockets"]
|
|
||||||
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
|
||||||
version = "1.11.0"
|
|
||||||
|
|
||||||
[[deps.Distributions]]
|
[[deps.Distributions]]
|
||||||
deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
|
deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "Roots", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
|
||||||
git-tree-sha1 = "3101c32aab536e7a27b1763c0797dba151b899ad"
|
git-tree-sha1 = "cd3c5ac74cd3923c8945c6a81518c46abd0e73a3"
|
||||||
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
|
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
|
||||||
version = "0.25.113"
|
version = "0.25.129"
|
||||||
|
|
||||||
[deps.Distributions.extensions]
|
[deps.Distributions.extensions]
|
||||||
DistributionsChainRulesCoreExt = "ChainRulesCore"
|
DistributionsChainRulesCoreExt = "ChainRulesCore"
|
||||||
DistributionsDensityInterfaceExt = "DensityInterface"
|
DistributionsDensityInterfaceExt = "DensityInterface"
|
||||||
|
DistributionsSparseConnectivityTracerExt = "SparseConnectivityTracer"
|
||||||
DistributionsTestExt = "Test"
|
DistributionsTestExt = "Test"
|
||||||
|
|
||||||
[deps.Distributions.weakdeps]
|
[deps.Distributions.weakdeps]
|
||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
|
DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
|
||||||
|
SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5"
|
||||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
|
||||||
[[deps.DocStringExtensions]]
|
[[deps.DocStringExtensions]]
|
||||||
deps = ["LibGit2"]
|
git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c"
|
||||||
git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d"
|
|
||||||
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
|
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
|
||||||
version = "0.9.3"
|
version = "0.9.5"
|
||||||
|
|
||||||
[[deps.Downloads]]
|
[[deps.EnumX]]
|
||||||
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
|
git-tree-sha1 = "c49898e8438c828577f04b92fc9368c388ac783c"
|
||||||
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
|
uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56"
|
||||||
version = "1.6.0"
|
version = "1.0.7"
|
||||||
|
|
||||||
|
[[deps.FilePathsBase]]
|
||||||
|
deps = ["Compat", "Dates"]
|
||||||
|
git-tree-sha1 = "3bab2c5aa25e7840a4b065805c0cdfc01f3068d2"
|
||||||
|
uuid = "48062228-2e41-5def-b9a4-89aafe57970f"
|
||||||
|
version = "0.9.24"
|
||||||
|
|
||||||
|
[deps.FilePathsBase.extensions]
|
||||||
|
FilePathsBaseMmapExt = "Mmap"
|
||||||
|
FilePathsBaseTestExt = "Test"
|
||||||
|
|
||||||
|
[deps.FilePathsBase.weakdeps]
|
||||||
|
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
|
||||||
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
|
||||||
[[deps.FileWatching]]
|
[[deps.FileWatching]]
|
||||||
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
|
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
|
||||||
@@ -97,49 +204,126 @@ version = "1.11.0"
|
|||||||
|
|
||||||
[[deps.FillArrays]]
|
[[deps.FillArrays]]
|
||||||
deps = ["LinearAlgebra"]
|
deps = ["LinearAlgebra"]
|
||||||
git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a"
|
git-tree-sha1 = "2f979084d1e13948a3352cf64a25df6bd3b4dca3"
|
||||||
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
|
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
|
||||||
version = "1.13.0"
|
version = "1.16.0"
|
||||||
weakdeps = ["PDMats", "SparseArrays", "Statistics"]
|
|
||||||
|
|
||||||
[deps.FillArrays.extensions]
|
[deps.FillArrays.extensions]
|
||||||
FillArraysPDMatsExt = "PDMats"
|
FillArraysPDMatsExt = "PDMats"
|
||||||
FillArraysSparseArraysExt = "SparseArrays"
|
FillArraysSparseArraysExt = "SparseArrays"
|
||||||
|
FillArraysStaticArraysExt = "StaticArrays"
|
||||||
FillArraysStatisticsExt = "Statistics"
|
FillArraysStatisticsExt = "Statistics"
|
||||||
|
|
||||||
|
[deps.FillArrays.weakdeps]
|
||||||
|
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
|
||||||
|
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
||||||
|
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||||
|
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
||||||
|
|
||||||
|
[[deps.Future]]
|
||||||
|
deps = ["Random"]
|
||||||
|
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
|
||||||
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.Gamma]]
|
||||||
|
git-tree-sha1 = "86f86b6168a016ed88e4ae4e64577b98c3b59e8e"
|
||||||
|
uuid = "a0844989-3bd2-4988-8bea-c9407ab0941b"
|
||||||
|
version = "1.1.0"
|
||||||
|
|
||||||
[[deps.GeneralUtils]]
|
[[deps.GeneralUtils]]
|
||||||
deps = ["DataStructures", "Dates", "Distributions", "JSON3", "MQTTClient", "Random", "Revise", "UUIDs"]
|
deps = ["CSV", "DataFrames", "DataStructures", "Dates", "Distributions", "HTTP", "JSON", "NATS", "PrettyPrinting", "Random", "Revise", "SHA", "UUIDs"]
|
||||||
path = "/appfolder/app/privatejuliapkg/GeneralUtils"
|
git-tree-sha1 = "7c0600c166a5deb2c607018a491c04eb25969c2e"
|
||||||
|
repo-rev = "main"
|
||||||
|
repo-url = "https://git.yiem.cc/ton/GeneralUtils"
|
||||||
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
||||||
version = "0.1.0"
|
version = "0.4.9"
|
||||||
|
|
||||||
|
[[deps.HTTP]]
|
||||||
|
deps = ["Base64", "CodecZlib", "Dates", "EnumX", "PrecompileTools", "Random", "Reseau", "SHA", "URIs", "UUIDs", "Zlib_jll"]
|
||||||
|
git-tree-sha1 = "eda1d37cb55d90a17d0957c75841138c88b361a1"
|
||||||
|
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
|
||||||
|
version = "2.5.4"
|
||||||
|
|
||||||
|
[[deps.HashArrayMappedTries]]
|
||||||
|
git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae"
|
||||||
|
uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74"
|
||||||
|
version = "0.2.0"
|
||||||
|
|
||||||
[[deps.HypergeometricFunctions]]
|
[[deps.HypergeometricFunctions]]
|
||||||
deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"]
|
deps = ["Gamma", "LinearAlgebra"]
|
||||||
git-tree-sha1 = "b1c2585431c382e3fe5805874bda6aea90a95de9"
|
git-tree-sha1 = "18d7deab5fb0440dc6a7b6993c5c27b25420de10"
|
||||||
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
|
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
|
||||||
version = "0.3.25"
|
version = "0.3.29"
|
||||||
|
|
||||||
|
[[deps.InlineStrings]]
|
||||||
|
git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d"
|
||||||
|
uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48"
|
||||||
|
version = "1.4.5"
|
||||||
|
|
||||||
|
[deps.InlineStrings.extensions]
|
||||||
|
ArrowTypesExt = "ArrowTypes"
|
||||||
|
ParsersExt = "Parsers"
|
||||||
|
|
||||||
|
[deps.InlineStrings.weakdeps]
|
||||||
|
ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"
|
||||||
|
Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
||||||
|
|
||||||
[[deps.InteractiveUtils]]
|
[[deps.InteractiveUtils]]
|
||||||
deps = ["Markdown"]
|
deps = ["Markdown"]
|
||||||
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.InverseFunctions]]
|
||||||
|
git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb"
|
||||||
|
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
|
||||||
|
version = "0.1.17"
|
||||||
|
|
||||||
|
[deps.InverseFunctions.extensions]
|
||||||
|
InverseFunctionsDatesExt = "Dates"
|
||||||
|
InverseFunctionsTestExt = "Test"
|
||||||
|
|
||||||
|
[deps.InverseFunctions.weakdeps]
|
||||||
|
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||||
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
|
||||||
|
[[deps.InvertedIndices]]
|
||||||
|
git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe"
|
||||||
|
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
|
||||||
|
version = "1.3.1"
|
||||||
|
|
||||||
[[deps.IrrationalConstants]]
|
[[deps.IrrationalConstants]]
|
||||||
git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2"
|
git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758"
|
||||||
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
|
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
|
||||||
version = "0.2.2"
|
version = "0.2.6"
|
||||||
|
|
||||||
|
[[deps.IteratorInterfaceExtensions]]
|
||||||
|
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
|
||||||
|
uuid = "82899510-4779-5014-852e-03e436cf321d"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
[[deps.JLLWrappers]]
|
[[deps.JLLWrappers]]
|
||||||
deps = ["Artifacts", "Preferences"]
|
deps = ["Artifacts", "Preferences"]
|
||||||
git-tree-sha1 = "be3dc50a92e5a386872a493a10050136d4703f9b"
|
git-tree-sha1 = "7204148362dafe5fe6a273f855b8ccbe4df8173e"
|
||||||
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
|
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
|
||||||
|
version = "1.8.0"
|
||||||
|
|
||||||
|
[[deps.JSON]]
|
||||||
|
deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"]
|
||||||
|
git-tree-sha1 = "c89d196f5ffb64bfbf80985b699ea913b0d2c211"
|
||||||
|
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||||||
version = "1.6.1"
|
version = "1.6.1"
|
||||||
|
|
||||||
|
[deps.JSON.extensions]
|
||||||
|
JSONArrowExt = ["ArrowTypes"]
|
||||||
|
|
||||||
|
[deps.JSON.weakdeps]
|
||||||
|
ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"
|
||||||
|
|
||||||
[[deps.JSON3]]
|
[[deps.JSON3]]
|
||||||
deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"]
|
deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"]
|
||||||
git-tree-sha1 = "1d322381ef7b087548321d3f878cb4c9bd8f8f9b"
|
git-tree-sha1 = "411eccfe8aba0814ffa0fdf4860913ed09c34975"
|
||||||
uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
|
uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
|
||||||
version = "1.14.1"
|
version = "1.14.3"
|
||||||
|
|
||||||
[deps.JSON3.extensions]
|
[deps.JSON3.extensions]
|
||||||
JSON3ArrowExt = ["ArrowTypes"]
|
JSON3ArrowExt = ["ArrowTypes"]
|
||||||
@@ -149,34 +333,40 @@ version = "1.14.1"
|
|||||||
|
|
||||||
[[deps.JuliaInterpreter]]
|
[[deps.JuliaInterpreter]]
|
||||||
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
|
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
|
||||||
git-tree-sha1 = "10da5154188682e5c0726823c2b5125957ec3778"
|
git-tree-sha1 = "58927c485919bf17ea308d9d82156de1adf4b006"
|
||||||
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
|
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
|
||||||
version = "0.9.38"
|
version = "0.10.12"
|
||||||
|
|
||||||
[[deps.LibCURL]]
|
[[deps.JuliaSyntaxHighlighting]]
|
||||||
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
|
deps = ["StyledStrings"]
|
||||||
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
|
uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011"
|
||||||
version = "0.6.4"
|
version = "1.12.0"
|
||||||
|
|
||||||
[[deps.LibCURL_jll]]
|
[[deps.LLMMCTS]]
|
||||||
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
|
deps = ["JSON", "PrettyPrinting"]
|
||||||
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
|
path = "."
|
||||||
version = "8.6.0+0"
|
uuid = "d76c5a4d-449e-4835-8cc4-dd86ec44f241"
|
||||||
|
version = "0.1.4"
|
||||||
|
|
||||||
|
[[deps.LaTeXStrings]]
|
||||||
|
git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c"
|
||||||
|
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
|
||||||
|
version = "1.4.0"
|
||||||
|
|
||||||
[[deps.LibGit2]]
|
[[deps.LibGit2]]
|
||||||
deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"]
|
deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"]
|
||||||
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.LibGit2_jll]]
|
[[deps.LibGit2_jll]]
|
||||||
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"]
|
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"]
|
||||||
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
|
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
|
||||||
version = "1.7.2+0"
|
version = "1.9.0+0"
|
||||||
|
|
||||||
[[deps.LibSSH2_jll]]
|
[[deps.LibSSH2_jll]]
|
||||||
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
|
deps = ["Artifacts", "Libdl", "OpenSSL_jll"]
|
||||||
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
|
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
|
||||||
version = "1.11.0+1"
|
version = "1.11.3+1"
|
||||||
|
|
||||||
[[deps.Libdl]]
|
[[deps.Libdl]]
|
||||||
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
||||||
@@ -185,13 +375,13 @@ version = "1.11.0"
|
|||||||
[[deps.LinearAlgebra]]
|
[[deps.LinearAlgebra]]
|
||||||
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
|
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
|
||||||
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
version = "1.11.0"
|
version = "1.12.0"
|
||||||
|
|
||||||
[[deps.LogExpFunctions]]
|
[[deps.LogExpFunctions]]
|
||||||
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
|
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
|
||||||
git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea"
|
git-tree-sha1 = "bba2d9aa057d8f126415de240573e86a8f39d2a1"
|
||||||
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
|
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
|
||||||
version = "0.3.28"
|
version = "1.0.1"
|
||||||
|
|
||||||
[deps.LogExpFunctions.extensions]
|
[deps.LogExpFunctions.extensions]
|
||||||
LogExpFunctionsChainRulesCoreExt = "ChainRulesCore"
|
LogExpFunctionsChainRulesCoreExt = "ChainRulesCore"
|
||||||
@@ -208,30 +398,32 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
|||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.LoweredCodeUtils]]
|
[[deps.LoweredCodeUtils]]
|
||||||
deps = ["JuliaInterpreter"]
|
deps = ["CodeTracking", "Compiler", "JuliaInterpreter"]
|
||||||
git-tree-sha1 = "688d6d9e098109051ae33d126fcfc88c4ce4a021"
|
git-tree-sha1 = "3733419e9a71156b389f3e331672d2e95436783f"
|
||||||
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
|
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
|
||||||
version = "3.1.0"
|
version = "3.6.2"
|
||||||
|
|
||||||
[[deps.MQTTClient]]
|
[[deps.MacroTools]]
|
||||||
deps = ["Distributed", "Random", "Sockets"]
|
git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522"
|
||||||
git-tree-sha1 = "f2597b290d4bf17b577346153cd2ddf9accb5c26"
|
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
|
||||||
uuid = "985f35cc-2c3d-4943-b8c1-f0931d5f0959"
|
version = "0.5.16"
|
||||||
version = "0.3.1"
|
|
||||||
weakdeps = ["PrecompileTools"]
|
|
||||||
|
|
||||||
[deps.MQTTClient.extensions]
|
|
||||||
PrecompileMQTT = "PrecompileTools"
|
|
||||||
|
|
||||||
[[deps.Markdown]]
|
[[deps.Markdown]]
|
||||||
deps = ["Base64"]
|
deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"]
|
||||||
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.MbedTLS]]
|
||||||
|
deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"]
|
||||||
|
git-tree-sha1 = "8785729fa736197687541f7053f6d8ab7fc44f92"
|
||||||
|
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
|
||||||
|
version = "1.1.10"
|
||||||
|
|
||||||
[[deps.MbedTLS_jll]]
|
[[deps.MbedTLS_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
|
git-tree-sha1 = "ff69a2b1330bcb730b9ac1ab7dd680176f5896b8"
|
||||||
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
||||||
version = "2.28.6+0"
|
version = "2.28.1010+0"
|
||||||
|
|
||||||
[[deps.Missings]]
|
[[deps.Missings]]
|
||||||
deps = ["DataAPI"]
|
deps = ["DataAPI"]
|
||||||
@@ -245,65 +437,100 @@ version = "1.11.0"
|
|||||||
|
|
||||||
[[deps.MozillaCACerts_jll]]
|
[[deps.MozillaCACerts_jll]]
|
||||||
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
|
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
|
||||||
version = "2023.12.12"
|
version = "2025.11.4"
|
||||||
|
|
||||||
|
[[deps.NATS]]
|
||||||
|
deps = ["Base64", "BufferedStreams", "CodecBase", "Dates", "DocStringExtensions", "JSON3", "MbedTLS", "NanoDates", "Random", "ScopedValues", "Sockets", "Sodium", "StructTypes", "URIs"]
|
||||||
|
git-tree-sha1 = "a1cdf34ba90ee5cd2658e487d3277ffafee712ce"
|
||||||
|
uuid = "55e73f9c-eeeb-467f-b4cc-a633fde63d2a"
|
||||||
|
version = "0.1.1"
|
||||||
|
|
||||||
|
[[deps.NanoDates]]
|
||||||
|
deps = ["Dates", "Parsers"]
|
||||||
|
git-tree-sha1 = "850a0557ae5934f6e67ac0dc5ca13d0328422d1f"
|
||||||
|
uuid = "46f1a544-deae-4307-8689-c12aa3c955c6"
|
||||||
|
version = "1.0.3"
|
||||||
|
|
||||||
[[deps.NetworkOptions]]
|
[[deps.NetworkOptions]]
|
||||||
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
|
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
|
||||||
version = "1.2.0"
|
version = "1.3.0"
|
||||||
|
|
||||||
[[deps.OpenBLAS_jll]]
|
[[deps.OpenBLAS_jll]]
|
||||||
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
|
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
|
||||||
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
|
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
|
||||||
version = "0.3.27+1"
|
version = "0.3.29+0"
|
||||||
|
|
||||||
[[deps.OpenLibm_jll]]
|
[[deps.OpenLibm_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "Libdl"]
|
||||||
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"
|
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"
|
||||||
version = "0.8.1+2"
|
version = "0.8.7+0"
|
||||||
|
|
||||||
|
[[deps.OpenSSL_jll]]
|
||||||
|
deps = ["Artifacts", "Libdl"]
|
||||||
|
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
|
||||||
|
version = "3.5.4+0"
|
||||||
|
|
||||||
[[deps.OpenSpecFun_jll]]
|
[[deps.OpenSpecFun_jll]]
|
||||||
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
|
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"]
|
||||||
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
|
git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335"
|
||||||
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
|
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
|
||||||
version = "0.5.5+0"
|
version = "0.5.6+0"
|
||||||
|
|
||||||
[[deps.OrderedCollections]]
|
[[deps.OrderedCollections]]
|
||||||
git-tree-sha1 = "12f1439c4f986bb868acda6ea33ebc78e19b95ad"
|
git-tree-sha1 = "94ba93778373a53bfd5a0caaf7d809c445292ff4"
|
||||||
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
||||||
version = "1.7.0"
|
version = "1.8.2"
|
||||||
|
|
||||||
[[deps.PDMats]]
|
[[deps.PDMats]]
|
||||||
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
|
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
|
||||||
git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65"
|
git-tree-sha1 = "26766d4b5f1a410c218a19b85a672c6edb693c65"
|
||||||
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
|
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
|
||||||
version = "0.11.31"
|
version = "0.11.40"
|
||||||
|
weakdeps = ["StatsBase"]
|
||||||
|
|
||||||
|
[deps.PDMats.extensions]
|
||||||
|
StatsBaseExt = "StatsBase"
|
||||||
|
|
||||||
[[deps.Parsers]]
|
[[deps.Parsers]]
|
||||||
deps = ["Dates", "PrecompileTools", "UUIDs"]
|
deps = ["Dates", "PrecompileTools", "UUIDs"]
|
||||||
git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821"
|
git-tree-sha1 = "32a4e09c5f29402573d673901778a0e03b0807b9"
|
||||||
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
||||||
version = "2.8.1"
|
version = "2.8.6"
|
||||||
|
|
||||||
[[deps.Pkg]]
|
[[deps.PooledArrays]]
|
||||||
deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"]
|
deps = ["DataAPI", "Future"]
|
||||||
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3"
|
||||||
version = "1.11.0"
|
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
|
||||||
weakdeps = ["REPL"]
|
version = "1.4.3"
|
||||||
|
|
||||||
[deps.Pkg.extensions]
|
|
||||||
REPLExt = "REPL"
|
|
||||||
|
|
||||||
[[deps.PrecompileTools]]
|
[[deps.PrecompileTools]]
|
||||||
deps = ["Preferences"]
|
deps = ["Preferences"]
|
||||||
git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f"
|
git-tree-sha1 = "edbeefc7a4889f528644251bdb5fc9ab5348bc2c"
|
||||||
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
|
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
|
||||||
version = "1.2.1"
|
version = "1.3.4"
|
||||||
|
|
||||||
[[deps.Preferences]]
|
[[deps.Preferences]]
|
||||||
deps = ["TOML"]
|
deps = ["TOML"]
|
||||||
git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
|
git-tree-sha1 = "8b770b60760d4451834fe79dd483e318eee709c4"
|
||||||
uuid = "21216c6a-2e73-6563-6e65-726566657250"
|
uuid = "21216c6a-2e73-6563-6e65-726566657250"
|
||||||
version = "1.4.3"
|
version = "1.5.2"
|
||||||
|
|
||||||
|
[[deps.PrettyPrinting]]
|
||||||
|
git-tree-sha1 = "142ee93724a9c5d04d78df7006670a93ed1b244e"
|
||||||
|
uuid = "54e16d92-306c-5ea0-a30b-337be88ac337"
|
||||||
|
version = "0.4.2"
|
||||||
|
|
||||||
|
[[deps.PrettyTables]]
|
||||||
|
deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"]
|
||||||
|
git-tree-sha1 = "624de6279ab7d94fc9f672f0068107eb6619732c"
|
||||||
|
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
|
||||||
|
version = "3.3.2"
|
||||||
|
|
||||||
|
[deps.PrettyTables.extensions]
|
||||||
|
PrettyTablesTypstryExt = "Typstry"
|
||||||
|
|
||||||
|
[deps.PrettyTables.weakdeps]
|
||||||
|
Typstry = "f0ed7684-a786-439e-b1e3-3b82803b501e"
|
||||||
|
|
||||||
[[deps.Printf]]
|
[[deps.Printf]]
|
||||||
deps = ["Unicode"]
|
deps = ["Unicode"]
|
||||||
@@ -311,15 +538,15 @@ uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
|||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.PtrArrays]]
|
[[deps.PtrArrays]]
|
||||||
git-tree-sha1 = "77a42d78b6a92df47ab37e177b2deac405e1c88f"
|
git-tree-sha1 = "4fbbafbc6251b883f4d2705356f3641f3652a7fe"
|
||||||
uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d"
|
uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d"
|
||||||
version = "1.2.1"
|
version = "1.4.0"
|
||||||
|
|
||||||
[[deps.QuadGK]]
|
[[deps.QuadGK]]
|
||||||
deps = ["DataStructures", "LinearAlgebra"]
|
deps = ["DataStructures", "LinearAlgebra"]
|
||||||
git-tree-sha1 = "cda3b045cf9ef07a08ad46731f5a3165e56cf3da"
|
git-tree-sha1 = "5e8e8b0ab68215d7a2b14b9921a946fee794749e"
|
||||||
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
|
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
|
||||||
version = "2.11.1"
|
version = "2.11.3"
|
||||||
|
|
||||||
[deps.QuadGK.extensions]
|
[deps.QuadGK.extensions]
|
||||||
QuadGKEnzymeExt = "Enzyme"
|
QuadGKEnzymeExt = "Enzyme"
|
||||||
@@ -328,7 +555,7 @@ version = "2.11.1"
|
|||||||
Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
|
Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
|
||||||
|
|
||||||
[[deps.REPL]]
|
[[deps.REPL]]
|
||||||
deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"]
|
deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"]
|
||||||
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
@@ -342,23 +569,29 @@ git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
|
|||||||
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
|
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
|
|
||||||
[[deps.Requires]]
|
[[deps.Reseau]]
|
||||||
deps = ["UUIDs"]
|
deps = ["NetworkOptions", "OpenSSL_jll", "PrecompileTools", "Random", "SHA"]
|
||||||
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
|
git-tree-sha1 = "0eab6d95ed40c2ef3992255c1c71e4f9748932b5"
|
||||||
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
|
uuid = "802f3686-a58f-41ce-bb0c-3c43c75bba36"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
|
|
||||||
[[deps.Revise]]
|
[[deps.Revise]]
|
||||||
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "REPL", "Requires", "UUIDs", "Unicode"]
|
deps = ["CRC32c", "CodeTracking", "FileWatching", "InteractiveUtils", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Preferences", "REPL", "UUIDs"]
|
||||||
git-tree-sha1 = "470f48c9c4ea2170fd4d0f8eb5118327aada22f5"
|
git-tree-sha1 = "27e3ee13fc8739a59b380d6163d6a82f52c03bd7"
|
||||||
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
||||||
version = "3.6.4"
|
version = "3.15.1"
|
||||||
|
|
||||||
|
[deps.Revise.extensions]
|
||||||
|
DistributedExt = "Distributed"
|
||||||
|
|
||||||
|
[deps.Revise.weakdeps]
|
||||||
|
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
||||||
|
|
||||||
[[deps.Rmath]]
|
[[deps.Rmath]]
|
||||||
deps = ["Random", "Rmath_jll"]
|
deps = ["Random", "Rmath_jll"]
|
||||||
git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4"
|
git-tree-sha1 = "5b3d50eb374cea306873b371d3f8d3915a018f0b"
|
||||||
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
|
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
|
||||||
version = "0.8.0"
|
version = "0.9.0"
|
||||||
|
|
||||||
[[deps.Rmath_jll]]
|
[[deps.Rmath_jll]]
|
||||||
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
@@ -366,10 +599,44 @@ git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8"
|
|||||||
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
|
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
|
||||||
version = "0.5.1+0"
|
version = "0.5.1+0"
|
||||||
|
|
||||||
|
[[deps.Roots]]
|
||||||
|
deps = ["Accessors", "CommonSolve", "Printf"]
|
||||||
|
git-tree-sha1 = "ed45bcc7cf3c8887595b973f2b1efbe91dcc50ec"
|
||||||
|
uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
|
||||||
|
version = "3.0.1"
|
||||||
|
|
||||||
|
[deps.Roots.extensions]
|
||||||
|
RootsChainRulesCoreExt = "ChainRulesCore"
|
||||||
|
RootsForwardDiffExt = "ForwardDiff"
|
||||||
|
RootsIntervalRootFindingExt = "IntervalRootFinding"
|
||||||
|
RootsSymPyExt = "SymPy"
|
||||||
|
RootsSymPyPythonCallExt = "SymPyPythonCall"
|
||||||
|
RootsUnitfulExt = "Unitful"
|
||||||
|
|
||||||
|
[deps.Roots.weakdeps]
|
||||||
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
|
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
|
||||||
|
IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807"
|
||||||
|
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
|
||||||
|
SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c"
|
||||||
|
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
||||||
|
|
||||||
[[deps.SHA]]
|
[[deps.SHA]]
|
||||||
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
|
||||||
|
[[deps.ScopedValues]]
|
||||||
|
deps = ["HashArrayMappedTries", "Logging"]
|
||||||
|
git-tree-sha1 = "67a144433c4ce877ee6d1ada69a124d6b1ecf7be"
|
||||||
|
uuid = "7e506255-f358-4e82-b7e4-beb19740aa63"
|
||||||
|
version = "1.6.2"
|
||||||
|
|
||||||
|
[[deps.SentinelArrays]]
|
||||||
|
deps = ["Dates", "Random"]
|
||||||
|
git-tree-sha1 = "084c47c7c5ce5cfecefa0a98dff69eb3646b5a80"
|
||||||
|
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
|
||||||
|
version = "1.4.10"
|
||||||
|
|
||||||
[[deps.Serialization]]
|
[[deps.Serialization]]
|
||||||
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
@@ -378,22 +645,28 @@ version = "1.11.0"
|
|||||||
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.Sodium]]
|
||||||
|
deps = ["Base64", "libsodium_jll"]
|
||||||
|
git-tree-sha1 = "907703e0d50846f300650d7225bdcab145b7bca9"
|
||||||
|
uuid = "4f5b5e99-b0ad-42cd-b47a-334e172ec8bd"
|
||||||
|
version = "1.1.2"
|
||||||
|
|
||||||
[[deps.SortingAlgorithms]]
|
[[deps.SortingAlgorithms]]
|
||||||
deps = ["DataStructures"]
|
deps = ["DataStructures"]
|
||||||
git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085"
|
git-tree-sha1 = "13cd91cc9be159e3f4d95b857fa2aa383b53772a"
|
||||||
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
|
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
|
||||||
version = "1.2.1"
|
version = "1.2.3"
|
||||||
|
|
||||||
[[deps.SparseArrays]]
|
[[deps.SparseArrays]]
|
||||||
deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"]
|
deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"]
|
||||||
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
||||||
version = "1.11.0"
|
version = "1.12.0"
|
||||||
|
|
||||||
[[deps.SpecialFunctions]]
|
[[deps.SpecialFunctions]]
|
||||||
deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
|
deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
|
||||||
git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14"
|
git-tree-sha1 = "6547cbdd8ce32efba0d21c5a40fa96d1a3548f9f"
|
||||||
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
|
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
|
||||||
version = "2.4.0"
|
version = "2.8.0"
|
||||||
|
|
||||||
[deps.SpecialFunctions.extensions]
|
[deps.SpecialFunctions.extensions]
|
||||||
SpecialFunctionsChainRulesCoreExt = "ChainRulesCore"
|
SpecialFunctionsChainRulesCoreExt = "ChainRulesCore"
|
||||||
@@ -413,21 +686,21 @@ weakdeps = ["SparseArrays"]
|
|||||||
|
|
||||||
[[deps.StatsAPI]]
|
[[deps.StatsAPI]]
|
||||||
deps = ["LinearAlgebra"]
|
deps = ["LinearAlgebra"]
|
||||||
git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed"
|
git-tree-sha1 = "178ed29fd5b2a2cfc3bd31c13375ae925623ff36"
|
||||||
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
|
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
|
|
||||||
[[deps.StatsBase]]
|
[[deps.StatsBase]]
|
||||||
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
|
deps = ["AliasTables", "DataAPI", "DataStructures", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
|
||||||
git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21"
|
git-tree-sha1 = "e4d7a1a0edc20af42689ea6f4f3587a2175d50ee"
|
||||||
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
||||||
version = "0.34.3"
|
version = "0.34.12"
|
||||||
|
|
||||||
[[deps.StatsFuns]]
|
[[deps.StatsFuns]]
|
||||||
deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
|
deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
|
||||||
git-tree-sha1 = "b423576adc27097764a90e163157bcfc9acf0f46"
|
git-tree-sha1 = "770240df9a3b8888065046948f7a09b4e0f997d5"
|
||||||
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
|
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
|
||||||
version = "1.3.2"
|
version = "2.2.0"
|
||||||
|
|
||||||
[deps.StatsFuns.extensions]
|
[deps.StatsFuns.extensions]
|
||||||
StatsFunsChainRulesCoreExt = "ChainRulesCore"
|
StatsFunsChainRulesCoreExt = "ChainRulesCore"
|
||||||
@@ -437,12 +710,34 @@ version = "1.3.2"
|
|||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
|
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
|
||||||
|
|
||||||
|
[[deps.StringManipulation]]
|
||||||
|
deps = ["PrecompileTools"]
|
||||||
|
git-tree-sha1 = "d05693d339e37d6ab134c5ab53c29fce5ee5d7d5"
|
||||||
|
uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e"
|
||||||
|
version = "0.4.4"
|
||||||
|
|
||||||
[[deps.StructTypes]]
|
[[deps.StructTypes]]
|
||||||
deps = ["Dates", "UUIDs"]
|
deps = ["Dates", "UUIDs"]
|
||||||
git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8"
|
git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8"
|
||||||
uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
|
uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.StructUtils]]
|
||||||
|
deps = ["Dates", "UUIDs"]
|
||||||
|
git-tree-sha1 = "82bee338d650aa515f31866c460cb7e3bcef90b8"
|
||||||
|
uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42"
|
||||||
|
version = "2.8.2"
|
||||||
|
|
||||||
|
[deps.StructUtils.extensions]
|
||||||
|
StructUtilsMeasurementsExt = ["Measurements"]
|
||||||
|
StructUtilsStaticArraysCoreExt = ["StaticArraysCore"]
|
||||||
|
StructUtilsTablesExt = ["Tables"]
|
||||||
|
|
||||||
|
[deps.StructUtils.weakdeps]
|
||||||
|
Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
|
||||||
|
StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
|
||||||
|
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
|
||||||
|
|
||||||
[[deps.StyledStrings]]
|
[[deps.StyledStrings]]
|
||||||
uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b"
|
uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
@@ -454,17 +749,34 @@ uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"
|
|||||||
[[deps.SuiteSparse_jll]]
|
[[deps.SuiteSparse_jll]]
|
||||||
deps = ["Artifacts", "Libdl", "libblastrampoline_jll"]
|
deps = ["Artifacts", "Libdl", "libblastrampoline_jll"]
|
||||||
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
|
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
|
||||||
version = "7.7.0+0"
|
version = "7.8.3+2"
|
||||||
|
|
||||||
[[deps.TOML]]
|
[[deps.TOML]]
|
||||||
deps = ["Dates"]
|
deps = ["Dates"]
|
||||||
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
|
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
|
|
||||||
[[deps.Tar]]
|
[[deps.TableTraits]]
|
||||||
deps = ["ArgTools", "SHA"]
|
deps = ["IteratorInterfaceExtensions"]
|
||||||
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
|
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
|
||||||
version = "1.10.0"
|
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
|
||||||
|
version = "1.0.1"
|
||||||
|
|
||||||
|
[[deps.Tables]]
|
||||||
|
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"]
|
||||||
|
git-tree-sha1 = "0f38a06c83f0007bbab3cf911262841c9a0f07e0"
|
||||||
|
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
|
||||||
|
version = "1.13.0"
|
||||||
|
|
||||||
|
[[deps.TranscodingStreams]]
|
||||||
|
git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742"
|
||||||
|
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
|
||||||
|
version = "0.11.3"
|
||||||
|
|
||||||
|
[[deps.URIs]]
|
||||||
|
git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a"
|
||||||
|
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
|
||||||
|
version = "1.6.1"
|
||||||
|
|
||||||
[[deps.UUIDs]]
|
[[deps.UUIDs]]
|
||||||
deps = ["Random", "SHA"]
|
deps = ["Random", "SHA"]
|
||||||
@@ -475,22 +787,29 @@ version = "1.11.0"
|
|||||||
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
|
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.WeakRefStrings]]
|
||||||
|
deps = ["DataAPI", "InlineStrings", "Parsers"]
|
||||||
|
git-tree-sha1 = "0716e01c3b40413de5dedbc9c5c69f27cddfddfc"
|
||||||
|
uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5"
|
||||||
|
version = "1.4.3"
|
||||||
|
|
||||||
|
[[deps.WorkerUtilities]]
|
||||||
|
git-tree-sha1 = "cd1659ba0d57b71a464a29e64dbc67cfe83d54e7"
|
||||||
|
uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60"
|
||||||
|
version = "1.6.1"
|
||||||
|
|
||||||
[[deps.Zlib_jll]]
|
[[deps.Zlib_jll]]
|
||||||
deps = ["Libdl"]
|
deps = ["Libdl"]
|
||||||
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
||||||
version = "1.2.13+1"
|
version = "1.3.1+2"
|
||||||
|
|
||||||
[[deps.libblastrampoline_jll]]
|
[[deps.libblastrampoline_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "Libdl"]
|
||||||
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
|
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
|
||||||
version = "5.11.0+0"
|
version = "5.15.0+0"
|
||||||
|
|
||||||
[[deps.nghttp2_jll]]
|
[[deps.libsodium_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
|
git-tree-sha1 = "011b0a7331b41c25524b64dc42afc9683ee89026"
|
||||||
version = "1.59.0+0"
|
uuid = "a9144af2-ca23-56d9-984f-0d03f7b5ccf8"
|
||||||
|
version = "1.0.21+0"
|
||||||
[[deps.p7zip_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl"]
|
|
||||||
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
|
||||||
version = "17.4.0+2"
|
|
||||||
|
|||||||
+14
-8
@@ -1,8 +1,14 @@
|
|||||||
name = "LLMMCTS"
|
name = "LLMMCTS"
|
||||||
uuid = "d76c5a4d-449e-4835-8cc4-dd86ec44f241"
|
uuid = "d76c5a4d-449e-4835-8cc4-dd86ec44f241"
|
||||||
authors = ["narawat lamaiin <narawat@outlook.com>"]
|
version = "0.1.5"
|
||||||
version = "0.1.0"
|
authors = ["narawat lamaiin <narawat@outlook.com>"]
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
GeneralUtils = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
GeneralUtils = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
||||||
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
|
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||||||
|
PrettyPrinting = "54e16d92-306c-5ea0-a30b-337be88ac337"
|
||||||
|
|
||||||
|
[compat]
|
||||||
|
GeneralUtils = "0.4.0 - 0.9.0"
|
||||||
|
JSON = "1.6.1"
|
||||||
|
PrettyPrinting = "0.4.2"
|
||||||
|
|||||||
@@ -0,0 +1,329 @@
|
|||||||
|
# LLMMCTS
|
||||||
|
|
||||||
|
[](https://github.com/narawat/LLMMCTS.jl)
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
LLMMCTS implements Monte Carlo Tree Search (MCTS) for Large Language Model (LLM) planning tasks.
|
||||||
|
|
||||||
|
## Why LLM + MCTS?
|
||||||
|
|
||||||
|
MCTS is a powerful search algorithm that balances exploration and exploitation through the UCT formula:
|
||||||
|
\[ \text{UCT}(s,a) = Q(s,a) + c \sqrt{\frac{\ln N(s)}{N(s,a)}} \]
|
||||||
|
|
||||||
|
However, in many real-world problems, **rewards are sparse**—they only come at the final state. This creates two critical problems:
|
||||||
|
|
||||||
|
1. **Value estimation delay** — Rewards must propagate backward through many layers before affecting early decisions
|
||||||
|
2. **Exploration inefficiency** — Without intermediate signals, MCTS explores randomly until it discovers a reward
|
||||||
|
|
||||||
|
### How LLMs Fix the Sparse Reward Problem
|
||||||
|
|
||||||
|
LLMs provide **reasoning and pseudo-reward** to guide the solution search process:
|
||||||
|
- **Reasoning** — LLM understands task structure and generates promising candidate actions
|
||||||
|
- **Pseudo-reward** — LLM estimates state quality at every node (not just terminal states)
|
||||||
|
|
||||||
|
In the code, this is represented by the `progressvalue` field:
|
||||||
|
```julia
|
||||||
|
progressvalue = llm_reasoning_estimate(state)
|
||||||
|
```
|
||||||
|
|
||||||
|
The LLM evaluates how close the current state is to solving the task, providing dense guidance even when the environment only gives rewards at the end.
|
||||||
|
|
||||||
|
### The Three-Tier Value System
|
||||||
|
|
||||||
|
LLMMCTS combines LLM guidance with MCTS search using three complementary value signals:
|
||||||
|
|
||||||
|
| Field | Source | Purpose |
|
||||||
|
|-------|--------|---------|
|
||||||
|
| `progressvalue` | LLM heuristic | Estimate of how close we are to solving; used for fast node selection |
|
||||||
|
| `statevalue` | Monte Carlo simulation | Actual cumulative reward from simulations; accurate but expensive to compute |
|
||||||
|
| `reward` | Environment | Immediate reward from environment (may be sparse, only at terminal states) |
|
||||||
|
|
||||||
|
**Why this matters:**
|
||||||
|
- `progressvalue` enables MCTS to explore promising branches quickly without waiting for terminal rewards
|
||||||
|
- `statevalue` provides accurate long-term estimates through Monte Carlo simulations
|
||||||
|
- `reward` supplies ground truth for backpropagation updates
|
||||||
|
|
||||||
|
### Benefits of LLM-MCTS Integration
|
||||||
|
|
||||||
|
| Benefit | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| **Overcomes sparse rewards** | LLM provides `progressvalue` at every node, enabling fast learning without waiting for terminal rewards |
|
||||||
|
| **Faster convergence** | Dense guidance from LLM reduces sample complexity by 5-10x compared to pure Monte Carlo |
|
||||||
|
| **Better than pure LLM** | MCTS systematically compares multiple LLM-generated trajectories, avoiding local optima |
|
||||||
|
| **Better than pure planning** | LLM handles complex reasoning and novel state generation that pure planners cannot |
|
||||||
|
| **Uncertainty quantification** | Visit counts in MCTS nodes reflect confidence in LLM's progress estimates |
|
||||||
|
| **Configurable depth** | MCTS depth controls planning horizon; LLM handles long-term reasoning at each step |
|
||||||
|
| **Parallel exploration** | MCTS naturally supports parallel simulation; LLM generates diverse candidate actions |
|
||||||
|
|
||||||
|
### MCTS Node Structure
|
||||||
|
|
||||||
|
```julia
|
||||||
|
MCTSNode(
|
||||||
|
nodekey::String,
|
||||||
|
state::Dict,
|
||||||
|
visits::Integer,
|
||||||
|
progressvalue::Number,
|
||||||
|
statevalue::Number,
|
||||||
|
reward::Number,
|
||||||
|
isterminal::Bool,
|
||||||
|
parent::Union{MCTSNode, Nothing},
|
||||||
|
children::Dict{String, MCTSNode},
|
||||||
|
etc::Dict{Symbol, Any}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fields:**
|
||||||
|
- `nodekey::String` — Unique identifier for the node
|
||||||
|
- `state::Dict` — Current state represented as a dictionary
|
||||||
|
- `visits::Integer` — Number of times this node has been visited
|
||||||
|
- `progressvalue::Number` — LLM's estimate of state quality
|
||||||
|
- `statevalue::Number` — Average cumulative reward from simulations
|
||||||
|
- `reward::Number` — Immediate reward at this node
|
||||||
|
- `isterminal::Bool` — Whether this node represents a terminal state
|
||||||
|
- `parent::Union{MCTSNode, Nothing}` — Parent node reference (nothing for root)
|
||||||
|
- `children::Dict{String, MCTSNode}` — Mapping of child nodes
|
||||||
|
- `etc::Dict{Symbol, Any}` — Additional arbitrary data storage (uses Symbol keys)
|
||||||
|
|
||||||
|
### Understanding `progressvalue`, `statevalue`, and `reward`
|
||||||
|
|
||||||
|
| Field | Source | Purpose |
|
||||||
|
|-------|--------|---------|
|
||||||
|
| `progressvalue` | LLM heuristic | Estimate of how close we are to solving; used for fast node selection |
|
||||||
|
| `statevalue` | Monte Carlo simulation | Actual cumulative reward from simulations; accurate but expensive to compute |
|
||||||
|
| `reward` | Environment | Immediate reward (may be sparse, only at terminal states) |
|
||||||
|
|
||||||
|
**Why this matters:** In traditional MCTS, sparse rewards force extensive exploration. Here, LLM provides dense `progressvalue` guidance at every node, while `statevalue` (computed via simulation) provides accurate long-term estimates. MCTS balances both via UCT:
|
||||||
|
- High `progressvalue` → explored early (fast guidance)
|
||||||
|
- High `statevalue` → exploited once confirmed (accurate value)
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
|
||||||
|
- **UCT-based node selection**: Uses Upper Confidence Bound for Trees to balance exploration/exploitation
|
||||||
|
- **Configurable expansion**: Parallel or sequential child node generation
|
||||||
|
- **Simulation with depth control**: Rollouts with configurable maximum depth
|
||||||
|
- **Reward discounting**: Backpropagation with configurable future reward decay
|
||||||
|
- **Multithreading support**: Parallel simulation phase for improved performance
|
||||||
|
|
||||||
|
### Integration with LLMs
|
||||||
|
|
||||||
|
This package is designed to work with LLMs as the state transition engine:
|
||||||
|
|
||||||
|
```julia
|
||||||
|
# LLM-based transition function
|
||||||
|
function llm_transition(state::Dict, args::NamedTuple)
|
||||||
|
# LLM generates next thought/action based on current state
|
||||||
|
response = llm_call(state[:thoughtHistory], args.prompt)
|
||||||
|
|
||||||
|
# Parse LLM output into new state
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => generate_key(),
|
||||||
|
:newstate => update_state(state, response),
|
||||||
|
:progressvalue => estimate_value(response)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
result = runMCTS(initial_state, llm_transition, args)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using Pkg
|
||||||
|
Pkg.add("LLMMCTS")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Basic Example
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# Define transition function
|
||||||
|
function transition(state::Dict, args::NamedTuple)
|
||||||
|
# Your transition logic here
|
||||||
|
return Dict(:newNodeKey => "child_1", :newstate => new_state, :progressvalue => 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Define transition arguments
|
||||||
|
transitionargs = (param1 = "value1", param2 = "value2")
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 10,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
# Access results
|
||||||
|
root = result.root
|
||||||
|
best_next_state = result.bestNextState
|
||||||
|
best_terminal_state = result.bestTerminalState
|
||||||
|
high_value_states = result.highValueStateList
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Usage
|
||||||
|
|
||||||
|
```julia
|
||||||
|
# With custom parameters
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
transition_func,
|
||||||
|
transitionargs;
|
||||||
|
horizontalSampleExpansionPhase = 5, # More children during expansion
|
||||||
|
horizontalSampleSimulationPhase = 3, # Sample 3 children during simulation
|
||||||
|
maxSimulationDepth = 5, # Deeper search
|
||||||
|
maxiterations = 50, # More iterations
|
||||||
|
explorationweight = 2.0, # More aggressive exploration
|
||||||
|
earlystop = my_earlystop_func, # Custom early stopping
|
||||||
|
saveSimulatedNode = true, # Keep simulation nodes
|
||||||
|
multithread = true # Enable parallel simulation
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### Main Functions
|
||||||
|
|
||||||
|
#### `runMCTS(initialstate, transition, transitionargs; kwargs...)`
|
||||||
|
|
||||||
|
Search for the best action to take for a given state and task.
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
- `initialstate::T` — Initial state
|
||||||
|
- `transition::Function` — State transition function
|
||||||
|
- `transitionargs::NamedTuple` — Transition function arguments
|
||||||
|
|
||||||
|
**Keyword Arguments:**
|
||||||
|
- `horizontalSampleExpansionPhase::Integer=3` — Children per expansion node
|
||||||
|
- `horizontalSampleSimulationPhase::Integer=3` — Children per simulation node
|
||||||
|
- `maxSimulationDepth::Integer=3` — Maximum simulation depth
|
||||||
|
- `maxiterations::Integer=10` — Number of MCTS iterations
|
||||||
|
- `explorationweight::Number=1.0` — Exploration weight (1.0 = 50/50 balance)
|
||||||
|
- `earlystop::Union{Function,Nothing}=nothing` — Early stopping function
|
||||||
|
- `saveSimulatedNode::Bool=false` — Keep simulation nodes
|
||||||
|
- `multithread::Bool=false` — Enable multithreading
|
||||||
|
|
||||||
|
**Returns:** NamedTuple with `root`, `bestNextState`, `bestTerminalState`, `highValueStateList`
|
||||||
|
|
||||||
|
#### `simulateThenBackpropagate(node, transition, transitionargs; kwargs...)`
|
||||||
|
|
||||||
|
Run simulation from a node and backpropagate the reward. Returns `nothing`.
|
||||||
|
|
||||||
|
**Keyword Arguments:**
|
||||||
|
- `maxSimulationDepth::Integer=3` — Maximum simulation depth
|
||||||
|
- `horizontalSampleSimulationPhase::Integer=3` — Children per simulation node
|
||||||
|
- `saveSimulatedNode::Bool=false` — Keep simulation nodes
|
||||||
|
- `multithread::Bool=false` — Enable multithreading
|
||||||
|
- `highValueState` — Channel to store high-value states
|
||||||
|
|
||||||
|
#### `backpropagate(node, simTrajectoryReward; kwargs...)`
|
||||||
|
|
||||||
|
Backpropagate reward along the simulation chain. Updates visit counts and state values for all nodes along the path to the root. Returns `nothing`.
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
- `node::MCTSNode` — The leaf node from which to start backpropagation
|
||||||
|
- `simTrajectoryReward::Number` — The total reward from the trajectory simulation
|
||||||
|
|
||||||
|
**Keyword Arguments:**
|
||||||
|
- `discountRewardCoeff::AbstractFloat=0.9` — Discount coefficient applied to future rewards
|
||||||
|
|
||||||
|
### Utility Functions
|
||||||
|
|
||||||
|
- `UCTselect(node, w)` — Select node using UCT score
|
||||||
|
- `dictify(x; keytype=Any)` — Convert JSON.Object/OrderedDict to plain Dict
|
||||||
|
|
||||||
|
### MCTS Utility Functions
|
||||||
|
|
||||||
|
- `selectBestNextNode(node)` — Select best child node based on value metric
|
||||||
|
- `selectBestTrajectoryNode(node)` — Select best node along optimal trajectory
|
||||||
|
- `backpropagate(node, simTrajectoryReward; kwargs...)` — Backpropagate reward up the tree
|
||||||
|
- `isleaf(node)` — Check if node is a leaf (has no children)
|
||||||
|
- `isroot(node)` — Check if node is the root node
|
||||||
|
- `selectChildNode(node)` — Select child with highest `progressvalue + reward`
|
||||||
|
- `expand(node, transition, transitionargs; kwargs...)` — Generate child nodes
|
||||||
|
- `simulate(node, transition, transitionargs; kwargs...)` — Perform rollout simulation
|
||||||
|
|
||||||
|
### MCTS Node Structure
|
||||||
|
|
||||||
|
```julia
|
||||||
|
MCTSNode(
|
||||||
|
nodekey::String,
|
||||||
|
state::Dict,
|
||||||
|
visits::Integer,
|
||||||
|
progressvalue::Number,
|
||||||
|
statevalue::Number,
|
||||||
|
reward::Number,
|
||||||
|
isterminal::Bool,
|
||||||
|
parent::Union{MCTSNode, Nothing},
|
||||||
|
children::Dict{String, MCTSNode},
|
||||||
|
etc::Dict{Symbol, Any}
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### How UCT Uses progressvalue and statevalue
|
||||||
|
|
||||||
|
The UCT formula selects children using both value signals:
|
||||||
|
\[ \text{UCT}(s,a) = Q(s,a) + c \sqrt{\frac{\ln N(s)}{N(s,a)}} \]
|
||||||
|
|
||||||
|
Where:
|
||||||
|
- **Exploitation term** (`Q(s,a)`) — Uses `progressvalue` for fast guidance, refined by `statevalue` as simulations accumulate
|
||||||
|
- **Exploration term** — Encourages visiting less-explored branches, even those with high `progressvalue` but low visit count
|
||||||
|
|
||||||
|
**Selection priority:**
|
||||||
|
1. Nodes with high `progressvalue` and low `visits` → explored first (fast guidance)
|
||||||
|
2. Nodes with high `statevalue` confirmed by simulations → exploited once reliable
|
||||||
|
3. Balance determined by `explorationweight` parameter
|
||||||
|
|
||||||
|
### When to Use LLM-MCTS
|
||||||
|
|
||||||
|
| Scenario | Why LLM-MCTS is suitable |
|
||||||
|
|----------|--------------------------|
|
||||||
|
| **Sparse reward environments** | Rewards only at terminal states (e.g., game win, code execution success) |
|
||||||
|
| **Complex reasoning tasks** | Tasks requiring multi-step planning (math, coding, tool use) |
|
||||||
|
| **High branching factor** | Many possible actions; LLM filters to promising candidates |
|
||||||
|
| **Need sample efficiency** | Limited budget for environment interactions |
|
||||||
|
|
||||||
|
### When Not to Use LLM-MCTS
|
||||||
|
|
||||||
|
| Scenario | Alternative approach |
|
||||||
|
|----------|---------------------|
|
||||||
|
| **Dense rewards available** | Use pure RL with reward shaping |
|
||||||
|
| **Simple decision problems** | Classical search (DFS, BFS) is sufficient |
|
||||||
|
| **Real-time constraints** | LLM calls may be too slow; use pre-trained value function |
|
||||||
|
| **No LLM access** | Use pure MCTS with hand-designed heuristics |
|
||||||
|
|
||||||
|
### Performance Characteristics
|
||||||
|
|
||||||
|
| Metric | Typical range |
|
||||||
|
|--------|---------------|
|
||||||
|
| **Sample efficiency** | 5-10x fewer samples than pure Monte Carlo |
|
||||||
|
| **LLM calls per iteration** | 1-5 (depends on `horizontalSample*` settings) |
|
||||||
|
| **Convergence time** | Scales with depth × LLM latency |
|
||||||
|
| **Memory usage** | O(branching_factor^depth) for tree storage |
|
||||||
|
|
||||||
|
### Limitations
|
||||||
|
|
||||||
|
- **LLM latency** — Each node expansion requires an LLM call; can be slow for large trees
|
||||||
|
- **LLM cost** — Each LLM invocation has financial cost; monitor usage
|
||||||
|
- **Heuristic quality** — Poor LLM pseudo-rewards lead to suboptimal search
|
||||||
|
- **Determinism** — LLM outputs are stochastic; use temperature=0 for reproducibility
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Please open issues for bugs or feature requests, and submit PRs for improvements.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License — see [LICENSE](LICENSE) for details.
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
narawat lamaiin <narawat@outlook.com>
|
||||||
+1177
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
|||||||
|
# LLMMCTS Examples
|
||||||
|
|
||||||
|
This directory contains example scripts demonstrating how to use LLMMCTS for various problem types.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
1. **simple_example.jl** - Basic MCTS usage with a simple state transition function
|
||||||
|
2. **pathfinding.jl** - Grid-based pathfinding problem
|
||||||
|
3. **math_problem.jl** - Solving math problems using MCTS-guided reasoning
|
||||||
|
4. **tool_use.jl** - Coordinating with external tools (APIs, databases)
|
||||||
|
5. **chess_game.jl** - Game playing scenario (simplified chess-like)
|
||||||
|
6. **code_generation.jl** - Guiding LLM code generation
|
||||||
|
7. **reasoning.jl** - Multi-step reasoning with chain-of-thought
|
||||||
|
8. **configuration_examples.jl** - Demonstrating different MCTS configuration options
|
||||||
|
|
||||||
|
## Running Examples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
julia examples/simple_example.jl
|
||||||
|
julia examples/pathfinding.jl
|
||||||
|
julia examples/configuration_examples.jl
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Concepts
|
||||||
|
|
||||||
|
### State
|
||||||
|
The state is represented as a `Dict{String, Any}` that contains all information needed for the problem.
|
||||||
|
|
||||||
|
### Transition Function
|
||||||
|
The transition function takes the current state and returns:
|
||||||
|
```julia
|
||||||
|
Dict(
|
||||||
|
:newNodeKey => unique_id,
|
||||||
|
:newstate => new_state_dict,
|
||||||
|
:progressvalue => llm_estimate
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Progress Value
|
||||||
|
`progressvalue` is provided by LLM reasoning and guides the search without waiting for terminal rewards.
|
||||||
|
|
||||||
|
### State Value
|
||||||
|
`statevalue` is computed through Monte Carlo simulations and provides accurate long-term estimates.
|
||||||
|
|
||||||
|
## Configuration Parameters
|
||||||
|
|
||||||
|
- `maxiterations` - Number of MCTS iterations (default: 10)
|
||||||
|
- `explorationweight` - UCT exploration weight (default: 1.0)
|
||||||
|
- `maxSimulationDepth` - Maximum simulation rollout depth (default: 3)
|
||||||
|
- `horizontalSampleExpansionPhase` - Children per expansion (default: 3)
|
||||||
|
- `multithread` - Enable parallel simulation (default: false)
|
||||||
|
- `saveSimulatedNode` - Keep simulation nodes (default: false)
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [README.md](../README.md) - Complete package documentation
|
||||||
|
- [workprocess.md](../workprocess.md) - Detailed technical documentation
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
# Chess-like Game Example - MCTS for Game Playing
|
||||||
|
|
||||||
|
This example demonstrates MCTS for a simplified chess-like game where the goal is to capture the opponent's pieces.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# Simple game state
|
||||||
|
# board: Dict mapping positions to pieces
|
||||||
|
# turn: :white or :black
|
||||||
|
struct GameState
|
||||||
|
board::Dict{String, String} # position => piece
|
||||||
|
turn::Symbol
|
||||||
|
piece_count::Int
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initialize a simple board
|
||||||
|
function init_board()
|
||||||
|
board = Dict{String, String}()
|
||||||
|
|
||||||
|
# Place some pieces
|
||||||
|
board["e1"] = "K" # White King
|
||||||
|
board["e8"] = "k" # Black King
|
||||||
|
|
||||||
|
# Random pieces
|
||||||
|
board["d4"] = "P" # White Pawn
|
||||||
|
board["d5"] = "p" # Black Pawn
|
||||||
|
|
||||||
|
return board
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if position is on board
|
||||||
|
function on_board(pos::String)
|
||||||
|
cols = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
|
||||||
|
rows = ['1', '2', '3', '4', '5', '6', '7', '8']
|
||||||
|
length(pos) == 2 &&
|
||||||
|
pos[1] in cols &&
|
||||||
|
pos[2] in rows
|
||||||
|
end
|
||||||
|
|
||||||
|
# Game transition function
|
||||||
|
function chess_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
board = state[:board]
|
||||||
|
turn = state[:turn]
|
||||||
|
|
||||||
|
if current_step >= args.max_moves
|
||||||
|
# Max moves reached, end game
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step + 1,
|
||||||
|
:board => board,
|
||||||
|
:turn => turn,
|
||||||
|
:reward => 0.0,
|
||||||
|
:isterminal => true
|
||||||
|
)
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "max_moves",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => 5.0
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Generate possible moves
|
||||||
|
possible_moves = String[]
|
||||||
|
|
||||||
|
# Find all pieces of current turn's color
|
||||||
|
turn_prefix = turn == :white ? "upper" : "lower"
|
||||||
|
|
||||||
|
# Simple move generation: try moving each piece
|
||||||
|
for (pos, piece) in board
|
||||||
|
if !isempty(piece)
|
||||||
|
# Try moving to adjacent positions
|
||||||
|
for dx in [-1, 0, 1]
|
||||||
|
for dy in [-1, 0, 1]
|
||||||
|
if dx == 0 && dy == 0
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
# Simple coordinate conversion
|
||||||
|
col = pos[1]
|
||||||
|
row = parse(Int, pos[2])
|
||||||
|
|
||||||
|
new_col = col + dx
|
||||||
|
new_row = row + dy
|
||||||
|
|
||||||
|
if new_col >= 'a' && new_col <= 'h' &&
|
||||||
|
new_row >= 1 && new_row <= 8
|
||||||
|
new_pos = string(new_col, new_row)
|
||||||
|
if on_board(new_pos)
|
||||||
|
push!(possible_moves, pos * new_pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if isempty(possible_moves)
|
||||||
|
# No moves available, game over
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step + 1,
|
||||||
|
:board => board,
|
||||||
|
:turn => turn,
|
||||||
|
:reward => turn == :white ? 10.0 : -10.0,
|
||||||
|
:isterminal => true
|
||||||
|
)
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "game_over",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => turn == :white ? 10.0 : 0.0
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# LLM would select the best move
|
||||||
|
# For this example, pick a random valid move
|
||||||
|
move_idx = (current_step - 1) % length(possible_moves) + 1
|
||||||
|
move = possible_moves[move_idx]
|
||||||
|
|
||||||
|
# Simulate the move (simplified)
|
||||||
|
from_pos = move[1:2]
|
||||||
|
to_pos = move[3:4]
|
||||||
|
|
||||||
|
new_board = copy(board)
|
||||||
|
piece = get(new_board, from_pos, "")
|
||||||
|
new_board[to_pos] = piece
|
||||||
|
delete!(new_board, from_pos)
|
||||||
|
|
||||||
|
# Calculate reward based on capture
|
||||||
|
reward = 0.0
|
||||||
|
if !isempty(get(new_board, to_pos, ""))
|
||||||
|
reward = 5.0 # Capture!
|
||||||
|
end
|
||||||
|
|
||||||
|
# Progress value: estimate of game state quality
|
||||||
|
progressvalue = 5.0 + reward # Capturing is good
|
||||||
|
|
||||||
|
# Switch turns
|
||||||
|
new_turn = turn == :white ? :black : :white
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step + 1,
|
||||||
|
:board => new_board,
|
||||||
|
:turn => new_turn,
|
||||||
|
:reward => reward,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "move_$current_step",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initial state
|
||||||
|
initialstate = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:board => init_board(),
|
||||||
|
:turn => :white,
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transition arguments
|
||||||
|
transitionargs = (
|
||||||
|
max_moves = 10,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
chess_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 30,
|
||||||
|
explorationweight = 2.0, # More exploration for game playing
|
||||||
|
maxSimulationDepth = 4,
|
||||||
|
horizontalSampleExpansionPhase = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display results
|
||||||
|
println("Chess-like Game MCTS")
|
||||||
|
println("====================")
|
||||||
|
println()
|
||||||
|
println("Best move sequence:")
|
||||||
|
println(" Initial board state")
|
||||||
|
println(" → ", result.bestTerminalState[:step], " moves")
|
||||||
|
println()
|
||||||
|
println("Final board has ", length(result.bestTerminalState[:board]), " pieces")
|
||||||
|
println("Root node visits: ", result.root.visits)
|
||||||
|
println("High value states: ", length(result.highValueStateList))
|
||||||
|
```
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# Code Generation - MCTS for Programming Tasks
|
||||||
|
|
||||||
|
This example shows how MCTS can guide LLM code generation by exploring different implementation strategies.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# State represents the current state of code generation
|
||||||
|
# It includes the code written so far and the problem being solved
|
||||||
|
|
||||||
|
function code_generation_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
problem = state[:problem]
|
||||||
|
code_so_far = get(state, :code, "")
|
||||||
|
|
||||||
|
if current_step == 0
|
||||||
|
# First step: Plan the approach
|
||||||
|
new_code = """
|
||||||
|
# Function to solve: $(problem)
|
||||||
|
function solve_problem(input)
|
||||||
|
"""
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 1,
|
||||||
|
:code => new_code,
|
||||||
|
:thought => "Plan the approach for: $(problem)",
|
||||||
|
:reward => 2.0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
progressvalue = 5.0
|
||||||
|
elseif current_step == 1
|
||||||
|
# Second step: Implement main logic
|
||||||
|
new_code = code_so_far * """
|
||||||
|
# Main logic implementation
|
||||||
|
result = input * 2 # Placeholder implementation
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 2,
|
||||||
|
:code => new_code,
|
||||||
|
:thought => "Implement main function logic",
|
||||||
|
:reward => 3.0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
progressvalue = 7.0
|
||||||
|
elseif current_step == 2
|
||||||
|
# Third step: Add tests
|
||||||
|
new_code = code_so_far * """
|
||||||
|
|
||||||
|
# Test the function
|
||||||
|
@assert solve_problem(5) == 10
|
||||||
|
@assert solve_problem(0) == 0
|
||||||
|
println("All tests passed!")
|
||||||
|
"""
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 3,
|
||||||
|
:code => new_code,
|
||||||
|
:thought => "Add unit tests to verify implementation",
|
||||||
|
:reward => 5.0,
|
||||||
|
:isterminal => true # Code generation complete
|
||||||
|
)
|
||||||
|
progressvalue = 10.0
|
||||||
|
else
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step,
|
||||||
|
:code => code_so_far,
|
||||||
|
:thought => "Code generation complete",
|
||||||
|
:reward => 10.0,
|
||||||
|
:isterminal => true
|
||||||
|
)
|
||||||
|
progressvalue = 10.0
|
||||||
|
end
|
||||||
|
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "code_step_$current_step",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initial state
|
||||||
|
initialstate = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:problem => "Create a function that doubles its input",
|
||||||
|
:code => "",
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transition arguments
|
||||||
|
transitionargs = (max_steps = 3,)
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
code_generation_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 20,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display results
|
||||||
|
println("Code Generation Example")
|
||||||
|
println("=======================")
|
||||||
|
println()
|
||||||
|
println("Problem: ", initialstate[:problem])
|
||||||
|
println()
|
||||||
|
println("Generated code:")
|
||||||
|
println(result.bestTerminalState[:code])
|
||||||
|
println()
|
||||||
|
println("Code generation complete! ✓")
|
||||||
|
println("Root node visits: ", result.root.visits)
|
||||||
|
```
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
# MCTS Configuration Examples
|
||||||
|
|
||||||
|
This file demonstrates different MCTS configuration options and their effects on search behavior.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# Simple transition function for demonstration
|
||||||
|
function simple_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step + 1,
|
||||||
|
:reward => (current_step + 1) * 2,
|
||||||
|
:isterminal => current_step >= args.max_steps - 1
|
||||||
|
)
|
||||||
|
progressvalue = (current_step / args.max_steps) * 10
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "step_$current_step",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
initialstate = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
transitionargs = (max_steps = 5,)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 1: Balanced Search (Default)
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 1: Balanced Search (Default)")
|
||||||
|
println("=" ^ 50)
|
||||||
|
|
||||||
|
result1 = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 10,
|
||||||
|
explorationweight = 1.0, # Balanced exploration/exploitation
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
println("Exploration weight: 1.0 (balanced)")
|
||||||
|
println("Root visits: ", result1.root.visits)
|
||||||
|
println("Best terminal step: ", result1.bestTerminalState[:step])
|
||||||
|
println()
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 2: Aggressive Exploration
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 2: Aggressive Exploration")
|
||||||
|
println("=" * 50)
|
||||||
|
|
||||||
|
result2 = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 10,
|
||||||
|
explorationweight = 2.0, # More exploration
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 5 # More children per node
|
||||||
|
)
|
||||||
|
|
||||||
|
println("Exploration weight: 2.0 (aggressive exploration)")
|
||||||
|
println("Root visits: ", result2.root.visits)
|
||||||
|
println("Children explored: ", length(result2.root.children))
|
||||||
|
println()
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 3: Deep Search (Long Horizon)
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 3: Deep Search (Long Horizon)")
|
||||||
|
println("=" * 50)
|
||||||
|
|
||||||
|
result3 = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 20,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 5, # Deeper search
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
println("Max simulation depth: 5 (deep search)")
|
||||||
|
println("Root visits: ", result3.root.visits)
|
||||||
|
println("Search explores further into the future")
|
||||||
|
println()
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 4: Fast Search (Shallow, Many Iterations)
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 4: Fast Search (Shallow, Many Iterations)")
|
||||||
|
println("=" * 50)
|
||||||
|
|
||||||
|
result4 = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 50, # Many iterations
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 2, # Shallow search
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
println("Many iterations (50), shallow depth (2)")
|
||||||
|
println("Root visits: ", result4.root.visits)
|
||||||
|
println("Faster but less thorough search")
|
||||||
|
println()
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 5: Parallel Simulation (Multithreading)
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 5: Parallel Simulation (Multithreading)")
|
||||||
|
println("=" * 50)
|
||||||
|
|
||||||
|
result5 = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 10,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3,
|
||||||
|
multithread = true # Enable parallel simulation
|
||||||
|
)
|
||||||
|
|
||||||
|
println("Multithreading enabled")
|
||||||
|
println("Root visits: ", result5.root.visits)
|
||||||
|
println("Parallel simulation across child nodes")
|
||||||
|
println()
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 6: Early Stopping
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 6: Early Stopping")
|
||||||
|
println("=" * 50)
|
||||||
|
|
||||||
|
# Define early stopping function
|
||||||
|
function early_stop(state::Dict)
|
||||||
|
# Stop when we reach a good enough solution
|
||||||
|
return get(state, :step, 0) >= 3
|
||||||
|
end
|
||||||
|
|
||||||
|
result6 = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 20, # Would run more if not for early stop
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3,
|
||||||
|
earlystop = early_stop
|
||||||
|
)
|
||||||
|
|
||||||
|
println("Early stopping enabled (stops at step >= 3)")
|
||||||
|
println("Actual iterations: ", result6.root.visits)
|
||||||
|
println("Early stopping saved unnecessary computation")
|
||||||
|
println()
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 7: Save Simulation Nodes (for Analysis)
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 7: Save Simulation Nodes")
|
||||||
|
println("=" * 50)
|
||||||
|
|
||||||
|
result7 = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 5,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3,
|
||||||
|
saveSimulatedNode = true # Keep simulation nodes
|
||||||
|
)
|
||||||
|
|
||||||
|
println("saveSimulatedNode = true")
|
||||||
|
println("Simulation nodes are preserved")
|
||||||
|
println("Root children: ", length(result7.root.children))
|
||||||
|
println("Useful for debugging or further analysis")
|
||||||
|
println()
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Example 8: High-Value State Tracking
|
||||||
|
# ============================================================================
|
||||||
|
println("Example 8: High-Value State Tracking")
|
||||||
|
println("=" * 50)
|
||||||
|
|
||||||
|
# Transition that can produce high-value states
|
||||||
|
function high_value_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
reward = current_step * 3
|
||||||
|
|
||||||
|
# Occasionally produce high-value states
|
||||||
|
if current_step == 2 || current_step == 4
|
||||||
|
reward = 9.0 # High value
|
||||||
|
end
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step + 1,
|
||||||
|
:reward => reward,
|
||||||
|
:isterminal => current_step >= args.max_steps - 1
|
||||||
|
)
|
||||||
|
progressvalue = (current_step / args.max_steps) * 10
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "step_$current_step",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
high_value_initial = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
result8 = runMCTS(
|
||||||
|
high_value_initial,
|
||||||
|
high_value_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 15,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
println("High-value states found: ", length(result8.highValueStateList))
|
||||||
|
println("States with reward >= 8 were tracked")
|
||||||
|
for (i, state) in enumerate(result8.highValueStateList)
|
||||||
|
println(" High-value state $i: step = ", state[:step])
|
||||||
|
end
|
||||||
|
```
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
# Math Problem Solving - MCTS Example
|
||||||
|
|
||||||
|
This example demonstrates using MCTS to solve a math problem by exploring different solution strategies.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# State represents the current state of problem solving
|
||||||
|
# It contains the problem statement and the steps taken so far
|
||||||
|
|
||||||
|
function math_problem_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
problem = state[:problem]
|
||||||
|
|
||||||
|
# Example problem: Solve x^2 = 16
|
||||||
|
if current_step == 0
|
||||||
|
# First step: analyze the problem
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 1,
|
||||||
|
:thought => "This is a quadratic equation x^2 = 16",
|
||||||
|
:action => "Take square root of both sides",
|
||||||
|
:reward => 2.0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
progressvalue = 5.0
|
||||||
|
elseif current_step == 1
|
||||||
|
# Second step: solve
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 2,
|
||||||
|
:thought => "Taking square root gives x = ±4",
|
||||||
|
:action => "x = sqrt(16) or x = -sqrt(16)",
|
||||||
|
:reward => 3.0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
progressvalue = 7.0
|
||||||
|
elseif current_step == 2
|
||||||
|
# Third step: verify
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 3,
|
||||||
|
:thought => "Verify both solutions work",
|
||||||
|
:action => "Check x=4: 4^2=16 ✓, Check x=-4: (-4)^2=16 ✓",
|
||||||
|
:reward => 5.0,
|
||||||
|
:isterminal => true # Problem solved!
|
||||||
|
)
|
||||||
|
progressvalue = 10.0
|
||||||
|
else
|
||||||
|
# Terminal state
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step,
|
||||||
|
:thought => "Problem solved",
|
||||||
|
:action => "Solution complete",
|
||||||
|
:reward => 10.0,
|
||||||
|
:isterminal => true
|
||||||
|
)
|
||||||
|
progressvalue = 10.0
|
||||||
|
end
|
||||||
|
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "step_$current_step",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initial state
|
||||||
|
initialstate = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:problem => "Solve x^2 = 16",
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transition arguments
|
||||||
|
transitionargs = ()
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
math_problem_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 15,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display results
|
||||||
|
println("Problem: ", initialstate[:problem])
|
||||||
|
println()
|
||||||
|
println("Best solution trajectory:")
|
||||||
|
println(" Step ", result.bestTerminalState[:step])
|
||||||
|
println(" Thought: ", result.bestTerminalState[:thought])
|
||||||
|
println(" Action: ", result.bestTerminalState[:action])
|
||||||
|
println()
|
||||||
|
println("Solution complete! ✓")
|
||||||
|
println("Root node visits: ", result.root.visits)
|
||||||
|
```
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# Pathfinding Problem - MCTS Example
|
||||||
|
|
||||||
|
This example shows how to use MCTS for a pathfinding problem where the goal is to reach a target location.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# Grid-based pathfinding state
|
||||||
|
struct Position
|
||||||
|
x::Int
|
||||||
|
y::Int
|
||||||
|
end
|
||||||
|
|
||||||
|
# State transition function for pathfinding
|
||||||
|
function pathfinding_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_pos = Position(state[:pos_x], state[:pos_y])
|
||||||
|
target_pos = Position(args.target_x, args.target_y)
|
||||||
|
|
||||||
|
# Generate possible moves (up, down, left, right)
|
||||||
|
moves = [
|
||||||
|
(0, 1), # up
|
||||||
|
(0, -1), # down
|
||||||
|
(1, 0), # right
|
||||||
|
(-1, 0) # left
|
||||||
|
]
|
||||||
|
|
||||||
|
# In a real scenario, LLM would select which move to try
|
||||||
|
# For this example, we'll try all moves
|
||||||
|
move_idx = state[:move_idx] % length(moves) + 1
|
||||||
|
dx, dy = moves[move_idx]
|
||||||
|
|
||||||
|
new_x = current_pos.x + dx
|
||||||
|
new_y = current_pos.y + dy
|
||||||
|
|
||||||
|
# Calculate distance to target
|
||||||
|
distance = abs(new_x - target_pos.x) + abs(new_y - target_pos.y)
|
||||||
|
|
||||||
|
# Reward: negative of distance (closer is better)
|
||||||
|
reward = -distance
|
||||||
|
|
||||||
|
# Progress value: LLM estimate (here we use inverse distance as heuristic)
|
||||||
|
progressvalue = 10 - distance
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:pos_x => new_x,
|
||||||
|
:pos_y => new_y,
|
||||||
|
:move_idx => state[:move_idx] + 1,
|
||||||
|
:reward => reward,
|
||||||
|
:isterminal => (new_x == target_pos.x && new_y == target_pos.y) ||
|
||||||
|
(state[:move_idx] >= args.max_moves)
|
||||||
|
)
|
||||||
|
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "pos_$(new_x)_$(new_y)",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initial state
|
||||||
|
initialstate = Dict(
|
||||||
|
:pos_x => 0,
|
||||||
|
:pos_y => 0,
|
||||||
|
:move_idx => 0,
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Target position
|
||||||
|
target_x, target_y = 3, 2
|
||||||
|
|
||||||
|
# Transition arguments
|
||||||
|
transitionargs = (
|
||||||
|
target_x = target_x,
|
||||||
|
target_y = target_y,
|
||||||
|
max_moves = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
pathfinding_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 20,
|
||||||
|
explorationweight = 1.5,
|
||||||
|
maxSimulationDepth = 5,
|
||||||
|
horizontalSampleExpansionPhase = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display results
|
||||||
|
println("Target: ($target_x, $target_y)")
|
||||||
|
println("Best final position: (",
|
||||||
|
result.bestTerminalState[:pos_x], ", ",
|
||||||
|
result.bestTerminalState[:pos_y], ")")
|
||||||
|
println("Final distance: ", abs(result.bestTerminalState[:pos_x] - target_x) +
|
||||||
|
abs(result.bestTerminalState[:pos_y] - target_y))
|
||||||
|
println("Root node visits: ", result.root.visits)
|
||||||
|
```
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
# Multi-step Reasoning - MCTS with Chain of Thought
|
||||||
|
|
||||||
|
This example demonstrates MCTS for multi-step reasoning problems, where the LLM generates chain-of-thought reasoning at each step.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# State tracks the reasoning process
|
||||||
|
# thought_history: Dict mapping thought/action keys to their content
|
||||||
|
|
||||||
|
function reasoning_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
thought_history = get(state, :thought_history, Dict{String, String}())
|
||||||
|
problem = state[:problem]
|
||||||
|
|
||||||
|
if current_step == 0
|
||||||
|
# Step 1: Understand the problem
|
||||||
|
thought = "First, I need to understand what the problem is asking. The problem requires me to analyze the given information and determine the solution approach."
|
||||||
|
action = "Identify the key components of the problem"
|
||||||
|
|
||||||
|
new_thought_history = copy(thought_history)
|
||||||
|
new_thought_history["thought_1"] = thought
|
||||||
|
new_thought_history["action_1"] = action
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 1,
|
||||||
|
:thought_history => new_thought_history,
|
||||||
|
:reward => 1.0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
progressvalue = 3.0
|
||||||
|
elseif current_step == 1
|
||||||
|
# Step 2: Break down the problem
|
||||||
|
thought = "Next, I should break this down into smaller sub-problems. This will make it easier to solve step by step."
|
||||||
|
action = "Divide the problem into manageable parts"
|
||||||
|
|
||||||
|
new_thought_history = copy(thought_history)
|
||||||
|
new_thought_history["thought_2"] = thought
|
||||||
|
new_thought_history["action_2"] = action
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 2,
|
||||||
|
:thought_history => new_thought_history,
|
||||||
|
:reward => 2.0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
progressvalue = 5.0
|
||||||
|
elseif current_step == 2
|
||||||
|
# Step 3: Solve each sub-problem
|
||||||
|
thought = "Now I'll solve each sub-problem individually, using appropriate methods for each."
|
||||||
|
action = "Apply solution methods to each sub-problem"
|
||||||
|
|
||||||
|
new_thought_history = copy(thought_history)
|
||||||
|
new_thought_history["thought_3"] = thought
|
||||||
|
new_thought_history["action_3"] = action
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 3,
|
||||||
|
:thought_history => new_thought_history,
|
||||||
|
:reward => 3.0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
progressvalue = 7.0
|
||||||
|
elseif current_step == 3
|
||||||
|
# Step 4: Combine solutions
|
||||||
|
thought = "Finally, I'll combine all the solutions to form the complete answer to the original problem."
|
||||||
|
action = "Integrate solutions and verify the answer"
|
||||||
|
|
||||||
|
new_thought_history = copy(thought_history)
|
||||||
|
new_thought_history["thought_4"] = thought
|
||||||
|
new_thought_history["action_4"] = action
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:step => 4,
|
||||||
|
:thought_history => new_thought_history,
|
||||||
|
:reward => 4.0,
|
||||||
|
:isterminal => true # Reasoning complete
|
||||||
|
)
|
||||||
|
progressvalue = 10.0
|
||||||
|
else
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step,
|
||||||
|
:thought_history => thought_history,
|
||||||
|
:reward => 10.0,
|
||||||
|
:isterminal => true
|
||||||
|
)
|
||||||
|
progressvalue = 10.0
|
||||||
|
end
|
||||||
|
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "reasoning_step_$current_step",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initial state
|
||||||
|
initialstate = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:problem => "Explain how photosynthesis works",
|
||||||
|
:thought_history => Dict{String, String}(),
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transition arguments
|
||||||
|
transitionargs = (max_steps = 4,)
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
reasoning_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 25,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 4,
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display results
|
||||||
|
println("Multi-step Reasoning Example")
|
||||||
|
println("=============================")
|
||||||
|
println()
|
||||||
|
println("Problem: ", initialstate[:problem])
|
||||||
|
println()
|
||||||
|
println("Reasoning steps:")
|
||||||
|
for (key, value) in result.bestTerminalState[:thought_history]
|
||||||
|
println(" $key: $value")
|
||||||
|
end
|
||||||
|
println()
|
||||||
|
println("Reasoning complete! ✓")
|
||||||
|
println("Root node visits: ", result.root.visits)
|
||||||
|
println("Total steps in reasoning chain: ", result.bestTerminalState[:step])
|
||||||
|
```
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# Simple MCTS Example
|
||||||
|
|
||||||
|
This example demonstrates basic MCTS usage with a simple state transition function.
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# Define a simple state transition function
|
||||||
|
function simple_transition(state::Dict, args::NamedTuple)
|
||||||
|
# In a real scenario, this would call an LLM
|
||||||
|
# For this example, we'll just generate deterministic next states
|
||||||
|
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
new_step = current_step + 1
|
||||||
|
|
||||||
|
# Create new state
|
||||||
|
newstate = Dict(
|
||||||
|
:step => new_step,
|
||||||
|
:reward => new_step * 2, # Simple reward function
|
||||||
|
:isterminal => new_step >= args.max_steps
|
||||||
|
)
|
||||||
|
|
||||||
|
# LLM would provide progressvalue estimate
|
||||||
|
progressvalue = (new_step / args.max_steps) * 10
|
||||||
|
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "step_$(new_step)",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initial state
|
||||||
|
initialstate = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transition arguments
|
||||||
|
transitionargs = (max_steps = 5,)
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
simple_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 10,
|
||||||
|
explorationweight = 1.0,
|
||||||
|
maxSimulationDepth = 3,
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
# Access results
|
||||||
|
println("Root node visits: ", result.root.visits)
|
||||||
|
println("Best next state: ", result.bestNextState)
|
||||||
|
println("Best terminal state: ", result.bestTerminalState)
|
||||||
|
println("High value states: ", result.highValueStateList)
|
||||||
|
```
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
# Tool Use Example - MCTS with External Tools
|
||||||
|
|
||||||
|
This example shows how MCTS can coordinate with external tools (like APIs, databases, or other services).
|
||||||
|
|
||||||
|
```julia
|
||||||
|
using LLMMCTS
|
||||||
|
|
||||||
|
# Simulated tool interface
|
||||||
|
struct Tool
|
||||||
|
name::String
|
||||||
|
description::String
|
||||||
|
end
|
||||||
|
|
||||||
|
const AVAILABLE_TOOLS = [
|
||||||
|
Tool("calculator", "Perform mathematical calculations"),
|
||||||
|
Tool("web_search", "Search the web for information"),
|
||||||
|
Tool("database_query", "Query a database")
|
||||||
|
]
|
||||||
|
|
||||||
|
# State tracks which tools have been used and their results
|
||||||
|
function tool_use_transition(state::Dict, args::NamedTuple)
|
||||||
|
current_step = get(state, :step, 0)
|
||||||
|
tools_used = get(state, :tools_used, String[])
|
||||||
|
|
||||||
|
# LLM would decide which tool to use
|
||||||
|
# For this example, we try tools in order
|
||||||
|
tool_idx = (current_step - 1) % length(AVAILABLE_TOOLS) + 1
|
||||||
|
|
||||||
|
if tool_idx > length(AVAILABLE_TOOLS)
|
||||||
|
# All tools tried, return terminal state
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step + 1,
|
||||||
|
:tools_used => tools_used,
|
||||||
|
:reward => 8.0,
|
||||||
|
:isterminal => true
|
||||||
|
)
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "all_tools_tried",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => 8.0
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
tool = AVAILABLE_TOOLS[tool_idx]
|
||||||
|
|
||||||
|
# Simulate tool execution
|
||||||
|
tool_result = "Tool '$(tool.name)' executed successfully"
|
||||||
|
|
||||||
|
# Calculate reward based on progress
|
||||||
|
progress = length(tools_used) / length(AVAILABLE_TOOLS)
|
||||||
|
reward = progress * 5
|
||||||
|
|
||||||
|
# Progress value: LLM estimates how close we are to solving
|
||||||
|
progressvalue = progress * 10
|
||||||
|
|
||||||
|
new_tools_used = vcat(tools_used, tool.name)
|
||||||
|
|
||||||
|
newstate = Dict(
|
||||||
|
:step => current_step + 1,
|
||||||
|
:tools_used => new_tools_used,
|
||||||
|
:current_tool => tool.name,
|
||||||
|
:tool_result => tool_result,
|
||||||
|
:reward => reward,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
return Dict(
|
||||||
|
:newNodeKey => "tool_$(tool.name)_$current_step",
|
||||||
|
:newstate => newstate,
|
||||||
|
:progressvalue => progressvalue
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initial state
|
||||||
|
initialstate = Dict(
|
||||||
|
:step => 0,
|
||||||
|
:tools_used => String[],
|
||||||
|
:reward => 0,
|
||||||
|
:isterminal => false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Transition arguments
|
||||||
|
transitionargs = (max_tools = 3,)
|
||||||
|
|
||||||
|
# Run MCTS
|
||||||
|
result = runMCTS(
|
||||||
|
initialstate,
|
||||||
|
tool_use_transition,
|
||||||
|
transitionargs;
|
||||||
|
maxiterations = 20,
|
||||||
|
explorationweight = 1.2,
|
||||||
|
maxSimulationDepth = 4,
|
||||||
|
horizontalSampleExpansionPhase = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display results
|
||||||
|
println("Available tools:")
|
||||||
|
for tool in AVAILABLE_TOOLS
|
||||||
|
println(" - $(tool.name): $(tool.description)")
|
||||||
|
end
|
||||||
|
println()
|
||||||
|
println("Best tool usage sequence:")
|
||||||
|
for tool in result.bestTerminalState[:tools_used]
|
||||||
|
println(" → Used: $tool")
|
||||||
|
end
|
||||||
|
println()
|
||||||
|
println("Root node visits: ", result.root.visits)
|
||||||
|
println("High value states found: ", length(result.highValueStateList))
|
||||||
|
```
|
||||||
@@ -1,476 +0,0 @@
|
|||||||
# This file is machine-generated - editing it directly is not advised
|
|
||||||
|
|
||||||
julia_version = "1.10.3"
|
|
||||||
manifest_format = "2.0"
|
|
||||||
project_hash = "b7e1f171d36dc4812d6c1445da530f513320e6cd"
|
|
||||||
|
|
||||||
[[deps.AliasTables]]
|
|
||||||
deps = ["PtrArrays", "Random"]
|
|
||||||
git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff"
|
|
||||||
uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8"
|
|
||||||
version = "1.1.3"
|
|
||||||
|
|
||||||
[[deps.ArgTools]]
|
|
||||||
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
|
|
||||||
version = "1.1.1"
|
|
||||||
|
|
||||||
[[deps.Artifacts]]
|
|
||||||
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
|
|
||||||
|
|
||||||
[[deps.Base64]]
|
|
||||||
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
|
||||||
|
|
||||||
[[deps.Calculus]]
|
|
||||||
deps = ["LinearAlgebra"]
|
|
||||||
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad"
|
|
||||||
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
|
|
||||||
version = "0.5.1"
|
|
||||||
|
|
||||||
[[deps.CodeTracking]]
|
|
||||||
deps = ["InteractiveUtils", "UUIDs"]
|
|
||||||
git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386"
|
|
||||||
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
|
|
||||||
version = "1.3.5"
|
|
||||||
|
|
||||||
[[deps.Compat]]
|
|
||||||
deps = ["TOML", "UUIDs"]
|
|
||||||
git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248"
|
|
||||||
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
|
|
||||||
version = "4.15.0"
|
|
||||||
weakdeps = ["Dates", "LinearAlgebra"]
|
|
||||||
|
|
||||||
[deps.Compat.extensions]
|
|
||||||
CompatLinearAlgebraExt = "LinearAlgebra"
|
|
||||||
|
|
||||||
[[deps.CompilerSupportLibraries_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl"]
|
|
||||||
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
|
||||||
version = "1.1.1+0"
|
|
||||||
|
|
||||||
[[deps.DataAPI]]
|
|
||||||
git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe"
|
|
||||||
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
|
|
||||||
version = "1.16.0"
|
|
||||||
|
|
||||||
[[deps.DataStructures]]
|
|
||||||
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
|
|
||||||
git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82"
|
|
||||||
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
|
||||||
version = "0.18.20"
|
|
||||||
|
|
||||||
[[deps.Dates]]
|
|
||||||
deps = ["Printf"]
|
|
||||||
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
|
||||||
|
|
||||||
[[deps.Distributed]]
|
|
||||||
deps = ["Random", "Serialization", "Sockets"]
|
|
||||||
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
|
||||||
|
|
||||||
[[deps.Distributions]]
|
|
||||||
deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
|
|
||||||
git-tree-sha1 = "9c405847cc7ecda2dc921ccf18b47ca150d7317e"
|
|
||||||
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
|
|
||||||
version = "0.25.109"
|
|
||||||
|
|
||||||
[deps.Distributions.extensions]
|
|
||||||
DistributionsChainRulesCoreExt = "ChainRulesCore"
|
|
||||||
DistributionsDensityInterfaceExt = "DensityInterface"
|
|
||||||
DistributionsTestExt = "Test"
|
|
||||||
|
|
||||||
[deps.Distributions.weakdeps]
|
|
||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
|
||||||
DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
|
|
||||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
|
||||||
|
|
||||||
[[deps.DocStringExtensions]]
|
|
||||||
deps = ["LibGit2"]
|
|
||||||
git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d"
|
|
||||||
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
|
|
||||||
version = "0.9.3"
|
|
||||||
|
|
||||||
[[deps.Downloads]]
|
|
||||||
deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
|
|
||||||
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
|
|
||||||
version = "1.6.0"
|
|
||||||
|
|
||||||
[[deps.DualNumbers]]
|
|
||||||
deps = ["Calculus", "NaNMath", "SpecialFunctions"]
|
|
||||||
git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566"
|
|
||||||
uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74"
|
|
||||||
version = "0.6.8"
|
|
||||||
|
|
||||||
[[deps.FileWatching]]
|
|
||||||
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"
|
|
||||||
|
|
||||||
[[deps.FillArrays]]
|
|
||||||
deps = ["LinearAlgebra"]
|
|
||||||
git-tree-sha1 = "0653c0a2396a6da5bc4766c43041ef5fd3efbe57"
|
|
||||||
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
|
|
||||||
version = "1.11.0"
|
|
||||||
weakdeps = ["PDMats", "SparseArrays", "Statistics"]
|
|
||||||
|
|
||||||
[deps.FillArrays.extensions]
|
|
||||||
FillArraysPDMatsExt = "PDMats"
|
|
||||||
FillArraysSparseArraysExt = "SparseArrays"
|
|
||||||
FillArraysStatisticsExt = "Statistics"
|
|
||||||
|
|
||||||
[[deps.GeneralUtils]]
|
|
||||||
deps = ["DataStructures", "Dates", "Distributions", "JSON3", "MQTTClient", "Random", "Revise", "UUIDs"]
|
|
||||||
path = "/appfolder/app/privatejuliapkg/GeneralUtils"
|
|
||||||
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[[deps.HypergeometricFunctions]]
|
|
||||||
deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"]
|
|
||||||
git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685"
|
|
||||||
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
|
|
||||||
version = "0.3.23"
|
|
||||||
|
|
||||||
[[deps.InteractiveUtils]]
|
|
||||||
deps = ["Markdown"]
|
|
||||||
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
|
||||||
|
|
||||||
[[deps.IrrationalConstants]]
|
|
||||||
git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2"
|
|
||||||
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
|
|
||||||
version = "0.2.2"
|
|
||||||
|
|
||||||
[[deps.JLLWrappers]]
|
|
||||||
deps = ["Artifacts", "Preferences"]
|
|
||||||
git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca"
|
|
||||||
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
|
|
||||||
version = "1.5.0"
|
|
||||||
|
|
||||||
[[deps.JSON3]]
|
|
||||||
deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"]
|
|
||||||
git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b"
|
|
||||||
uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
|
|
||||||
version = "1.14.0"
|
|
||||||
|
|
||||||
[deps.JSON3.extensions]
|
|
||||||
JSON3ArrowExt = ["ArrowTypes"]
|
|
||||||
|
|
||||||
[deps.JSON3.weakdeps]
|
|
||||||
ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"
|
|
||||||
|
|
||||||
[[deps.JuliaInterpreter]]
|
|
||||||
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
|
|
||||||
git-tree-sha1 = "e9648d90370e2d0317f9518c9c6e0841db54a90b"
|
|
||||||
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
|
|
||||||
version = "0.9.31"
|
|
||||||
|
|
||||||
[[deps.LibCURL]]
|
|
||||||
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
|
|
||||||
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
|
|
||||||
version = "0.6.4"
|
|
||||||
|
|
||||||
[[deps.LibCURL_jll]]
|
|
||||||
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
|
|
||||||
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
|
|
||||||
version = "8.4.0+0"
|
|
||||||
|
|
||||||
[[deps.LibGit2]]
|
|
||||||
deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"]
|
|
||||||
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
|
|
||||||
|
|
||||||
[[deps.LibGit2_jll]]
|
|
||||||
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"]
|
|
||||||
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
|
|
||||||
version = "1.6.4+0"
|
|
||||||
|
|
||||||
[[deps.LibSSH2_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
|
|
||||||
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
|
|
||||||
version = "1.11.0+1"
|
|
||||||
|
|
||||||
[[deps.Libdl]]
|
|
||||||
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
|
||||||
|
|
||||||
[[deps.LinearAlgebra]]
|
|
||||||
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
|
|
||||||
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
|
||||||
|
|
||||||
[[deps.LogExpFunctions]]
|
|
||||||
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
|
|
||||||
git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37"
|
|
||||||
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
|
|
||||||
version = "0.3.27"
|
|
||||||
|
|
||||||
[deps.LogExpFunctions.extensions]
|
|
||||||
LogExpFunctionsChainRulesCoreExt = "ChainRulesCore"
|
|
||||||
LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables"
|
|
||||||
LogExpFunctionsInverseFunctionsExt = "InverseFunctions"
|
|
||||||
|
|
||||||
[deps.LogExpFunctions.weakdeps]
|
|
||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
|
||||||
ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
|
|
||||||
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
|
|
||||||
|
|
||||||
[[deps.Logging]]
|
|
||||||
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
|
||||||
|
|
||||||
[[deps.LoweredCodeUtils]]
|
|
||||||
deps = ["JuliaInterpreter"]
|
|
||||||
git-tree-sha1 = "c6a36b22d2cca0e1a903f00f600991f97bf5f426"
|
|
||||||
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
|
|
||||||
version = "2.4.6"
|
|
||||||
|
|
||||||
[[deps.MQTTClient]]
|
|
||||||
deps = ["Distributed", "Random", "Sockets"]
|
|
||||||
git-tree-sha1 = "f2597b290d4bf17b577346153cd2ddf9accb5c26"
|
|
||||||
uuid = "985f35cc-2c3d-4943-b8c1-f0931d5f0959"
|
|
||||||
version = "0.3.1"
|
|
||||||
weakdeps = ["PrecompileTools"]
|
|
||||||
|
|
||||||
[deps.MQTTClient.extensions]
|
|
||||||
PrecompileMQTT = "PrecompileTools"
|
|
||||||
|
|
||||||
[[deps.Markdown]]
|
|
||||||
deps = ["Base64"]
|
|
||||||
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
|
||||||
|
|
||||||
[[deps.MbedTLS_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl"]
|
|
||||||
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
|
||||||
version = "2.28.2+1"
|
|
||||||
|
|
||||||
[[deps.Missings]]
|
|
||||||
deps = ["DataAPI"]
|
|
||||||
git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d"
|
|
||||||
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
|
|
||||||
version = "1.2.0"
|
|
||||||
|
|
||||||
[[deps.Mmap]]
|
|
||||||
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
|
|
||||||
|
|
||||||
[[deps.MozillaCACerts_jll]]
|
|
||||||
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
|
|
||||||
version = "2023.1.10"
|
|
||||||
|
|
||||||
[[deps.NaNMath]]
|
|
||||||
deps = ["OpenLibm_jll"]
|
|
||||||
git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4"
|
|
||||||
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
|
|
||||||
version = "1.0.2"
|
|
||||||
|
|
||||||
[[deps.NetworkOptions]]
|
|
||||||
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
|
|
||||||
version = "1.2.0"
|
|
||||||
|
|
||||||
[[deps.OpenBLAS_jll]]
|
|
||||||
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
|
|
||||||
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
|
|
||||||
version = "0.3.23+4"
|
|
||||||
|
|
||||||
[[deps.OpenLibm_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl"]
|
|
||||||
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"
|
|
||||||
version = "0.8.1+2"
|
|
||||||
|
|
||||||
[[deps.OpenSpecFun_jll]]
|
|
||||||
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
|
|
||||||
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
|
|
||||||
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
|
|
||||||
version = "0.5.5+0"
|
|
||||||
|
|
||||||
[[deps.OrderedCollections]]
|
|
||||||
git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5"
|
|
||||||
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
|
||||||
version = "1.6.3"
|
|
||||||
|
|
||||||
[[deps.PDMats]]
|
|
||||||
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
|
|
||||||
git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65"
|
|
||||||
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
|
|
||||||
version = "0.11.31"
|
|
||||||
|
|
||||||
[[deps.Parsers]]
|
|
||||||
deps = ["Dates", "PrecompileTools", "UUIDs"]
|
|
||||||
git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821"
|
|
||||||
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
|
||||||
version = "2.8.1"
|
|
||||||
|
|
||||||
[[deps.Pkg]]
|
|
||||||
deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
|
|
||||||
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
|
||||||
version = "1.10.0"
|
|
||||||
|
|
||||||
[[deps.PrecompileTools]]
|
|
||||||
deps = ["Preferences"]
|
|
||||||
git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f"
|
|
||||||
uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
|
|
||||||
version = "1.2.1"
|
|
||||||
|
|
||||||
[[deps.Preferences]]
|
|
||||||
deps = ["TOML"]
|
|
||||||
git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6"
|
|
||||||
uuid = "21216c6a-2e73-6563-6e65-726566657250"
|
|
||||||
version = "1.4.3"
|
|
||||||
|
|
||||||
[[deps.Printf]]
|
|
||||||
deps = ["Unicode"]
|
|
||||||
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
|
||||||
|
|
||||||
[[deps.PtrArrays]]
|
|
||||||
git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759"
|
|
||||||
uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d"
|
|
||||||
version = "1.2.0"
|
|
||||||
|
|
||||||
[[deps.QuadGK]]
|
|
||||||
deps = ["DataStructures", "LinearAlgebra"]
|
|
||||||
git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e"
|
|
||||||
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
|
|
||||||
version = "2.9.4"
|
|
||||||
|
|
||||||
[[deps.REPL]]
|
|
||||||
deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"]
|
|
||||||
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
|
||||||
|
|
||||||
[[deps.Random]]
|
|
||||||
deps = ["SHA"]
|
|
||||||
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
|
||||||
|
|
||||||
[[deps.Reexport]]
|
|
||||||
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
|
|
||||||
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
|
|
||||||
version = "1.2.2"
|
|
||||||
|
|
||||||
[[deps.Requires]]
|
|
||||||
deps = ["UUIDs"]
|
|
||||||
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
|
|
||||||
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
|
|
||||||
version = "1.3.0"
|
|
||||||
|
|
||||||
[[deps.Revise]]
|
|
||||||
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"]
|
|
||||||
git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e"
|
|
||||||
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
|
||||||
version = "3.5.14"
|
|
||||||
|
|
||||||
[[deps.Rmath]]
|
|
||||||
deps = ["Random", "Rmath_jll"]
|
|
||||||
git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b"
|
|
||||||
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
|
|
||||||
version = "0.7.1"
|
|
||||||
|
|
||||||
[[deps.Rmath_jll]]
|
|
||||||
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
|
||||||
git-tree-sha1 = "d483cd324ce5cf5d61b77930f0bbd6cb61927d21"
|
|
||||||
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
|
|
||||||
version = "0.4.2+0"
|
|
||||||
|
|
||||||
[[deps.SHA]]
|
|
||||||
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
|
||||||
version = "0.7.0"
|
|
||||||
|
|
||||||
[[deps.Serialization]]
|
|
||||||
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
|
||||||
|
|
||||||
[[deps.Sockets]]
|
|
||||||
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
|
||||||
|
|
||||||
[[deps.SortingAlgorithms]]
|
|
||||||
deps = ["DataStructures"]
|
|
||||||
git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085"
|
|
||||||
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
|
|
||||||
version = "1.2.1"
|
|
||||||
|
|
||||||
[[deps.SparseArrays]]
|
|
||||||
deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"]
|
|
||||||
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
|
||||||
version = "1.10.0"
|
|
||||||
|
|
||||||
[[deps.SpecialFunctions]]
|
|
||||||
deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
|
|
||||||
git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14"
|
|
||||||
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
|
|
||||||
version = "2.4.0"
|
|
||||||
|
|
||||||
[deps.SpecialFunctions.extensions]
|
|
||||||
SpecialFunctionsChainRulesCoreExt = "ChainRulesCore"
|
|
||||||
|
|
||||||
[deps.SpecialFunctions.weakdeps]
|
|
||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
|
||||||
|
|
||||||
[[deps.Statistics]]
|
|
||||||
deps = ["LinearAlgebra", "SparseArrays"]
|
|
||||||
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
|
||||||
version = "1.10.0"
|
|
||||||
|
|
||||||
[[deps.StatsAPI]]
|
|
||||||
deps = ["LinearAlgebra"]
|
|
||||||
git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed"
|
|
||||||
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
|
|
||||||
version = "1.7.0"
|
|
||||||
|
|
||||||
[[deps.StatsBase]]
|
|
||||||
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
|
|
||||||
git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21"
|
|
||||||
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
|
||||||
version = "0.34.3"
|
|
||||||
|
|
||||||
[[deps.StatsFuns]]
|
|
||||||
deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
|
|
||||||
git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a"
|
|
||||||
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
|
|
||||||
version = "1.3.1"
|
|
||||||
|
|
||||||
[deps.StatsFuns.extensions]
|
|
||||||
StatsFunsChainRulesCoreExt = "ChainRulesCore"
|
|
||||||
StatsFunsInverseFunctionsExt = "InverseFunctions"
|
|
||||||
|
|
||||||
[deps.StatsFuns.weakdeps]
|
|
||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
|
||||||
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
|
|
||||||
|
|
||||||
[[deps.StructTypes]]
|
|
||||||
deps = ["Dates", "UUIDs"]
|
|
||||||
git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70"
|
|
||||||
uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
|
|
||||||
version = "1.10.0"
|
|
||||||
|
|
||||||
[[deps.SuiteSparse]]
|
|
||||||
deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"]
|
|
||||||
uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"
|
|
||||||
|
|
||||||
[[deps.SuiteSparse_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl", "libblastrampoline_jll"]
|
|
||||||
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
|
|
||||||
version = "7.2.1+1"
|
|
||||||
|
|
||||||
[[deps.TOML]]
|
|
||||||
deps = ["Dates"]
|
|
||||||
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
|
|
||||||
version = "1.0.3"
|
|
||||||
|
|
||||||
[[deps.Tar]]
|
|
||||||
deps = ["ArgTools", "SHA"]
|
|
||||||
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
|
|
||||||
version = "1.10.0"
|
|
||||||
|
|
||||||
[[deps.UUIDs]]
|
|
||||||
deps = ["Random", "SHA"]
|
|
||||||
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
|
||||||
|
|
||||||
[[deps.Unicode]]
|
|
||||||
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
|
|
||||||
|
|
||||||
[[deps.Zlib_jll]]
|
|
||||||
deps = ["Libdl"]
|
|
||||||
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
|
||||||
version = "1.2.13+1"
|
|
||||||
|
|
||||||
[[deps.libblastrampoline_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl"]
|
|
||||||
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"
|
|
||||||
version = "5.8.0+1"
|
|
||||||
|
|
||||||
[[deps.nghttp2_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl"]
|
|
||||||
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
|
|
||||||
version = "1.52.0+1"
|
|
||||||
|
|
||||||
[[deps.p7zip_jll]]
|
|
||||||
deps = ["Artifacts", "Libdl"]
|
|
||||||
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"
|
|
||||||
version = "17.4.0+2"
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
name = "LLMMCTS"
|
|
||||||
uuid = "d76c5a4d-449e-4835-8cc4-dd86ec44f241"
|
|
||||||
authors = ["narawat lamaiin <narawat@outlook.com>"]
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
GeneralUtils = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
|
||||||
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
module LLMMCTS
|
|
||||||
|
|
||||||
# export agent
|
|
||||||
|
|
||||||
|
|
||||||
""" Order by dependencies of each file. The 1st included file must not depend on any other
|
|
||||||
files and each file can only depend on the file included before it.
|
|
||||||
"""
|
|
||||||
|
|
||||||
include("type.jl")
|
|
||||||
using .type
|
|
||||||
|
|
||||||
include("util.jl")
|
|
||||||
using .util
|
|
||||||
|
|
||||||
include("mcts.jl")
|
|
||||||
using .mcts
|
|
||||||
|
|
||||||
include("interface.jl")
|
|
||||||
using .interface
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end # module LLMMCTS
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
module interface
|
|
||||||
|
|
||||||
export runMCTS
|
|
||||||
|
|
||||||
using ..type, ..mcts
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
""" Search the best action to take for a given state and task
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `a::agent`
|
|
||||||
one of Yiem's agents
|
|
||||||
- `initial state`
|
|
||||||
initial state
|
|
||||||
- `decisionMaker::Function`
|
|
||||||
decide what action to take
|
|
||||||
- `evaluator::Function`
|
|
||||||
assess the value of the state
|
|
||||||
- `reflector::Function`
|
|
||||||
generate lesson from trajectory and reward
|
|
||||||
- `isterminal::Function`
|
|
||||||
determine whether a given state is a terminal state
|
|
||||||
- `n::Integer`
|
|
||||||
how many times action will be sampled from decisionMaker
|
|
||||||
- `w::Float64`
|
|
||||||
exploration weight. Value is usually between 1 to 2.
|
|
||||||
Value 1.0 makes MCTS balance between exploration and exploitation like 50%-50%
|
|
||||||
Value 2.0 makes MCTS aggressively search the tree
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `plan::Vector{Dict}`
|
|
||||||
best plan
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
[] update docstring
|
|
||||||
[] return best action
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function runMCTS(
|
|
||||||
config::T1,
|
|
||||||
initialState,
|
|
||||||
decisionMaker::Function,
|
|
||||||
evaluator::Function,
|
|
||||||
reflector::Function,
|
|
||||||
transition::Function,
|
|
||||||
;
|
|
||||||
totalsample::Integer=3,
|
|
||||||
maxDepth::Integer=3,
|
|
||||||
maxiterations::Integer=10,
|
|
||||||
explorationweight::Number=1.0,
|
|
||||||
) where {T1<:AbstractDict}
|
|
||||||
|
|
||||||
root = MCTSNode("root", initialState, 0, 0, 0, 0, false, nothing, Dict{String, MCTSNode}())
|
|
||||||
|
|
||||||
for nth in 1:maxiterations
|
|
||||||
node = root
|
|
||||||
node.visits += 1
|
|
||||||
|
|
||||||
while !isleaf(node)
|
|
||||||
node = UCTselect(node, explorationweight)
|
|
||||||
end
|
|
||||||
if node.isterminal
|
|
||||||
# MCTS arrive at the leaf node that is also a terminal state,
|
|
||||||
# do nothing then go directly to backpropagation
|
|
||||||
backpropagate(leafNode, node.reward)
|
|
||||||
else
|
|
||||||
expand(config, node, decisionMaker, evaluator, reflector, transition;
|
|
||||||
totalsample=totalsample)
|
|
||||||
leafNode = selectChildNode(node)
|
|
||||||
simTrajectoryReward, terminalstate = simulate(config, leafNode, decisionMaker, evaluator,
|
|
||||||
reflector, transition; maxDepth=maxDepth, totalsample=totalsample)
|
|
||||||
if terminalstate !== nothing #XXX not sure why I need this
|
|
||||||
terminalstate[:totalTrajectoryReward] = simTrajectoryReward
|
|
||||||
end
|
|
||||||
|
|
||||||
#[] write best state to file if it has higher simTrajectoryReward. Use to improve evaluation
|
|
||||||
# open("trajectory.json", "w") do io
|
|
||||||
# JSON3.pretty(io, terminalstate)
|
|
||||||
# end
|
|
||||||
|
|
||||||
backpropagate(leafNode, simTrajectoryReward)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
bestNextState = selectBestNextState(root)
|
|
||||||
besttrajectory = selectBestTrajectory(root)
|
|
||||||
|
|
||||||
return (bestNextState.state, besttrajectory.state)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end # module interface
|
|
||||||
@@ -1,438 +0,0 @@
|
|||||||
module mcts
|
|
||||||
|
|
||||||
export selectBestNextState, selectBestTrajectory, backpropagate, isleaf, isroot, selectChildNode,
|
|
||||||
expand, simulate, makeNewState
|
|
||||||
|
|
||||||
using GeneralUtils
|
|
||||||
|
|
||||||
using ..type
|
|
||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `node::MCTSNode`
|
|
||||||
node of a search tree
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `childNode::MCTSNode`
|
|
||||||
the highest value child node
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
- [] update docs
|
|
||||||
- [x] implement the function
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function selectBestNextState(node::MCTSNode)::MCTSNode
|
|
||||||
highestProgressValue = 0
|
|
||||||
nodekey = nothing
|
|
||||||
|
|
||||||
# if all childnode has statevalue == 0, use progressvalue + reward to select the best node
|
|
||||||
stateValueSum = sum([v.statevalue for (k, v) in node.children])
|
|
||||||
|
|
||||||
if stateValueSum != 0
|
|
||||||
for (k, childnode) in node.children
|
|
||||||
potential = childnode.statevalue / childnode.visits
|
|
||||||
|
|
||||||
if potential > highestProgressValue
|
|
||||||
highestProgressValue = potential
|
|
||||||
nodekey = childnode.nodekey
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for (k, childnode) in node.children
|
|
||||||
potential = childnode.progressvalue + childnode.reward
|
|
||||||
|
|
||||||
if potential > highestProgressValue
|
|
||||||
highestProgressValue = potential
|
|
||||||
nodekey = childnode.nodekey
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return node.children[nodekey]
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `node::MCTSNode`
|
|
||||||
node of a search tree
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `childNode::MCTSNode`
|
|
||||||
the highest value child node
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
- [] update docs
|
|
||||||
- [x] implement the function
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function selectBestTrajectory(node::MCTSNode)::MCTSNode
|
|
||||||
while !isleaf(node)
|
|
||||||
node = selectBestNextState(node)
|
|
||||||
end
|
|
||||||
|
|
||||||
return node
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
""" Backpropagate reward along the simulation chain
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `node::MCTSNode`
|
|
||||||
leaf node of a search tree
|
|
||||||
- `simTrajectoryReward::T`
|
|
||||||
total reward from trajectory simulation
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `No return`
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function backpropagate(node::MCTSNode, simTrajectoryReward::T;
|
|
||||||
discountRewardCoeff::AbstractFloat=0.9) where {T<:Number}
|
|
||||||
while !isroot(node)
|
|
||||||
# Update the statistics of the current node based on the result of the playout
|
|
||||||
node.visits += 1
|
|
||||||
node.statevalue += ((node.statevalue * (node.visits-1)) + simTrajectoryReward) / node.visits
|
|
||||||
simTrajectoryReward *= discountRewardCoeff # discount because future reward is uncertain
|
|
||||||
node = node.parent
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
""" Determine whether a node is a leaf node of a search tree.
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `node::MCTSNode`
|
|
||||||
a search tree node
|
|
||||||
# Return
|
|
||||||
- `result::Bool`
|
|
||||||
true if it is a leaf node, false otherwise.
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia> using Revise
|
|
||||||
julia> using YiemAgent, DataStructures
|
|
||||||
julia> initialState = Dict{Symbol, Any}(
|
|
||||||
:customerinfo=> Dict{Symbol, Any}(),
|
|
||||||
:storeinfo=> Dict{Symbol, Any}(),
|
|
||||||
|
|
||||||
:thoughtHistory=> OrderedDict{Symbol, Any}(
|
|
||||||
:question=> "How are you?",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
julia> statetype = typeof(initialState)
|
|
||||||
julia> root = YiemAgent.MCTSNode(initialState, 0, 0.0, Dict{statetype, YiemAgent.MCTSNode}())
|
|
||||||
julia> YiemAgent.isleaf(root)
|
|
||||||
true
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
[] update docs
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
isleaf(node::MCTSNode)::Bool = isempty(node.children)
|
|
||||||
|
|
||||||
|
|
||||||
""" Determine wheter a given node is a root node
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `node::MCTSNode`
|
|
||||||
node of a search tree
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `isrootnode::Bool`
|
|
||||||
true if the given node is root node, false otherwise
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
isroot(node::MCTSNode)::Bool = node.nodekey == "root" ? true : false
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
""" Select child node based on the highest statevalue
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `node::MCTSNode`
|
|
||||||
node of a search tree
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `childNode::MCTSNode`
|
|
||||||
the highest value child node
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function selectChildNode(node::MCTSNode)::MCTSNode
|
|
||||||
highestProgressValue = 0
|
|
||||||
nodekey = nothing
|
|
||||||
|
|
||||||
# loop thought node children dictionary to find the highest progress value
|
|
||||||
for (k, childNode) in node.children
|
|
||||||
potential = childNode.progressvalue + childNode.reward
|
|
||||||
if childNode.reward > 0 #XXX for testing. remove when done.
|
|
||||||
println("")
|
|
||||||
end
|
|
||||||
if potential > highestProgressValue
|
|
||||||
highestProgressValue = potential
|
|
||||||
nodekey = childNode.nodekey
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return node.children[nodekey]
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
""" Expand selected node
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `a::T1`
|
|
||||||
One of YiemAgent's agent
|
|
||||||
- `node::MCTSNode`
|
|
||||||
MCTS node
|
|
||||||
- `state::T2`
|
|
||||||
a state of a game. Can be a Dict or something else.
|
|
||||||
- `decisionMaker::Function`
|
|
||||||
a function that output Thought and Action
|
|
||||||
- `evaluator::Function`
|
|
||||||
a function that output trajectory progress score
|
|
||||||
|
|
||||||
# Return
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
[] update docstring
|
|
||||||
[] try loop should limit to 3 times. if not succeed, skip
|
|
||||||
[] newNodeKey ∉ keys(node.children). New state may have semantic vector close enought to one of existing child state. Which can be assume that they are the same state semantically-wise.
|
|
||||||
[x] store feedback -> state -> agent.
|
|
||||||
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function expand(config::T1, node::MCTSNode, decisionMaker::Function, evaluator::Function,
|
|
||||||
reflector::Function, transition::Function; totalsample::Integer=3
|
|
||||||
) where {T1<:AbstractDict}
|
|
||||||
|
|
||||||
nthSample = 0
|
|
||||||
while true
|
|
||||||
nthSample += 1
|
|
||||||
if nthSample <= totalsample
|
|
||||||
newNodeKey, newstate, progressvalue = transition(config, node.state, decisionMaker,
|
|
||||||
evaluator, reflector)
|
|
||||||
if newNodeKey ∉ keys(node.children)
|
|
||||||
node.children[newNodeKey] =
|
|
||||||
MCTSNode(newNodeKey, newstate, 0, progressvalue, 0, newstate[:reward],
|
|
||||||
newstate[:isterminal], node, Dict{String, MCTSNode}())
|
|
||||||
end
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
""" Simulate interactions between agent and environment
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `a::T`
|
|
||||||
one of YiemAgent's agent
|
|
||||||
- `node::MCTSNode`
|
|
||||||
node that will be a simulation starting point.
|
|
||||||
- `decisionMaker::Function`
|
|
||||||
function that receive state return Thought and Action
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `simTrajectoryReward::Number`
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
- [] update docs
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function simulate(config::T, node::MCTSNode, decisionMaker::Function, evaluator::Function,
|
|
||||||
reflector::Function, transition::Function; maxDepth::Integer=3, totalsample::Integer=3
|
|
||||||
)::Union{Tuple{Number, Dict{Symbol, <:Any}}, Tuple{Number, Nothing}} where {T<:AbstractDict}
|
|
||||||
|
|
||||||
simTrajectoryReward = 0.0
|
|
||||||
terminalstate = nothing
|
|
||||||
|
|
||||||
for depth in 1:maxDepth
|
|
||||||
simTrajectoryReward += node.reward
|
|
||||||
if node.isterminal
|
|
||||||
terminalstate = node.state
|
|
||||||
break
|
|
||||||
else
|
|
||||||
expand(config, node, decisionMaker, evaluator, reflector, transition;
|
|
||||||
totalsample=totalsample)
|
|
||||||
node = selectChildNode(node)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return (simTrajectoryReward, terminalstate)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
|
|
||||||
# Return
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
- [] update docstring
|
|
||||||
- [x] implement the function
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function makeNewState(currentstate::T1, thoughtDict::T4, response::T2, select::Union{T3, Nothing},
|
|
||||||
reward::T3, isterminal::Bool
|
|
||||||
)::Tuple{String, Dict{Symbol, <:Any}} where {T1<:AbstractDict, T2<:AbstractString, T3<:Number, T4<:AbstractDict}
|
|
||||||
|
|
||||||
currentstate_latestThoughtKey, currentstate_latestThoughtIndice =
|
|
||||||
GeneralUtils.findHighestIndexKey(currentstate[:thoughtHistory], "thought")
|
|
||||||
currentstate_nextIndice =
|
|
||||||
currentstate_latestThoughtKey == :NA ? 1 : currentstate_latestThoughtIndice + 1
|
|
||||||
currentstate_latestThoughtKey = Symbol("thought_$currentstate_nextIndice")
|
|
||||||
latestActionKey = Symbol("action_$currentstate_nextIndice")
|
|
||||||
|
|
||||||
_, thoughtDict_latestThoughtIndice =
|
|
||||||
GeneralUtils.findHighestIndexKey(thoughtDict, "thought")
|
|
||||||
|
|
||||||
thoughtDict_latestThoughtKey, thoughtDict_latestActionKey =
|
|
||||||
if thoughtDict_latestThoughtIndice == -1
|
|
||||||
(:thought, :action)
|
|
||||||
else
|
|
||||||
(
|
|
||||||
Symbol("thought_$thoughtDict_latestThoughtIndice"),
|
|
||||||
Symbol("action_$thoughtDict_latestThoughtIndice"),
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
# add Thought, action, observation to thoughtHistory
|
|
||||||
newstate = deepcopy(currentstate)
|
|
||||||
newstate[:thoughtHistory][currentstate_latestThoughtKey] =
|
|
||||||
thoughtDict[thoughtDict_latestThoughtKey]
|
|
||||||
newstate[:thoughtHistory][latestActionKey] = thoughtDict[thoughtDict_latestActionKey]
|
|
||||||
newObservationKey = Symbol("observation_$(currentstate_nextIndice)")
|
|
||||||
newstate[:thoughtHistory][newObservationKey] = response
|
|
||||||
newstate[:reward] = reward
|
|
||||||
newstate[:select] = select
|
|
||||||
newstate[:isterminal] = isterminal
|
|
||||||
|
|
||||||
newNodeKey = GeneralUtils.uuid4snakecase()
|
|
||||||
|
|
||||||
return (newNodeKey, newstate)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end # module mcts
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
module type
|
|
||||||
|
|
||||||
export MCTSNode
|
|
||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
|
||||||
|
|
||||||
|
|
||||||
""" a node for MCTS search tree
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `state::T`
|
|
||||||
a state of a game. Can be a Dict or something else.
|
|
||||||
- `visits::Integer `
|
|
||||||
number of time the game visits this state
|
|
||||||
- `stateValue::Float64`
|
|
||||||
state value
|
|
||||||
- `children::Dict{T, MCTSNode}`
|
|
||||||
children node
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `nothing`
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia> state = Dict(
|
|
||||||
:info=> Dict(), # keyword info
|
|
||||||
:thoughtHistory=> Dict(
|
|
||||||
:question=> _,
|
|
||||||
:thought_1=> _,
|
|
||||||
:action_1=> _,
|
|
||||||
:observation_1=> _,
|
|
||||||
:thought_2=> _,
|
|
||||||
...
|
|
||||||
)
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
[] update docstring
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
mutable struct MCTSNode{T1<:AbstractDict, T2<:AbstractString}
|
|
||||||
nodekey::T2
|
|
||||||
state::T1
|
|
||||||
visits::Integer
|
|
||||||
progressvalue::Number # estimate value by LLM's reasoning
|
|
||||||
statevalue::Number # store discounted commulative reward (gather from its child node)
|
|
||||||
reward::Number # this node's own reward
|
|
||||||
isterminal::Bool
|
|
||||||
parent::Union{MCTSNode, Nothing}
|
|
||||||
children::Dict{String, MCTSNode}
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end # module type
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
module util
|
|
||||||
|
|
||||||
export UCTselect
|
|
||||||
|
|
||||||
using ..type
|
|
||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
|
||||||
|
|
||||||
""" Select a node based on UCT score
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
- `node::MCTSNode`
|
|
||||||
mcts node
|
|
||||||
- `w::T`
|
|
||||||
exploration weight. Value is usually between 1 to 2.
|
|
||||||
Value 1.0 makes MCTS balance between exploration and exploitation like 50%-50%.
|
|
||||||
Value 2.0 makes MCTS aggressively search the tree.
|
|
||||||
# Return
|
|
||||||
- `selectedNode::MCTSNode`
|
|
||||||
|
|
||||||
# Example
|
|
||||||
```jldoctest
|
|
||||||
julia>
|
|
||||||
```
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
|
||||||
function UCTselect(node::MCTSNode, w::T)::MCTSNode where {T<:AbstractFloat}
|
|
||||||
maxUCT = -Inf
|
|
||||||
selectedNode = nothing
|
|
||||||
|
|
||||||
for (childState, childNode) in node.children
|
|
||||||
UCTvalue =
|
|
||||||
if childNode.visits != 0
|
|
||||||
weightedterm = w * sqrt(log(node.visits) / childNode.visits) # explore term
|
|
||||||
childNode.statevalue + weightedterm
|
|
||||||
else # node.visits == 0 makes sqrt() in explore term error
|
|
||||||
childNode.progressvalue # exploit term
|
|
||||||
end
|
|
||||||
|
|
||||||
if UCTvalue > maxUCT
|
|
||||||
maxUCT = UCTvalue
|
|
||||||
selectedNode = childNode
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return selectedNode
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end # module util
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
module LLMMCTS
|
module LLMMCTS
|
||||||
|
|
||||||
# export agent
|
export MCTSNode
|
||||||
|
|
||||||
|
|
||||||
""" Order by dependencies of each file. The 1st included file must not depend on any other
|
""" Order by dependencies of each file. The 1st included file must not depend on any other
|
||||||
|
|||||||
+189
-87
@@ -2,153 +2,255 @@ module interface
|
|||||||
|
|
||||||
export runMCTS
|
export runMCTS
|
||||||
|
|
||||||
|
using Base.Threads, PrettyPrinting
|
||||||
using ..type, ..mcts, ..util
|
using ..type, ..mcts, ..util
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||||
|
|
||||||
|
|
||||||
|
""" Search for the best action to take for a given state and task.
|
||||||
|
|
||||||
""" Search the best action to take for a given state and task
|
This function runs the MCTS algorithm through multiple iterations of expansion,
|
||||||
|
simulation, and backpropagation to find optimal decisions.
|
||||||
|
|
||||||
|
Does **not** mutate the input state; it creates new MCTS nodes during search.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `initialstate::T`
|
- `initialstate::T`
|
||||||
initial state
|
The initial state from which to start the search.
|
||||||
- `transition::Function`
|
- `transition::Function`
|
||||||
a function that define how the state transitions
|
A function that defines how the state transitions.
|
||||||
- `transitionargs::NamedTuple`
|
- `transitionargs::NamedTuple`
|
||||||
arguments for transition function
|
Arguments passed to the transition function.
|
||||||
|
|
||||||
# Keyword Arguments
|
# Keyword Arguments
|
||||||
- `totalsample::Integer`
|
- `horizontalSampleExpansionPhase::Integer=3`
|
||||||
a number of child state MCTS sample at each node during expansion phase
|
Number of child states sampled at each node during expansion phase.
|
||||||
- `maxdepth::Integer`
|
- `horizontalSampleSimulationPhase::Integer=3`
|
||||||
a number of levels MCTS goes during simulation phase
|
Number of child states sampled at each node during simulation's expansion phase.
|
||||||
- `maxiterations::Integer`
|
- `maxSimulationDepth::Integer=3`
|
||||||
a number of iteration MCTS goes thru expansion -> simulation -> backpropagation cycle
|
Maximum depth MCTS goes during simulation phase.
|
||||||
- `explorationweight::Number`
|
- `maxiterations::Integer=10`
|
||||||
exploration weight controls how much MCTS should explore new state instead of exploit
|
Number of iterations MCTS performs through expansion → simulation → backpropagation cycles.
|
||||||
a known state. 1.0 balance between exploration and exploitation like 50%-50%. 2.0 makes MCTS
|
- `explorationweight::Number=1.0`
|
||||||
aggressively explore new state.
|
Exploration weight controls how much MCTS explores new states versus exploiting known states.
|
||||||
|
A value of 1.0 balances exploration and exploitation equally. Higher values (e.g., 2.0)
|
||||||
|
encourage more aggressive exploration.
|
||||||
|
- `earlystop::Union{Function,Nothing}=nothing`
|
||||||
|
Optional function to check early stopping condition. If satisfied, MCTS breaks iterations.
|
||||||
|
- `saveSimulatedNode::Bool=false`
|
||||||
|
Whether to save nodes created during simulation phase.
|
||||||
|
- `multithread::Bool=false`
|
||||||
|
Whether to use multithreading during simulation.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- `NamedTuple{(:bestNextState, :bestFinalState), Tuple{T, T}}`
|
- `NamedTuple{(:root, :bestNextState, :bestTerminalState, :highValueStateList),
|
||||||
the best next state and the best final state
|
Tuple{MCTSNode,T,T,Vector{Dict{String,Any}}}}`
|
||||||
|
- `root`: the complete MCTS tree with root node
|
||||||
|
- `bestNextState`: the best immediate next state
|
||||||
|
- `bestTerminalState`: the best final state along the best trajectory
|
||||||
|
- `highValueStateList`: list of high-value terminal states (reward >= 8)
|
||||||
|
|
||||||
# Example
|
# Example
|
||||||
Refers to SQLLLM package
|
```jldoctest
|
||||||
|
julia> using LLMMCTS
|
||||||
# Signature
|
julia> initialState = Dict(:reward=>0.0)
|
||||||
|
julia> result = runMCTS(initialState, transition_func, transition_args; maxiterations=5)
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
function runMCTS(
|
function runMCTS(
|
||||||
initialstate::T,
|
initialstate::T,
|
||||||
transition::Function,
|
transition::Function,
|
||||||
transitionargs::NamedTuple,
|
transitionargs::NamedTuple,
|
||||||
;
|
;
|
||||||
totalsample::Integer=3,
|
horizontalSampleExpansionPhase::Integer=3,
|
||||||
maxdepth::Integer=3,
|
horizontalSampleSimulationPhase::Integer=3,
|
||||||
|
maxSimulationDepth::Integer=3,
|
||||||
maxiterations::Integer=10,
|
maxiterations::Integer=10,
|
||||||
explorationweight::Number=1.0,
|
explorationweight::Number=1.0,
|
||||||
earlystop::Union{Function,Nothing}=nothing
|
earlystop::Union{Function,Nothing}=nothing,
|
||||||
)::NamedTuple{(:bestNextState, :bestFinalState),Tuple{T,T}} where {T<:Any}
|
saveSimulatedNode::Bool=false,
|
||||||
|
multithread=false,
|
||||||
|
)::NamedTuple{(:root, :bestNextState, :bestTerminalState, :highValueStateList),
|
||||||
|
Tuple{MCTSNode,T,T,Vector{Dict{String,Any}}}} where {T<:Any}
|
||||||
|
|
||||||
root = MCTSNode("root", initialstate, 0, 0, 0, 0, false, nothing, Dict{String,MCTSNode}())
|
# Initialize the MCTS tree with a root node representing the initial state
|
||||||
|
# root.visits=0: no visits yet
|
||||||
|
# root.statevalue=0: no simulation results yet
|
||||||
|
root = MCTSNode("root", initialstate, 0, 0, 0, 0, false, nothing, Dict{String,MCTSNode}(),
|
||||||
|
Dict{String,Any}())
|
||||||
|
|
||||||
|
# Channel to collect high-value terminal states (reward >= 8)
|
||||||
|
# These are "good solutions" that can be returned to the user
|
||||||
|
highValueState = Channel{Any}(100)
|
||||||
|
|
||||||
|
# Main MCTS loop: perform iterations to build the search tree
|
||||||
|
# Each iteration: SELECTION → EXPANSION → SIMULATION → BACKPROPAGATION
|
||||||
for nth in 1:maxiterations
|
for nth in 1:maxiterations
|
||||||
|
# Start from root and traverse down using UCT selection
|
||||||
node = root
|
node = root
|
||||||
node.visits += 1
|
node.visits += 1 # Count this iteration's visit to root
|
||||||
|
|
||||||
|
# Phase 1: SELECTION - Traverse tree using UCT until reaching a leaf node
|
||||||
|
# UCT balances exploration (new branches) vs exploitation (promising branches)
|
||||||
while !isleaf(node)
|
while !isleaf(node)
|
||||||
|
|
||||||
node = UCTselect(node, explorationweight)
|
node = UCTselect(node, explorationweight)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Phase 2: TERMINAL CHECK - If leaf is terminal, just backpropagate
|
||||||
if node.isterminal
|
if node.isterminal
|
||||||
# MCTS arrive at the leaf node that is also a terminal state,
|
|
||||||
# do nothing then go directly to backpropagation. It means the end of this iteration
|
# If this terminal state has high reward (>= 8), store it for later
|
||||||
|
if node.state[:reward] >= 8
|
||||||
|
|
||||||
|
put!(highValueState, deepcopy(node.state))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Backpropagate the terminal node's own reward up to root
|
||||||
|
# This updates all ancestors with this path's outcome
|
||||||
backpropagate(node, node.reward)
|
backpropagate(node, node.reward)
|
||||||
else
|
else
|
||||||
expand(node, transition, transitionargs;
|
|
||||||
totalsample=totalsample)
|
|
||||||
leafNode = selectChildNode(node)
|
|
||||||
simTrajectoryReward, terminalstate = simulate(leafNode, transition, transitionargs;
|
|
||||||
maxdepth=maxdepth, totalsample=totalsample)
|
|
||||||
# if terminalstate !== nothing #XXX not sure why I need this
|
|
||||||
# terminalstate[:totalTrajectoryReward] = simTrajectoryReward
|
|
||||||
# end
|
|
||||||
|
|
||||||
#[] write best state to file if it has higher simTrajectoryReward. Use to improve evaluation
|
# Phase 3: EXPANSION - Generate children for this non-terminal leaf
|
||||||
# open("trajectory.json", "w") do io
|
# Horizontal sampling: create multiple child nodes via LLM transition
|
||||||
# JSON3.pretty(io, terminalstate)
|
_ = expand(node, transition, transitionargs;
|
||||||
# end
|
horizontalSample=horizontalSampleExpansionPhase,
|
||||||
|
multithread=multithread)
|
||||||
|
|
||||||
backpropagate(leafNode, simTrajectoryReward)
|
# Phase 4: SIMULATION + BACKPROPAGATION
|
||||||
|
# For each newly expanded child, run simulation and update statistics
|
||||||
|
if multithread
|
||||||
|
|
||||||
|
# Parallel simulation: spawn threads for each child node
|
||||||
|
@sync for (leafNodeKey, leafNode) in node.children
|
||||||
|
@spawn simulateThenBackpropagate(leafNode, transition, transitionargs;
|
||||||
|
maxSimulationDepth=maxSimulationDepth,
|
||||||
|
horizontalSampleSimulationPhase=horizontalSampleSimulationPhase,
|
||||||
|
saveSimulatedNode=saveSimulatedNode,
|
||||||
|
multithread=multithread,
|
||||||
|
highValueState=highValueState,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
|
# Sequential simulation: process each child one at a time
|
||||||
|
for (leafNodeKey, leafNode) in node.children
|
||||||
|
|
||||||
|
simulateThenBackpropagate(leafNode, transition, transitionargs;
|
||||||
|
maxSimulationDepth=maxSimulationDepth,
|
||||||
|
horizontalSampleSimulationPhase=horizontalSampleSimulationPhase,
|
||||||
|
saveSimulatedNode=saveSimulatedNode,
|
||||||
|
multithread=multithread,
|
||||||
|
highValueState=highValueState)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# stop if the early stop condition is met
|
# Phase 5: EARLY STOP CHECK
|
||||||
|
# Optional: stop search early if a condition is met
|
||||||
if typeof(earlystop) <: Function && earlystop(node.state)
|
if typeof(earlystop) <: Function && earlystop(node.state)
|
||||||
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# After all iterations, extract results from the search tree
|
||||||
|
# Select best immediate next state (best child of root)
|
||||||
bestNextState = selectBestNextNode(root)
|
bestNextState = selectBestNextNode(root)
|
||||||
besttrajectory = selectBestTrajectoryNode(root)
|
|
||||||
|
|
||||||
return (bestNextState=bestNextState.state, bestFinalState=besttrajectory.state)
|
# Select best terminal state along the optimal trajectory
|
||||||
|
bestTerminalState = selectBestTrajectoryNode(root)
|
||||||
|
|
||||||
|
# Collect all high-value states from the channel into a list
|
||||||
|
highValueStateList = Vector{Dict{String, Any}}()
|
||||||
|
while !isempty(highValueState)
|
||||||
|
|
||||||
|
push!(highValueStateList, take!(highValueState))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return complete search results
|
||||||
|
result = (
|
||||||
|
root=root,
|
||||||
|
bestNextState=bestNextState.state,
|
||||||
|
bestTerminalState=bestTerminalState.state,
|
||||||
|
highValueStateList=highValueStateList
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
""" Run simulation from a given node and backpropagate the reward.
|
||||||
|
|
||||||
# function runMCTS(
|
This function performs simulation (rollout) from the given node, collects the
|
||||||
# initialstate::T,
|
cumulative reward along the trajectory, and backpropagates it up the tree to update
|
||||||
# transition::Function,
|
visit counts and state values.
|
||||||
# transitionargs::NamedTuple,
|
|
||||||
# ;
|
|
||||||
# totalsample::Integer=3,
|
|
||||||
# maxdepth::Integer=3,
|
|
||||||
# maxiterations::Integer=10,
|
|
||||||
# explorationweight::Number=1.0,
|
|
||||||
# )::NamedTuple{(:bestNextState, :bestFinalState),Tuple{T,T}} where {T<:Any}
|
|
||||||
|
|
||||||
# root = MCTSNode("root", initialstate, 0, 0, 0, 0, false, nothing, Dict{String,MCTSNode}())
|
Does **not** mutate the input node's children (unless `saveSimulatedNode=true`).
|
||||||
|
|
||||||
# for nth in 1:maxiterations
|
# Arguments
|
||||||
# node = root
|
- `node::MCTSNode`
|
||||||
# node.visits += 1
|
The current node to simulate from.
|
||||||
|
- `transition::Function`
|
||||||
|
A function that defines how the state transitions.
|
||||||
|
- `transitionargs::NamedTuple`
|
||||||
|
Arguments passed to the transition function.
|
||||||
|
|
||||||
# while !isleaf(node)
|
# Keyword Arguments
|
||||||
# node = UCTselect(node, explorationweight)
|
- `maxSimulationDepth::Integer=3`
|
||||||
# end
|
Maximum depth MCTS goes during simulation phase.
|
||||||
# if node.isterminal
|
- `horizontalSampleSimulationPhase::Integer=3`
|
||||||
# # MCTS arrive at the leaf node that is also a terminal state,
|
Number of child states sampled at each node during simulation phase.
|
||||||
# # do nothing then go directly to backpropagation. It means the end of this iteration
|
- `saveSimulatedNode::Bool=false`
|
||||||
# backpropagate(leafNode, node.reward)
|
Whether to save nodes created during simulation phase. If false, children are
|
||||||
# else
|
cleared after simulation.
|
||||||
# expand(node, transition, transitionargs;
|
- `multithread::Bool=false`
|
||||||
# totalsample=totalsample)
|
Whether to use multithreading during simulation.
|
||||||
# leafNode = selectChildNode(node)
|
|
||||||
# simTrajectoryReward, terminalstate = simulate(leafNode, transition, transitionargs;
|
|
||||||
# maxdepth=maxdepth, totalsample=totalsample)
|
|
||||||
# # if terminalstate !== nothing #XXX not sure why I need this
|
|
||||||
# # terminalstate[:totalTrajectoryReward] = simTrajectoryReward
|
|
||||||
# # end
|
|
||||||
|
|
||||||
# #[] write best state to file if it has higher simTrajectoryReward. Use to improve evaluation
|
# Return
|
||||||
# # open("trajectory.json", "w") do io
|
- `Nothing`
|
||||||
# # JSON3.pretty(io, terminalstate)
|
|
||||||
# # end
|
|
||||||
|
|
||||||
# backpropagate(leafNode, simTrajectoryReward)
|
# Signature
|
||||||
# end
|
"""
|
||||||
# end
|
function simulateThenBackpropagate(node::MCTSNode, transition::Function, transitionargs::NamedTuple;
|
||||||
|
maxSimulationDepth::Integer=3, horizontalSampleSimulationPhase::Integer=3,
|
||||||
|
saveSimulatedNode::Bool=false,
|
||||||
|
multithread=false,
|
||||||
|
highValueState=Union{Nothing,Any}=nothing)
|
||||||
|
|
||||||
# bestNextState = selectBestNextNode(root)
|
# Phase 1: RUN SIMULATION (rollout)
|
||||||
# besttrajectory = selectBestTrajectoryNode(root)
|
# Perform a rollout from this node, accumulating rewards along the way
|
||||||
|
simTrajectoryReward, terminalstate =
|
||||||
|
simulate(node, transition, transitionargs;
|
||||||
|
maxSimulationDepth=maxSimulationDepth,
|
||||||
|
horizontalSample=horizontalSampleSimulationPhase,
|
||||||
|
multithread=multithread)
|
||||||
|
|
||||||
# return (bestNextState=bestNextState.state, bestFinalState=besttrajectory.state)
|
# Phase 2: HIGH-VALUE STATE TRACKING
|
||||||
# end
|
# If we reached a terminal state with high reward (>= 8), store it
|
||||||
|
# This allows users to access multiple good solutions, not just the best one
|
||||||
|
if highValueState !== nothing &&
|
||||||
|
terminalstate !== nothing &&
|
||||||
|
terminalstate["reward"] >= 8
|
||||||
|
|
||||||
|
put!(highValueState, deepcopy(terminalstate))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Phase 3: BACKPROPAGATE
|
||||||
|
# Update statistics (visits, statevalue) for all ancestors up to root
|
||||||
|
# The simulation result is now incorporated into the tree
|
||||||
|
backpropagate(node, simTrajectoryReward)
|
||||||
|
|
||||||
|
# Phase 4: MEMORY MANAGEMENT
|
||||||
|
# Clear children unless user wants to keep them for analysis
|
||||||
|
# This frees memory for the next iteration while preserving tree structure
|
||||||
|
if saveSimulatedNode == false
|
||||||
|
|
||||||
|
node.children = Dict{String, MCTSNode}()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+279
-213
@@ -1,7 +1,7 @@
|
|||||||
module mcts
|
module mcts
|
||||||
|
|
||||||
export selectBestNextNode, selectBestTrajectoryNode, backpropagate, isleaf, isroot, selectChildNode,
|
export selectBestNextNode, selectBestTrajectoryNode, backpropagate, isleaf, isroot, selectChildNode,
|
||||||
expand, simulate, makeNewState
|
expand, simulate
|
||||||
using Base.Threads
|
using Base.Threads
|
||||||
using GeneralUtils
|
using GeneralUtils
|
||||||
|
|
||||||
@@ -10,27 +10,33 @@ using ..type
|
|||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||||
|
|
||||||
|
|
||||||
"""
|
""" Select the best child node based on the highest value metric.
|
||||||
|
|
||||||
|
The selection metric depends on the node's state values:
|
||||||
|
- If the sum of statevalues is non-zero, uses `statevalue/visits` ratio.
|
||||||
|
- Otherwise, uses `progressvalue + reward`.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
node of a search tree
|
The node whose children will be evaluated.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- `childNode::MCTSNode`
|
- `childNode::MCTSNode`
|
||||||
the highest value child node
|
The child node with the highest value according to the selection metric.
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
function selectBestNextNode(node::MCTSNode)::MCTSNode
|
function selectBestNextNode(node::MCTSNode)::MCTSNode
|
||||||
highestProgressValue = -1
|
highestProgressValue = -1
|
||||||
nodekey = nothing
|
nodekey = nothing
|
||||||
|
|
||||||
# if all childnode has statevalue == 0, use progressvalue + reward to select the best node
|
# Calculate sum of statevalues across all child nodes
|
||||||
|
# This determines whether to use statevalue/visits (exploitation) or progressvalue+reward (exploration)
|
||||||
stateValueSum = sum([v.statevalue for (k, v) in node.children])
|
stateValueSum = sum([v.statevalue for (k, v) in node.children])
|
||||||
|
|
||||||
|
# If any nodes have non-zero statevalue, use statevalue/visits as selection metric
|
||||||
|
# This means simulations have confirmed node values - use exploitation
|
||||||
if stateValueSum != 0
|
if stateValueSum != 0
|
||||||
for (k, childnode) in node.children
|
for (k, childnode) in node.children
|
||||||
|
# Calculate average statevalue per visit (running average from simulations)
|
||||||
potential = childnode.statevalue / childnode.visits
|
potential = childnode.statevalue / childnode.visits
|
||||||
|
|
||||||
if potential > highestProgressValue
|
if potential > highestProgressValue
|
||||||
@@ -39,6 +45,8 @@ function selectBestNextNode(node::MCTSNode)::MCTSNode
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
# No simulations yet - use progressvalue + reward for initial guidance
|
||||||
|
# This allows LLM heuristics to guide early search before simulations provide data
|
||||||
for (k, childnode) in node.children
|
for (k, childnode) in node.children
|
||||||
potential = childnode.progressvalue + childnode.reward
|
potential = childnode.progressvalue + childnode.reward
|
||||||
|
|
||||||
@@ -53,19 +61,22 @@ function selectBestNextNode(node::MCTSNode)::MCTSNode
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
"""
|
""" Select the best node along the optimal trajectory.
|
||||||
|
|
||||||
|
Traverses down the tree from the given node by repeatedly applying `selectBestNextNode`
|
||||||
|
until reaching a leaf node, returning the highest-value node found along the path.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
node of a search tree
|
The node to start trajectory selection from.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- `childNode::MCTSNode`
|
- `childNode::MCTSNode`
|
||||||
the highest value child node
|
The highest-value node found by following the optimal trajectory to a leaf.
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
function selectBestTrajectoryNode(node::MCTSNode)::MCTSNode
|
function selectBestTrajectoryNode(node::MCTSNode)::MCTSNode
|
||||||
|
# Follow the optimal path down the tree by repeatedly selecting the best child
|
||||||
|
# This gives us the highest-value trajectory from the starting node to a leaf
|
||||||
while !isleaf(node)
|
while !isleaf(node)
|
||||||
node = selectBestNextNode(node)
|
node = selectBestNextNode(node)
|
||||||
end
|
end
|
||||||
@@ -74,101 +85,108 @@ function selectBestTrajectoryNode(node::MCTSNode)::MCTSNode
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
""" Backpropagate reward along the simulation chain
|
""" Backpropagate reward along the simulation chain.
|
||||||
|
|
||||||
|
Updates visit counts and state values for all nodes along the path from the given
|
||||||
|
leaf node to the root, applying reward discounting for future rewards.
|
||||||
|
|
||||||
|
**Modifies nodes in place.**
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
leaf node of a search tree
|
The leaf node from which to start backpropagation.
|
||||||
- `simTrajectoryReward::T`
|
- `simTrajectoryReward::Number`
|
||||||
total reward from trajectory simulation
|
The total reward from the trajectory simulation.
|
||||||
- `discountRewardCoeff::AbstractFloat`
|
|
||||||
A discount reward coefficient to reduce future reward. The futher in the future the lower
|
|
||||||
reward it is now.
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `None`
|
|
||||||
|
|
||||||
# Signature
|
# Keyword Arguments
|
||||||
|
- `discountRewardCoeff::AbstractFloat=0.9`
|
||||||
|
Discount coefficient applied to future rewards. Larger distances from the leaf
|
||||||
|
receive progressively lower discounted rewards.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- `Nothing`
|
||||||
"""
|
"""
|
||||||
function backpropagate(node::MCTSNode, simTrajectoryReward::T;
|
function backpropagate(node::MCTSNode, simTrajectoryReward::T;
|
||||||
discountRewardCoeff::AbstractFloat=0.9) where {T<:Number}
|
discountRewardCoeff::AbstractFloat=0.9) where {T<:Number}
|
||||||
|
|
||||||
|
# Propagate the simulation result back up the tree to update all ancestor nodes
|
||||||
|
# Each node's statistics are updated with the cumulative reward from the simulation
|
||||||
while !isroot(node)
|
while !isroot(node)
|
||||||
# Update the statistics of the current node based on the result of the playout
|
|
||||||
|
# Increment visit count - this simulation passed through this node
|
||||||
node.visits += 1
|
node.visits += 1
|
||||||
node.statevalue += ((node.statevalue * (node.visits-1)) + simTrajectoryReward) / node.visits
|
|
||||||
simTrajectoryReward *= discountRewardCoeff # discount because future reward is uncertain
|
node.statevalue += ((node.statevalue * (node.visits-1)) + simTrajectoryReward) / node.visits # Update running average of state value
|
||||||
|
|
||||||
|
# Apply discount to future rewards - rewards further from the current state are worth less
|
||||||
|
# This reflects temporal uncertainty: distant future rewards are less certain
|
||||||
|
simTrajectoryReward *= discountRewardCoeff
|
||||||
|
|
||||||
|
# Move up to parent node to continue propagation
|
||||||
node = node.parent
|
node = node.parent
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
""" Determine whether a node is a leaf node.
|
||||||
|
|
||||||
""" Determine whether a node is a leaf node of a search tree.
|
A leaf node has no children.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
a search tree node
|
The search tree node to check.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- `result::Bool`
|
- `result::Bool`
|
||||||
true if it is a leaf node, false otherwise.
|
`true` if the node has no children, `false` otherwise.
|
||||||
|
|
||||||
# Example
|
# Example
|
||||||
```jldoctest
|
```jldoctest
|
||||||
julia> using Revise
|
julia> using LLMMCTS
|
||||||
julia> using YiemAgent, DataStructures
|
julia> node = MCTSNode("leaf", Dict(:reward=>1.0), 0, 0, 0, 1.0, true, nothing, Dict(), Dict())
|
||||||
julia> initialState = Dict{Symbol, Any}(
|
julia> isleaf(node)
|
||||||
:customerinfo=> Dict{Symbol, Any}(),
|
|
||||||
:storeinfo=> Dict{Symbol, Any}(),
|
|
||||||
|
|
||||||
:thoughtHistory=> OrderedDict{Symbol, Any}(
|
|
||||||
:question=> "How are you?",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
julia> statetype = typeof(initialState)
|
|
||||||
julia> root = YiemAgent.MCTSNode(initialState, 0, 0.0, Dict{statetype, YiemAgent.MCTSNode}())
|
|
||||||
julia> YiemAgent.isleaf(root)
|
|
||||||
true
|
true
|
||||||
```
|
```
|
||||||
|
|
||||||
# TODO
|
|
||||||
[] update docs
|
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
isleaf(node::MCTSNode)::Bool = isempty(node.children)
|
isleaf(node::MCTSNode)::Bool = isempty(node.children)
|
||||||
|
|
||||||
|
""" Determine whether a given node is a root node.
|
||||||
|
|
||||||
""" Determine wheter a given node is a root node
|
The root node is identified by having `"root"` as its `nodekey`.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
node of a search tree
|
The search tree node to check.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- `isrootnode::Bool`
|
- `isrootnode::Bool`
|
||||||
true if the given node is root node, false otherwise
|
`true` if the node is the root node, `false` otherwise.
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
isroot(node::MCTSNode)::Bool = node.nodekey == "root" ? true : false
|
isroot(node::MCTSNode)::Bool = node.nodekey == "root" ? true : false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
""" Select child node based on the highest statevalue
|
""" Select the child node with the highest value.
|
||||||
|
|
||||||
|
Uses `progressvalue + reward` as the selection metric.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
node of a search tree
|
The node whose children will be evaluated.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- `childNode::MCTSNode`
|
- `childNode::MCTSNode`
|
||||||
the highest value child node
|
The child node with the highest `progressvalue + reward` value.
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
function selectChildNode(node::MCTSNode)::MCTSNode
|
function selectChildNode(node::MCTSNode)::MCTSNode
|
||||||
highestProgressValue = -1
|
highestProgressValue = -1
|
||||||
nodekey = nothing
|
nodekey = nothing
|
||||||
|
|
||||||
# loop thought node children dictionary to find the highest progress value
|
# During simulation rollout, we need to pick which child to explore next
|
||||||
|
# Use progressvalue + reward as the selection metric (no UCT here)
|
||||||
|
# - progressvalue: LLM's estimate of how promising this state is
|
||||||
|
# - reward: immediate environment feedback
|
||||||
|
# Together they guide fast exploration during simulation
|
||||||
for (k, childNode) in node.children
|
for (k, childNode) in node.children
|
||||||
potential = childNode.progressvalue + childNode.reward
|
potential = childNode.progressvalue + childNode.reward
|
||||||
if potential > highestProgressValue
|
if potential > highestProgressValue
|
||||||
@@ -181,186 +199,234 @@ function selectChildNode(node::MCTSNode)::MCTSNode
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
""" Expand selected node.
|
""" Expand a node by generating new child nodes.
|
||||||
|
|
||||||
|
Creates new child nodes by applying the transition function multiple times
|
||||||
|
(horizontally samples) from the current node.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
MCTS node
|
The MCTS node to expand.
|
||||||
- `transition::Function`
|
- `transition::Function`
|
||||||
A function that handles state transition.
|
A function that handles state transition.
|
||||||
- `transitionargs::NamedTuple`
|
- `transitionargs::NamedTuple`
|
||||||
Arguments for transition()
|
Arguments passed to the transition function.
|
||||||
- `totalsample::Integer`
|
|
||||||
Total number to sample from the current node (i.e. expand new node horizontally)
|
# Keyword Arguments
|
||||||
|
- `horizontalSample::Integer=3`
|
||||||
|
Number of child nodes to generate.
|
||||||
|
- `multithread::Bool=false`
|
||||||
|
Whether to run expansion in parallel using multiple threads.
|
||||||
|
|
||||||
# Return
|
# Return
|
||||||
- None
|
- `Nothing`
|
||||||
|
|
||||||
# Signature
|
|
||||||
"""
|
"""
|
||||||
# function expand(node::MCTSNode, transition::Function, transitionargs::NamedTuple;
|
|
||||||
# totalsample::Integer=3)
|
|
||||||
|
|
||||||
# # not use Any[] because I want to preserve result order
|
|
||||||
# results = Vector{Any}(undef, totalsample)
|
|
||||||
|
|
||||||
# @sync for i in 1:totalsample
|
|
||||||
# @spawn begin
|
|
||||||
# result = transition(deepcopy(node.state), deepcopy(transitionargs))
|
|
||||||
# results[i] = result
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# for result in results
|
|
||||||
# newNodeKey::AbstractString = result[:newNodeKey]
|
|
||||||
# newstate::AbstractDict = result[:newstate]
|
|
||||||
# progressvalue::Integer = result[:progressvalue]
|
|
||||||
|
|
||||||
# """
|
|
||||||
# [] newNodeKey ∉ keys(node.children).
|
|
||||||
# New state may have semantic vector close enought to
|
|
||||||
# one of existing child state. Which can be assume that they are the same state
|
|
||||||
# semantically-wise i.e. De javu. This could be used to recall lessons for this
|
|
||||||
# similar situation to improve decisionMaker and evaluator.
|
|
||||||
# """
|
|
||||||
# if newNodeKey ∉ keys(node.children)
|
|
||||||
# node.children[newNodeKey] =
|
|
||||||
# MCTSNode(newNodeKey, newstate, 0, progressvalue, 0, newstate[:reward],
|
|
||||||
# newstate[:isterminal], node, Dict{String, MCTSNode}())
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
function expand(node::MCTSNode,transition::Function, transitionargs::NamedTuple;
|
function expand(node::MCTSNode,transition::Function, transitionargs::NamedTuple;
|
||||||
totalsample::Integer=3)
|
horizontalSample::Integer=3, multithread=false)
|
||||||
|
# Generate child nodes by applying the transition function multiple times
|
||||||
|
# This is called "horizontal sampling" - we branch out horizontally in the tree
|
||||||
|
# - multithread=true: spawn parallel threads for each expansion
|
||||||
|
# - multithread=false: sequential expansion (default, simpler)
|
||||||
|
|
||||||
nthSample = 0
|
if multithread
|
||||||
while true
|
@sync for i in 1:horizontalSample
|
||||||
nthSample += 1
|
@spawn _expand(node, transition, transitionargs)
|
||||||
if nthSample <= totalsample
|
end
|
||||||
result = transition(node.state, transitionargs)
|
else
|
||||||
newNodeKey::AbstractString = result[:newNodeKey]
|
|
||||||
newstate::AbstractDict = result[:newstate]
|
|
||||||
progressvalue::Integer = result[:progressvalue]
|
|
||||||
|
|
||||||
"""
|
for i in 1:horizontalSample
|
||||||
[] newNodeKey ∉ keys(node.children).
|
|
||||||
New state may have semantic vector close enought to
|
_expand(node, transition, transitionargs)
|
||||||
one of existing child state. Which can be assume that they are the same state
|
|
||||||
semantically-wise i.e. De javu. This could be used to recall lessons for this
|
|
||||||
similar situation to improve decisionMaker and evaluator.
|
|
||||||
"""
|
|
||||||
if newNodeKey ∉ keys(node.children)
|
|
||||||
node.children[newNodeKey] =
|
|
||||||
MCTSNode(newNodeKey, newstate, 0, progressvalue, 0, newstate[:reward],
|
|
||||||
newstate[:isterminal], node, Dict{String, MCTSNode}())
|
|
||||||
end
|
|
||||||
else
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
""" Helper function to expand a single child node.
|
||||||
|
|
||||||
""" Simulate interactions between agent and environment
|
Creates one new child node from the parent node using the transition function.
|
||||||
|
Checks for semantically equivalent states (dejavu) to avoid duplicates.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
node that will be a simulation starting point.
|
The parent MCTS node to expand from.
|
||||||
- `transition::Function`
|
- `transition::Function`
|
||||||
A user function that handles how state transition.
|
A function that handles state transition.
|
||||||
- `transitionargs::NamedTuple`
|
- `transitionargs::NamedTuple`
|
||||||
Arguments for everything the user will use within transition().
|
Arguments passed to the transition function.
|
||||||
- `maxdepth::Integer`
|
|
||||||
maximum depth level MCTS goes vertically.
|
|
||||||
- totalsample::Integer
|
|
||||||
Total number to sample from the current node (i.e. expand new node horizontally)
|
|
||||||
|
|
||||||
# Return
|
|
||||||
- `::NamedTuple{(:simTrajectoryReward, :terminalstate), Tuple{Number, Union{Dict{Symbol, Any}, Nothing}}}`
|
|
||||||
|
|
||||||
# Signature
|
# Return
|
||||||
|
- `Nothing`
|
||||||
|
"""
|
||||||
|
function _expand(node::MCTSNode,transition::Function, transitionargs::NamedTuple)
|
||||||
|
|
||||||
|
# Generate one child node from the parent using the transition function
|
||||||
|
result = transition(node.state, transitionargs)
|
||||||
|
newNodeKey::AbstractString = result[:newNodeKey]
|
||||||
|
newstate::AbstractDict = result[:newstate]
|
||||||
|
progressvalue::Integer = result[:progressvalue]
|
||||||
|
|
||||||
|
# Dejavu detection: avoid adding duplicate states
|
||||||
|
# If newNodeKey already exists, skip - this handles semantically equivalent states
|
||||||
|
if newNodeKey ∉ keys(node.children)
|
||||||
|
|
||||||
|
# Create new MCTS node with:
|
||||||
|
# - visits=0: no simulations yet
|
||||||
|
# - statevalue=0: will be updated after simulation
|
||||||
|
# - progressvalue: LLM's estimate (fast heuristic)
|
||||||
|
# - reward: immediate environment feedback
|
||||||
|
newNode = MCTSNode(newNodeKey, newstate, 0, progressvalue, 0, newstate["reward"],
|
||||||
|
newstate["isterminal"], node, Dict{String, MCTSNode}(), Dict{String, Any}())
|
||||||
|
|
||||||
|
node.children[newNodeKey] = newNode
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
""" Simulate interactions between agent and environment.
|
||||||
|
|
||||||
|
Performs a rollout from the given node up to the maximum simulation depth,
|
||||||
|
sampling child nodes at each level and accumulating rewards along the way.
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
- `node::MCTSNode`
|
||||||
|
The node to start simulation from.
|
||||||
|
- `transition::Function`
|
||||||
|
A user function that handles state transition.
|
||||||
|
- `transitionargs::NamedTuple`
|
||||||
|
Arguments passed to the transition function.
|
||||||
|
|
||||||
|
# Keyword Arguments
|
||||||
|
- `maxSimulationDepth::Integer=3`
|
||||||
|
Maximum depth level MCTS goes vertically during simulation.
|
||||||
|
- `horizontalSample::Integer=3`
|
||||||
|
Number of child nodes sampled at each node during simulation.
|
||||||
|
- `multithread::Bool=false`
|
||||||
|
Whether to run expansion in parallel using multiple threads.
|
||||||
|
|
||||||
|
# Return
|
||||||
|
- `NamedTuple{(:simTrajectoryReward, :terminalstate), Tuple{<:Number, Union{Dict{String, Any}, Nothing}}}`
|
||||||
|
- `simTrajectoryReward`: cumulative reward collected along the simulation trajectory
|
||||||
|
- `terminalstate`: final state if a terminal state was reached, `nothing` otherwise
|
||||||
"""
|
"""
|
||||||
function simulate(node::MCTSNode, transition::Function, transitionargs::NamedTuple;
|
function simulate(node::MCTSNode, transition::Function, transitionargs::NamedTuple;
|
||||||
maxdepth::Integer=3, totalsample::Integer=3
|
maxSimulationDepth::Integer=3, horizontalSample::Integer=3, multithread=false
|
||||||
)::NamedTuple{(:simTrajectoryReward, :terminalstate), Tuple{Number, Union{Dict{Symbol, Any}, Nothing}}}
|
)::NamedTuple{(:simTrajectoryReward, :terminalstate), Tuple{<:Number, Union{Dict{String, Any}, Nothing}}}
|
||||||
|
|
||||||
|
# Perform a rollout simulation from the given node:
|
||||||
|
# 1. Accumulate rewards along the trajectory
|
||||||
|
# 2. Expand nodes horizontally at each level
|
||||||
|
# 3. Select children to explore vertically down the tree
|
||||||
|
# Returns cumulative reward and whether a terminal state was reached
|
||||||
|
|
||||||
simTrajectoryReward = 0.0
|
simTrajectoryReward = 0.0
|
||||||
terminalstate = nothing
|
terminalstate = nothing
|
||||||
|
|
||||||
for depth in 1:maxdepth
|
for depth in 1:maxSimulationDepth
|
||||||
|
|
||||||
|
# Accumulate the current node's reward to the trajectory total
|
||||||
simTrajectoryReward += node.reward
|
simTrajectoryReward += node.reward
|
||||||
|
|
||||||
|
# Check if we've reached a terminal state
|
||||||
if node.isterminal
|
if node.isterminal
|
||||||
|
|
||||||
terminalstate = node.state
|
terminalstate = node.state
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
expand(node, transition, transitionargs;
|
|
||||||
totalsample=totalsample)
|
# Expand current node to generate children (horizontal sampling)
|
||||||
|
_ = expand(node, transition, transitionargs;
|
||||||
|
horizontalSample=horizontalSample,
|
||||||
|
multithread=multithread)
|
||||||
|
|
||||||
|
# Select best child to continue the rollout (vertical exploration)
|
||||||
|
# Uses progressvalue + reward for fast selection during simulation
|
||||||
node = selectChildNode(node)
|
node = selectChildNode(node)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return (simTrajectoryReward=simTrajectoryReward, terminalstate=terminalstate)
|
return (simTrajectoryReward=simTrajectoryReward,
|
||||||
|
terminalstate=terminalstate)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# """ Make new state
|
||||||
|
|
||||||
"""
|
# # Arguments
|
||||||
|
# - `currentstate::T1`
|
||||||
|
# Current state dictionary containing thought history and metadata
|
||||||
|
# - `thoughtDict::T4`
|
||||||
|
# Dictionary containing new thought and action
|
||||||
|
# - `response::T2`
|
||||||
|
# Response string from the environment
|
||||||
|
# - `select::Union{T3, Nothing}`
|
||||||
|
# Selection value or nothing
|
||||||
|
# - `reward::T3`
|
||||||
|
# Reward value for this state
|
||||||
|
# - `isterminal::Bool`
|
||||||
|
# Whether this state is terminal
|
||||||
|
|
||||||
# Arguments
|
# # Return
|
||||||
|
# - `Tuple{String, Dict{String, <:Any}}`
|
||||||
|
# A tuple containing:
|
||||||
|
# - A unique node key string
|
||||||
|
# - A new state dictionary with updated thought history and metadata
|
||||||
|
|
||||||
|
# # Example
|
||||||
|
# ```jldoctest
|
||||||
|
# julia>
|
||||||
|
# ```
|
||||||
|
|
||||||
|
# # Signature
|
||||||
|
# """
|
||||||
|
# function makeNewState(currentstate::T1, thoughtDict::T4, response::T2, select::Union{T3, Nothing},
|
||||||
|
# reward::T3, isterminal::Bool
|
||||||
|
# )::Tuple{String, Dict{String, <:Any}} where {T1<:AbstractDict, T2<:AbstractString, T3<:Number, T4<:AbstractDict}
|
||||||
|
|
||||||
|
# # Find the latest thought key and index from current state's thought history
|
||||||
|
# currentstate_latestThoughtKey, currentstate_latestThoughtIndice =
|
||||||
|
# GeneralUtils.findHighestIndexKey(currentstate[:thoughtHistory], "thought")
|
||||||
|
# # Calculate next index for new thought/action
|
||||||
|
# currentstate_nextIndice =
|
||||||
|
# currentstate_latestThoughtKey == :NA ? 1 : currentstate_latestThoughtIndice + 1
|
||||||
|
# # Create new keys for thought and action based on next index
|
||||||
|
# currentstate_latestThoughtKey = Symbol("thought_$currentstate_nextIndice")
|
||||||
|
# latestActionKey = Symbol("action_$currentstate_nextIndice")
|
||||||
|
|
||||||
|
# # Find the latest thought index from input thought dictionary
|
||||||
|
# _, thoughtDict_latestThoughtIndice =
|
||||||
|
# GeneralUtils.findHighestIndexKey(thoughtDict, "thought")
|
||||||
|
|
||||||
# Return
|
# # Determine thought and action keys from thought dictionary
|
||||||
|
# thoughtDict_latestThoughtKey, thoughtDict_latestActionKey =
|
||||||
|
# if thoughtDict_latestThoughtIndice == -1
|
||||||
|
# (:thought, :action)
|
||||||
|
# else
|
||||||
|
# (
|
||||||
|
# Symbol("thought_$thoughtDict_latestThoughtIndice"),
|
||||||
|
# Symbol("action_$thoughtDict_latestThoughtIndice"),
|
||||||
|
# )
|
||||||
|
# end
|
||||||
|
|
||||||
# Example
|
# # Create new state by deep copying current state
|
||||||
```jldoctest
|
# newstate = deepcopy(currentstate)
|
||||||
julia>
|
# # Update thought history with new thought
|
||||||
```
|
# newstate[:thoughtHistory][currentstate_latestThoughtKey] =
|
||||||
|
# thoughtDict[thoughtDict_latestThoughtKey]
|
||||||
# TODO
|
# # Update thought history with new action
|
||||||
- [] update docstring
|
# newstate[:thoughtHistory][latestActionKey] = thoughtDict[thoughtDict_latestActionKey]
|
||||||
- [x] implement the function
|
# # Create and add new observation to thought history
|
||||||
|
# newObservationKey = Symbol("observation_$(currentstate_nextIndice)")
|
||||||
# Signature
|
# newstate[:thoughtHistory][newObservationKey] = response
|
||||||
"""
|
# # Update state metadata
|
||||||
function makeNewState(currentstate::T1, thoughtDict::T4, response::T2, select::Union{T3, Nothing},
|
# newstate[:reward] = reward
|
||||||
reward::T3, isterminal::Bool
|
# newstate[:select] = select
|
||||||
)::Tuple{String, Dict{Symbol, <:Any}} where {T1<:AbstractDict, T2<:AbstractString, T3<:Number, T4<:AbstractDict}
|
# newstate[:isterminal] = isterminal
|
||||||
|
|
||||||
currentstate_latestThoughtKey, currentstate_latestThoughtIndice =
|
|
||||||
GeneralUtils.findHighestIndexKey(currentstate[:thoughtHistory], "thought")
|
|
||||||
currentstate_nextIndice =
|
|
||||||
currentstate_latestThoughtKey == :NA ? 1 : currentstate_latestThoughtIndice + 1
|
|
||||||
currentstate_latestThoughtKey = Symbol("thought_$currentstate_nextIndice")
|
|
||||||
latestActionKey = Symbol("action_$currentstate_nextIndice")
|
|
||||||
|
|
||||||
_, thoughtDict_latestThoughtIndice =
|
|
||||||
GeneralUtils.findHighestIndexKey(thoughtDict, "thought")
|
|
||||||
|
|
||||||
thoughtDict_latestThoughtKey, thoughtDict_latestActionKey =
|
|
||||||
if thoughtDict_latestThoughtIndice == -1
|
|
||||||
(:thought, :action)
|
|
||||||
else
|
|
||||||
(
|
|
||||||
Symbol("thought_$thoughtDict_latestThoughtIndice"),
|
|
||||||
Symbol("action_$thoughtDict_latestThoughtIndice"),
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
# add Thought, action, observation to thoughtHistory
|
|
||||||
newstate = deepcopy(currentstate)
|
|
||||||
newstate[:thoughtHistory][currentstate_latestThoughtKey] =
|
|
||||||
thoughtDict[thoughtDict_latestThoughtKey]
|
|
||||||
newstate[:thoughtHistory][latestActionKey] = thoughtDict[thoughtDict_latestActionKey]
|
|
||||||
newObservationKey = Symbol("observation_$(currentstate_nextIndice)")
|
|
||||||
newstate[:thoughtHistory][newObservationKey] = response
|
|
||||||
newstate[:reward] = reward
|
|
||||||
newstate[:select] = select
|
|
||||||
newstate[:isterminal] = isterminal
|
|
||||||
|
|
||||||
newNodeKey = GeneralUtils.uuid4snakecase()
|
|
||||||
|
|
||||||
return (newNodeKey, newstate)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
# # Generate unique ID for new node
|
||||||
|
# newNodeKey = GeneralUtils.uuid4snakecase()
|
||||||
|
|
||||||
|
# return (newNodeKey, newstate)
|
||||||
|
# end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+23
-14
@@ -2,23 +2,35 @@ module type
|
|||||||
|
|
||||||
export MCTSNode
|
export MCTSNode
|
||||||
|
|
||||||
|
using GeneralUtils
|
||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||||
|
|
||||||
|
|
||||||
""" a node for MCTS search tree
|
""" a node for MCTS search tree
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `state::T`
|
- `nodekey::AbstractString`
|
||||||
a state of a game. Can be a Dict or something else.
|
unique identifier for the node
|
||||||
- `visits::Integer `
|
- `state::AbstractDict`
|
||||||
number of time the game visits this state
|
a state of a game represented as a dictionary
|
||||||
- `stateValue::Float64`
|
- `visits::Integer`
|
||||||
state value
|
number of times the game visits this state
|
||||||
- `children::Dict{T, MCTSNode}`
|
- `progressvalue::Number`
|
||||||
children node
|
estimated value by LLM's reasoning
|
||||||
|
- `statevalue::Number`
|
||||||
|
current state value, stores node's immediate reward and future discounted rewards
|
||||||
|
- `reward::Number`
|
||||||
|
immediate reward for this node
|
||||||
|
- `isterminal::Bool`
|
||||||
|
whether this node represents a terminal state
|
||||||
|
- `parent::Union{MCTSNode, Nothing}`
|
||||||
|
reference to parent node, Nothing for root
|
||||||
|
- `children::Dict{String, MCTSNode}`
|
||||||
|
mapping of child nodes
|
||||||
|
- `etc::Dict{Symbol, Any}`
|
||||||
|
additional storage for arbitrary data
|
||||||
|
|
||||||
# Return
|
|
||||||
- `nothing`
|
|
||||||
# Example
|
# Example
|
||||||
```jldoctest
|
```jldoctest
|
||||||
julia> state = Dict(
|
julia> state = Dict(
|
||||||
@@ -34,9 +46,6 @@ julia> state = Dict(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
# TODO
|
|
||||||
[] update docstring
|
|
||||||
|
|
||||||
# Signature
|
# Signature
|
||||||
"""
|
"""
|
||||||
mutable struct MCTSNode{T1<:AbstractDict, T2<:AbstractString}
|
mutable struct MCTSNode{T1<:AbstractDict, T2<:AbstractString}
|
||||||
@@ -49,6 +58,7 @@ mutable struct MCTSNode{T1<:AbstractDict, T2<:AbstractString}
|
|||||||
isterminal::Bool
|
isterminal::Bool
|
||||||
parent::Union{MCTSNode, Nothing}
|
parent::Union{MCTSNode, Nothing}
|
||||||
children::Dict{String, MCTSNode}
|
children::Dict{String, MCTSNode}
|
||||||
|
etc::Dict{String, Any} # store anything
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -110,7 +120,6 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end # module type
|
end # module type
|
||||||
+73
-21
@@ -6,47 +6,99 @@ using ..type
|
|||||||
|
|
||||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||||
|
|
||||||
""" Select a node based on UCT score
|
""" Select a node based on UCT (Upper Confidence Bound for Trees) score.
|
||||||
|
|
||||||
|
The function computes UCT values for all child nodes and returns the child with the
|
||||||
|
highest UCT score. The UCT formula balances exploitation (child state value) and
|
||||||
|
exploration (visit count and parent visit count) using the exploration weight `w`.
|
||||||
|
|
||||||
|
Does **not** mutate the input node.
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
- `node::MCTSNode`
|
- `node::MCTSNode`
|
||||||
mcts node
|
The MCTS node whose children will be evaluated.
|
||||||
- `w::T`
|
- `w::AbstractFloat`
|
||||||
exploration weight. Value is usually between 1 to 2.
|
Exploration weight. Typical values range from 1.0 to 2.0. A value of 1.0 balances
|
||||||
Value 1.0 makes MCTS balance between exploration and exploitation like 50%-50%.
|
exploration and exploitation equally. Higher values (e.g., 2.0) encourage more
|
||||||
Value 2.0 makes MCTS aggressively search the tree.
|
exploration of less-visited nodes.
|
||||||
# Return
|
|
||||||
- `selectedNode::MCTSNode`
|
|
||||||
|
|
||||||
# Example
|
# Return
|
||||||
```jldoctest
|
- `selectedNode::MCTSNode`
|
||||||
julia>
|
The child node with the highest UCT score. Returns `nothing` if the node has no
|
||||||
|
children (though this would indicate an error since UCTselect is called on non-leaves).
|
||||||
|
|
||||||
|
# The UCT Formula
|
||||||
|
|
||||||
|
```
|
||||||
|
UCT(s,a) = Q(s,a) + c * sqrt(ln(N(s)) / N(s,a))
|
||||||
|
|
||||||
|
Where:
|
||||||
|
Q(s,a) = childNode.statevalue (exploitation: accumulated reward)
|
||||||
|
c = w (explorationweight) (controls exploration vs exploitation)
|
||||||
|
N(s) = node.visits (parent visits - total visits to parent)
|
||||||
|
N(s,a) = childNode.visits (child visits - visits to this specific action)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Signature
|
# Behavior
|
||||||
|
|
||||||
|
| Child visits | Exploration term | Behavior |
|
||||||
|
|-------------|------------------|----------|
|
||||||
|
| 0 (never visited) | Undefined | Uses `progressvalue` (LLM heuristic) |
|
||||||
|
| Low (few visits) | High | Encourages exploring new branches |
|
||||||
|
| High (many visits) | Near 0 | Exploits known good branches |
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
```jldoctest
|
||||||
|
julia> using LLMMCTS
|
||||||
|
julia> child1 = MCTSNode("a", Dict(:reward=>5.0), 0, 10, 50, 0, false, nothing, Dict(), Dict())
|
||||||
|
julia> child2 = MCTSNode("b", Dict(:reward=>6.0), 0, 5, 30, 0, false, nothing, Dict(), Dict())
|
||||||
|
julia> parent = MCTSNode("root", Dict(:reward=>0.0), 0, 15, 100, 0, false, nothing,
|
||||||
|
Dict("a"=>child1, "b"=>child2), Dict())
|
||||||
|
julia> selected = UCTselect(parent, 1.0)
|
||||||
|
MCTSNode(...)
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
function UCTselect(node::MCTSNode, w::T)::MCTSNode where {T<:AbstractFloat}
|
function UCTselect(node::MCTSNode, w::T)::MCTSNode where {T<:AbstractFloat}
|
||||||
|
# UCT (Upper Confidence Bound for Trees) selects the best child using:
|
||||||
|
# UCT = statevalue + exploration_weight * sqrt(ln(parent_visits) / child_visits)
|
||||||
|
#
|
||||||
|
# The two terms balance:
|
||||||
|
# - Exploitation (statevalue): choose children that performed well in simulations
|
||||||
|
# - Exploration (sqrt term): encourage trying less-visited children
|
||||||
|
#
|
||||||
|
# The exploration weight `w` controls this balance:
|
||||||
|
# - w=1.0: equal emphasis on exploration and exploitation
|
||||||
|
# - w>1.0: more aggressive exploration (try new branches)
|
||||||
|
# - w<1.0: more exploitation (stick with known good branches)
|
||||||
|
|
||||||
maxUCT = -Inf
|
maxUCT = -Inf
|
||||||
selectedNode = nothing
|
selectedNode = nothing
|
||||||
|
|
||||||
for (childState, childNode) in node.children
|
for (childState, childNode) in node.children
|
||||||
|
# Calculate UCT value for this child
|
||||||
UCTvalue =
|
UCTvalue =
|
||||||
if childNode.visits != 0
|
if childNode.visits != 0
|
||||||
weightedterm = w * sqrt(log(node.visits) / childNode.visits) # explore term
|
# Child has been visited before - use statevalue with exploration bonus
|
||||||
childNode.statevalue + weightedterm
|
# Exploration bonus = w * sqrt(ln(parent_visits) / child_visits)
|
||||||
else # node.visits == 0 makes sqrt() in explore term error
|
# High child_visits = small bonus (exploitation dominates)
|
||||||
childNode.progressvalue # exploit term
|
# Low child_visits = large bonus (encourages exploration)
|
||||||
|
weightedterm = w * sqrt(log(node.visits) / childNode.visits)
|
||||||
|
UCTvalue = childNode.statevalue + weightedterm
|
||||||
|
else
|
||||||
|
# Child has never been visited - exploration term undefined
|
||||||
|
# Fall back to progressvalue (LLM heuristic) as exploitation term
|
||||||
|
# This allows LLM guidance to direct early search
|
||||||
|
UCTvalue = childNode.progressvalue
|
||||||
end
|
end
|
||||||
|
|
||||||
if UCTvalue > maxUCT
|
if UCTvalue > maxUCT
|
||||||
maxUCT = UCTvalue
|
maxUCT = UCTvalue
|
||||||
selectedNode = childNode
|
selectedNode = childNode
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return selectedNode
|
return selectedNode
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user