I have the following queries:
I want to know how to create a graph dynamically
How to manage multiple weights on a graph
How to find the distance from a particular node to another in a minimum spanning tree using kruskal.In kruskals the minimum spanning tree is output as a vector of edges.Hence the vertices are not explicitly stored. I do not know how to get the distance for say an example node 0 to the node furthest from it. I tried getting the vertices using sourc and target and then storing the verices in an array.After that, locating node 0 and from there iterating and reverse iterating through the vertices calculating the weights to find the largest diatance from the node 0. But I fell I'm using the most round about way of going about it.There must be a function for this, or perhaps a clevere way of going about this.
Does kruskal store the edges in the spanning tree in order of the spanning tree? Or at least is the first node of the first edge stored the actual first node? How can I get the order of the nodes in spanning tree in kruskals?
Similarly how can I get the weight of the spanning tree using Prim? The way I did it was to use the predecessor array where predecessors are stored and find what edge in weightsMap and add it.Is there an easier way? And in prims the distanceMap stores the distance from node 0 to the others in the original graph and not the spanning tree right?
Related
Let's say I have a fully connected undirected graph (nodes and edges) that is constrained by the fact that all nodes represent coordinates in 3D space and nodes can only be adjacent in the graph if they represent adjacent cubes i.e. (1,0,8) could be adjacent to (0,0,8) or (2,0,8) or (1,0,9).
Now let's say I dynamically start deleting nodes from the graph. I'd like an algorithm that lets me know, at each delete, if the graph connectivity has been broken & if so what the connected components are. Is there a way to optimise the spatial nature of the graph to do so or am I doomed to using standard graph processing algorithms?
I'm thinking I'll need some sort of an algorithm that maintains dynamically the connectivity relationship of nodes in the graph as nodes are deleted from the graph. All I've managed to find so far is A*, jump point search and shortest path algorithms, and I also brushed upon an algorithm here: https://en.wikipedia.org/wiki/Dynamic_connectivity#Decremental_connectivity.
Note: my graph can definitely be cyclic.
OK, so after thinking about this, the best answer I can come up with still does not exploit the spatial constraints of the graph, but I believe it runs with an amortized cost of O(log(n). Here's a sketch of the idea:
First, we compute an arbitrary spanning tree of the graph, starting at any node and choosing arbitrary edges for the tree. Ideally we'd want to make this as balanced as possible i.e. minimize the depth.
Then, at each deletion, we update our spanning tree as follows:
If the edge deleted is not in the spanning tree, do nothing
Else, it's a parent-child relationship that's been removed, and we note the child node
For all children of this child node, we flag them temporarily i.e. we set some marker on each node marking it as part of this affected tree that's possibly broken from the main tree
Now we run this recursive algorithm, starting at the child node. Let's say the algorithm is currently processing node n:
If there is an edge from n in the graph to an unmarked node in the graph, update the spanning tree with this edge and return "true"
Else for each child of the node, we run the recursive algorithm and proceed as follows
If the algorithm returned false for any child, then the graph is broken i.e. disconnected
Else we can choose any node and point our node n at this node and return "true" ourselves
If we actually maintain two separate spanning trees, we can process edge deletions in the background and toggle between using one tree or the other, to improve the efficiency of this for use in a real-time program e.g. a game.
I have a non-oriented graph and I have to find a subgraph that is a binary tree and contains all nodes of the graph.
The only solution that I know is to generate all subgraphs that are trees and print the first one (or the only one) that has same number of nodes as the initial graph. (even so I don't really know how to do it)
The starting node can be any node.
Example:
I think what you are trying to get is a spanning tree or maybe a minimum spanning tree.
Refer to this for more details or google about spanning tree:
https://en.wikipedia.org/wiki/Spanning_tree
I am trying to create an algo that will get a spanning tree with root node such that, the spanning tree will have least number of edges removed from Original Graph G.
Thanks in advance
For any connected graph, the spanning tree always contains n-1 edges where n is the number of nodes in the graph. So you will have to remove all the remaining edges. (If I have understood your question correctly)
Even for disconnected graphs, the number of edges in a spanning tree is defined by the number of components and number of nodes in each component.
I have a cyclic directed graph and I was wondering if there is any algorithm (preferably an optimum one) to make a list of common descendants between any two nodes? Something almost opposite of what Lowest Common Ancestor (LCA) does.
As user1990169 suggests, you can compute the set of vertices reachable from each of the starting vertices using DFS and then return the intersection.
If you're planning to do this repeatedly on the same graph, then it might be worthwhile first to compute and contract the strong components to supervertices representing a set of vertices. As a side effect, you can get a topological order on supervertices. This allows a data-parallel algorithm to compute reachability from multiple starting vertices at the same time. Initialize all vertex labels to {}. For each start vertex v, set the label to {v}. Now, sweep all vertices w in topological order, updating the label of w's out-neighbors x by setting it to the union of x's label and w's label. Use bitsets for a compact, efficient representation of the sets. The downside is that we cannot prune as with single reachability computations.
I would recommend using a DFS (depth first search).
For each input node
Create a collection to store reachable nodes
Perform a DFS to find reachable nodes
When a node is reached
If it's already stored stop searching that path // Prevent cycles
Else store it and continue
Find the intersection between all collections of nodes
Note: You could easily use BFS (breadth first search) instead with the same logic if you wanted.
When you implement this keep in mind there will be a few special cases you can look for to further optimize your search such as:
If an input node doesn't have any vertices then there are no common nodes
If one input node (A) reaches another input node (B), then A can reach everything B can. This means the algorithm wouldn't have to be ran on B.
etc.
Why not just reverse the direction of the edge and use LCA?
I have a minimum spanning tree (MST) from a given graph. I am trying to compute the unique sub-path (which should be part of the MST, not the graph) for any two vertices but I am having trouble finding an efficient way of doing it.
So far, I have used Kruskal's algorithm (using Disjoint Data structure) to calculate the MST (for example: 10 vertices A to J).. But now I want to calculate the sub-path between C to E.. or J to C (assuming the graph is undirected).
Any suggestions would be appreciated.
If you want just one of these paths, doing a DFS on your tree is probably the easiest solution, depending on how you store your tree. If it's a proper graph, then doing a DFS is easy, however, if you only store parent pointers, it might be easier to find the least common ancestor of the two nodes.
To do so you can walk from both nodes u,v to the root r and then compare the r->u and r->v paths. The first node where they differ is the least common ancestor.
With linear preprocessing you can answer least common ancestor queries in constant time. If you want to find the paths between pairs of nodes often, you might want to consider implementing that data structure. This paper explains it quite nicely, I think.