//Finds max visit value within child nodes of referenced Node public static MonteCarloNode findBestUCTNode(MonteCarloNode _node) { //creates a new int parent visit, setting the value to that of the referenced node's state's visit count int _parentVisit = _node.GetState().GetVisits(); //creates variables used to assist in finding the best UCT node int _childIndex = 0; double _uctValue; double _prevUctValue = int.MinValue; //loops which iterates for the number of children in the referenced node, finding the best child node with UCT for (int i = 0; i < _node.GetChildren().Count; i++) { //finds the UCT value of the current child node _uctValue = UCTValue(_parentVisit, _node.GetChildren()[i].GetState().GetScore(), _node.GetChildren()[i].GetState().GetVisits()); //checks if the current UCT value is greater than that of the previous UCT value if (_uctValue > _prevUctValue) { //sets the child index to the index of the current child node _childIndex = i; } //sets the previous UCT value to the current UCT value _prevUctValue = _uctValue; } //returns the child node at the index which produced the best UCT value return(_node.GetChildren()[_childIndex]); }
//function used to perform the MCTS Cycle public void MCTSCycle(MonteCarloNode _rootNode) { // Phase 1 - Selection //finds best node from root node using UCT (Upper Confidence Bound for Trees) MonteCarloNode _selectionNode = Selection(_rootNode); // Phase 2 - Expansion //Checks if the selected node produces a win state, otherwise expanding on the selected node if (_selectionNode.GetState().GetBoard().CheckStatus() == MonteCarloBoard._inProgress) { //Performs expansion on the seleted node Expansion(_selectionNode); } // Phase 3 - Simulation //sets the node to explore to the selected node MonteCarloNode _nodeToExplore = _selectionNode; //checks if the node to explore contains any children if (_selectionNode.GetChildren().Count > 0) { //sets the node to explore to a random child node if any are available _nodeToExplore = _selectionNode.GetRandomChild(); } //simulates the node to explore and produces the number of the winner of the simulation, storing the result int _simulationWinner = Simulation(_nodeToExplore); // Phase 4 - Update //backpropagates up the tree, updating node scores from the node to explore to root based upon the winner of the simulation Backpropogation(_nodeToExplore, _simulationWinner); }
//function used to perform the selection of the MCTS cycle private MonteCarloNode Selection(MonteCarloNode _rootNode) { //sets a new node variable to the root node passed through MonteCarloNode _UCTnode = _rootNode; //checks if the node contains any child nodes while (_UCTnode.GetChildren().Count != 0) { //finds the best child node using UCT (Upper Confidence Bound for Trees) of the current node, then updates the node //this is looped while the node contains children, finding the best child node with no more child nodes _UCTnode = MonteCarloUCT.findBestUCTNode(_UCTnode); } //the UCT node is returned return(_UCTnode); }
public MonteCarloNode(MonteCarloNode _newNode) { this._children = new List <MonteCarloNode>(); this._state = new MonteCarloState(_newNode.GetState()); if (_newNode.GetParent() != null) { this._parent = _newNode.GetParent(); } List <MonteCarloNode> _nodeChildren = _newNode.GetChildren(); foreach (MonteCarloNode _child in _nodeChildren) { this._children.Add(new MonteCarloNode(_child)); } }
//function used to perform expansion of the MCTS cycle private void Expansion(MonteCarloNode _nodeToExpand) { //finds all legal states for the current node List <MonteCarloState> _legalStates = _nodeToExpand.GetState().GetLegalStates(); //loops through each legal state found foreach (MonteCarloState _state in _legalStates) { //creates a new node, setting it's state to a legal state found MonteCarloNode _newNode = new MonteCarloNode(_state); //sets the parent as the node to expand as passed through _newNode.SetParent(_nodeToExpand); //adds the new node to the child array of the node to expand _nodeToExpand.GetChildren().Add(_newNode); } }
public void addChild(MonteCarloNode _parent, MonteCarloNode _child) { _parent.GetChildren().Add(_child); }