update
This commit is contained in:
+26
-14
@@ -74,7 +74,7 @@ function runMCTS(
|
||||
multithread=false,
|
||||
)::NamedTuple{(:root, :bestNextState, :bestTerminalState, :highValueStateList),
|
||||
Tuple{MCTSNode,T,T,Vector{Dict{String,Any}}}} where {T<:Any}
|
||||
|
||||
println("--> LLMMCTS runMCTS 1")
|
||||
# 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
|
||||
@@ -91,33 +91,38 @@ function runMCTS(
|
||||
# Start from root and traverse down using UCT selection
|
||||
node = root
|
||||
node.visits += 1 # Count this iteration's visit to root
|
||||
|
||||
println("--> LLMMCTS runMCTS 2")
|
||||
# Phase 1: SELECTION - Traverse tree using UCT until reaching a leaf node
|
||||
# UCT balances exploration (new branches) vs exploitation (promising branches)
|
||||
while !isleaf(node)
|
||||
println("--> LLMMCTS runMCTS 3")
|
||||
node = UCTselect(node, explorationweight)
|
||||
end
|
||||
|
||||
println("--> LLMMCTS runMCTS 4")
|
||||
# Phase 2: TERMINAL CHECK - If leaf is terminal, just backpropagate
|
||||
if node.isterminal
|
||||
println("--> LLMMCTS runMCTS 5")
|
||||
# If this terminal state has high reward (>= 8), store it for later
|
||||
if node.state[:reward] >= 8
|
||||
println("--> LLMMCTS runMCTS 6")
|
||||
put!(highValueState, deepcopy(node.state))
|
||||
end
|
||||
|
||||
println("--> LLMMCTS runMCTS 7")
|
||||
# Backpropagate the terminal node's own reward up to root
|
||||
# This updates all ancestors with this path's outcome
|
||||
backpropagate(node, node.reward)
|
||||
else
|
||||
println("--> LLMMCTS runMCTS 8")
|
||||
# Phase 3: EXPANSION - Generate children for this non-terminal leaf
|
||||
# Horizontal sampling: create multiple child nodes via LLM transition
|
||||
_ = expand(node, transition, transitionargs;
|
||||
horizontalSample=horizontalSampleExpansionPhase,
|
||||
multithread=multithread)
|
||||
|
||||
println("--> LLMMCTS runMCTS 9")
|
||||
# Phase 4: SIMULATION + BACKPROPAGATION
|
||||
# For each newly expanded child, run simulation and update statistics
|
||||
if multithread
|
||||
println("--> LLMMCTS runMCTS 10")
|
||||
# Parallel simulation: spawn threads for each child node
|
||||
@sync for (leafNodeKey, leafNode) in node.children
|
||||
@spawn simulateThenBackpropagate(leafNode, transition, transitionargs;
|
||||
@@ -129,8 +134,10 @@ function runMCTS(
|
||||
)
|
||||
end
|
||||
else
|
||||
println("--> LLMMCTS runMCTS 11")
|
||||
# Sequential simulation: process each child one at a time
|
||||
for (leafNodeKey, leafNode) in node.children
|
||||
println("--> LLMMCTS runMCTS 11-1")
|
||||
simulateThenBackpropagate(leafNode, transition, transitionargs;
|
||||
maxSimulationDepth=maxSimulationDepth,
|
||||
horizontalSampleSimulationPhase=horizontalSampleSimulationPhase,
|
||||
@@ -140,27 +147,29 @@ function runMCTS(
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
println("--> LLMMCTS runMCTS 12")
|
||||
# Phase 5: EARLY STOP CHECK
|
||||
# Optional: stop search early if a condition is met
|
||||
if typeof(earlystop) <: Function && earlystop(node.state)
|
||||
println("--> LLMMCTS runMCTS 13")
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
println("--> LLMMCTS runMCTS 14")
|
||||
# After all iterations, extract results from the search tree
|
||||
# Select best immediate next state (best child of root)
|
||||
bestNextState = selectBestNextNode(root)
|
||||
|
||||
println("--> LLMMCTS runMCTS 15")
|
||||
# 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)
|
||||
println("--> LLMMCTS runMCTS 16")
|
||||
push!(highValueStateList, take!(highValueState))
|
||||
end
|
||||
|
||||
println("--> LLMMCTS runMCTS 17")
|
||||
# Return complete search results
|
||||
result = (
|
||||
root=root,
|
||||
@@ -209,6 +218,7 @@ function simulateThenBackpropagate(node::MCTSNode, transition::Function, transit
|
||||
saveSimulatedNode::Bool=false,
|
||||
multithread=false,
|
||||
highValueState=Union{Nothing,Any}=nothing)
|
||||
println("--> LLMMCTS simulateThenBackpropagate 1")
|
||||
# Phase 1: RUN SIMULATION (rollout)
|
||||
# Perform a rollout from this node, accumulating rewards along the way
|
||||
simTrajectoryReward, terminalstate =
|
||||
@@ -216,28 +226,30 @@ function simulateThenBackpropagate(node::MCTSNode, transition::Function, transit
|
||||
maxSimulationDepth=maxSimulationDepth,
|
||||
horizontalSample=horizontalSampleSimulationPhase,
|
||||
multithread=multithread)
|
||||
|
||||
println("--> LLMMCTS simulateThenBackpropagate 2")
|
||||
# Phase 2: HIGH-VALUE STATE TRACKING
|
||||
# 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
|
||||
|
||||
terminalstate["reward"] >= 8
|
||||
println("--> LLMMCTS simulateThenBackpropagate 3")
|
||||
put!(highValueState, deepcopy(terminalstate))
|
||||
end
|
||||
|
||||
println("--> LLMMCTS simulateThenBackpropagate 4")
|
||||
# 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)
|
||||
|
||||
println("--> LLMMCTS simulateThenBackpropagate 5")
|
||||
# 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
|
||||
println("--> LLMMCTS simulateThenBackpropagate 6")
|
||||
node.children = Dict{String, MCTSNode}()
|
||||
end
|
||||
println("--> LLMMCTS simulateThenBackpropagate 7")
|
||||
end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user