Huge memory usage in C++ MCTS algorithm - c++

I am implementing a Monte Carlo Tree Search algorithm in C++. I create one huge tree at a time in a for loop, a different one at each iteration. My problem is that each tree is vast and if i create 12000 trees, my program crashes because all available memory in the PC is allocated.
The thing is, that the tree that i create in the iteration 5 for example, is useless in the next iterations, so i would like to free the memory it has allocated. I create each node as std::make_shared<Node<T, A, E> where Node is a class that i have created, and the tree as an instance of a class mcts = MCTS(laneFreeState(state), backpropagation, terminationCheck,scoring)

The call to std::make_shared is using new to allocate memory on the heap. So when you finish using the tree, just recursively iterate it, deleting the nodes as you go (deepest first, then work backwards).

Related

How to quickly deallocate an entire subtree?

I'm implementing an Alpha-Beta pruning (MiniMax) algorithm for a board game. I have a Board class with GetAvailableMoves(), PlayMove(Move x) and UndoMove() which all modify the game position inside the Board class. To implement Alpha-Beta I need a tree structure to keep track of the alpha and beta values of every position.
Since I'll want to calculate the best move multiple times in a game, I want to reuse the part of the tree that I already calculated and throw away the rest. If I implement the tree as doubly-linked nodes, then I'll have to call delete on every node in all subtrees that I want to delete. This can be very expensive.
How can I implement a tree that allows me to quickly cut and destroy an entire branch, possibly in O(1) time?
You can implement a datapool for your data. To get an allocated node you get it from the pool, and when you delete you put it back in the pool. Then you only allocate new memory when your pool is empty, and you only delete at the end of your runtime.
This will still need to move all the out of data objects back to the pool when you cut a subtree, so not O(1). But no delete calls.
Alternatively, if you have plenty of memory available and you just want a O(1) way to delete your subtrees, you can move the root of your subtree to a ToDeleteLater queue. And at the end of your run or whenever your program has free time, it can clear out this queue by running through trees deleting.
Unless the subtrees are huge, deleting honestly should not take too long, so instead of using pointers that you need to delete. You can implement destructors that take care of the deleting (RAII) So you don't have to write a complicated deleter.
Note: It is usually recommended that you post some code or more details so users can give more specific advice.

Implement a heap not using an array

I'm prepping for a Google developer interview and have gotten stuck on a question about heaps. I need to implement a heap as a dynamic binary tree (not array) where each node has a pointer to the parent and two children and there is a global pointer to the root node. The book asks "why won't this be enough?"
How can the standard tree implementation be extended to support heap operations add() and deleteMin()? How can these operations be implemented in this data structure?
Can you keep the size of total nodes ? if so, it's easy to know where you should add new element, because that's an almost full tree.
About deleteMin, I think that it will be less effective because you can't access directly to all leaves, as in array (N/2).
You should travel through all paths till you get leaf and then compare them, probably it will cost O(n)

Odd behaviour from Array in BinaryHeap

I have a tree-like structure using Node objects with references to other Node objects. Node is a class. Now, one of the routines I'm writing needs a minimum priority queue, which I'm implementing using std.container.BinaryHeap and std.container.Array. I'm instantiating it as follows:
Node[] r;
auto heap = BinaryHeap!(Array!(Node), "a > b")(Array!Node(r));
As part of the routine, I insert elements into heap using insert and remove elements from it using removeAny. Now, the routine works correctly, but afterwards, the tree-like structure breaks (my invariants for it fail), due to nodes being missing. What's going on here and why is this happening?
could be http://d.puremagic.com/issues/show_bug.cgi?id=6998 - std.container.Array destroys class instances

STL Implementation of reheapify

In a graph algorithm, I need to find the node with the smallest value.
In a step of the algorithm the value of this node or its neighbors can be decreased and a few of its neightbors can be removed dependent on their value.
Also, I don't want to search the whole graph for this node each time (although it is not so big (<1000 nodes)).
Therefore I looked at the STL library and found the heap structure which almost does what I want. I can insert and delete nodes very fast, but is there a method to update the heap fast when I only changed the value of one node without resorting the whole heap? I feel it would be a huge bottleneck in the program.
First the conceptual part:
If you use the heap insertion method with the element that decreased it's value as the starting point for insertion instead of starting at the back of the collection everything just works.
I haven't done that in C++ yet, but std::push_heap looks fine for that purpose.

Indexing: Implementing Tree data structures with Arrays/Vectors

I have been implementing a heap in C++ using a vector. Since I have to access the children of a node (2n, 2n+1) easily, I had to start at index 1. Is it the right way? As per my implementation, there is always a dummy element at zeroth location.
Your way works. Alternatively you can have root at index 0 and have children at 2n+1 and 2n+2
While this works well for heaps, you end up using a huge amount of redundant memory for other tree data structures that do not necessarily have a full and complete Binary tree. For example, this means that if you have a Binary search tree of 20 nodes with a depth of 5, you end up having to use an array of 2^5=32 instead of 20. Now imagine if you need a tree of 25 nodes with a depth of 22. You end up using a huge array of 4194304, whereas you could have used a linked representation to store just the 25 nodes.
You can still use an array and not incur such a memory hit. Just allocate a large block of memory as an array and use array indices as pointers to the children.
Thus, where you had
node.left = (node.index*2)
node.right = (node.index*2+1)
You simply use
node.left = <index of left child>
node.right = <index of right child>
Or you can just use pointers/references instead of integer indices to an array if your language supports it.
Edit:
It might not be obvious to everyone that a complete binary search tree takes up O(2^d) memory. There are d levels and every level has twice as many nodes as the level its parent is in (because every node except those at the bottom has exactly two children - never one). A binary heap is a binary tree (but not a Binary Search Tree) that is always complete by definition, so an array based implementation outlined by the OP does not incur any real memory overhead. For a heap, that is the best way to implement it in code. OTOH, most other binary trees (esp. Binary Search Trees) are not guaranteed to be complete. So trying to use this approach on would need O(2^depth) memory where depth can be as large as n, where we only need O(n) memory in a linked implementation.
So my answer is: yes, this is the best way for a heap. Just don't try it for other binary trees (unless you're sure they will always be complete).