diff --git a/src/algorithms.hpp b/src/algorithms.hpp
index 797f471bc51afac58f650d728ea57cfec445e4ab..39df831c26a8c8a0321128a19396ea6a5d092b30 100644
--- a/src/algorithms.hpp
+++ b/src/algorithms.hpp
@@ -112,29 +112,86 @@ namespace algorithms{
     }
 
     template<typename C>
-    bool is_contiguously_numbered(const C &parent_list)
+    bool has_contiguous_segments(const C &parent_index)
     {
         static_assert(
             std::is_integral<typename C::value_type>::value,
             "integral type required"
         );
 
-        std::vector<bool> is_leaf(parent_list.size(), false);
+        if (!is_minimal_degree(parent_index)) {
+            return false;
+        }
+
+        std::vector<bool> is_leaf(parent_index.size(), false);
 
-        auto ret = true;
-        for (std::size_t i = 1; i < parent_list.size(); ++i) {
-            if (is_leaf[parent_list[i]]) {
-                ret = false;
-                break;
+        for (std::size_t i = 1; i < parent_index.size(); ++i) {
+            auto p = parent_index[i];
+            if (is_leaf[p]) {
+                return false;
             }
 
-            if (parent_list[i] != i-1) {
+            if (p != i-1) {
                 // we have a branch and i-1 is a leaf node
                 is_leaf[i-1] = true;
             }
         }
 
-        return ret;
+        return true;
+    }
+
+    template<typename C>
+    std::vector<typename C::value_type> child_count(const C &parent_index)
+    {
+        static_assert(
+            std::is_integral<typename C::value_type>::value,
+            "integral type required"
+        );
+
+        std::vector<typename C::value_type> count(parent_index.size(), 0);
+        for (std::size_t i = 1; i < parent_index.size(); ++i) {
+            ++count[parent_index[i]];
+        }
+
+        return count;
+    }
+
+    template<typename C, bool CheckStrict = true>
+    std::vector<typename C::value_type> branches(const C &parent_index)
+    {
+        static_assert(
+            std::is_integral<typename C::value_type>::value,
+            "integral type required"
+        );
+
+        if (CheckStrict && !has_contiguous_segments(parent_index)) {
+            throw std::invalid_argument(
+                "parent_index has not contiguous branch numbering"
+            );
+        }
+
+        auto num_child = child_count(parent_index);
+        std::vector<typename C::value_type> branch_index(
+            parent_index.size(), 0
+        );
+
+        std::size_t num_branches = (num_child[0] == 1) ? 1 : 0;
+        for (std::size_t i = 1; i < parent_index.size(); ++i) {
+            auto p = parent_index[i];
+            if (num_child[p] > 1) {
+                ++num_branches;
+            }
+
+            branch_index[i] = num_branches;
+        }
+
+        return branch_index;
+    }
+
+    template<typename C>
+    std::vector<typename C::value_type> branches_fast(const C &parent_index)
+    {
+        return branches<C, false>(parent_index);
     }
 
 } // namespace algorithms
diff --git a/tests/test_algorithms.cpp b/tests/test_algorithms.cpp
index 91e43c8b86717ce536110caa7394b9b8b6d74d0d..05da8c0c41f8aeb39c29f35f65c814542cd1355b 100644
--- a/tests/test_algorithms.cpp
+++ b/tests/test_algorithms.cpp
@@ -170,7 +170,7 @@ TEST(algorithms, is_positive)
     );
 }
 
