I'm tasked with creating a family tree drawing application. I ported the code for n-ary tree drawing from http://billmill.org/pymag-trees/ and while it's fine for drawing a tree where every node has only one parent but i need a way to let nodes have two parents and also allow parents to have other spouses and children with those spouses. I can't find any algorithms for family trees that would also include spouses.
I'm programming this in objective-c and i need it to look like a top down tree and not a force directed graph or circular tree.
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'm new to data structures, and had a question on terminology. Is there a term for non-tree like graphs?
I realize that bidirectional/undirected graphs are inherently non-tree like. Is that the appropriate term? I'm asking because it seems that the tree is such a common subcategory of a graph that I figured there might be a term denoting all graphs that fall outside the subcategory.
P.s.: Please feel free to hack through any vernacular above. Would love tips on appropriate terminology in general concerning data structures.
I don't think there is a single universal term for a non-tree graph (except perhaps "non-tree graph" itself).
Trees are connected, acyclic, directed graphs, with some additional rules like each node (except the root) having exactly one parent. Some kinds of trees have other additional rules that are not common among other kinds of graphs (such as there being a significance to the order of a node's children). Depending on which of those limitations a non-tree graph violates, you might describe it differently.
A tree-like graph that is not fully connected can be described as a "forest". A forest has several root nodes, each anchoring a disjoint subtree.
If you have a graph with multiple root nodes, but their descendents overlap (so that a given child node may have more than one parent node), you have a "multitree". A human family tree may be a multitree if there there are no marriages between cousins or other relatives.
The next more general term is probably a "directed acyclic graph" or "DAG". A DAG is more general than a multitree because an ancestor node may be connected to a descendent node by more than one path. Human genealogical trees are more properly though of as DAGs, since sufficiently distant relatives are generally allowed to get married and have children (but nobody can be their own ancestor). There are many algorithms designed to work on DAGs, as forbidding cycles allows better performance for many useful applications (such as path finding).
More general still is a "directed graph" or "digraph", which relaxes the restrictions cycles. A common digraph data structure is an adjacency list (a list of arcs from one node to another).
I don't think there's any more general term beyond that, other than just "graph". If you have a specific application for a graph, there might be a specialized term for the kind of graph you will use (and perhaps algorithms or even library code to go along with it), but you'd need to ask about that specifically.
I have an undirected graph and from it, I redrew the same graph but in a tree-like structure (with levels). I know how the Breadth First Search (BFS) algorithm works, but I am not sure how to do the transitioning from graph --> tree.
Here, in this Wikipedia article, if you scroll down a tiny bit, you'll see the two pictures of German cities. Even after reading the pseduo code on there, I just don't understand how you get from the first picture to the second.
One standard way to get a BFS tree from a graph is to run BFS and, as you do so, keep a table mapping each node in the graph to its parent in the tree. You populate it as follows: the source node has no parent (it's the root, after all). Then, whenever you're processing a node u and explore one of its unexplored neighbors v, you set v's parent to be u. Try tracing this out on some small examples and you'll see that this implicitly builds up the tree, except with the edges going backwards (edges point from children up to parents rather than the other way around). You can then just reverse the edges to get back the BFS tree.
Hope this helps!
We all know what a tree is: on the first level of a tree we have a root, and from the root come branches that are trees as well. But how do I name the "opposite" structure: on the i-th level we have a set of "leaf" nodes, and those nodes form groups of 1+ nodes, and a group points to a "trunk" node on i+1th level. If you want a visual example, imagine raindrops flowing down a window and combining as they collide.
A lot of tree data structures are actually constructed from leaf to root, and can be stored to allow for going one or both directions.
I don't think it really has a special name as it's more a convention than a requirement for trees typically to go from root to leaf rather than the other way or both ways. Also there are a number of tree data structures that allow for going both ways.
Every tree is a DAG, a directed acyclic graph, and so is the data-structure that you describe. What you describe is also a multitree, a subset of DAGs. Possibly there is a more precise real subset of multitrees that describes your graph, but I am not aware of it. Hope this helps.
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.