Is there any way to turn simple matrix to graph? - c++

For example, I have a matrix like this;
1 2 3 4
2 4 5 1
1 2 4 1
5 3 2 1
and I select 3 nodes from this matrix as random. How can I make graph from these nodes? Is there any algorithm or way to make this happen? I know how to make adjacency matrix from graph but I just can't make the graph from the random matrix right now.
EDIT:
For example, I select row:1 col:1 as first node and row:3 col:1 as second node, it should find the shortest way between first node and second node and make graph of them.

I assume that this 4x4 matrix represents the adjacency matrix from a graph with 4 nodes. In this case, taking 3 nodes randomly, would mean to select 3 random lines and take the corresponding columns, and you have a reduced graph defined by its adjacency list.
EDIT:
According to your edit, each of the 16 matrix item would be a node uniquely identified by its coordinates (i,j). Each of these nodes would be connected at least to his 2 to 4 neighbors. Then some clarifications are needed:
is the value of the item just the label of on of the 16 nodes ?
are the only moves vertical and horitontal or are diagonal allowed ?
are moves bound by the borders or can thy flip over (i.e. The last item of a row is connected with the first) ?
are the cost of each move from one to the next equal or is the cost of each move related to the values of the node traversed ?
You can then easily build the 16*16 ajacency matrix for the 16 items and apply the method of the shortest path.

Related

Breadth-first limiting on each node within a result in Gremlin?

Background
Looking at the below image, we're facing an issue with how we want to do our limiting at a breadth-level.
The goal is to ensure that off each neighbor, we never read more than X edges off the current node to avoid timeouts on nodes with a large amount of edges.
Example
We have a max-breadth limit of X where X is the number of neighbors we aggregate off a single node. We begin a BFS traversal from 0 and aggregate 3, 1 and 2.
Assuming our max-breath limit is 3, the problem that can occur is that we first pull 1 and immediately begin reading all of 1's neighbors. As a result, we completely disregard the neighbors that could exist off of nodes 3 and 2 because 1 would fulfill the max-breadth.
Question
How can we, in Gremlin (in a single query), say that we want an edge limit for each node in my list of neighbors?
In other words, I want X neighbors from node 3, X neighbors from node 1 and X neighbors from node 2. This idea should hold true recursively up until some depth D.
Attempt
g.V(idsList).outE().limit(50).inV().dedup.by(T.id).fold()
The issue with the above is that we blindly limit all edges from all neighbors to X which can favor a single subgraph.

Breaking an un-directed connected graph into two components

