def fgss_for_nets(
        pvalues: np.ndarray,
        a_max: float = 0.5,
        restarts: int = 10,
        image_to_node_init: bool = False,
        score_function: Callable[[np.ndarray, np.ndarray, np.ndarray], np.ndarray] = ScoringFunctions.get_score_bj_fast,
    ) -> tuple[float, np.ndarray, np.ndarray, float]:
        """
        Finds the highest scoring subset of records and attribute. Return the subsets, the score, and the alpha that
        maximizes the score iterates between images and nodes, each time performing NPSS efficient maximization.

        :param pvalues: pvalue ranges.
        :param a_max: alpha threshold
        :param restarts: number of iterative restarts
        :param image_to_node_init: intializes what direction to begin the search: image to node or vice-versa
        :param score_function: scoring function
        :return: (best_score, image_sub, node_sub, optimal_alpha)
        """
        best_score = -100000.0

        if len(pvalues) < restarts:
            restarts = len(pvalues)

        for r_indx in range(0, restarts):  # do random restarts to come close to global maximum
            image_to_node = image_to_node_init
            if r_indx == 0:
                if image_to_node:
                    # all 1's for number of rows
                    indices_of_seeds = np.arange(pvalues.shape[0])
                else:
                    # all 1's for number of cols
                    indices_of_seeds = np.arange(pvalues.shape[1])

                (
                    best_score_from_restart,
                    best_image_sub_from_restart,
                    best_node_sub_from_restart,
                    best_alpha_from_restart,
                ) = ScanningOps.single_restart(pvalues, a_max, indices_of_seeds, image_to_node, score_function)

                if best_score_from_restart > best_score:
                    best_score = best_score_from_restart
                    image_sub = best_image_sub_from_restart
                    node_sub = best_node_sub_from_restart
                    optimal_alpha = best_alpha_from_restart

                # Finished A Restart
            else:
                # New Restart
                # some some randomizing and only leave in a random number of rows of pvalues TODO
                prob = np.random.uniform(0, 1)
                if image_to_node:
                    indices_of_seeds = np.random.choice(
                        np.arange(pvalues.shape[0]),
                        int(pvalues.shape[0] * prob),
                        replace=False,
                    )
                else:
                    indices_of_seeds = np.random.choice(
                        np.arange(pvalues.shape[1]),
                        int(pvalues.shape[1] * prob),
                        replace=False,
                    )
                while indices_of_seeds.size == 0:
                    # eventually will make non zero
                    prob = np.random.uniform(0, 1)
                    if image_to_node:
                        indices_of_seeds = np.random.choice(
                            np.arange(pvalues.shape[0]),
                            int(pvalues.shape[0] * prob),
                            replace=False,
                        )
                    else:
                        indices_of_seeds = np.random.choice(
                            np.arange(pvalues.shape[1]),
                            int(pvalues.shape[1] * prob),
                            replace=False,
                        )

                indices_of_seeds.astype(int)
                # process a random subset of rows of pvalues array
                (
                    best_score_from_restart,
                    best_image_sub_from_restart,
                    best_node_sub_from_restart,
                    best_alpha_from_restart,
                ) = ScanningOps.single_restart(pvalues, a_max, indices_of_seeds, image_to_node, score_function)

                if best_score_from_restart > best_score:
                    best_score = best_score_from_restart
                    image_sub = best_image_sub_from_restart
                    node_sub = best_node_sub_from_restart
                    optimal_alpha = best_alpha_from_restart

                # Finished A Restart

        return best_score, image_sub, node_sub, optimal_alpha

        Finds the highest scoring subset of records and attribute. Return the subsets, the score, and the alpha that
        maximizes the score iterates between images and nodes, each time performing NPSS efficient maximization.

        :param pvalues: pvalue ranges.
        :param a_max: alpha threshold
        :param restarts: number of iterative restarts
        :param image_to_node_init: intializes what direction to begin the search: image to node or vice-versa
        :param score_function: scoring function
        :return: (best_score, image_sub, node_sub, optimal_alpha)
        
art/defences/detector/evasion/subsetscanning/scanner.py