-TEST(algorithms, is_contiguously_numbered)
+TEST(algorithms, has_contiguous_segments)
 {
     //
     //       0
@@ -178,13 +178,13 @@ TEST(algorithms, is_contiguously_numbered)
     //       1
     //       |
     //       2
-    //      /|\
+    //      /|\.
     //     3 7 4
-    //    /     \
+    //    /     \.
     //   5       6
     //
     EXPECT_FALSE(
-        nest::mc::algorithms::is_contiguously_numbered(
+        nest::mc::algorithms::has_contiguous_segments(
             std::vector<int>{0, 0, 1, 2, 2, 3, 4, 2}
         )
     );
@@ -201,7 +201,7 @@ TEST(algorithms, is_contiguously_numbered)
     //   4       7
     //
     EXPECT_FALSE(
-        nest::mc::algorithms::is_contiguously_numbered(
+        nest::mc::algorithms::has_contiguous_segments(
             std::vector<int>{0, 0, 1, 2, 3, 2, 2, 5}
         )
     );
@@ -218,7 +218,7 @@ TEST(algorithms, is_contiguously_numbered)
     //   4       6
     //
     EXPECT_TRUE(
-        nest::mc::algorithms::is_contiguously_numbered(
+        nest::mc::algorithms::has_contiguous_segments(
             std::vector<int>{0, 0, 1, 2, 3, 2, 5, 2}
         )
     );
@@ -235,23 +235,130 @@ TEST(algorithms, is_contiguously_numbered)
     //   4       6
     //
     EXPECT_TRUE(
-        nest::mc::algorithms::is_contiguously_numbered(
+        nest::mc::algorithms::has_contiguous_segments(
             std::vector<int>{0, 0, 1, 2, 3, 2, 5, 1}
         )
     );
 
     // Soma-only list
     EXPECT_TRUE(
-        nest::mc::algorithms::is_contiguously_numbered(
+        nest::mc::algorithms::has_contiguous_segments(
             std::vector<int>{0}
         )
     );
 
     // Empty list
     EXPECT_TRUE(
-        nest::mc::algorithms::is_contiguously_numbered(
+        nest::mc::algorithms::has_contiguous_segments(
             std::vector<int>{}
         )
     );
+}
+
+TEST(algorithms, child_count)
+{
+    {
+        //
+        //        0
+        //       /|\
+        //      1 4 6
+        //     /  |  \
+        //    2   5   7
+        //   /         \
+        //  3           8
+        //             / \
+        //            9   11
+        //           /     \
+        //          10      12
+        //                   \
+        //                    13
+        //
+        std::vector<int> parent_index =
+            { 0, 0, 1, 2, 0, 4, 0, 6, 7, 8, 9, 8, 11, 12 };
+        std::vector<int> expected_child_count =
+            { 3, 1, 1, 0, 1, 0, 1, 1, 2, 1, 0, 1, 1, 0 };
+
+        // auto count = nest::mc::algorithms::child_count(parent_index);
+        EXPECT_EQ(expected_child_count,
+                  nest::mc::algorithms::child_count(parent_index));
+    }
+
+}
+
+TEST(algorithms, branches)
+{
+    using namespace nest::mc;
+
+    {
+        //
+        //        0
+        //       /|\
+        //      1 4 6
+        //     /  |  \
+        //    2   5   7
+        //   /         \
+        //  3           8
+        //             / \
+        //            9   11
+        //           /     \
+        //          10      12
+        //                   \
+        //                    13
+        //
+        std::vector<int> parent_index =
+            { 0, 0, 1, 2, 0, 4, 0, 6, 7, 8, 9, 8, 11, 12 };
+        std::vector<int> expected_branches =
+            { 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5 };
 
+        auto actual_branches = algorithms::branches_fast(parent_index);
+        EXPECT_EQ(expected_branches, actual_branches);
+    }
+
+    {
+        //
+        //    0
+        //    |
+        //    1
+        //    |
+        //    2
+        //    |
+        //    3
+        //
+        std::vector<int> parent_index =
+            { 0, 0, 1, 2 };
+        std::vector<int> expected_branches =
+            { 0, 1, 1, 1 };
+
+        auto actual_branches = algorithms::branches_fast(parent_index);
+        EXPECT_EQ(expected_branches, actual_branches);
+    }
+
+    {
+        //
+        //    0
+        //    |
+        //    1
+        //    |
+        //    2
+        //   / \
+        //  3   4
+        //       \
+        //        5
+        //
+        std::vector<int> parent_index =
+            { 0, 0, 1, 2, 2, 4 };
+        std::vector<int> expected_branches =
+            { 0, 1, 1, 2, 3, 3 };
+
+        auto actual_branches = algorithms::branches_fast(parent_index);
+        EXPECT_EQ(expected_branches, actual_branches);
+    }
+
+    {
+        std::vector<int> parent_index = { 0 };
+        std::vector<int> expected_branches = { 0 };
+
+        auto actual_branches = algorithms::branches_fast(parent_index);
+        EXPECT_EQ(expected_branches, actual_branches);
+    }
 }