Finding path between given pair of nodes in a unweighted, undirected graph - data-structures

->Given graph can have around 100,000 nodes.
->The edges between these nodes can be stored in adjacency list or adjacency
matrix. (Although I think adjacency list will be a better choice due to the
larger number of nodes).
->Each pair of nodes has only one path between them.(So a graph with n nodes has
n-1 edges)
->We are given a set consisting of pairs of vertices . We have to find out path
between each of these pairs. How to go about it in the most efficient way
possible.

Related

How to build undirected graph from city vertex

I have citie's location, I treat the cities as vertex. I want to created
undirected graph to later to calculate shortest path tree. My question is
how to create undirected graph for the cities first?
Graph consists of vertices and edges. So your task is to gather information about edges somehow.
If you don't have information about which cities are directly connected to which neighboring cities by plain road (with no cities in between), then you might use some heuristic assumption. For example, you could safely assume that each city has no more than N (let's say N=50) roads going out of it and then just fill your graph with edges that represent roads to N closest neighboring cities.
To find those, you could take all cities surrounding a certain city, for example in radius of M miles (let's say M=100), and out of those pick no more than N closest ones. Those city pairs would represent roads in your graph.
Generally graphs are created using Adjacency Matrix or Adjacency List, whether they are weighed or non-weighed.
Adjacency matrix is a simple 2D array edge[n][n] where n are the number of vertices and edge[a][b] = 1 or weight represents a connection between a & b nodes.
edge[a][b] = 0 means no connection. Adjacency Matrix is always symmetric for undirected graphs.
Depending on the type of application you may want to switch between Adjacency Matrix or Adjacency List. The former has less time complexity in graph operations but requires more space compared to the later.
You can find more about Adjacency Matrix here

How will applying breadth first algorithm on an undirected graph produce a star graph?

I got this question from a data structure and algorithm textbook saying
A simple undirected graph is complete if it contains an edge between every pair of distinct vertices. A star graph is a tree of n nodes with one node having vertex degree n-1 and the other n-1 having vertex degree 1.
(a) Draw a complete undirected graph with 6 vertices.
(b) Show that applying breath-first algorithm on the undirected graph in (a) will produce a star graph.
I know how the BFS works using queues and I can provide a result of the traversal. What I'm confused about is on part (b) how can I show that applying BFS on an undirected graph will produce a star graph?
In a, there is n * (n - 1) / 2 edges in total.
It means that for every two nodes, there is an edge between them.
if applying BFS on (a) using a queue, Steps as follow:
1.) you pick up a random node, which is the root of the graph.
2.) you travel from the root node, and put all the nodes having edges with it to the queue. In addition, you have a boolean array to mark who is already processed.
in 2.), all the nodes except the root will be put into the queue.
At last, the root node have N - 1 edges, others have only one edge, and this edge is with the root

Which algorithm+representation should I use for finding minimum path distance in a huge sparse undirected graph?

I need to find the minimum distance between two nodes in a undirected graph, here are some details
The graph is undirected and huge(no of nodes is in order of 100,000)
The graph is sparse, no of edges is less than no of nodes
I am not interested in the actual path, just the distance.
What representation and algorithm should I use for a) Space efficiency b)time efficiency?
EDIT: If it matters,
The wieghts are all non zero positive integers.
No node connects to itself.
Only single edge between two adjacent nodes
It depends on the weights of the edges. If they are non-negative - Dijkstra suits you. If your graph is planar, you can use A*.
If you have negative weights, you have to use Bellman-Ford.

how to find all edge-disjoint equi-cost paths in an undirected graph between a pair of nodes?

