assuming you don't have any heuristic function about the distance to the target, a good solution that is valid is bi-directional BFS.
Algorithm idea: do a BFS search simultaneously from the source and the target: [BFS until depth 1 in both, until depth 2 in both. ].
The algorithm will end when you find a vertex v, which is in both BFS's front.
Algorithm behavior. The vertex v that terminates the algorithm's run will be exactly in the middle between the source and the target.
This algorithm will yield much better result in most cases then BFS from the source [explanation why it is better then BFS follows], and will surely provide an answer, if one exist.
why is it better then BFS from the source?
assume the distance between source to target is k. and the branch factor is B [every vertex has B edges].
BFS will open: 1 + B + B^2 +. + B^k vertices.
bi-directional BFS will open: 2 + 2B + 2B^2 + 2B^3 +. + 2B^(k/2) vertices.
for large B and k, the second is obviously much better than the first.
NOTE, that this solution does NOT require storing the whole graph in memory, it only requires implementing a function: successor(v) which returns all the successors of a vertex [all vertices you can get to, within 1 step from v]. With this, only the nodes you open [ 2 + 2B +. + 2B^(k/2) as explained above] should be stored. To further save memory, you can use Iterative Deepening DFS from one direction, instead of BFS, but it will consume more time.
In your case, the difference between BFS and bi-directional BFS, assuming 6 degrees of seperation is between developing
200^6 = 2.4e13 nodes, and 2*200^3=16,000,000. As you can see, bi-directional BFS needs much less nodes to be developed than the alternative.
I'm trying to write code that will traverse an undirected, unweighted graph. Essentially, the method will be passed a node (which knows all its neighbors). The method then has to build a model of the graph as efficiently* by going from node to node and collecting information which nodes link to each other. At the end, the method will have a complete list of all the nodes and all the vertices that connect them.
*The crux of the problem lies in the word efficiently and what I mean by it. Let me direct your attention to this small graph:
Let's say I start at node G. I can either visit C, B, F, D, H, J or E. I want to minimize the amount of times I visit a node and in order to visit a node, I must pass through all nodes on the way to that node.
Example: let's say I decide to visit node C. The next node to visit could be either A, B, F, D, H, J or E. However, to visit any node except for A, I would have to pass through G again which is considered inefficient. And in order to visit A, I would have to visit G and C again and then pass through C and then G to get back to the rest of the graph. So I decide to visit A. This means I have to pass through C again to reach G. Thus, from a logical point of view, it makes sense to visit the C branch last.
However, the program, when it starts at Node G, is unaware that branch C leads to a dead-end. As I write this, I think it might be impossible, but I ask it anyways: is there anyway to traverse this graph as efficiently as possible (as I have previously defined it) using only the information given (i.e. that the program only knows about the nodes its visited and the edges emanating from those nodes? Or should I just go with a variation Dijkstra's algorithm in order to insure I visit every node?
This will all be written in Java if that matters.
asked Nov 27 '10 at 7:54
Do you want simply to traverse the whole graph (regardless of the path taken), and do some operation on each node, or do you want to compute the shortest path from one node to any other node? (I might not understand your goal.)
In the first case, stick to a traversal algorithm such as Breadth First Search . For the other, you may want to consider Dijkstra by using same-weighted edges (i.e. = 1).
You can see the BFS as a special case of Dijkstra when you are interested only in one starting node and all edges have the same weight. With different costs you could use Uniform Cost Search.
answered Nov 27 '10 at 8:34
Would a DFS be more efficient taking into consideration the numerous cycles? I guess I can write both and find out experimentally using a number of data sets. I can't believe I forgot this, but it's probably the best answer. Thanks! – Smipims Nov 27 '10 at 8:40
@Smipims, Breadth First Search or Djikstra will not be any better or worse cycle wise than the recursion. In order to visit all nodes, you need to visit all nodes. There may be an advantage in using a non-recursive solution to avoid a too deep call stack (for large graphs). – Martin Algesten Nov 27 '10 at 8:49
I guess it all depends on the resource you have and that you value more: time and/or memory-space: consider that you have to keep track of the nodes expanded but to be visited yet in the BFS. If your graph can stay all in memory I guess it does not matter (but imagine an implicit graph that you explore only node-by-node) – rano Nov 27 '10 at 8:50
An interesting problem. but still not clear what the original problem/goal is from the responses to-date.
Is this a valid re-statement of the problem?:
If that is a correct "read" of your problem, then consider these observations:
Thus: all nodes are "connected" via some "distance", and you want to visit all nodes, while minimizing the "distance" traveled.
Is that correct?
If so, I submit that your problem is almost exactly the classical "Traveling Salesman Problem". The only difference I see is that sometimes the statement of the TSP requires "start-node and end-node to be the same". But -- I think -- you allow the start-node and end-node to be different.
If that sounds right -- and you are really just trying to "solve" the TSP in an efficient manner -- then join the multitudes ahead of you who have tried to do the same thing! There might not be a better solution than simply "try all combinations, score each, and take the minimum".
@Boris Is it possible, though, to get some nicer estimates on the complexity of enumerating all paths in terms of how many such paths there are? It won't be polynomial in the number of nodes of the graph, but the enumeration might be polynomial in the number of paths it outputs, or something like that? Or is there an obstruction to such an algorithm as well? – Mikael Vejdemo-Johansson Mar 18 '10 at 16:49
@mikael that's not a problem. start at the first node, and do a DFS. Each time you reach the second node, spit out the current path, and note which edge on the stack got you there. So overall the time taken is linear in the total length of all the paths, which is at most n times the number of paths. – Suresh Venkat Mar 18 '10 at 17:31
@Suresh: Are you sure a DFS will find all paths? Asssume two $K_n$ connected by a single bridge edge, with the source node in one $K_n$ and the target node in the other. DFS will traverse the bride edge exactly once, while there is certainly a much larger number of distinct paths from source to target that are crossing this edge. – MRA Mar 19 '10 at 12:50
There is an easy way to partition the set of $s$-$t$ paths in a graph $G$. Fix an edge $tt'$ in $G$. Let $P_1$ be the set of paths from $s$ to $t$ which use the edge $tt'$, and let $P_2$ be the set of paths from $s$ to $t$ in $G-tt'$. Then $P_1 \cap P_2 = \emptyset$ and the set of $s$-$t$ paths $P = P_1 \cup P_2$. Moreover, there is a one to one correspondence between the set of paths $P_1$ and the set of $s$-$t'$ paths in the graph $G-t$.
Thus, we get an easy recursive algorithm to find the set of paths $s$-$t$ paths in a graph $G$. Pick an edge $tt'$ incident the vertex $t$ and recursively calculate the sets $P_1$ and $P_2$. With a small amount of pre-processing, we can ensure that the runtime is $O(m(p+1))$ where $m$ is the number of edges and $p$ is the number of $s$-$t$ paths.
To make the recurrence relation on the runtime work, consider the following. We can test in time $O(m)$ if a given graph $G$ and pair of vertices $s$ and $t$ if $G$ has 0, exactly one, or at least two distinct $s$-$t$ paths. To see this, simply find the block decomposition of the graph and, and check if there is any non-trivial block between $s$ and $t$ in the tree.
We can push this slightly farther. Given an instance of the problem $G$ and vertices $s$ and $t$, we can reduce the problem in time $O(m)$ to a graph $\bar
To see this, again using the block decomposition, we contract any bridge in the graph and delete edges not contained in any $s$-$t$ path. As above, this can be done in $O(m)$ time.
We give an $O(m(p-1))$ time algorithm to find the set of $s$-$t$ paths in a given graph $G$ with at least two $s$-$t$ paths.
Step 1 can be performed in $c'm$ operations for some constant $c'$. The initial check in steps $2$ and $3$ can be performed in $c'(m-1)$ steps. If we must recursively run the algorithm, this will require another $c(m-1)(p_i - 1)$ operations for $i = 1, 2$ in Steps 2 and 3, respectively. As $p_i \ge 1$, we can bound the work in each of Steps 2 and 3 by $c'm + cm(p_i - 1)$. Thus, the total number of operations is at most $3c'm + c(m)(p_1 +p_2 - 2) \le cm(p-1)$ if we choose $c \ge 3c'$.
answered Apr 26 '12 at 21:33
Let $G=(V,E)$ be a graph.
$FindPaths(p,f)$ prints all paths which end in $f$ and can be obtained by adding nodes to path $p$. $p$ is for path, $f$ is for final (node).
Let $x$ be the last node of $p$.
For each edge $xy$ for some $y$ in $E$
$\ \ \ \ $If $y$ is not in $p$
$\ \ \ \ $$\ \ \ \ $If $y=f$
$\ \ \ \ $$\ \ \ \ $$\ \ \ \ $Print $p-y$
$\ \ \ \ $$\ \ \ \ $Else
$\ \ \ \ $$\ \ \ \ $$\ \ \ \ $$FindPaths(p-y,f)$
If $s$ is the start node and $t$ is the ending node, run $FindPaths(s,t)$.
You can represent path and edges as strings. To check if a node is in a path $p$ you just have to check whether the string contains the character that represents the node. To get the final node of a path use the function to get the last character of a string.
EDIT: My answer is not math research level, but introduction to programming.
answered Apr 27 '12 at 5:53
For shortest paths look at the Wikipedia page of the Floyd–Warshall algorithm
"An algorithm for computing all paths in a graph" by Lars-Erik Thorelli in BIT Numerical Mathematics, July 1966, Volume 6, Issue 4, pp 347-349
answered Mar 19 '10 at 1:42
Since the source and the target are fixed and since there are no weights on edges, the shortest path is best computed by BFS, rather than Roy-Floyd-Warshall. – rgrig Mar 19 '10 at 10:36
If I'm not mistaken, I think an adaptation of a dynamic programming all-pairs-shortest-path algorithm (like the Floyd-Warshall algorithm, considering edge weights of 1) might find all paths. Consider the following scheme to find the total number of all paths leading from u to v (or, in fact, from any start node to any destination):
A matrix $M_1$ is initialized as the adjacency matrix of the graph. That is, $M_1[u,v]$ containes the number of simple paths of length at most 1 from u to v. After that, for all $i$ from 2 to the number of nodes the matrix $M_i$ is updated as follows: $M_i[u,v]$ equals the sum of the entries $M_
answered Mar 19 '10 at 12:44
(Submitted on 5 May 2010)
Abstract: Given an undirected graph $G$ and an error parameter $\epsilon > 0$, the <\em graph sparsification> problem requires sampling edges in $G$ and giving the sampled edges appropriate weights to obtain a sparse graph $G_<\epsilon>$ with the following property: the weight of every cut in $G_<\epsilon>$ is within a factor of $(1\pm \epsilon)$ of the weight of the corresponding cut in $G$. If $G$ is unweighted, an $O(m\log n)$-time algorithm for constructing $G_<\epsilon>$ with $O(n\log n/\epsilon^2)$ edges in expectation, and an $O(m)$-time algorithm for constructing $G_<\epsilon>$ with $O(n\log^2 n/\epsilon^2)$ edges in expectation have recently been developed (Hariharan-Panigrahi, 2010). In this paper, we improve these results by giving an $O(m)$-time algorithm for constructing $G_<\epsilon>$ with $O(n\log n/\epsilon^2)$ edges in expectation, for unweighted graphs. Our algorithm is optimal in terms of its time complexity; further, no efficient algorithm is known for constructing a sparser $G_<\epsilon>$. Our algorithm is Monte-Carlo, i.e. it produces the correct output with high probability, as are all efficient graph sparsification algorithms.
Data Structures and Algorithms (cs.DS)
Generating Random Directed Unweighted Graphs
Generating Random Directed Weighted Graphs
Generating Random Undirected Unweighted Graphs
Generating Random Undirected Weighted Graphs
This article is contributed by Rachit Belwariar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to firstname.lastname@example.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.Related Posts:
We offer the following domain as an example to compare and contrast approaches to the definition and implementation of product-line architectures. We believe this a good example, because it deals with a classical domain whose algorithms (i.e. graph algorithms) are common-knowledge to computer scientists. This relieves readers of burden and overhead that accompanies the understanding of an unfamiliar domain. (Also, there are lots of texts that discuss these very algorithms, so obtaining information on the domain should be easy).
In the following paragraphs we describe the family by stating the features -- i.e. algorithms, types of graphs, and searches -- a member could implement. A member of the family implements any valid combination of the following algorithms:
with the following types of graphs:
Note: we assume that the weights in weighted graphs are always nonnegative and integer.
with the following graph search algorithms:
That is, a family member can implement a valid combination of one or more graph algorithms, one directed or undirected graph that is weighted or unweighted, and exactly one search algorithm if required by the graph algorithms combination. For example, a family member could implement < vertex numbering, cycle checking, and strongly connected component> algorithms using an unweighted directed graph and depth-first search.
As in typical product-lines, not all combinations of features are valid. The table below summarizes the constraints for each algorithm. For example the combination of Connected Components and Strongly Connected Components is not valid because it would require that the graph be both directed and undirected at the same time.
Searches that can be used
Graph Types Allowed
* For simplicity we dont consider MST for directed graphs.
For example, if we want a member of our graph product line to implement Vertex Numbering, we could use either directed or undirected graphs, and either weighted or unweighted graphs. However if we want a member to implement Minimum Spanning Trees we are required to use weighted and undirected graphs, and no implementation of DFS or BFS is required. Similarly, to compute Single-Source Shortest Paths the member must implement directed and weighted graphs, and no implementation of DFS or BFS is required.On Implementation Issues
How you formally represent this domain is up to you and the method that you use. Regarding the implementation, we would appreciate if the resulting code is in Java, because this is the language we have used for our implementations and this would make the comparison more meaningful and accurate.
We provide references to the algorithms we are considering in the following table.
 Sections 23.2, 23.3
 Section 22.1, 23.2, 23.3
Strongly Connected Components
 Section 23.3 using DFS to detect back edges
Minimum Spanning Trees
 Section 24.2. Kruskal or Prim Algorithms
Single-Source Shortest Path
 Section 25.2. Dijkstra's Algorithm.
Please direct questions to:References
[CSE2304 ], [FAQ ], [progress ] & [plan ], Bib'. Alg's. C - L.A. Sem'1, 2006, FIT, Monash. au
Instructions. Topics discussed in these lecture notes are examinable unless otherwise indicated. You need to follow instructions, take more notes & draw diagrams especially as [indicated] or as done in lectures, work through examples, and do extra reading. Hyper-links not in [square brackets] are mainly for revision, for further reading, and for lecturers of the subject.
Weighted Undirected Graph
Weighted Directed Graph
Un directed Graphs
(Edge-) Weighted Graphs
[lecturer: derive a graph from some real example; class: take notes!]
lloyd/tildeAlgDS/Graph/PICS/Directed.gif" /> read on.