Method for avoiding re-visiting of nodes in a large DFS? - c++

I'm exploring a tree of moves for a match-3 type game (with horizontal piece swapping), using a DFS to a depth of 4 moves ahead (because working towards bigger clear combos is much higher scoring). I'm evaluating each possible move of each board to look for the best overall next move to maximise score.
I'm representing the game board as a vector<char> with 100 chars per board, however my current DFS implementation doesn't check if a given board state has already been evluated (there's multiple move sequences that could lead to a given board state).
Given that each board has 90 possible moves, a DFS search to depth 4 evaluates 65,610,000 board states (in 100ms), and therefore I'd assume it's impractical to store each board state for the sake of DFS pruning to avoid re-evaluating a given board state. However, I recognise I could significantly prune the search tree if I avoid re-evaluation of previously evaluated states.
Is there an efficient and or memory conserving method to avoid re-evaluating previously evaluated board states in this DFS?

Related

Best data structure for an N-ary tree

I need to represent a tree with multiple branches per node. What structure should I use? It's for computing chess game states. It explodes exponentially so memory will be a concern. I'm using C++11 but am open to other standards. Also, pruning should be O(1).
EDIT1
To expand, I am going to be holding a Chess AI competition. The main PvP game is complete already, and I am programming the AI API next. Contestants will write their own AI, and then we will have them compete in a tournament. The winner's AI will be used in Player vs Computer games. I am just thinking about the best structure to store my game states and AI thoughts.
I was reading up on Deep Blue, and it thinks from 5 to ~25 moves ahead. I can imagine most computers capable of handling 5 moves deep with BFS, but anything deeper and I believe I will have to use DFS.
AI's will be timed, and competing AI's will only be played locally, so as not to introduce advantages in CPU power.
I am reading up on Monte Carlo and Alpha Beta searches now.
My initial thoughts on a data structure are as follows :
union CHESS_MOVE {
unsigned short m;
ChessPosT pos[2];
///...
};
class ChessMoveNode {
CHESS_MOVE move;
std::set<ChessMoveNode> nextmoves;
};
class ChessMoveTree {
std::set<ChessMoveNode> next;
};
The board can be calculated at any time by concatenating the path from the root to the leaf. Although recalculating the board could get very expensive over time. Ideas? Should I store the board? The board is stored as an array of 64 char indices holding a piece number. So it's 16 bytes, compared to 2, but the memory use would save a lot of re-calculation of the board state.
For my own personal AI, I will be implementing a board scoring function that will rank the game states, and then all non maximal game states will be discarded, as well as pruning game states that are invalidated by choosing a move.
One simple approach to do this that works well for Monte-Carlo Tree Search (MCTS) is to use a vector of some custom class. Inside the class you have whatever state information you need in addition to child information -- the number of the children and their index in the vector. This avoids storing a separate pointer for each child, which can introduce significant overhead.
So, the root is at index 0. Inside that index there would be two integers indicating that the children start at index 1 and that there are k children. (From index 1 to k.) At index 1 the children would start at index k+1 with l total children, and so on throughout the tree.
This works really well based on the assumptions that (1) the number of children is fixed, (2) that they are all added at once, and (3) that states are not removed from the tree.
If you are trying to prune states from the tree, this doesn't work as well, because you will leave gaps in tree if you remove them. Using explicit pointers for storing each child is expensive, so something else is done in practice.
First, with alpha-beta search you typically search the tree with a DFS and don't store branches. But, you use a hash table to store states and check for duplicates. The branches of the tree can be implicitly computed from the state, so you can reconstruct the tree without storing everything explicitly.
Note, however, that hash tables (called transposition tables in the context of game tree search) are not typically used deep in the tree because there are many states and the cost of storing grows while the benefit of removing duplicates shrinks.
To summarize, based on the assumption that you are doing something alpha-beta like and you have a good reason to store the tree explicitly, I suggest store the states in a hash table and leave the edges to be implicitly computed from a move-generation function. (Which would apply moves and take the hash of the resulting state to find them in the hash table. If they aren't there they have been pruned.)

What is the best data structure to model a path through an undirected graph?

I'm working on modeling a path search and deduction board game, to practice some concepts I am learning in school. This is a first attempt at analyzing graphs for me, and I would appreciate some advice on what kind of data structure might be appropriate for what I am trying to do.
The game I am modeling presents as a series of ~200 interconnected nodes, as shown below. Given a known starting position for the adversary (node 84, for example, in the figure below) the goal is to identify possible locations of the adversary's hideout. The adversary's moves away from 84 are, naturally unknown.
Fig 1 - Illustrative Sub-Graph with Adversary Initial Position at Node 84
Initially, this leads to a situation like the one below. Given the adversary started at 84, he/she can only be at 66, 86 or 99 after taking their first turn. And so on.
Fig 2 - Possible Locations for Adversary after 1, 2 and 3 Turns (Based on Fig 1 Graph)
So far, I have modeled the board itself as an undirected graph - using an implementation of OCaml's ocamlgraph library. What I am now trying to do is to model the path taken by the adversary through the graph, so as to identify potential locations of the adversary after each turn.
While convenient for illustration purposes, the tree representation implied by the figure above has several drawbacks:
First, keeping track of all possible paths through the network is unnecessary (I care only about terminal location of the adversary's hideout, not the path taken) as well as burdensome: each node is connected to ~7 other nodes, on average. By the time we hit the end of the game's 15 turns, that's a lot of branches!
Second, I suspect pruning would become an issue as well. Indeed, part of the exercise here is to maximally exploit the limited information about the adversary's movements that revealed as the game goes on. This information either states that the adversary "has never been to node X" or "has previously visited node X."
Information of the first type (e.g. "adversary has never been to node 65") would lead me to want to prune the tree "from above" by traveling down through the branches and cutting off any branch that is invalidated by the revealed information.
Fig 3 - Pruning from the Top ("Adversary Has Never Been to Node 65")
Information of the second type (e.g. "Adversary has Visited Node 100") would, however, invite pruning "from below" to cut off any branch that was not consistent with the information.
Fig 4 - Pruning from the Bottom (e.g. "Adversary Has Visited Node 100")
It seems to me that a naive tree approach would be a messy proposition, so I thought I would ask for any suggestions or advice on the best data structure to use here, or how to better approach the problem.
It's really hard to give advice for your case, as any optimization should be preceded by profiling. It sounds like you need a bitset of some sort and/or incidence matrix. For BitSet you can either use Batteries implementation or just implement your own using OCaml arbitrary precision numbers with Zarith library. For incidence matrix, you can opt into trivial _ array array, use the Bigarray module, or, again, use Zarith and implement your own efficient representation using bitwise operations.
And if I were you, I would start with defining the abstraction that you need (i.e., the interface) then start with a drop in implementation, and later optimize based on the real input, by substituting implementations.

Good way to handle collisions between mass-spring systems

I am programming a C++ simulation application in which several mass-spring structures will move and collide and I'm currently struggling with the collision detection and response part. These structures might or might not be closed (it might be a "ball" or just a chain of masses and springs) so it is (I think) impossible to use a "classic" approach where we test for 2 overlapping shapes.
Furthermore, the collisions are a really important part of that simulation and I need them to be as accurate as possible, both in terms of detection and response (real time is not a constraint here). I want to be able to know the forces applied to each Nodes (the masses), as far as possible.
At the moment I am detecting collisions between Nodes and springs at each time step, and the detection seems to work. I can compute the time of collision between one node and a spring, and thus find the exact position of the collision. However, I am not sure if this is the right approach for this problem and after lots of researches I can't quite find a way to make things work properly, mainly on the response aspect of the collisions.
Thus I would really like to hear from any technique, algorithm or library that seems well suited for this kind of collisions problems or any idea you might have to make this work. Really, any kind of help will be greatly appreciated.
If you can meet the following conditions:
0) All collisions are locally binary - that is to say
collisions only occur for pairs of particles, not triples etc,
1) you can predict the future time for a collision between
objects i and j from knowledge of their dynamics (assuming that no other
collision occurs first)
2) you know how to process the physics/dynamicseac of the collision
then you should be able to do the following:
Let Tpq be the predicted time for a collision between particles p and q, and Vp (Vq) be a structure holding the local dynamics of each particle p (q) (i.e its velocity, position, spring-constants, whatever)
For n particles...
Initialise by calculating all Tpq (p,q in 1..n)
Store the n^2 values of Tpq in a Priority Queue (PQ)
repeat
extract first Tpq from the PQ
Advance the time to Tpq
process the collision (i.e. update Vp and Vq according to your dynamics)
remove all Tpi, and Tiq (i in 1..n) from the PQ
// these will be invalid now as the changes in Vp, Vq means the
// previously calculated collision of p and q with any other particle
// i might occur sooner, later or not at all
recalculate new Tpi and Tiq (i in 1..n) and insert in the PQ
until done
There is an o(n^2) initial setup cost, but the repeat loop should be O(nlogn) - the cost of removing and replacing the 2n-1 invalidated collisions. This is fairly efficient for moderate numbers of particles (up to hundreds). It has the benefit that you only need to process things at collision time, rather than for equally spaced time steps. This makes things particularly efficient for a sparsely populated simulation.
I guess an octree approach would do best with your problem. An octree devides the virtual space into several recursive leaves of a tree and lets you compute possible collisions between the most probable nodes.
Here a short introduction: http://www.flipcode.com/archives/Introduction_To_Octrees.shtml :)

