I'm working on a project where I need to perform pathfinding to find the route which costs the least. I don't really care if it's the shortest route possible. So far it seems A* is out of the question and I honestly do not understand Prim's algorithm.
Let me explain the kind of maps that I need to find routes on. This is an example map:
+------|-*----
+------|----|-
+--|--------|-
+#-|----------
The "*" is the start location, the "#" is the destination. The "+" signs in a line indicate a direct route which a) costs the same as a single step, and b) halves the cost of the entire route.
This means there are 10 "steps" from the start position to the destination via the "+" route, which ends up with a cost of 5. There are 15 steps to use the left-most "|" route ("|" is a lower cost than "-", but worse than "+"), which ends up with a cost of 15. Obviously, the route with a cost of 5 is the route to use.
Now I'm having trouble implementing this in C#. I currently have a "step" function which moves and returns if the way was blocked or the cost of the step, and the new position. This works well, but at the moment it is extremely naive in that it'll go down a "|" if it finds one before a "+" (which means the entire trip costs significantly more, as it hasn't found the faster route).
I was thinking of marking each location as "visited", but it's completely plausible that the lowest-cost route will loop back on itself. There are also many different paths, each of which is unique, and each of which may use different path segments (that may have already been visited by a previous run). Obviously each path needs to be traversed in order to find the cheapest path, but I can't figure out how to do that without ending up searching the same routes over and over again.
If it makes it simpler, I can limit any movement to only move towards the destination (ie, can't go back up again after going down).
If anyone could provide some insight, that'd be great!
From what I understand, the '-' fields in your map are graph nodes. Each '-' node has at most 8 edges to neighboring '-' fields. 8 if you allow diagonal movement, otherwise only 4 neighboring '-' nodes are valid. There is no edge between a '-' node and a '|' node.
This is enough to implement a simple depth-first search / breadth-first-search in which you keep a queue of unvisted nodes (LIFO for depth-first, FIFO for breadth-first) and a list of visited nodes (to avoid cycling). Both algorithms will be relatively inefficient, but can be easily improved upon.
I'm not sure what the meaning of your '+' nodes is. Is moving from one '+' to the next '+' mode a free move? If so, you can model this using edge costs. A move from or to a '-' node has cost 1, a move from '+' to '+' node has cost 0.
The breadth-first-search algorithm can be extended to Dijkstra's algorithm that calculates the shortest path between your source and destination as long as all graph edges are non-negative:
http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
The Dijkstra algorithm can be further improved with the addition of a simple heuristic, making it the A* algorithm. If you have the coordinates of your goal in 2D coordinates, you could use the euclidian distance between a node and the goal as a rough estimate of which node is best to follow. If the '+' fields are something of a tunnel through your map with zero cost to move, the A* algorithm may not help that much because heuristically moving towards your destination will often be wrong if you should have moved towards the tunnel. If there are multiple tunnels or tunnels not leading to your destination, there may not be an heuristic better than the naive Dijkstra algorithm.
Please note that it is impossible for the lowest-cost route to contain a loop: If the lowest-cost route contained a loop, stripping the loop would still yield a valid route to the goal with lower cost contradicting the assumption that we started from a route with lowest-cost.
Have a look at Cormen's Introduction to Algorithms, or the relevant Wikipedia pages:
http://en.wikipedia.org/wiki/Shortest_path
http://en.wikipedia.org/wiki/Breadth-first_search
http://en.wikipedia.org/wiki/Depth-first_search
http://en.wikipedia.org/wiki/A*_search_algorithm
Related
This might be a weird application.
The brief description of the problem is "How to get Absolute Coordination of nodes based on Relative Positions (distances) ?"
We have a number of Nodes (each with a unique ID) and a list specifying its Adjacent nodes and distance to each of them as Input.
The required output would be one possible way to lay out these nodes on a 2D Surface.
The resulting algorithm is going to be used in C#... So external .net libraries might help too.
It would be a great help if you could advise me an approach to do that.
Thank you in advance.
You must have coordinates of at least three known points at start.
Way I. If the known points are adjacent, the process is simple - you loop all your points, looking for such, which have in their lists three known points. Use two of them to count two possible positions, then use the third to choose right or left variant. Repeat the loops until you have no new points during a loop.
That simple algorithm has bad convergence - the errors are accumulating and far points could have bad coordinates. But as you have the coordinates integer, you can repair coords after each counting and have them good.
Way II. If the known points are not adjacent to each other, the process is more complicated.
Let's say, you have start known points A,B,C.
Take A and some its adjacent point D. Place it somewhere at the correct distance from A.
Find some point E adjacent to A and D. Choose any of two possible positions.
Starting from A, D, E, use the way I.
When you reach by distances the second start known point, let it be B, of course, it will be in bad place. Turn all the net you have built around A so, that B will get the correct coordinates. Continue the looping.
When you will reach the last of the start known points, C, it will be set correct or not. If not, mirror the whole net relatively AB axis - the C will be set correctly. (If not, you have bad data). Continue the way I looping till the end.
Both these two ways work if you have long lists for all points. If points have only few distances given, the task becomes much, much more complicated.
I have a list of line segments in no particular order.
I want to find all enclosed spaces (polygons) formed by the segments. Is there an efficient algorithm or method that I could use to do this?
The following image illustrates the problem. How can I detect the green polygons, given the black line segments?
One way would be to build a graph as follows:
the nodes are the intersection points of the edges
there's an edge between nodes i and j iff points i and j are on the same edge
Once you've built the graph:
Run the Connected Components Algorithm on it, and check for connected components of size > 2
Run a convex hull algorithm on the intersection points within such a component
Edit modified from original due to excellent point by FooBar.
This is indeed a classical problem in computational geometry.
Your are looking for the faces of an arrangement of your segments.
For a discussion of this topics with (too many) details, and source code, there is this wonderful library: CGAL .
Note that you'll have to decide what you do for e.g. a polygon inside another, many polygons intertwined, etc.
Ami's answer is a good pointer in the correct direction, but here are the more detailed steps you might need to know about:
Take the list of line segments and build a collection of vertexes. Since check each individual segment for intersections with each other segment is basically a N^2 operation when done via brute force, you might want to build a quad-tree and use that to reduce the number of checks you are performing. If n is small or you have a lot of cpu time to burn, just brute force it, otherwise you need to be clever about your collision detection. Here is a library that implements quad-tree collision detection: https://github.com/hroger1030/SpatialTrees
With your list of nodes and edges, you have the pieces to build a graph. you can call your lines nodes and the intersections the edges or vice-versa, it kind of doesn't matter. The important thing is you can now just go find all the cycles on the graph where the number of nodes in the cycle > 2.
I just so happens that I wrote an implementation of Tarjan Cycle detection in c#: Tarjan cycle detection help C#. This might be an alternative to the suggested Connected Components Algorithm.
I am trying to implement a pathfinding algorithm, but I think I'm running into terminology issues, in that I'm not quite sure how to explain what I need the algorithm to do.
I have a regular grid of nodes, and I am trying to find all nodes within a certain "Manhattan Distance".
Finding the nodes within, say, 5, is simple enough.
But I am interested in a "Weighted Manhattan Distance", where certain squares "cost" twice as much (or more) to enter. For instance, if orange squares cost 2 to enter, and purple squares cost 10, the graph I'm interested in looks like this:
Firstly, is there a term for this? It's hard to look up info on things when you're not entirely sure what they're called in the first place.
Secondly, how can I calculate which nodes fall within my parameters? I'm not looking for a full solution, necessarily, just some hints to get started; when I realized my implementation would require three Dictionarys, I began to think there might be an easier way of handling things.
For terminology, you're basically asking for all points within a certain distance on an arbitrary (positive) weighted graph. The use of differing weights means it no longer corresponds to a specific metric such as Manhattan distance.
As for algorithms, Dijkstra's algorithm is probably what you want. The basic idea is to maintain the minimum cost to each square that you've found so far, and a priority queue of the best squares to explore next.
Unlike traditional Dijkstra's where you keep going until you find the minimal path to every square, you'll want to stop adding nodes to the queue if the distance to them is too long. Once you're done, you'll have a list of all squares whose shortest path from the starting square is at most x, which sounds like what you want.
Eric Lippert provides an excellent blog-series on writing an A-* path finding algorithm in C# here:
Part 1:http://blogs.msdn.com/b/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx
Part 2: http://blogs.msdn.com/b/ericlippert/archive/2007/10/04/path-finding-using-a-in-c-3-0-part-two.aspx
Part 3: http://blogs.msdn.com/b/ericlippert/archive/2007/10/08/path-finding-using-a-in-c-3-0-part-three.aspx
Part 4: http://blogs.msdn.com/b/ericlippert/archive/2007/10/10/path-finding-using-a-in-c-3-0-part-four.aspx
You are probably best to go with Dijkstra's algorithm with weighted graph, like described here:
http://www.csl.mtu.edu/cs2321/www/newLectures/29_Weighted_Graphs_and_Dijkstra's_Algorithm.html
(There is algorithm description near the middle of the page.)
Manhattan distance in your case probably just means you don't want the diagonal paths in the graph.
I have a 2D int array which I processed and got from an image. Each index can be thought as weight of that pixel. I want to find a path between 2 indexes (I'll give these indexes as input) that has the least cost. It would be great if the direction of movements can be modified (like only down&left, up&left. or all. etc. otherwise it may be down, left and right)
How can i do that in C#?
Regardless of language, I would calculate the cost for a direct path first. This will became the first base line. Then I would recursively search for a shorter path. You can make a few boundary checks to reduce the recursion.
Any path that is >= the base line (or current best) is terminated
Any path that would hit an index twice is terminated
Any successful path sets the new base line (or best)
The A* algorithm (as was already tagged :)) is a good choice for this.
See, for example, How to implement an A* algorithm?
Was wondering if anyone has knowledge on implementing pathfinding, but using scent. The stronger the scent in the nodes surrounding, is the way the 'enemy' moves towards.
Thanks
Yes, I did my university final project on the subject.
One of the applications of this idea is for finding the shortest path.
The idea is that the 'scent', as you put it, will decay over time. But the shortest path between two points will have the strongest scent.
Have a look at this paper.
What did you want to know exactly??
Not quite clear what the question is in particular - but this just seems like another way of describing the Ant colony optimization problem:
In computer science and operations
research, the ant colony optimization
algorithm (ACO) is a probabilistic
technique for solving computational
problems which can be reduced to
finding good paths through graphs.
Well, think about it for a minute.
My idea would to divide the game field into sections of 32x32 (or whatever size your character is). Then run some checks every x seconds (so if they stay still the tiles around them will have more 'scent') to figure out how strong a scent is on any given tile. Some examples might be: 1) If you cross over the tile, add 3; 2) if you crossed over an adjacent tile, add 1.
Then add things like degradation over time, reduce every tile by 1 every x seconds until it hits zero.
The last thing you will need to worry about is using AI to track this path. I would recommend just putting the AI somewhere, and telling it to find a node with a scent, then goto an adjacent node with a higher/equal value scent. Also worry about crossing off paths taken. If the player goes up a path, then back down it another direction, make sure the AI does always just take the looped back path.
The last thing to look at with the AI would be to add a bit of error. Make the AI take the wrong path every once in a while. Or lose the trail a little more easily.
Those are the key points, I'm sure you can come up with some more, with some more brainstorming.
Every game update (or some other, less frequent time frame), increase the scent value of nodes near to where the target objects (red blobs) are.
Decrease all node scent values by some fall-off amount to zero.
In the yellow blob's think/move function get available nodes to move to. Move towards the node with the highest scent value.
Depending on the number of nodes the 'decrease all node scent values' could do with optomisation, e.g. maybe maintaining a a list of non-zero nodes to be decreased.
I see a big contradiction between scent model and pathfinding. For a hunter in the nature finding the path by scent means finding exactly the path used by the followed subject. And in games pathfinding means finding the fastest path between two points. It is not the same.
1. While modelling the scent you will count the scent concentration in the point as the SUM of the surrounding concentrations multiplied by different factors. And searching for the fastest path from the point means taking the MINIMUM of the times counted for surrounding points, multiplied by the different parametres.
2. Counting the scent you should use recursive model - scent goes in all directions, including backward. In the case of the pathfinding, if you have found the shortest paths for points surrounding the target, they won't change.
3 Level of scent can rise and fall. In pathfinding, while searching for minimum, the result can never rise.
So, the scent model is really much more complicated than your target. Of course, what I have said, is true only for the standard situation and you can have something very special...