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.
Related
I'm looking if there is a known solution for the task I have in mind
Given: Undirected graph with V > 100k nodes. Most of the vertices have a degree of 1-2, but some of them might have up to 10-20k edges.
I'm interested in all simple paths between two vertices or all paths ending on the start verticle limited by maxLength. Path can't contain the visited nodes but might end on the start node.
Goal: Occasionally some graph's edges are updated in batch. I'd like to find out what routes between vertices of interest were updated. Ideally in the form of Iterator but List is fine too.
Effectively I'm looking for a reactive way to find out about the affected routes.
The implementation could be in any language but Java/Kotlin specific is more preferred :)
Any references/relevant information would be very appreciated.
I wasn't sure if it's a question for CS StackExchange but it looks more relevant to SO.
To find paths between two nodes that do not share any nodes except the start and end.
Run Dijskta to find shortest simple path between start, end
Add large cost ( = largest integer for example ) to the in-edges of all nodes on shortest path, except start,end
Repeat until no new path found with cost less than largest integer
To find out what routes between vertices of interest were updated. This is trivial
- Multimap of edges, keyed by route index
- Vector of updated edges
- Loop over updated edges
- IF edge in multimap
- print index of affected route
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.
I had a question about whether or not Java has its own data structure for what I am looking for. It is something like a combination of an array, linked list and a tree.
If it is not in Java, but exists already as a concept in computer science/other languages, that is also an acceptable answer so I can research it more and find out how to implement it myself.
Here is a picture to better illustrate what I am looking for. Excuse the lack of professionalism; I made it as best as I could:
I am looking for something that starts with several indexed starting elements, that eventually link to other elements and end in a convergence of sorts (one final element). In the end, each index has its corresponding starting element, which is linked all the way to the final converged element.
It should be the case that asking for unknownStructure[i] or something should grab an object that is a representation of the ith starting element linked all the way to the final converged element. (This thing to be grabbed is outlined in various bright colors in the picture).
It seems to me that you are looking for a directed Graph data structure.
You may need to use a list of graphs if needed.
See this page for algorithms and this for implementation.
There is no "name" for this that I know of, but an array of linked list nodes would work quite well for this.
Traditionally linked lists are separate and simply a row of items pointing to the next. However, there is no reason why certain linked list nodes cannot point to the same child node. After all, trees and linked lists are essentially created the same way in Java.
The only foreseeable problem would be if you want to traverse this "tree" back to the starting node in the array. (Which could still be achieved with multiple parent support.)
To implement your linked-list array, simply created a Node class as for a linked list and then created an array of these elements:
Node[] myTreeArray = new Node[];
Then simply fill this array with your "base" nodes and link them to their appropriate children (eventually leading the the "end" node, which has a child of null)
Is it possible to create a traversal in java using neo4j that keeps a state for the duration of the traversal?
For example, I need an Evaluator that is almost identical to toDepth(), except that the depth at the current node is based on another comparison. Say that you had a linked list with 20 items, and you wanted the 10th [valid] one, meaning that some of the items had a particular property flag excluding them from the count. So the final returned item might actually be the 12th in the Path.
The only efficient way I can think of doing this is being able to store some state variable that is accessible to each individual evaluation. Is that possible?
I understand that I could write my own custom traversing functions to do this, but it would be nice if I could build it into the Traversal Framework.
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.