How to detect a cycle in a grid in least time complexity possible?

I have a maxiumum 35 character grid it maybe (1x35..5x7) or anything else .The value of each cell on the grid can be binary only.In simulating a game having certain moves which implies a possible change in the grade state after a move .If I have to detect the cycle/the period of this game,what algorithm/data structure can I use in the least possible time complexity? I tried a log n tree based approach to store the state of the grid but it wasn't fast enough for my purpose when the period is larger than 2^17. Is there a technique to perform hashing on the grid state without taking too much memory?
the grid is a 35-bit number, so you can store the grid as an integer (on a 64-bit machine) or 2 words on a lesser one. you can keep states you've already seen in a giant direct-address array or a hash table.

Addressing "procrastination" in minimax

I'm implementing minimax for a small game and am noticing something that I'm calling "procrastination". Boiled down to a very simple example:
In a capture-the-flag game, the flag is one square UP from player A, and player B is 50 spaces away. It's A's turn, and he can search 6 moves ahead. What I'm seeing is that all possible moves have a value of "Win" since A knows he can get to the flag before B even if he doesn't grab it immediately. So if UP is the last move in the ordering, he'll just go LEFT and RIGHT for a while until B is within striking distance and then he has to finally get the flag.
At first the behavior looked like a bug, but stepping through it I convinced myself that each move really is a "Win", but the behavior is not good. I could influence the evaluation by making a flag captured 4 moves from now less valuable than a flag captured now, but I wondered if there was an aspect to the minimax search than I'm missing? Is there the any concept of a high score earlier being most desirable than an equally high score obtained only later?
There's nothing in the minimax search itself that would make winning sooner preferable. Since all terminal positions evaluate to the same score, the algorithm effectively chooses a move at random. Make your evaluation function decrease the winning score slightly for each level deeper in the tree where it is called and minimax will choose to win sooner.