def tree_based_non_dominated_sort(F):
    """
    Tree-based efficient non-dominated sorting (T-ENS).
    This algorithm is very efficient in many-objective optimization problems (MaOPs).
    Parameters
    ----------
    F: np.array
        objective values for each individual.
    Returns
    -------
        indices of the individuals in each front.
    References
    ----------
    X. Zhang, Y. Tian, R. Cheng, and Y. Jin,
    A decision variable clustering based evolutionary algorithm for large-scale many-objective optimization,
    IEEE Transactions on Evolutionary Computation, 2018, 22(1): 97-112.
    """

    N, M = F.shape
    # sort the rows in F
    indices = np.lexsort(F.T[::-1])
    F = F[indices]

    obj_seq = np.argsort(F[:, :0:-1], axis=1) + 1

    k = 0

    forest = []

    left = np.full(N, True)
    while np.any(left):
        forest.append(None)
        for p, flag in enumerate(left):
            if flag:
                update_tree(F, p, forest, k, left, obj_seq)
        k += 1

    # convert forest to fronts
    fronts = [[] for _ in range(k)]
    for k, tree in enumerate(forest):
        fronts[k].extend([indices[node.key] for node in tree.traversal()])
    return fronts

    Tree-based efficient non-dominated sorting (T-ENS).
    This algorithm is very efficient in many-objective optimization problems (MaOPs).
    Parameters
    ----------
    F: np.array
        objective values for each individual.
    Returns
    -------
        indices of the individuals in each front.
    References
    ----------
    X. Zhang, Y. Tian, R. Cheng, and Y. Jin,
    A decision variable clustering based evolutionary algorithm for large-scale many-objective optimization,
    IEEE Transactions on Evolutionary Computation, 2018, 22(1): 97-112.
    
pymoo/util/nds/tree_based_non_dominated_sort.py