Dynamic Decremental Connectivity of Cubic Graph - algorithm

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.

Related

how to test for bipartite in directed graph

Although we can check a if a graph is bipartite using BFS and DFS (2 coloring ) on any given undirected graph, Same implementation may not work for the directed graph.
So for testing same on directed graph , Am building a new undirected graph G2 using my source graph G1, such that for every edge E[u -> v] am adding an edge [u,v] in G2.
So by applying a 2 coloring BFS I can now find if G2 is bipartite or not.
and same applies for the G1 since these two are structurally same. But this method is costly as am using extra space for graph. Though this will suffice my purpose as of now, I'd like know if there any better implementations for the same.
Thanks In advance.
You can execute the algorithm to find the 2-partition of an undirected graph on a directed graph as well, you just need a little twist. (BTW, in the algorithm below I assume that you will eventually find a 2-coloring. If not, then you will run into a node that is already colored and you find you need to color it to the other color. Then you just exit saying it's not bipartite.)
Start from any node and do the 2-coloring by traversing the edges. If you have traversed every edge and every node in the graph then you have your partition. If not, then you have a component that is 2-colored and there are no edges leaving the component. Pick any node not in the component and repeat. If you get into a situation when you have a few components that are all 2-colored, and there are no edges leaving any of them, and you encounter an edge that originates in a node in the component you are currently building and goes into a node in one of the previous components then you just merge the current component with the older one (and possibly need to flip the color of every node in one of the components -- flip it in the smaller component). After merging just continue. You can do the merge, because at the time of the merge you have scanned only one edge between the two components, so flipping the coloring of one of the components leaves you in a valid state.
The time complexity is still O(max(|N|,|E|)), and all you need is an extra field for every node indicating which component that node is in.

Finding the list of common children (descendants) for any two nodes in a cyclic graph

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?

directed graphs with a given root node - match another directed graph for equality

There is a directed graph having a single designated node called root from which all other nodes are reachable. Each terminal node (no outgoing edges) takes an string value.
Intermediate nodes have one or more outgoing edges but no value associated with them. Edges connecting a node to its neighbor have a string label. The labels for edges emanating from a single node are unique. There could be possible cycles in the graph!
What is the best graph algorithm for checking if two such directed (possibly having cycles) graphs (as described above) are equal?
The graph isomorphism problem is one of the more intriguing problems in TCS. There is an entire page dedicated to it on the wiki.
In your particular case you have two rooted directed graph with a source and a sink.
You could start two BFS in parallel, and check for isomorphism level by level; i.e. levelize the graph and check whether the subset of nodes at each level are isomorphic across the two graphs.
Note that since you have a Directed, Rooted graph you should still be able to levelize it for the purpose of finding isomorphism. Do not enque nodes already visited during the BFS; i.e. levelize using the shortest path to the node from the root when determining the level to group in.
Within a set the comparison should be relatively easy. You have many properties to distinguish nodes at the same level (degree, labels) and should be able to create suitable signatures to sort them. Since you are looking for perfect isomorphism, you should get an exact match.

How to detect if breaking an edge will make a graph disjoint?

I have a graph that starts off with a single, root node. Nodes are added one by one to the graph. At node creation time, they have to be linked either to the root node, or to another node, by a single edge. Edges can also be created and deleted (one by one, between any two nodes). Nodes can be deleted one at a time. Node and edge creation, deletion operations can happen in any arbitrary order.
OK, so here's my question: When an edge is deleted, is it possible do determine, in constant time (i.e. with an O(1) algorithm), if doing this will divide the graph into two disjoint subgraphs? If it will, then which side of the edge will the root node belong?
I'm willing to maintain, within reasonable limits, any additional data structure that can facilitate the derivation of this information.
Maybe it is not possible to do it in O(1), if so any pointers to literature will be appreciated.
Edit: The graph is a directed graph.
Edit 2: OK, maybe I can restrict the case to deletion of edges from the root node. [Edit 3: not, actually] Also, no edge lands into the root node.
To speed things up a little over the obvious O(|V|+|E|) solution, you could keep a spanning tree which is fairly easy to update as the graph is changed.
If an edge not in the spanning tree is deleted, then the graph isn't disconnected and do nothing. If an edge in the spanning tree is deleted, then you must try to find a new path between those two vertices (if you find one, use it to update the spanning tree, otherwise the graph is disconnected).
So, best case O(1), worst-case O(|V|+|E|), but fairly simple to implement anyway.
Is this a directed graph? The below assumes undirected.
What you are looking for is whether the given edge is a Bridge in the graph. I believe this can be found using a traversal looking for cycles containing that edge and would be O(|V| + |E|).
O(1) is too much to ask.
You might find that looking to maintain 2-edge connected components in dynamic graphs could be useful to you.
Eppstein et al have a paper on this: http://www.ics.uci.edu/~eppstein/pubs/EppGalIta-TR-93-20.pdf
which can maintain 2-edge connected components, in a graph of n nodes where edge insertions and deletions are allowed. It has O(sqrt(n)) time per update and O(log n) time per query.
So any time you delete, you can query in O(logn) to determine if the number of 2-edge connected components has changed. I suppose it can also tell you which component a specific node is in.
This paper is more general and applies to other graph problems, not only 2 edge connected components.
I suggest you look for bridges and dynamic 2-edge connectivity to get you started.
Hope that helps.
as said by Moron just before, you are actually looking for a Bridge in your graph.
Now a Bridge is an edge that has the described attribute and also originates and ends up in Cut Vertexes. Cut vertex is exactly what a Bridge is, but in a vertex (node) edition.
So the only way (though quite bending the initial data structure hypothesis) I can think of, to get a O(1) complexity for this, is if you first check every node in your graph if it is a Cut Vertex and then simply in constant time checking if the edge you want to delete is a attached to one of those two.
Finding if a node in a graph is a Cut Vertex takes O(m+n) where m = # edges and n= # nodes.
Cheers

How to modify preorder tree traversal algorithm to handle nodes with multiple parents?

I've been searching for a while now and can't seem to find an alternative solution. I need the tree traversal algorithm in such a way that a node can have more than 1 parent, if it's possible (found a great article here: Storing Hierarchical Data in a Database). Are there any algorithms so that, starting from a root node, we can determine the sequence and dependencies of nodes (currently reading topological sorting)?
The structure you described isn't a tree, it's a directed graph. As it would be suitable for hierarchical drawing you might be tempted to think of it as a tree (which itself is an acyclic connected graph).
Typical traversal algorithms for graphs are depth-first and breadth-first. The graph implementation is only different as it records the nodes it has already visited in order to avoid visiting certain nodes multiple times. However, if your data structure guarantees that it's acyclic, you can use tree algorithms on your graph by simply treating "parents" as "children".
I made a simple sketch to illustrate what I mean (the perfect chance to try Google Docs' new drawing feature):
As you see, it's possible to treat any graph that has an acyclic directed form as a tree and apply tree algorithms on it. As soon as you can't guarantee this property you'll have to go for dedicated graph algorithms.
A tree is basically a directed unweighted graph, where each vertice has N or less edges, and no cycles can happen.
If your'e certain there are no cycles in your tree, you could just treat a parent as another child of the specified node, and preform a preorder traversal normally.
However, if cycles might happen, you need graph algorithms.
Specifically: Breadth first search.
Just checking for maybe a simple case: can the two parents have different parents?
If no you could turn them into single node (conceptually) and have a tree again.
Otherwise you will have to split the child node and duplicate a branch for the other parent.
(This can of course lead to inconsistency and/or inneficient algorithms later, depending if you will need to maintain the data structure).
The above options hold if you insist on having the tree structure, which by definition can have only one parent.
So maybe you need to step back and explain what are you trying to accomplish and why it must be a tree structure if nodes can have two parents.
You aren't describing a tree here. You can NOT call your graph a tree.
A tree is an undirected graph without cycles. Parent/child relationship is NOT an interpretation of directions drawn on the edges. They are the result of naming one vertex the root.
We name a vertex "parent" to current, because it's the next one to the path to root. All other vertexes adjacent to current one are "children".
You can't just lay out an arbitrary graph in such a way that "parents" are "above" or "point to vertex", and children are "below" or "vertex points to them". A tree is a tree because a root is picked. What you depict in your question is not a tree. And tree traversal algorithms are NOT applicable to traversing arbitrary graphs.
There are several graph traversal algorithms, such as breadth-first search or depth-first search (check side notes in those pages for more). Use them instead of trying to tie your full-featured graph into your knowledge about trees.

Resources