BFS algorithm - shortest walk on grid with constrained steps - c++

The problem is as follows: A wanderer begins on the grid coordinates (x,y) and wants to reach the coordinates (0,0). From every gridpoint, the wanderer can go 8 steps north OR 3 steps south OR 5 steps east OR 6 steps west (8N/3S/5E/6W).
How can I find the shortest route from (X,Y) to (0,0) using breadth-first search?
Clarifications:
Unlimited grid
Negative coordinates are allowed
A queue (linked list or array) must be used
No obstacles present

The algorithm for this problem would be:
For each axis, step towards it until your position on the other axis is 0.
Pseudocode:
while (x!=0) {
if (x>0) x-=6;
else x+=5;
}
while (y!=0) {
if (y>0) y-=8;
else y+=3;
}
However, I don't understand why you need to search for a route - it's not that complicated.

As "thejh" remarked there's no need for a search, but your assignment calls for one.
A reasonable approach is
Analyze. Is it all possible for arbitrary (x, y) starting position? Checking the allowed moves you see that they can be combined to yield 1-step horizontal moves, and 1-step vertical moves, so the answer to that is yes (for your hand-in provide the details of this).
Figure out what "breadth-first search" is. Wikipedia is your friend (although, if you have access to a university library, I really do recommend Patrick Henry Winston's old Artifical Intelligence, it's really good, very lucid explanations). Try it out with some simpler problem.
Do the assignment's problem in just about the same way. Ask here if you encounter any technical C++ problem.
Cheers & hth.,

Here's my answer (really based off of thejh's answer) that uses a queue:
//set x to start position
//set y to start position
do {
if (x<0) Queue.Push(8N);
if (x>0) Queue.Push(3S);
if (y<0) Queue.Push(5E);
if (y>0) Queue.Push(6W);
while (!Queue.Empty())
{
Move(Queue.Pop());
}
} while (x && y);
It's convoluted, but follows the directions.

I'm going to go ahead and answer my own question for future reference.
Psuedocode:
while (true) {
if (destination reached)
break;
addToQueue(go north);
addToQueue(go south);
addToQueue(go east);
addToQueue(go west);
getNextFromQueue;
}
It should also be noted that the execution time for this application grows very, very fast, so test it out with small coordinate values. For example, the coordinates (1,1) gives 7 levels of breadth and requires 16384 iterations.

Related

Find coordinates in a vector c++

