def dda_ns(f_scores: np.ndarray, **kwargs) -> List[List[int]]:
    """
    dda_ns runs the DDA-NS algorithm.

    Parameters
    ----------
    f_scores : np.ndarray
        an N x M matrix of N (population size) objective function values for M objectives

    Returns
    -------
    List[List[int]]
        A list of members of each Pareto front. The index in the outer most list corresponds to the level in the Pareto front
        while the value in the inner-most list is the id of the member of the population belonging to that front.
    """
    d_mx = construct_domination_matrix(f_scores)
    max_d = np.empty((f_scores.shape[0],), dtype=np.int32)

    fronts = []
    count = 0
    while count < f_scores.shape[0]:
        # Max(D) is the row vector containing the maximum elements from each column of D
        np.max(d_mx, out=max_d, axis=0)
        front = [i for i, m_d in enumerate(max_d) if 0 <= m_d < f_scores.shape[-1]]
        count += len(front)
        d_mx[front] = -1
        d_mx[:, front] = -1
        fronts.append(front)

    return fronts

    dda_ns runs the DDA-NS algorithm.

    Parameters
    ----------
    f_scores : np.ndarray
        an N x M matrix of N (population size) objective function values for M objectives

    Returns
    -------
    List[List[int]]
        A list of members of each Pareto front. The index in the outer most list corresponds to the level in the Pareto front
        while the value in the inner-most list is the id of the member of the population belonging to that front.
    
pymoo/util/nds/dominance_degree_non_dominated_sort.py