Is there any algorithm to break a Connected Undirected Graph into exactly 2 connected components by deleting Minimum number of vertices.
Example 1: edge list [1-2, 2-3, 3-4], here we can delete vertex number 2 or vertex number 3 to decompose the graph into two connected component.
Example 2: edge list [1-2, 2-5, 2-3, 3-4], here we cannot delete vertex number 2 as it decomposes the graph into 3 connected components (which we don't want) but we can delete vertex number 3 to decompose the graph into two connected components.
You need to look for minimal vertex separator algorithm.

Algorithm for pathing between graph components

First, this is a homework question. I have a boolean matrix where 1s represent nodes, and adjacent nodes are considered connected.
for example:
1 0 0 0 1
1 1 1 0 0
1 0 0 1 1
0 0 0 0 0
0 0 0 0 0
This matrix contains 3 groups by the definition I've been given. One in the top left, consisting of 5 nodes, one in the top right consisting of 1 node, and one below that consisting of 2 nodes.
What I need to do is write a function(s) that determines the fewest number of nodes that must be added to the matrix in order to connect all of the separate components. Two groups are connected when a path can be made from any node in one group to the other.
So, what I'm asking is for someone to shove me in the right direction in terms of algorithms. I've considered how I might use path finding algorithms to find the shortest path between two groups, but am unsure of how I could do this for every group in the matrix. If I use a depth first traversal to determine the separate groups, could I then use a path finding algorithm for any arbitrary node within each group to another?
The generic problem is called the Steiner Tree problem, and it is NP-complete.
There is an algorithm that's not exponential, but gives you a suboptimal solution.
The way you can do it is to compute shortest paths between any two pair of components, do the minimum spanning tree on using just the initial components and the weights you computed, then go through you solution and eliminate cycles.
Since you have a bunch of options for connecting islands I would add a step to optimize the connections.
But an algorithm for the optimal answer: NP-complete (try every combination).
Consider every connected component(group) as a node. Then you can run MST (Minimum Spanning Tree) algorithm to find the min cost to connect all the groups.
Complexity: Complexity to build the edges = O(M*M) + O(ElgV) (M is the number of 1's on the the given grid and M*M operations to find Manhattan distance every pair of 1's to find the Manhattan distance of every pair of groups) and O(ElgV) is the complexity of finding MST

Comparing two graphs

I need to compare many graphs(up to a few millions graph comparisons) and I wonder what is the fastest way to do that.
Graphs' vertices can have up to 8 neighbours/edges and vertex can have value 0 or 1. Rotated graph is still the same graph and every graph has identical number of vertices.
Graph can look like this:
Right now I'm comparing graphs by taking one vertex from first graph and comparing it with every vertex from second graph. If I find identical vertex then I check if both vertices' neighbours are identical and I repeat this until I know if graphs are identical or not.
This approach is too slow. Without discarding graphs that are for sure different, it takes more than 40 seconds to compare several thousands graphs with about one hundred vertices.
I was thinking about calculating unique value for every graph and then only compare values. I tried to do this, but I only managed to come up with values that if are equal then graphs may be equal and if values are different then graphs are different too.
If my program compares these values, then it calculates everything in about 2.5 second(which is still too slow).
And what is the best/fastest way to add vertex to this graph and update edges? Right now I'm storing this graph in std::map< COORD, Vertex > because I think searching for vertex is easier/faster that way.
COORD is vertex position on game board(vertices' positions are irrelevant in comparing graphs) and Vertex is:
struct Vertex
{
Player player; // Player is enum, FIRST = 0, SECOND = 1
Vertex* neighbours[8];
};
And this graph is representing current board state of Gomoku with wrapping at board edges and board size n*n where n can be up to 2^16.
I hope I didn't made too many errors while writing this. I hope someone can help me.
First you need to get each graph into a consistent representation, the natural way to do this is to create an ordered representation of the graph.
The first level of ordering is achieved by grouping according to the number of neighbours.
Each group of nodes with the same number of neighbours is then sorted by mapping their neighbours values (which are 0 and 1) on a binary number which is then used to enforce an order amongst the group nodes.
Then you can use a hashing function which iterates over each node of each group in the ordered form. The hashed value can then be used to provide an accelerated lookup
The problem you're trying to solve is called graph isomorphism.
The problem is in NP (although it is not known whether it's NP-Complete) and no polynomial time algorithm for it has been found.
The algorithm you describe seems to take exponential time.
This is a possible suggestion for optimization.
I would recommend to try memoization (store all the vertex pairs that are found to be different), so that the next time those two vertices are compared you just do a simple lookup and reply. This may improve the performance (or worsen it), depending on the type of graphs you have.
You have found out yourself that checking isomorphism can be done by checking one bord with all the n*n shifts times 8 rotations of the other, thus having O(n^3) complexity.
This can be reduced to O(n^2). Let's shift only in one direction, say by moving the x axis. Then we only have to find the proper y-offset. For this, we concatenate the elements as follows for both graphs:
. . 1 . 0 . . 3
0 1 . . => 0 1 2 . => 0 3 0 1 2 0 2
. 0 . . 0 . 2 .
_______
1 2 3 4 ^---- a 0 indicates start of a row
We get two arrays of size n and we have to check whether one is a cyclic permutation of the other. For this, we concatenate array a with itself and search for the other.
For example if the two arrays would be a=0301202 and b=0203012 we search for 0203012 in 03012020301202 using KMP or similar, which runs in O(n + 2n)=O(n) time (we can get rid of the whole preprocessing since the first array always is the same).
Combining this O(n) x-check with the n y-shifts and the 8 rotations gives O(n^2) overall complexity by using O(n) additional space.

transform given edges to an adjacency matrix

If we have as inputs the edges of a graph for example as shown below as matrix
(1,2)
(2,3)
(3,1)
and from these inputs you want to create your adjacency matrix.
My idea was to iterate throught the matrix and push_back in a vector which contains the unique nodes (1,2,3) and then creating a zero matrix with dimensions equals to the nodes_vector, iterating through the matrix again and see which nodes are connected to put 1 in our matrix.
Is there a faster solution than this?
Yes. If elements are numbered 1-N, then on the first run through, all you have to do is find the biggest number in the edge-list, and the width of your adjacency matrix will be that minus one. Finding all unique nodes is slower than you'd immediately think.
Of course, if you actually need to know which nodes actually exist, then the method you list is optimal.