code: def selNSGA3(
      individuals,
      k,
      ref_points,
      nd="log",
      best_point=None,
      worst_point=None,
      extreme_points=None,
      return_memory=False,
  ):
      """Implementation of NSGA-III selection as presented in [Deb2014]_.
  
      This implementation is partly based on `lmarti/nsgaiii
      <https://github.com/lmarti/nsgaiii>`_. It departs slightly from the
      original implementation in that it does not use memory to keep track
      of ideal and extreme points. This choice has been made to fit the
      functional api of DEAP. For a version of NSGA-III see
      :class:`~deap.tools.selNSGA3WithMemory`.
  
      :param individuals: A list of individuals to select from.
      :param k: The number of individuals to select.
      :param ref_points: Reference points to use for niching.
      :param nd: Specify the non-dominated algorithm to use: 'standard' or 'log'.
      :param best_point: Best point found at previous generation. If not provided
          find the best point only from current individuals.
      :param worst_point: Worst point found at previous generation. If not provided
          find the worst point only from current individuals.
      :param extreme_points: Extreme points found at previous generation. If not provided
          find the extreme points only from current individuals.
      :param return_memory: If :data:`True`, return the best, worst and extreme points
          in addition to the chosen individuals.
      :returns: A list of selected individuals.
      :returns: If `return_memory` is :data:`True`, a namedtuple with the
          `best_point`, `worst_point`, and `extreme_points`.
  
  
      You can generate the reference points using the :func:`uniform_reference_points`
      function::
  
          >>> ref_points = tools.uniform_reference_points(nobj=3, p=12)   # doctest: +SKIP
          >>> selected = selNSGA3(population, k, ref_points)              # doctest: +SKIP
  
      .. [Deb2014] Deb, K., & Jain, H. (2014). An Evolutionary Many-Objective Optimization
          Algorithm Using Reference-Point-Based Nondominated Sorting Approach,
          Part I: Solving Problems With Box Constraints. IEEE Transactions on
          Evolutionary Computation, 18(4), 577-601. doi:10.1109/TEVC.2013.2281535.
      """
      if nd == "standard":
          pareto_fronts = sortNondominated(individuals, k)
      elif nd == "log":
          pareto_fronts = sortLogNondominated(individuals, k)
      else:
          raise Exception(
              "selNSGA3: The choice of non-dominated sorting "
              "method '{0}' is invalid.".format(nd)
          )
  
      # Extract fitnesses as a numpy array in the nd-sort order
      # Use wvalues * -1 to tackle always as a minimization problem
      fitnesses = numpy.array(
          [ind.fitness.wvalues for f in pareto_fronts for ind in f]
      )
      fitnesses *= -1
  
      # Get best and worst point of population, contrary to pymoo
      # we don't use memory
      if best_point is not None and worst_point is not None:
          best_point = numpy.min(
              numpy.concatenate((fitnesses, best_point), axis=0), axis=0
          )
          worst_point = numpy.max(
              numpy.concatenate((fitnesses, worst_point), axis=0),
              axis=0,
          )
      else:
          best_point = numpy.min(fitnesses, axis=0)
          worst_point = numpy.max(fitnesses, axis=0)
  
      extreme_points = find_extreme_points(
          fitnesses, best_point, extreme_points
      )
      front_worst = numpy.max(
          fitnesses[: sum(len(f) for f in pareto_fronts), :], axis=0
      )
      intercepts = find_intercepts(
          extreme_points, best_point, worst_point, front_worst
      )
      niches, dist = associate_to_niche(
          fitnesses, ref_points, best_point, intercepts
      )
  
      # Get counts per niche for individuals in all front but the last
      niche_counts = numpy.zeros(len(ref_points), dtype=numpy.int64)
      index, counts = numpy.unique(
          niches[: -len(pareto_fronts[-1])], return_counts=True
      )
      niche_counts[index] = counts
  
      # Choose individuals from all fronts but the last
      chosen = list(chain(*pareto_fronts[:-1]))
  
      # Use niching to select the remaining individuals
      sel_count = len(chosen)
      n = k - sel_count
      selected = niching(
          pareto_fronts[-1],
          n,
          niches[sel_count:],
          dist[sel_count:],
          niche_counts,
      )
      chosen.extend(selected)
  
      if return_memory:
          return chosen, NSGA3Memory(
              best_point, worst_point, extreme_points
          )
      return chosen
  
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 15 for calling a global function with example usage: selNSGA3(individuals, k, ref_points, nd, best_point, worst_point, extreme_points, return_memory) and returns: chosen, chosen,  NSGA3Memory