If I have a list of points returned from a breadth-first-search through a type of 2D array maze in Java, how could I find the shortest path in that list of points?
For example, if my potential target points are [2, 4] and [6, 0] and I have a list of points that goes to each target point, how can I find out which route is shortest?
I'm thinking I might have to use Djikstra's Algorithm or something, but I'm unsure.
Thanks very much
You can use Dijkstra's algorithm here. Given the array maze you mentioned, the first step would be to get all the edges in your maze between 2 adjacent nodes, and the edge costs. For the nodes, you would need to know if each node has been visited, and the current cost of visiting that node.
Now, if you are not concerned with getting the shortest path, you might not need Dijkstra's. Instead, you can use a DP/Recursion approach to get possible paths from a source coordinate to a target coordinate. If you want to see a Dijkstra's implementation, this is something I had written. To get the shortest path, you would obviously need the distance between nodes.
To just find a path between 2 points, I would suggest something like this implementation. It includes both DP and recursion implementations and compares the running times for both (recursion can take very long to run for large datasets).
I feel this much should be enough to get you started. Let me know if you need some other information.
I didn't end up using Dijkstra's, but instead changed my breadth-first-search to add a "level" value or "distance" value from the origin point that would count upward with each visited node. The counts would stay consistent if the path ever branched, and since I already knew the end point, all it would take is to check out what the "count" was in my end points and compare.
Thank you for your help though! You'll get an upvote if the site lets me.
For those facing a similar problem:
I made a simple class called PointC which inherits from Point, but with an added "count" value. The count was updated appropriately with each step of the breadth first search, then the end points were compared at the end to obtain the most optimal path.
Related
I've been given a homework in Java, where I have to write an algorithm.
I have to find the path between two vertices, through the highest possible point (like a geographic point, with the height from the water surface). I have to use BFS.
So therefore I would like to ask if someone could point me in the right direction. I've been digging through the internet for a while now and I can't seem to find anything that could help me with my problem.
The code I've been given to modify and add methods is here .
Thank you.
As it can be seen, your path from A to B through H (the highest vertix) can be splitted into 2 paths: from A to H, and from H to B. Then BFS can be used for these 2 paths separately.
It is more interesting if there are several vertices H with the same value of 'height' crtireium. It is subject to think whether there is something better than simple looking through all options.
I know, this is an old problem, if given a matrix like:
[1 1 2 3,
2 3 4 4,
3 4 1 3,
2 1 3 4]
Start at a given position, from right to left, only move right or up or down, can not go back in same way and stop at right, find a path to get max value.
I am considering to use DP(May need try all possible path and calculate value), but it seems it will cost a lot of memory since it store all the possible solutions and may also be slow.
I am wondering if there are any other thoughts or ways to make a better solution? A quicker solution if possible?
I think that there is a way to do a DP and I just can't quickly find it. Because no one answered it so far I will give a graph method. Create a directed graph where an edge from A to B will be equal to the number in that vertex. It is clear from your description that it will not have any cycles. You will get a grid graph like this, but only directed:
Now get an vertex source which is somewhere on the right and connect it to the first layer (put all the edges equal to 0). The same with a destination, but it is on the left.
Now run longest path in directed acyclic graph
If you want to optimize for memory, you might try Backtracking. This would involve only storing the current path, and the path and value for the best solution yet.
Outline is:
You store a list of steps (right, up, down)
You go depth-first so to speak, try to make a new step if you can
If you can't, just go back one and change the step to the next possible direction. (Store this path if it's better than previously stored one).
If there is no next possible direction for the step, repeat 3.
If all possibilities are exhausted, return the stored best path.
Backtracking at wikipedia: https://en.wikipedia.org/wiki/Backtracking
I am developing a simple program to calculate the shortest path from one city to other, using directed weighted nodes of a graph to represent a train trail map.
So far I tried Bellman-Ford, Dijkstra, Floyd-Warshall and Johnson algorithms and all of them are good to find the shortest path to a different destination which is not the same as the start.
But when I need to calculate the path between city A and back to city A through other cities, I always get 0 value because those methods ignore the path from a city to itself in order to don't get caught in an infinity loop.
I know that it might be simple to resolve that loop problem by creating another parameter which is target to aim the algorithm to stop when it catches this target node, but I don't have the skill to modify one of those libraries.
Can anyone show me the way?
My graph is AB5 - BC4 - CD8 - DC8 - DE6 - AD5 - CE2 - EB3 - AE7 and the distance from B to B should be 9, but in all those algorithms it's returning 0.
Note: it's not a duplicate, since nobody bothered so far on finding routes at ends at the beginning, as I searched on StackOverflow and Google, at least in Java.
A simple approach would be to use the shortest path algorithms/libraries that you already have with a modified graph. You could duplicate each node and the corresponding adjacent outgoing edges, and then find the shortest path from the duplicated node to the original one.
Here is how the transformation would look like for A-A path (without weight for simplicity):
I have a graph in which i have two nodes (0 and 6) and i have to cut the least edges possible so that they aren´t connected. For example in this graph
Being the nodes 0 and 6 the least edges that i have to cut are 2-7 and 3-7.
My idea was finding the shortest path between the both using bfs, i find one (0-2-7-6) but then i don´t know how to find the other (0-3-7-6). Even then i have no idea how choose the edges to cut.
It would be nice if someone could give me some pointers on this matter.
This problem seems very similar to that of finding articulation nodes within a graph. The technical definition of an articulation point, or a biconnected component is a node whose removal would cause a graph to be split in two.
The discovery of articulated nodes from a graph is a largely solved problem and you can find more details about it here: http://en.wikipedia.org/wiki/Biconnected_component
It seems to me that the way you would like to approach a problem like this in general would something along these lines:
1. Find all articulation points
2. Do a bfs from each node and determine articulation points along the path
3. Split graph at the articulation point, choosing the side with minimal edges
4. Continue until the two nodes are not connected
In the above example, 7 is the only articulation point and so you would snip the edges between 7, 2 and 3 since there are only two edges between 7 and the 0-4 graph and 3 edges between 7 and the 5,6,8 graph.
There is a more established algorithm for doing this (read: one that I didn't come up with) called Karger's algorithm that can solve your problem, albeit in n^2 time.
That algorithm works by effectively joining adjacent nodes to each other until there are only two nodes and then by counting the number of edges left between the two nodes. The number of edges is then the minimum number of cuts required to split the graph.
The way you would implement Karger's algorithm in your problem would just need the caveat that you should always be joining nodes to the two nodes you want to split. Additionally, in order to be able to go backward to the original edges you need to cut you should keep a reference to which nodes the edges originally belonged to.
There's a great visualization of Karger's algorithm here: http://en.wikipedia.org/wiki/Karger%27s_algorithm
What you want is a min s-t cut. The usual way to find one in a general graph is to run an algorithm like push relabel with source 0 and sink 6, which computes a min s-t cut as a byproduct of computing a maximum flow.
Karger's algorithm finds a min cut, i.e., it minimizes over s and t as well as cuts. Since s and t are fixed for you, Karger's is not appropriate. An articulation vertex is a vertex whose removal disconnects the graph. You are interested in removing edges, not vertices.
I want to find all possible paths starting from a specific node and ending at specific node. I tried depth first search in java but it did not work on my case. Because my paths will be on the same direction. I do not want to traverse all other nodes around selected ones.
I couldn't upload the image that shows what I want. Anyway, I'll try to explain.
Among nodes
0 1 2 3 4 5 6 7 8 9
The paths I want to find are, for example, will start from 2 to 9. The possible paths produced by the algorithm should be
2-7-9
2-4-6-8-9
2-4-6-9
For node-1 my next possibility would be node-2 only, so I will not try node 0 and and node -3. Because of some special rules I set, only node-2 fits for node-1. Next nodes for node-2, node-4 and node-7 are selected. For node-4, only node-6 is suitable. For node-6, node 8 and node 9 are suitable. On the other hand, for node-7, the next node would be 9 only.
All these paths are created and saved in a hashmap or list structure.
DFS finds paths, for instance, between 0-1 and 1-3 which are unacceptable for me. Since the nature of the algorithm, it finds the shortest path. I want all possiblities according to the rule not the shortest one only. The rule is not the problem, so I do not want make you confused and bored. The general way to solve this problem is important for me.
Thanks in advance
You will want to use breadth-first search using a Queue.
Edit: after re-reading your question I think the issue lies in how you're representing a directional graph, rather than in what algorithm you choose. Either DFS or BFS would work for your case, but you need to correctly implement the graph so that the algorithm knows not to try a path in the wrong direction.
DFS finds paths, for instance, between 0-1 and 1-3 which are unacceptable for me. Since the nature of the algorithm, it finds the shortest path. I want all possiblities according to the rule not the shortest one only.
Actually, BFS is typically used to find a shortest path, while both can be used to find all possible paths. I would stick to DFS since it is easier to implement (using recursion rather than a Queue, etc.)
If you represent your nodes & rules properly, the algorithm would not be finding paths that aren't legit. Eg, if you want to start with node 2, make that the starting node.
Simplest is to define a class to represent a node. In the class have an array list of all the "child" nodes of this "parent". Also in the node have an integer that is used as a "cursor" for your depth-first walk. (Doesn't hurt to also have another integer/char string that is the node # or other identifier.)
Set the integer "cursor" in all nodes to zero. Pick your start node -- make it the "current node". Call a method on that node to walk it. It picks up the cursor and extracts the corresponding array list element. Then it calls the "walk" method for the node in that array list element. On return the "cursor" is incremented.
The "walk" method returns when it reaches the target node, or when the "cursor" is incremented beyond the size of the child array.
Along the way you keep whatever record of the path you want. One way is to pass an array list of the nodes visited on each "walk" call, adding the current node to the list before passing it along. When the walk gets to the terminal node the array list is copied as one of the answers. On return from "walk" the added element is removed.