Given an undirected graph G = (V, E), the edges in G have non-negative weights.
[1] how to find all the edge-disjoint and equal-cost paths between two nodes s and t ?
[2] how to find all the edge-disjoint paths between two nodes s and t ?
[3] how to find all the vertex-disjoint and equal-cost paths between two nodes s and t ?
[4] how to find all the vertex-disjoint paths between two nodes s and t ?
Any approximation algorithms instead ?
Build a tree where each node is a representation of a path through your unidirectional graph.
I know, a tree is a graph too, but in this answer I will use the following terms with this meanings:
vertex: is a vertex in your unidirectional graph. It is NOT a node in my tree.
edge: is an edge in your unidirectional graph. It is NOT part of my tree.
node: a vertex in my tree, not in your graph.
root: the sole node on top of my tree that has no parent.
leaf: any node in my tree that has no children.
I will not talk about edges in my tree, so there is no word for tree-edges. Every edge in this answer is part of your graph.
Algorithm to build the tree
The root of the tree is the representation of a path that contains only of the vertex s and contains no edge. Let its weight be 0.
Do for every node in that tree:
Take the end-vertex of the path represented by that node (I call it the actual node) and find all edges that lead away from that end-vertex.
If: there are no edges that lead away from this vertex, you reached a dead end. This path never will lead to vertex t. So mark this node as a leaf and give it an infinite weight.
Else:
For each of those edges:
add a child-node to the actual node. Let it be a copy of the actual node. Attach the edge to the end of path and then attach the edges end-vertex to the path too. (so each path follows the pattern vertex-edge-vertex-edge-vertex-...)
Now traverse up in the tree, back to the root and check if any of the predecessors has an end-vertex that is identic with the just added end-vertex.
If you have a match, the newly generated node is the representation of a path that contains a loop. Mark this node as a leaf and give it an infinite weight.
Else If there is no loop, just add the newly added edges weight to the nodes weight.
Now test, if the end-vertex of the newly generated node is the vertex t.
If it really is, mark this node as a leaf, since the path represented by this node is a valid path from s to t.
This algorithm always comes to an end in finite time. At the end you have 3 types of leafs in your tree:
nodes that represent dead ends with an infinite weight
nodes that represent loops, also with an infinite weight
nodes that represent a valid path from s to t, with its weight beeing the sum of all edges weights that are part of this path.
Each path represented by a leaf has its individual sequence of edges (but might contain the same sequence of vertexes), so the leafs with finite weights represent the complete set of edge-disjoint pathes from s to t. This is the solution of exercise [2].
Now do for all leafs with finite weight:
Write its weight and its path into a list. Sort the list by the weights. Now paths with identic weight are neighbours in the list, and you can find and extract all groups of equal-cost paths in this sorted list. This is the solution of exercise [1].
Now, do for each entry in this list:
add to each path in this list the list of its vertexes. After you have done this, you have a table with this columns:
weight
path
1st vertex (is always s)
2nd vertex
3rd vertex
...
Sort this table lexigraphic by the vertexes and after all vertexes by the weight (sort by 1st vertex, 2nd vertex, 3rd vertex ,... ,weight)
If one row in this sorted table has the same sequence of vertexes as the row before, then delete this row.
This is the list of all vertex-disjoint paths between two nodes s and t, and so it is the solution of exercise [4].
And in this list you find all equal-cost paths as neighbours, so you can easily extract all groups of vertex-disjoint and equal-cost paths between two nodes s and t from that list, so here you have the solution of exercise [3].

Deriving a weighted graph from groups of existing nodes - is there a smarter way?

I have an undirected weighted graph and derive a new graph based on groups of existing nodes: each group becomes a node in the new graph, connected to others based on the total weight of the edges between the original nodes.
In the current data structure, each node has a list of its neighbors and weights, and the algorithm takes each group / each node in group / each edge in node, and sums up the weights in order to determine the edges of the new graph.
This algorithm works fine, but it's slow - is there a way to avoid the 3-level iterations?
Keeping a single list of edges is an option, but when the new graph is built, the new list of edges would have to be scanned at each step to see if that edge already exists (and to increment its weight).
If O(E + Ngroups^2) is an option where E is the number of edges in the given graph and Ngroups is the number of groups, you can do it as follows.
You can create an adjacency matrix for the resulting graph. Then loop through all the edges in the given graph like
for each edge u in Graph
for v such that edge u->v exists
let w be the weight of u->v
A[group(u)][group(v)] := A[group(u)][group(v)] + w;
You can rebuild the new graph from adjacency matrix if you wish.
One possible optimization is to use a balanced tree to hold the edges starting in a particular node group instead of the whole adjacency matrix, this would lead to O(E*log(Ngroups)) time complexity.

Resources