I'm creating a game in Qt in c++, and I store every coordinate of specific size into a vector like :
std::vector<std::unique_ptr<Tile>> all_tiles = createWorld(bgTile);
for(auto & tile : all_tiles) {
tiles.push_back(std::move(tile));
}
Each level also has some healthpacks which are stored in a vector aswell.
std::vector<std::unique_ptr<Enemy>> all_enemies = getEnemies(nrOfEnemies);
for(auto &healthPackUniquePtr : all_healthpacks) {
std::shared_ptr<Tile> healthPackPtr{std::move(healthPackUniquePtr)};
int x = healthPackPtr->getXPos();
int y = healthPackPtr->getYPos();
int newYpos=checkOverlapPos(healthPackPtr->getXPos(),healthPackPtr->getYPos());
newYpos = checkOverlapEnemy(healthPackPtr->getXPos(),newYpos);
auto healthPack = std::make_shared<HealthPack>(healthPackPtr->getXPos(), newYpos, healthPackPtr->getValue());
healthPacks.push_back(healthPack);
}
But know I'm searching for the fastest way to check if my player position is at an healthpack position. So I have to search on 2 values in a vector : x and y position. Anyone a suggestion how to do this?
Your 'real' question:
I have to search on 2 values in a vector : x and y position. Anyone a
suggestion how to do this?"
Is a classic XY question, so I'm ignoring it!
I'm searching for the fastest way to check if my player position is at
an healthpack position.
Now we're talking. The approach you are using now won't scale well as the number of items increase, and you'll need to do something similar for every pair of objects you are interested in. Not good.
Thankfully this problem has been solved (and improved upon) for decades, you need to use a spacial partitioning scheme such as BSP, BVH, quadtree/octree, etc. The beauty of the these schemes is that a single data structure can hold the entire world in it, making arbitrary item intersection queries trivial (and fast).
You can implement a callback system. Then a player moves a tile, fire a callback to that tile which the player is on. Tiles should know its state and could add health to a player or do nothing if there is nothing on that tile. Using this technique, you don`t need searching at all.
If all_leathpacks has less than ~50 elements I wouldn't bother to improve. Simple loop is going to be sufficiently fast.
Otherwise you can split the vector into sectors and check only for the elements in the same sector as your player (and maybe a few around if it's close to the edge).
If you need something that's better for the memory you and use a KD-tree to index the healtpacks and search for them fast (O(logN) time).

c++ implementing collision detection and handling for tiled 2D world with smooth wall sliding

Im using SFML 2.1 for graphics and my game structure follows SFML book quite closely (SceneGraph implementation etc)
My world consists mostly of characters (around 1-400, moving around) and tiles (3600, stationary) and I'll check for collisions everytime something moves
In worst case scenario with ~400 characters moving around and ~3600 tiles, I have 4000 possible entities with collision and 800 collision check calls (separate X and Y movement) each frame -> 3.2M collision checks in total.
Almost all my entities have size of 16x16 pixels and I've been looking into implementing either quadtree or simpler grid for collision detection, which should bring number of collision checks down quite a bit. By grid I mean http://conkerjo.wordpress.com/2009/06/13/spatial-hashing-implementation-for-fast-2d-collisions/
But I have no idea how I should implement simple grid for example. All help is welcome. There's propably even a lot better ways to bruteforce this.
Entity update step.
I do X/Y-axis movement separately. Because I want to slide against entities when colliding diagonally.
Move entity horizontally
Check and handle collisions
Move entity vertically
Check and handle collisions
Repeat 1-4 for all entities
.
void Entity::updateCurrent(sf::Time dt, CommandQueue& commands)
{
setPreviousPosition(getPosition());
move(sf::Vector2f(mVelocity.x, 0) * dt.asSeconds());
handleCollision();
setPreviousPosition(getPosition());
move(sf::Vector2f(0, mVelocity.y) * dt.asSeconds());
handleCollision();
}
I've had the following problem before when I tried to handle both X and Y movement at the same time:
I had no idea if I should reset X or Y position after collision.
Collision handling.
I'll handle collisions only when entities are moving (currently only character entities, later projectiles and some special tiles)
if entity is tile -> do nothing
if entity is character -> check collisions with characters and tiles and reset movement if collision happened
.
void Entity::handleCollision()
{
if (getCategory() & Category::Tile)
return;
if (getCategory() & Category::Character)
{
std::set<SceneNode::Pair> collisionPairs;
checkCollision(*mSceneGraph, collisionPairs);
for (SceneNode::Pair pair : collisionPairs)
{
if (matchesCategories(pair, Category::Character, Category::NonPassableCharacterOrTile))
{
resetPreviousPosition();
break;
}
}
}
}
I'll check collision simply by using SFML's intersects-function. This is propably good enough for this?
bool collision(const SceneNode& l, const SceneNode& r)
{
return l.getBoundingRect().intersects(r.getBoundingRect());
}
If I were to implement grid or quadtree for collision detection, when should I populate it, when update? Should I update it every time I move one entity, or should I try to come up with a way to move all entities at once, then build grid/quadtree and only after that try to handle all collisions.
So my questions are: (1) In this scenario how and when should I do collision handling? My current implementation works, but I think I do it too often and all examples I looked into grids/quadtrees assumed that I do first all movement and do collision detection and handling after.
and (2) When do I clear/populate/update my grid/quadtree. For example if I have 3600 tiles and 3 moving characters. Should I seek for entity each time one moves in the grid and try to move it to different grid cell / tree branch?
Edit:
What I'll propably try next unless anyone gives better advice
Updated update step.
Is this smart or in anyway reasonable way to do this?
Remove entity from grid/quadtree
Move entity horizontally
Add entity to grid/quadtree
Check and handle collisions
Remove entity from grid/quadtree
Move entity vertically
Add entity to grid/quadtree
Check and handle collisions
Repeat 1-8 for all entities
.
Entity::move()
{
grid.getCell(getPosition()).remove(this);
... move x
grid.getCell(getPosition()).add(this);
... if collision, reset x
grid.getCell(getPosition()).remove(this);
... move y
grid.getCell(getPosition()).add(this);
... if collision, reset y
}
Entity::checkCollision()
{
list<Entity*> possibleColliders;
possibleColliders = grid.getEntitiesInRectangle(x - s, y - s, x + s, y + s);
... now only check collision against possibleColliders
}
I think a quadtree would work quite well and since it will be standalone there's really no issue in adding it into your current system.
The important question you've ask is probably, when to populate and update the quadtree. I think this largely depends on your use case. Since you have around 400 characters that can change position for each frame, it probably wouldn't make a lot of difference if you try to move the nodes in the quadtree or if you fully rebuild the quadtree. Which is really more performant depends on your algorithm and datastructure, which would need some performance testing.
In this tutorial, they also suggest to rebuild the quadtree every frame iteration.
For the "how to fix collision handling" you'll need to provide more information/a separate SO question, since it's not that clear what the issue is.

how to avoid overlaps during midpoint displacement? (2D)

hell-o guys!
well, I'm playing with random walks. Midpoint displacement gives some nice results, but I would like a random walk without walk loops, like the ones (in yellow) on this screen-hot :
My first idea to deal with that problem is to check for each segment if there is an intersection with all others segments, then to delete the walk loop between the both segments and bind at the interesection point. But for some walks, it would give a strange result, like that one :
where the yellow part is a loop, and we can see that a big part of the walk would be deleted if I do what I said.
Maybe another method would be to check, when the displacement of the midpoint is made, if the segments are interesecting. In case of there is an intersection, get another displacment. But it looks to become very time consuming quickly when the number of subdivisions rises...
So I would like to know if there is a way to avoid these loops
so... it's seems playing with the amplitudes of the random numbers is a good way to avoid overlaps :
the path without displacement is drawn in cyan. I didn't get overlaps with these displacments :
do{
dx = (D>0)? 0.5*sqrt((double)(rand()%D)) - sqrt((double)D)/2. : 0 ;
dz = (D>0)? 0.5*sqrt((double)(rand()%D)) - sqrt((double)D)/2. : 0 ;
}while(dx*dx+dz*dz>D);
where D is the squared distance between the two neibourers of the point we want to displace. The (D>0)? is needed to avoid some Floating Point Exception.

Shortest path with figures on board

I'm having trouble with my homework assignment(C++). I'm not asking for the complete solution, but tilt in the right direction could be helpful. :)
I have a NxN board (max N = 100) and a 1x2 figure (cube) on that board. The cube is painted red on the one side and blue on the other. Default position for the cube is left upper angle of the board, blue side up:
B B . .
. . . .
. . . .
. . . .
(4x4 example, B stands for blue)
There could be stones (obstacles) on the blackboard.
Moves I can make with my figure:
rotating it for 90/180/270 degrees clockwise
you can flip the cube around its right/left/upper/lower edge, changing its ''upward color''
For an example, using flip right on the default position:
. . R R
. . . .
. . . .
. . . .
and then using rotate 90:
. . R .
. . R .
. . . .
. . . .
and then using flip left:
. B . .
. B . .
. . . .
. . . .
Of course, when rotating or flipping, you cannot land on the stone.
So, the problem is - for any given configuration of the board (figure position and stone positions) write a program that will ''bring the cube home'' in the default position (blue side upwards!) using minimal number of moves and return 1 if that's possible or return 0 if that's impossible.
I find this problem interesting, but I have to admit I'm slightly confused with it. Especially the blue side/red side part. I can't really figure out how to ''translate'' those moves I can use in the language of usual shortest path algorithms (and I never used any of these).
So, I would be grateful for every piece of advice you can give! :)
First, since you are asked to find the exact optimal path, I would go with Dijksta's algorithm.
For this algorithm, you'll need:
A function which gives the next
possible move.
A function which tell you if a position was already
visited.
A function which tell you the total cost of each path.
And of course a function which tell you when you've reached the final
position
Given an initial position, your cube can reach exactly 7 new positions. It's easy to pick which ones are possible.
G is simply the number of moves you've made so far + 1 for the next move :)
I would use a hashtable to keep track of the visited position. (This is probably the most difficult function to write), but you don't need to over think it right now. A simple vector and a term-by-term comparison would do. You can optimize this once your code is running.
And finally, you need to check if the cube is in its initial position blue side upwards.
You can interpret each possible 1x2 block and a color (red or blue) combination as a vertex and moves as edges. If it is possible to reach a particular 1x2 block and color combination (vertex) from some other combination in one move then there is a connection (edge) between those two combinations. Then you have to find shortest path between the given configuration and "home" configuration in the resulting graph (probably Breadth-first search since cost of the move is the same no matter what move you perform).
And if want to go further you can use advanced graph search algorithms that use heuristics during the graph traversal (heuristic being the minimum amount of moves needed to reach destination assuming there are no obstacles on the blackboard). For example you can use A* algorithm.
When dealing with this kind of problems, the first thing to do is to find a representation of the state of your problem.
In this case, you need:
Two integers which represents the top-left position of your figure
One boolean which represents the color of the figure (red/blue)
One boolean which represents the orientation of the figure (horizontal/vertical)
If you are familiar with bitmasks, you should use just a 32 bit integer to do this (8 bits for x position, 8 bits for y position, 2 bits for the rest).
In this way you don't need to implement a comparison operator.
OR
You define a simple struct (call it state) with these 3 information and a strict-ordering comparison on this (this is only needed to put state in std::set.
After this, you can solve this problem using a BFS.
To do that, you need:
An std::map<state,state> to store the position you already visited in the key, and the position you came from in the value (replace map with unordered_map if you can use c++11 and you use a bitmask to store your state)
A std::queue<state> in which push and pop up the states to be processed.
Some code to determine every possible state reachable from a given one (i.e. implements all the possible moves, taking care of the board dimension)
Pseudo code:
map<state,state> visited;
queue<state> to_be_processed;
visited.insert( initial_state,initial_state); //you are not coming from anywhere
to_be_processed.push ( initial_state);
while(!to_be_processed.empty()) {
state cur = to_be_processed.pop();
if ( cur == end_state) //you are done
{
//to get the path from initial_state to end_state you have just to walk visited in the inverse order.
return 1;
}
for ( i = every possible state reachable from cur) {
if (visited.count(i) != 0) continue; //already visited
to_be_processed.push(i);
visited.insert(i,cur); //i has been visited, and you reached i from cur
}
}
return 0; //if you get here, no way
The presence of obstacles make just the problem more difficult to code, but is no conceptually different.
Note that in this case BFS works because the cost you pay for going from one state to another is always the same.

count of distinct acyclic paths from A[a,b] to A[c,d]?

I'm writing a sokoban solver for fun and practice, it uses a simple algorithm (something like BFS with a bit of difference).
now i want to estimate its running time ( O and omega). but need to know how to calculate count of acyclic paths from a vertex to another in a network.
actually I want an expression that calculates count of valid paths, between two vertices of a m*n matrix of vertices.
a valid path:
visits each vertex 0 or one times.
have no circuits
for example this is a valid path:
alt text http://megapic.ir/images/f1hgyp5yxcu8887kfvkr.png
but this is not:
alt text http://megapic.ir/images/wnnif13ir5gaqwvnwk9d.png
What is needed is a method to find count of all acyclic paths between the two vertices a and b.
comments on solving methods and tricks are welcomed.
Not a solution but maybe you can think this idea a bit further. The problem is that you'll need to calculate also the longest possible path to get all paths. The longest path problem is NP complete for general graphs, so it will get a very long time even for relative small graphs (8x8 and greater).
Imagine the start-vertex is in the top, left corner and the end vertex is in the lower, right corner of the matrix.
For a 1x2 matrix there is only 1 possible path
2x2 matrix => 2***1** paths => 2
3x2 matrix => 2***2** paths => 4
3x3 matrix => 2***4** + 2*2 paths => 12
3x4 matrix => 2***12** + 12 + 2 paths => 38
Everytime I combined the results from the previous calculation for the current number of paths. It could be that there is a close formular for such a planar graph, maybe there is even a lot of theory for that, but I am too stupid for that ...
You can use the following Java (sorry, I am not a c++ expert :-/) snippet to calculate possible paths for larger matrices:
public static void main(String[] args) {
new Main(3, 2).start();
}
int xSize;
int ySize;
boolean visited[][];
public Main(int maxX, int maxY) {
xSize = maxX;
ySize = maxY;
visited = new boolean[xSize][ySize];
}
public void start() {
// path starts in the top left corner
int paths = nextCell(0, 0);
System.out.println(paths);
}
public int nextCell(int x, int y) {
// path should end in the lower right corner
if (x == xSize - 1 && y == ySize - 1)
return 1;
if (x < 0 || y < 0 || x >= xSize || y >= ySize || visited[x][y]) {
return 0;
}
visited[x][y] = true;
int c = 0;
c += nextCell(x + 1, y);
c += nextCell(x - 1, y);
c += nextCell(x, y + 1);
c += nextCell(x, y - 1);
visited[x][y] = false;
return c;
}
=>
4x4 => 184
5x5 => 8512
6x6 => 1262816
7x7 (even this simple case takes a lot of time!) => 575780564
This means you could (only theoretically) compute all possible paths from any position of a MxM matrix to the lower, right corner and then use this matrix to quickly look up the number of paths. Dynamic programming (using previous calculated results) could speed up things a bit.
The general problem of counting the number of simple paths in a graph is #P complete. Some #P-complete problems have fully polynomial randomized approximation schemes, and some don't, but you claim not to be interested in an approximation. Perhaps there's a way to take advantage of the grid structure, as there is for computing the Tutte polynomial, but I don't have any ideas for how to do this.
There is a similar but less general problem on project Euler: http://projecteuler.net/index.php?section=problems&id=237
I think some of the solutions described in the forum there can be extended to solve your general case. It's a pretty difficult problem though, especially for your general case.
To get access to their forums, you first need to solve the problem. I won't post the answer here, nor link to a certain site that lists the answer, a site that you can easily find on google by searching for something really obvious.
This is an open question in Mathematics with direct application to chemistry and physics in using it to model polymer bonds. Some of the earliest work done on this was done during the Manhattan project (nuclear bomb WWII.)
It is better known as the Self Avoiding Walk problem.
I spent a summer at my university mathematics department researching a monte-carlo algorithm called the pivot algorithm to approximate the parameters of the asymptotic fit of the number of Self-Avoiding Walks of a given length n.
Please refer to Gordon Slade's excellent book titled "The Self Avoiding Walk" for extensive coverage of the types of techniques used to approach this problem thus far.
This is a very complex problem and I wonder what your motivation may be for considering it. Perhaps you can find a simpler model for what you want, because Self Avoiding Walks are not simple at all.
Would a matrix showing the edges work? Consider building a Matrix showing where the edges are,i.e. [a,b]=1 <=> a->b is an edge in the graph, 0 otherwise. Now, raise this Matrix to various powers to show how many ways exist to get between vertices using n steps and then sum them to get the result. This is just an idea of one way to solve the problem, there may be other ways to frame the problem.
I wonder if this belongs on MathOverflow, as another idea
True, that once you have a zero matrix you could stop exponentiating as in your case, there aren't many places to go after 3, but the paths from 1 to 3 would be the direct one and the one that goes through 2, so there are only a few matrices to add together before the all zero one is found.
I'd think there should be a way to compute a bound of say n^(n+1), where n is the number of vertices in the graph, that would indicate a stopping point as by that point, every vertex will have been visited once. I'm not sure how to get the cyclic paths out of the problem though, or can one assume that the graph is free of cycles?