My problem is the following.
I have a "backup" node and others nodes.
From theses nodes, I need to generate a common path to the backup node which is minimal (unweighted and undirected graph)
I don't need a solution everytime. Just how I can know if I can generate this path or not.
I was thinking about splitting the graph into some sub-graphs and searching for minimal "subpath".
But I'm not so good in graph theory.
I use Python and C++.
Thanks you from advance.
(Sorry If there is already a question like this, I have searched, but not found)
If you need to find a node with a minimal distance to the "backup" node, then BFS would be appropriate.
As I understood, you need to find a minimal path from several( if not all) noes in your graph to the "backup" node.
For that, I think, you need to look into algorithms that deal with Minimum Spanning Trees
Also, I've found another StackOverflow question that resembles yours:
SO#1
You may also find this page useful:
Shortest Path Tree. It doesn't provide any code samples, but it is a starting point. Once you get the theory behind it, I am sure you will either come up with code or will be able to find it.
so the problem is not about "shortest", it's about whether they are connected or not.
you can do bfs or dfs starting from the "backup" node, each node you've reached can generate a path to the "backup" node.
check out:
http://en.wikipedia.org/wiki/Breadth-first_search
http://en.wikipedia.org/wiki/Depth-first_search
Related
So I'm trying to create a program that finds the shortest path from nodeA to nodeB, however, I want to block certain nodes so that it would find another path. I'm not really aiming for an optimal code here I'm just trying things out, exploring etc.
Is it still considered a BFS if I modify it a little?
Yes, it still is a BFS, with just a few constraints. The essence of BFS algorithm is the way it explores the graph, you are just exploring a subgraph (through filtering out a bit of it).
In my unweighed graph, I need from a source vertex to reach an imposed vertex and come back to source.
All vertex may be visited at most once.
(There may be cycles in that graph.)
I want the length of the shortest such path.
Looking for a "fast" algorithm:
I have already made several attempts in Python but not fast enough. ;-)
Latest for instance : generator of all paths from source to imposed point (in order of increasing length), every time I get a new path, compare it with all those already calculated and stop if disjoint.
Good result, but too slow / memory expensive.
Earlier (same issue) : consider sub states with information : position, already been to imposed point or not, set of already visited vertexes... good result too but too slow / memory expensive.
DP solution welcome.
Could not find something with google. Point me to if you know where there is something.
Thanks.
--- example ---
e...
#!!#
#!.#
...s
This is a maze; you enter at 'e' and need to reach the sword 's' and back to the entrance 'e'.
'#' are unpassable. '!' are traps, when you walk on these, you trigger them and cannot pass again.
I have turned this into a graph with 5 vertices in this case : e,s, (2,2), (3,2) and (2,3)
--- case where Suurballe algo yields two not disjoined paths ----
.....
##!!#
#!!!#
#!!##
.....
For unweighted graph shortest path BFS in both directions might be the most efficient solution.
You can use BFS to determine how far every node is from your source.
after you find the path, you can remove every node beside the source and target so you will not repeat a node on the path more than once, and then use BFS from the target back to your source.
The total complexity is linear O(V+E)
more on that:
https://www.geeksforgeeks.org/shortest-path-unweighted-graph/
If I understood your question correctly, then I think what you're looking for are node disjoint paths. The classic algorithm to uncover them was proposed by Suurballe. Another algorithm based on network flow is implemented in networkx: networkx.algorithms.connectivity.disjoint_paths.node_disjoint_paths.
Hopefully these pointers solve the problem in your graphs with sufficient speed.
So given a graph that has a cycle from vertex S to E as it goes through every vertex then ends on E. My goal here is to remove all extra edges so that there is just a path from S to E. To help me with this I have a function called check(node) I'm not given the code for it but it returns True or False if there still exist a path from S to E such that all nodes were visited only once until we end at E.
Example:
The plan is to remove a edge from vertex a to b and then run check(node) on the mutated graph and see if it still returns True so we know its safe to remove that edge, and if it returns False then add it back. Do that for every edge so only the needed edge remains, however I have no idea how to iterate through the edges.
I stored the graphs in a dictionary
Usually the approach to an Algorithms problem like this is you first figure out what algorithmic tools you can use. Most basic problems can be solved with an existing algorithm. Your first objective is to see if you can modify the problem set (ie the given graph) in such a way that you don't need to modify the algorithm, because modifying the algorithm lends to difficulties in assessing Big-O for the problem. If the graph can't be modified in any way that makes running a black boxed Algorithm easy, then you modify the algorithm. The last resort is to come up wit your own algorithm to solve the problem.
If my Algorithms recollection is correct, in short this is the Travelling Salesman Problem. If I'm understanding your question correctly, you want the shortest path possible that visits every node. You don't even need to modify your given graph in order to use the algorithm. It should theoretically find you the desired path. Only after the algorithm has run do you need to reduce the graph to its desired state. So I suggest finding some way to implement TSP to your specifications, and remove all edges that aren't part of the solution.
Here is some sample code from GeeksForGeeks that could help you get started
I'm working on a problem where I have a bunch of directed graphs with a single source/sink for each and the edges are probabilistic connections (albeit with 90% of the nodes having only 1 input and 1 output). There also is a critical node in each graph and I'd like to determine if there is any way to traverse the graph that bypasses this node. Ideally I'd also like to enumerate the specific paths which would bypass this node. I've been able to import an example graph into NetworkX and can run some of the functions on the graph without difficulty, but I'm not sure if what I'm looking for is a common request and I just don't know the right terminology to find it in the help files, or if this is something I'll need to code by hand. I'm also open to alternative tools or methods.
First, you might want some way to quantify critical nodes. For that you can use some measure of centrality, probably betweenness centrality in your case. Read more here.
Next, if you know the two nodes you want to travel between you can use this as a kind of psuedocode to help you get there. You can also loop through all possible pairs of nodes that could be traveled through, but that might take a while.
import NetworkX as nx
important_nodes=[]#list of important nodes
paths = nx.all_simple_paths(G, source, target)
paths=list(paths)
#This is pseudocode, next four lines could be done with list comprehension
exclusive_paths=[]
for path in paths:
if important_nodes not in path:
exclusive_paths.append(path)
Read more on all_simple_paths here.
list comprehension might look like this
exclusive_paths=[x for x in paths if important_nodes not in x]
The algorithm can be found here: http://en.wikipedia.org/wiki/Uniform-cost_search
I am struggling with keeping the solution. I am writing in Python, and my implementation finds the optimal solution as expected, but I don't know how to store it.
I would imagine when exploring new neighbors, I need to add the current node to the new neighbors paths, however it isn't working how I expect.
It is a homework assignment so I won't post code yet, but if it is necessary for your help I can post snippets.
Thanks!
Are you looking for finding the final path? In that case you can just store the address of the parent node in each node and traverse upwards to root when you find the destination.