code: def niching(individuals, k, niches, distances, niche_counts):
      selected = []
      available = numpy.ones(len(individuals), dtype=bool)
      while len(selected) < k:
          # Maximum number of individuals (niches) to select in that round
          n = k - len(selected)
  
          # Find the available niches and the minimum niche count in them
          available_niches = numpy.zeros(len(niche_counts), dtype=bool)
          available_niches[numpy.unique(niches[available])] = True
          min_count = numpy.min(niche_counts[available_niches])
  
          # Select at most n niches with the minimum count
          selected_niches = numpy.flatnonzero(
              numpy.logical_and(
                  available_niches, niche_counts == min_count
              )
          )
          numpy.random.shuffle(selected_niches)
          selected_niches = selected_niches[:n]
  
          for niche in selected_niches:
              # Select from available individuals in niche
              niche_individuals = numpy.flatnonzero(
                  numpy.logical_and(niches == niche, available)
              )
              numpy.random.shuffle(niche_individuals)
  
              # If no individual in that niche, select the closest to reference
              # Else select randomly
              if niche_counts[niche] == 0:
                  sel_index = niche_individuals[
                      numpy.argmin(distances[niche_individuals])
                  ]
              else:
                  sel_index = niche_individuals[0]
  
              # Update availability, counts and selection
              available[sel_index] = False
              niche_counts[niche] += 1
              selected.append(individuals[sel_index])
  
      return selected
  
imports: import bisect
  from collections import defaultdict, namedtuple
  from itertools import chain
  import math
  from operator import attrgetter, itemgetter
  import random
  import numpy
label_desc: Use image node_id 19 for calling a global function with example usage: niching(individuals, k, niches, distances, niche_counts) and returns: selected