This is the main method and it will compute the number of duplications and loss for a given gene node g where G is the child set of g and max_partition_random is the maximum number of times that the algorithm will try to find a partition. 0. ComputeMutation(G as a set of childnodes, max_partition_random as integer) 1. P = ComputePartition(G, max_partition_random) 2. let duplications = size(P) - 1 3. let loss = ComputeLossBinary(BuildGeneTree(P)) 4. return (duplications, loss) The Proorder method has to be called using the root of the species tree as the argument before any other of the methods below can be called. 0. Preorder(s as the root of the species tree) 1. PreorderRecursive(s, 1, 1) 0. PreorderRecursive(s as a species node, next_number as integer, depth as integer) 1. let s.in = next_number 2. let s.depth = depth 3. next_number = next_number + 1 4. for every child s_i of s 5. next_number = PreorderRecursive(s_i, next_number, depth + 1) 6. let s.out = next_number 7. return next_number 0. Below(s_1 as species node, s_2 as species node) 1. return s_2.in < s_1.in and s_1.in < s_2.out 0. SameRootPath(s_1 as species, s_2 as species) 1. return Below(s_1, s_2) or Below(s_2, s_1) or s_1 = s_2 0. Lca(s_1 as species node, s_2 as species node) 1. if s_2.depth < s_1.depth then 2. let s = s_1 3. s_1 = s_2 4. s_2 = s 5. while not SameRootPath(s_1, s_2) do 6. s_1 = parent(s_1) 7. return s_1 For the methods below the result will be saved for later use. Since the methods are used many times this will speed up the algorithm. For more information see the definition of SL in section 4.3.3. 0. SL(g as a gene node) 1. if g.SL has been set then 2. return g.SL 3. let g.SL be an empty set 4. for every s_i in M(g) 5. add all in the set leaves(s_i) to g.SL where leaves(s_i) are the leaves of the rooted subtree where s_i is the root For more information see the definition of M in section 4.3.3. 0. M(g as a gene node) 1. if g.M has been set then 2. return g.M 3. let g.M be an empty set 4. if m(g) has children then 5. if m(g) has more then two children then 6. for every child g_i under gene node g 7. for every species node s_i in M(g_i) 8. let s = s_i 9. while parent(s) != m(g) do 10. s = parent(s) 11. add s to g.M 12. else 13. add the two children of m(g) to g.M 14. else 15. add m(g) to g.M 16. return g.M For more information see the definition of m in section 4.1.1. 0. m(g as gene node) 1. if g.m has been set then 2. return g.m 3. if g has no children then 4. set g.m which is already known or can be found in constant time 5. return g.m 6. let s = m(children(g)[0]) 7. for i = 1 to size(children(g)) - 1 8. s = Lca(s, children(g)[i]) 9. g.m = s 10. return g.m