Why BFS to get shortest path? - graph-algorithm

BFS has the extremely useful property that if all of the edges in a
graph are unweighted (or the same weight) then the first time a node
is visited is the shortest path to that node from the source node.
How this property can be verified? why not in case of DFS such property holds?

To answer your question, you should first understand how BFS and DFS work in a general sense.
Consider a binary search tree, which is just a very simple graph, as shown below:
*a
/ \
*b *c
/ \ / \
*d *e *f *g
Breadth First Search (BFS), as its name implies, will first explore the nodes closest to the source node. Suppose you start your search from node *a, the BFS algorithm will first explore *b, following *c, and then *d, *e, *f, *g.
Depth First Search (DFS), on the other hand, go depth first. From the source node *a, you will expore *b, and then *d, *e (until you reach the end pretty much).
Hence, the statement:
... the first time a node is visited is the shortest path to that node from the source node
Suppose, as the BFS is running, you visited node *b. This is indeed the shortest path from the source node to node *b, because BFS has the property of always exploring the nodes that are closest to the source node first.
Similar concepts can be applied for a more complex graphs. They all work the same.
Hope this helps! Cheers!

* A
/ \
| \
| \
* B \
\ \
\ \
\ \
* D \
\ \
\______* C
Take a look at this simple graph.
If you would do DFS starting from A, for example, and the first neighbour visited will be vertex B, then the first time you'll visit vertex C will be through D, so you'll get a path of length 3.
So, when A will look for his other neighbour (C) he won't visit it, and A-B-D-C is definitely not the shortest path from A to C.

Related

Longest path in a graph

Given a undirected graph with vertices form 0 to n-1, write a function that will find the longest path (by number of edges) which vertices make an increasing sequence.
What kind of approach would you recommend for solving this puzzle?
You can transform the original graph into a Directed Acyclic Graph by replacing each of the (undirected) edges by a directed edge going towards the node with bigger number.
Then you end up with this: https://www.geeksforgeeks.org/find-longest-path-directed-acyclic-graph/
I would do a Dynamic Programming algorithm. Denote L(u) to be the longest valid path starting at node u. Your base case is L(n-1) = [n-1] (i.e., the path containing only node n-1). Then, for all nodes s from n-2 to 0, perform a BFS starting at s in which you only allow traversing edges (u,v) such that v > u. Once you hit a node for which you've already started at (i.e., a node u such that you've already computed L(u)), L(s) = longest path from s to u + L(u) out of all possible u > s.
The answer to your problem is the node u that has the maximum value of L(u), and this algorithm is O(E), where E is the number of edges in your graph. I don't think you can do faster than this asymptotically
EDIT: Actually, the "BFS" isn't even a BFS: it's simply traversing the edges (s,v) such that v > s (because you have already visited all nodes v > s, so there's no traversal: you'll immediately hit a node you've already started at)
So actually, the simplified algorithm would be this:
longest_path_increasing_nodes():
L = Hash Map whose keys are nodes and values are paths (list of nodes)
L[n-1] = [n-1] # base case
longest_path = L[n-1]
for s from n-2 to 0: # recursive case
L[s] = [s]
for each edge (s,v):
if v > s and length([s] + L[v]) > length(L[s]):
L[s] = [s] + L[v]
if length(L[s]) > length(longest_path):
longest_path = L[s]
return longest_path
EDIT 2022-03-01: Fixed typo in the last if-statement; thanks user650654!
There are algorithms like Dijkastras algorithm which can be modified to find the longest instead of the shortest path.
Here is a simple approach:
Use a recursive algorithm to find all paths between 2 nodes.
Select the longest path.
If you need help with the recursive algorithm just ask.

BFS cycle detection

Could someone provide a step by step pseudocode using BFS to search a cycle in a directed/undirected graph?
Can it get O(|V|+|E|) complexity?
I have seen only DFS implementation so far.
You can take a non-recursive DFS algorithm for detecting cycles in undirected graphs where you replace the stack for the nodes by a queue to get a BFS algorithm. It's straightforward:
q <- new queue // for DFS you use just a stack
append the start node of n in q
while q is not empty do
n <- remove first element of q
if n is visited
output 'Hurray, I found a cycle'
mark n as visited
for each edge (n, m) in E do
append m to q
Since BFS visits each node and each edge only once, you have a complexity of O(|V|+|E|).
I find BFS algorithm perfect for that.
Time complexity is the same.
You want something like this(Edited from Wikipedia):
Cycle-With-Breadth-First-Search(Graph g, Vertex root):
create empty set S
create empty queue Q
root.parent = null
Q.enqueueEdges(root)
while Q is not empty:
current = Q.dequeue()
for each node n that is adjacent to current:
if n is not in S:
add n to S
n.parent = current
Q.enqueue(n)
else //We found a cycle
n.parent = current
return n and current
I added only the else its a cycle block for the cycle detection and removed the original if reached target block for target detection. In total it's the same algorithm.
To find the exact cycle you will have to find a common ancestor for n and current. The lowest one is available in O(n) time. Than the cycle is known. ancestor to n and current. current and n are connected.
For more info about cycles and BFS read this link https://stackoverflow.com/a/4464388/6782134

Push-relabel gap heuristics

I don't understand how to implement gap heuristics with push relabel. Wiki described it like this:
"In gap relabeling heuristic we maintain an array A of size n, holding in A[i]
the number of nodes for each label (up to n). If a label d is found, such that
A[d] = 0, then all nodes with label > d are relabeled to label n."
Use a gap heuristic. If there is a 'k' such that for no node height(u) =k, you can set height(u) = max(height(u), height(source) +1) for all nodes except source, for which height(u) >k. This is because any such 'k' represents a minimal cut in the graph, and no more flow will go from the nodes S={u where height(u) > k} to nodes in T={v, where height(v)0. But then height(u) > height(v)+1 , contradicting height(u) > k and height(v) < k.
Can someone explain to me in pseudocode how to add the gap heuristic to a FIFO push-relabel as shown in wiki's sample code?
Thanks,
Vince
It might be a little late but here is a link to a Stanford University notebook where you can find a push-relabel maximum flow using a Gap Heuristic in C.
I hope it helps you.
http://www.stanford.edu/~liszt90/acm/notebook.html#file3

Placing number tiles in Settlers of Catan for iOS

I'm coding Settlers of Catan for iOS and currently have my data tiles in a matix. Now, I'm trying to attach the numbers to each tile. But I'm stuck as to the correct way to do this algorithmically. There are specific rules for putting down the number tiles on the board. These are:
1) They must go in the pre-defined sequence shown in the image.
2) You must start in a corner of the board.
3) You must work your way around the board counter-clockwise, spiraling toward the center.
4) You must skip the desert tile.
Since there are only 6 places on the board where you can actually start putting tiles down, I realize that it wouldn't be difficult to hand-code the 6 solutions into my data grid. But there is a variation of the game in which the board gets larger, so I figured it would be worth exploring an algorithm.
Any thoughts how this can be achieved?
What you want to do will involve the geometric relationships between tiles (entries in your matrix)
You need a way of storing and querying that information.
There are several methods people have developed for assigning coordinates to hexagons:
http://playtechs.blogspot.com/2007/04/hex-grids.html
http://jemgine.omnisu.com/?page_id=412
http://www-cs-students.stanford.edu/~amitp/Articles/GridToHex.html
One way to do what you want, off the top of my head, would be for each hex to have 6 'pointers' to its neighbors. These pointers could really be indices in your array, of course.
You could detect a 'corner' hex by noting that it will have 3 'null' neighbors. Then you can traverse counter-clockwise from there, remembering which you've already visited.
Update (in response to comment)
Let's suppose that for a given hex, we store the 6 neighbors as I described.
For this discussion, we'll name those neighbors A-F.
We assign these counter-clockwise, because that's convenient for us.
Graphically:
A
_____
B / \ F
/ \
( )
\ /
C \_____/ E
D
For a 'corner' hex, we might have:
A
_____
B / \ NULL
/ \
( )
\ /
C \_____/ NULL
NULL
So if we are looking at this hex, and we list our adjacency information (wrapping around), we have:
A, B, C, NULL, NULL, NULL, A, B, C, ...
A soon as we find 3 NULLs in a row, we know that the next spot should "point" in our starting direction. In this case we should start off in the direction of 'A'.
Another example:
NULL
_____
NULL / \ NULL
/ \
( )
\ /
C \_____/ E
D
Just as before, we make a list, starting from the top.
NULL, NULL, C, D, E, NULL, NULL, NULL, C
As soon as we find 3 NULLs, the next one is our starting direction - 'C' in this case.
Spiraling onward in the same direction from there should be fairly straightforward (well not literally - har har).
PS: thanks to http://ascii.co.uk/art/hexagon for quick ascii art (:

the shortest path in cycle directed Graph

i need an example of the shortest path of directed graph cycle bye one node (it should reach to all nodes of graph from anode will be the input) please if there is an example i need it in c++ or algorithm thanks very much.........
You require to find the minimum spanning tree for it.
For directed graph according to wikipedia you can use this algorithm.
In Pseudocode:
//INPUT: graph G = (V,E)
//OUTPUT: shortest cycle length
min_cycle(G)
min = ∞
for u in V
len = dij_cyc(G,u)
if min > len
min = len
return min
//INPUT: graph G and vertex s
//OUTPUT: minimum distance back to s
dij_cyc(G,s)
for u in V
dist(u) = ∞
//makequeue returns a priority queue of all V
H = makequeue(V) //using dist-values as keys with s First In
while !H.empty?
u = deletemin(H)
for all edges (u,v) in E
if dist(v) > dist(u) + l(u,v) then
dist(v) = dist(u) + l(u,v)
decreasekey(H,v)
return dist(s)
This runs a slightly different Dijkstra's on each vertex. The mutated Dijkstras
has a few key differences. First, all initial distances are set to ∞, even the
start vertex. Second, the start vertex must be put on the queue first to make
sure it comes off first since they all have the same priority. Finally, the
mutated Dijkstras returns the distance back to the start node. If there was no
path back to the start vertex the distance remains ∞. The minimum of all these
returns from the mutated Dijkstras is the shortest path. Since Dijkstras runs
at worst in O(|V|^2) and min_cycle runs this form of Dijkstras |V| times, the
final running time to find the shortest cycle is O(|V|^3). If min_cyc returns
∞ then the graph is acyclic.
To return the actual path of the shortest cycle only slight modifications need to be made.

Resources