def _class_balanced_indices(
    data: ClassificationDataset,
    num_experiences: int,
    shuffle: bool = True,
    seed: Optional[int] = None,
) -> List[List[int]]:
    """class-balanced indices.

    Internal helper for `new_instances_benchmark`.

    :param data: the `AvalancheDataset` to split
    :param num_experiences: length of the stream
    :param shuffle: -
    :param seed: -
    """
    if seed is not None:
        torch.random.manual_seed(seed)

    # Validate function arguments
    if num_experiences < 1:
        raise ValueError(
            "Invalid number of experiences (n_experiences "
            "parameter): must be greater than 0"
        )

    # experience -> idxs assignment
    exps_idxs: List[List[int]] = [[] for _ in range(num_experiences)]
    # TODO: fix pycharm type hints
    for class_id, class_idxs in data.targets.val_to_idx.items():
        # INVARIANT: class_idxs keeps only indices that are not assigned yet.
        # Whenever we add idxs to an experience, we remove them from class_idxs

        if shuffle:  # shuffle each class
            perm = torch.randperm(len(class_idxs))
            class_idxs = torch.as_tensor(class_idxs)[perm].tolist()

        # distribute equally each class to experiences
        npats = len(class_idxs) // num_experiences
        for eid in range(num_experiences):
            exps_idxs[eid].extend(class_idxs[:npats])
            class_idxs = class_idxs[npats:]

        # distribute remainder if not divisible by num_experiences
        if len(class_idxs) > 0:
            if shuffle:
                exps_remaining: Iterable[int] = torch.randperm(
                    num_experiences
                ).tolist()[: len(class_idxs)]
            else:
                exps_remaining = range(len(class_idxs))
            for eid in exps_remaining:
                exps_idxs[eid].append(class_idxs[0])
                class_idxs = class_idxs[1:]

    # sort to keep original order instead of class-order
    for eid in range(len(exps_idxs)):
        exps_idxs[eid].sort()
    return exps_idxs
class-balanced indices.

    Internal helper for `new_instances_benchmark`.

    :param data: the `AvalancheDataset` to split
    :param num_experiences: length of the stream
    :param shuffle: -
    :param seed: -
    
avalanche/benchmarks/scenarios/supervised.py