Storing data for trees and graphs? - algorithm

In most tree or graph problems i tried to solve,the input is generally the entire tree or graph structure in a node1->leafs or node1->adjacent nodes format.
Is there any list of commonly used structures to save this data in memory which later helps for the intended algorithm.For example:
Say i have a list of graph nodes like:
1 3 8 2 4.....# 1 is connected to 3 8 2 4...nodes
2 5 1 3... # 2 is connected to 5 1 3...nodes
3 1 2... #likewise
. ...
8 ......
so if i want to use the random contraction algorithm (in which i will have to contract edges say i contract 1 and 8..i use a multi-linked list structure in which each node on the adjacency list points to its corresponding row i.e.8 in the first line points to the 8th node.
Now the question,why i chose this structure to store data?
contracting is effectively making 1 and 8 one single entity,
so i read 1's adjacency list starting from 3 and go to 3rds adjacency list change 1 to 8 and next 8's row make 1 to 8 now go to 2's list change 1 to 8....and finally i append 1s list to 8 and remove duplicates..Yep,so finally 1 is deleted from graph after contracting 1 and 8
I want to know all the usually or rarely used structures for storing trees and graphs,if associated with algos the algo name as well?Thank You

One common way to store graphs is to use an n-by-n matrix, where n is the number of vertices in the graph. If you simply wanted to store the adjacency, if X is the matrix, then X[i][j] = 1 if vertex j is reachable from vertex i, and 0 otherwise. You could also store edge costs or edge capacities in this manner. The disadvantage is of course the amount of memory being used, O(n^2) instead of O(n+m) where m is the number of edges, but the advantage is O(1) lookup for every possible vertex pair.
Floyd's algorithm for solving the All Pairs Shortest Paths problem can naturally make use of such a matrix, as well as more complex sub-cubic algorithms for solving various graph paths problems that utilize faster matrix multiplication over a ring.

Related

Minimum Hop Count in Directed Graph based on Conditional Statement

A directed graph G is given with Vertices V and Edges E, representing train stations and unidirectional train routes respectively.
Trains of different train numbers move in between pairs of Vertices in a single direction.
Vertices of G are connected with one another through trains with allotted train numbers.
A hop is defined when a passenger needs to shift trains while moving through the graph. The passenger needs to shift trains only if the train-number changes.
Given two Vertices V1 and V2, how would one go about calculating the minimum number of hops needed to reach V2 starting from V1?
In the above example, the minimum number of hops between Vertices 0 and 3 is 1.
There are two paths from 0 to 3, these are
0 -> 1 -> 2 -> 7-> 3
Hop Count 4
Hop Count is 4 as the passenger has to shift from Train A to B then C and B again.
and
0 -> 5 -> 6 -> 8 -> 7 -> 3
Hop Count 1
Hop Count is 1 as the passenger needs only one train route, B to get from Vertices 0 to 3
Thus the minimum hop count is 1.
Input Examples
Input Graph Creation
Input To be solved
Output Example
Output - Solved with Hop Counts
0 in the Hop Count column implies that the destination can't be reached
Assuming number of different trainIDs is relatively small (like 4 in your example), then I suggest using layered graph approach.
Let number of vertices be N, number of edges M, and number of different trainIDs K.
Let's divide our graph to K graphs. (graphA, graphB, ...)
graphA contains only edges labeled with A, and so on.
Weight of each edge in each of the graphs is 0.
Now create edges between these graphs.
Edge between graphs is representing a 'hop'
grapha[i] connects to graphB[i], graphC[i], ...
Each of these edges has weight 1.
Now for every graph run Dijkstra's shortest path algorithm from V1 in that graph, and read results from V2 in all graphs, take minimal value.
This way minimum of results for running dijkstra's for every graph will be your minimum number of hops.
Memory complexity is O(K*(N+M))
And time complexity is O(K*(((2^K)*N+M)*log(KV)))
(2^K)*N comes from fact that for every 1<=i<=N, vertices graphA[i],graphB[i],... must be connected to each other, and this gives 2^K connections for every i, and (2^K)*N connections in total.
For cases where K is relatively small, like 4 in your example, but N and M are quite big, this algorithm works like a charm. It isn't suitable for situation where K is big though.
I'm not sure if that's clear. Tell me if you need more detailed explanation.
EDIT:
Hope this makes my algorithm more clear.
Black edges have weight 0, and red edges have weight 1.
By using layered graph approach, we translated our special graph into plain weighted graph, so we can just run Dijkstra's algorithm on it.
Sorry for ugly image.
EDIT:
Since max K = 10, we would like to remove 2^K from our time complexity. I believe this can be done by making edges that represent possible hops virtual, instead of physically storing them on adjacency list.

How to merge nodes given an adjacency matrix

I have an adjacency matrix, and I can't seem to find a quick way to combine multiple nodes to know what the final number of "super-nodes" are. I thought an easy solution was to essentially compute the sum of the upper triangular part of the adjacency matrix, and subtracting the total amount of nodes minus the previous sum would give me the answer, but it looks a bit more tricky.
Suppose:
I have 6 nodes from 1 to 6:
Nodes 1,2,3 are connected all to each other.
Nodes 4 and 6 are connected to each other,
Node 5 is not connected to anything.
At this point it seems trivial that of the 6 initial nodes I will only have 3 remaining super nodes. Now the problem by using my method before is that suppose the first super-node is connected like this:
1 to 2
2 to 3,
but not 1 to 3 directly. (even though they merge).
Here sum(upptriangle(Adj))=3 works, but for the first case I am adding a "dummy node" (the connection 1-3) outputs: sum(upptriangle(Adj))=4, and this type of connection should not affect the final result.
Is there a standard algorithm I am missing, to solve this problem (and compensate for overcomplete of non fully connected sub-graphs?), instead of iteratively going over every node to see if it's been merged?
In other words, is there a fast computation of node merging that I can get only from the adjacency matrix?
When your problem is not dynamic you can use BFS or DFS to find the components.
Using BFS or DFS to determine the connectivity in a non connected graph?
But if your problem is dynamic you should use union find data-structure.
Union-find data structure

Algorithm to sort numbers

I have different numbers which needs to be sorted in ascending order by exchanging each number with 0.
The resultant number should be obtained only from exchanging each number with 0.
for eg, I have 3x3 matrix,
3 4 1
2 5 0
6 8 7
In above matrix, the number should be exchanged with 0 to make an ascending order. From above, only 5,7 and 1 are exchanged with 0 at first step. The final output should be like this
1 2 3
4 5 6
7 8 0
What is an optimal solution to achieve this.
Thanks
This is an easier version of the famous 15-puzzle.
The general way to approach such a problem is to model it as states graph, and run a shortest-path algorithm in order to find a path from the source (given board) to the target (sorted board).
The states graph is G=(V,E) where: V= { all possible boards } and E={(u,v) | can change board u to v with a single swap }`.
You can run BFS or bi-directional BFS (since you have one source and one target), or even A* Algorithm with an appropriate admissible heuristic function to find the path on the states graph, which represents a series of swaps that yield a solution.

Using disjoint-set data structure, graph theory

I'm practicing solving programming problems in free time. This problem I spotted some time ago and still don't know how to solve it:
For a given undirected graph with n vertices and m edges (both less than 2 × 106)
I need to split its vertices into as many groups as possible, but with one
condition: each pair of vertices from different groups are connected by edge.
Each vertex is in exactly one group. At the end I need to know the size of
each group.
I was proud when I came up with this solution: consider complemented graph of the original graph and use Disjoint-set data structure for it. It gives us the right answer (not difficult to prove). But it's only theoretical solution. With given constraints it's very very bad, not optimal. But I believe this approach can be somehow smartly fixed. But how?
Can anyone help?
EDIT: for a graph with vertices from 1 to 7 and 16 edges:
1 3
1 4
1 5
2 3
3 4
4 5
4 7
4 6
5 6
6 7
2 4
2 7
2 5
3 5
3 7
1 7
we have 3 groups with sizes: 1, 2 and 4.
These groups are: {4}, {5,7}, {1,2,3,6} respectively. There are edges connecting each pair of vertices from different groups and we can't create more groups.
I think the only ingredient you're missing is how to deal with sparse graphs.
Let's think about this in terms of finding the biggest possible complete graph where the only operation I can do is group a set of nodes (say v_1, ..., v_k) together and give the new supernode edges only to those nodes u that were connected to all of v_1, ..., v_k.
If your graph has fewer than n^2/4 edges, randomly sample n node pairs, noting which pairs are not joined by an edge. Union-find is an easy way to code this up. Now rebuild the graph using as groups the sets you found by this random sampling. Recurse on this reduced graph. (I'm not quite sure how to analyse this step, but I believe each sample-rebuild cycle reduces the graph size by at least a constant factor with high probability, so this whole process takes near-linear time.)
Once you have a fairly dense graph (at least n^2/4 edges), you can convert to an adjacency matrix representation and do exactly what you were suggesting --- check all node pairs, do a union whenever you see that two nodes aren't joined by an edge, and read off the sets.

Graph and permutation problem

I have a graph (with nodes and edges) containing symmetry and a group of permutations to label the nodes so no edges are changed (automorphisms). Now I would like to determine for which nodes a permutation exchanges two equivalent (i.e. nodes with the same color or symmetry class) neighboring nodes.
When the nodes with equivalent neighbors stay the same, simply checking if the neighbors are exchanged in the permutation is enough. However, when the nodes with equivalent neighbors are also permuted (i.e. there are multiple nodes with the same color/symmetry class with the same equivalent neighbors), the problem becomes more complex.
Is there any known algorithm for such a problem?
Some remarks:
The graph has no coordinates, it's a topology only
An example:
Identity permutation: http://imagebin.ca/view/2vAOi0I.html
There are 384 automorphic permutations: http://pastebin.org/157954
Simple example where the permutation inverts nodes 5 & 23: http://imagebin.ca/view/myQCvZnp.html
As long as 5 and 23 remain in the same place it is easy to determine if they are inverted (compared to the identity permutation). However, when these points are also interchanged it becomes more difficult.
Difficult example, permutation 67: http://imagebin.ca/view/9gl-Wmzt.html
I don't think your problem is well-defined. Imagine the following graph:
1
/ \
/ \
2 3
/ \ / \
4 5 6 7
Now consider the two automorphisms that swap the two subtrees of 1.
automorphism A: 1<->1, 2<->3, 4<->6, and 5<->7
automorphism B: 1<->1, 2<->3, 4<->7, and 5<->6
Which one of these "inverts" the children of 2? Because 2 gets mapped to 3, we have to decide whether the natural correspondence is 4-6 and 5-7, or 4-7 and 5-6. But we have no information we can use to decide this fact.

Resources