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.
Related
I'm doing an adjacency list implementation of a graph class in C++ (but that's kinda irrelevant). I have a weighted directionless graph and I am writing the addVertex method. I have basically everything down, but I'm not sure what I should do when I add a vertex in between two others that were already there and had their own corresponding weights.
Should I just throw away the old weight that the vertex stored? Should I use the new one that was passed in? A mix of both? Or does it not matter at all what I pick?
I just wanted to make sure that I was not doing something I shouldn't.
Thanks!
I guess it depends on what you want to achieve. Usually, an adjacency list is a nested list whereby each row i indicates the i-th node's neighbourhood. To be precise, each entry in the i-th node's neighbourhood represents an outgoing connection from node i to j. The adjacency list does not comprise edge or arc weights.
Hence, adding a vertex n should do not affect the existing adjacency list's entries but adds a new empty row n to the adjacency list. However, adding or removing edges alter the adjacency list's entries. Thus, adding a vertex n "between two other [nodes i and j] that were already there and had their own corresponding weights" implies that you remove the existing connection between i and j and eventually add two new connections (i,n) and (n,j). If there are no capacity restrictions on the edges and the sum of distances (i,n) and (n,j) dominates the distance (I,j) this could be fine. However, if the weights represent capacities (e.g. max-flow problem) you should keep both connections.
So your question seems to be incomplete or at least unprecise. I assume that your goal is to calculate the shortest distances between each pair of nodes within an undirected graph. I suggest keeping all the different connections in your graph. Shortest path algorithms can calculate the shortest connections between each node pair after you have finished your graph's creation.
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.
It is well-known, that if one wants to layout square grid(aka matrix) of real numbers he can use array with row-major order. Let's draw neighbourhood of some element i:
...................................
...|i-width-1|i-width|i-width+1|...
...| i-1 | i | i+1 |...
...|i+width-1|i+width|i+width+1|...
...................................
Let us for simplicity assume that i somewhere in the middle of square grid, so no bordering issues.(We can add %(width*height) and get connected on borders grid). So if one wants to do something with each element in neighbourhood of i'th element one should do:
//function which does something with element at idx
void DoSomethinWithElement(size_t idx);
//left neighbour
DoSomethinWithElement(i-1);
//right neighbour
DoSomethinWithElement(i+1);
//top neighbour
DoSomethinWithElement(i-width);
//bottom neighbour
DoSomethinWithElement(i+width);
I want to generalize this algorithm for any type of regular polygon grid (i.e. triangle, square, pentagonal, hexagonal etc.) Regular means that it constructed only from one type of polygon (i.e only from triangles).
How to generalize for any type of polygon grid:
1. Layout of other grid in array?
2. These N(for square mesh four) statements in a loop?
The problem "How to find all neighbors of a tile in a polygonal grid?" is solved quickly using graphs. But I want to use arrays so I could copy them to graphics card with CUDA.
Examples of grids:
I want to generalize this algorithm for any type of regular polygon grid (i.e. triangle, square, pentagonal, hexagonal etc.)
Your definition of regular polygon grid is unusual. Typically you may not rotate or mirror the faces of the grid (tiling) for it to be considered regular. There are only 3 regular tilings (triangle, square, hexagon). All pentagonal tilings require mirroring or rotation or both.
Let's simplify your problem to this: "How to find all neighbors of a face in a polygonal grid?" Once you've got that figured out, it's trivial to call a function on each neighbor.
Grids are graphs with certain limitations. It is possible to generalize the search for neighbors by representing the grid with a general graph. The vertices of the graph represent the faces and they have edges to their neighbors. Graph of a grid is a planar graph. When the grid is represented by a graph, the problem becomes: "Given a vertex in a graph, how do I find all adjacent vertices?"
Note that the vertices and edges of the graph are not the same thing as the vertices and edges of the grid. For example, the grid-vertices of a hexagonal grid have three connected edges, while the faces have six neighboring faces and therefore the graph-vertices have six edges each.
One way to represent graphs is the adjacency list. In this representation, you simply need to look up the adjacency list of the vertex to find all it's neighbors.
But I want to use arrays
Well since the size of each adjacency list is constant, they can be implemented with arrays like in decltype_auto's answer. Or you can represent the graph with an adjacency matrix.
But if you want a generic algorithm for any tabular representation of a grid, then I think that you've painted yourself into a corner with that requirement. Each representation is different and you'll need a different algorithm for each.
You can represent the adjacencies of K-polygonal grid of polygon count N by a 1D vector v of N*K length, or a 2D NxK matrix M. Use std::size_t -1, a nullptr or whatever suites the reference type you've stored in v or M to indicate missing neighbors at the border.
Given such a NxK matrix M:
For the neighbors of polygon n you iterate from M[n][0] to M[n][K-1], fetch the neighbors by whatever reference you've stored in M, and apply whatever function you want on them.
I'm new to graph theory and have been solving a few problems lately.
I was looking for a way to find the depth of every node in the graph. Here's how I formalized it on paper:
Run a for loop iterating over every vertex
If the vertex is not visited, run a DFS with that vertex as a source
In the DFS, as long as we have more vertices to go to, we keep going (as in the Depth First Search) and we keep a counter, cnt1, which increments every time
While backtracking in the recursive DFS call, we initialize a new counter starting from the current count at the last vertex, and give the value cnt1-cnt2 to each vertex so on and keep decreasing cnt2.
I'm not sure if this is correct and am not able to implement the same in code. Any suggestions? For the record, my graph is stored in the form of an adjacency list, in the form of an array of vectors like:
vector <int> a[100];
EDIT:The input graph is a collection of directed trees. We have a depth label for each node - denoting the number of nodes on the simple path from the root to it. Hence we need to find the maximum depth of each node
You may find these links helpful:
http://www.geeksforgeeks.org/breadth-first-traversal-for-a-graph/
http://www.geeksforgeeks.org/depth-first-traversal-for-a-graph/
Here classes are used to implement BFS/DFS using an adjacency list representation.Just like the array 'visited' of bool type used here...you have to also create another array 'depth' in wich you can store the depth of each element while computation..and then output that array in the end..
So I have a raw file that is 250x200px that I've read into a 2D array like rawFile[250][200] with each pixel (each array index) acting as a node and each pixel value representing an elevation (think: topographical map). I want to find the shortest path using Dijkstra's algorithm from rawFile[0][0] to rawFile[250][200] with the distance cost being the absolute value of the difference of going from node1 to node2 plus the shortest path distance to the currently visited node. Each node can move in the four cardinal directions (N, E, S, W) assuming there is an adjacent node in the respective direction. I've read the pseudocode and various implementations that all require an adjacency matrix or adjacency list, which in this case would be adjMatrix[50000][50000]. However, I am struggling to figure out how I can populate the adjacency matrix from just the raw file.
Do any of you have any suggestions on solving this problem? Thanks!
Converting an image into an adjacency matrix is completely unnecessary; the only thing you need is the "neighbor-ness" information which is already implicitly present.
The neighbors of any pixel i,j are represented by the pixels at (i-1,j), (i+1,j), (i,j-1), (i,j+1) subject to image boundaries. You don't need a matrix to encode that; any time the algorithm says to look at neighbors, just supply the neighboring pixels.