Commit 9541f220 authored by Temujin's avatar Temujin

degree and relationship method added

parent 46c29998
...@@ -4,9 +4,6 @@ ...@@ -4,9 +4,6 @@
TODO: TODO:
Find a way to get isolated nodes. Find a way to get isolated nodes.
current structure:
bin tree, nodes in a dict
Problems to consider -- Problems to consider --
What to do if not rooted? What to do if not rooted?
...@@ -25,6 +22,16 @@ Is there only one root? ...@@ -25,6 +22,16 @@ Is there only one root?
Total nodes of the tree? Total nodes of the tree?
11 generations = 2^11 - 1 11 generations = 2^11 - 1
Tree setup procedure:
1 get all the nodes and edges, check if they're valid.
2 Make sure there's only one root.
3 Find and set the root
4 Set the generations
5 run precompute method
6 done
""" """
...@@ -147,23 +154,48 @@ class FamilyTree: ...@@ -147,23 +154,48 @@ class FamilyTree:
visited.append(rc.get_name()) visited.append(rc.get_name())
self.dfs(rc.get_name(), *funcs) self.dfs(rc.get_name(), *funcs)
def slow_find_lca(self, a, b): def lca(self, name1, name2):
"""Find the lowest common ancestor of two nodes.
TODO: when one is the ancestor of the other
"""
return self.slow_lca(name1, name2)
def slow_lca(self, name1, name2):
"""Find the lca slowly. """Find the lca slowly.
two pointer method Two pointer method.
""" """
return p1 = self.family_tree[name1]
p2 = self.family_tree[name2]
def lca(self, a, b): assert (p1 is not None)
assert (p2 is not None)
# Make sure they have the same generation
while p1.get_generation() < p2.get_generation():
p2 = p2.get_parent()
while p2.get_generation() < p1.get_generation():
p1 = p1.get_parent()
# Keep moving up at the same time until they're equal
while p1 is not p2:
p1 = p1.get_parent()
p2 = p2.get_parent()
return p1.get_name()
def fast_lca(self, a, b):
"""Find the lca fast. """Find the lca fast.
Reduction to range min. query Reduction to range min. query
""" """
return return
def degree(self, a, b): def degree(self, p1, p2):
"""Find the degree between two cousins.""" """Find the degree between two cousins."""
pass l_ancestor = self.lca(p1, p2)
return min([self.lca(p1, l_ancestor), self.lca(p2, l_ancestor)])
def relationship(self, p1, p2): def relationship(self, p1, p2):
"""Determine the relationship between two distinct people in the tree. """Determine the relationship between two distinct people in the tree.
...@@ -261,19 +293,29 @@ class Person: ...@@ -261,19 +293,29 @@ class Person:
def main(): def main():
"""For testing.""" r"""For testing.
A
/ \
B C
/ \
D E
"""
ftree = FamilyTree() ftree = FamilyTree()
A = Person("A", 69, True) A = Person("A", 69, True)
B = Person("B", 69, True) B = Person("B", 69, True)
C = Person("C", 69, True) C = Person("C", 69, True)
D = Person("D", 69, True) D = Person("D", 69, True)
E = Person("E", 666, False)
ftree.insert_person(A) ftree.insert_person(A)
ftree.insert_person(B) ftree.insert_person(B)
ftree.insert_person(C) ftree.insert_person(C)
ftree.insert_person(D) ftree.insert_person(D)
ftree.insert_person(E)
B.set_parent(A) B.set_parent(A)
C.set_parent(A) C.set_parent(A)
D.set_parent(B) D.set_parent(B)
E.set_parent(B)
ftree.find_root() ftree.find_root()
ancestors = ftree.get_ancestors(D.get_name()) ancestors = ftree.get_ancestors(D.get_name())
descendants = ftree.get_descendants(A.get_name()) descendants = ftree.get_descendants(A.get_name())
...@@ -283,6 +325,8 @@ def main(): ...@@ -283,6 +325,8 @@ def main():
ftree.precompute() ftree.precompute()
for key, node in ftree.family_tree.items(): for key, node in ftree.family_tree.items():
print("{}: {}".format(node, node.get_generation())) print("{}: {}".format(node, node.get_generation()))
print("The lca of {} and {} is {}".format(D, C, ftree.lca("D", "C")))
print("The lca of {} and {} is {}".format(B, D, ftree.lca("B", "D")))
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment