docs: def random_reset_mutation(random, candidate, args):
      """Return the mutants produced by randomly choosing new values.
  
      This function performs random-reset mutation. It assumes that 
      candidate solutions are composed of discrete values. This function
      makes use of the bounder function as specified in the EC's 
      ``evolve`` method, and it assumes that the bounder contains
      an attribute called *values* (which is true for instances of
      ``DiscreteBounder``).
      
      The mutation moves through a candidate solution and, with rate
      equal to the *mutation_rate*, randomly chooses a value from the 
      set of allowed values to be used in that location. Note that this
      value may be the same as the original value.
  
      .. Arguments:
         random -- the random number generator object
         candidate -- the candidate solution
         args -- a dictionary of keyword arguments
  
      Optional keyword arguments in args:
      
      - *mutation_rate* -- the rate at which mutation is performed (default 0.1)
      
      The mutation rate is applied on an element by element basis.
      
      """
      bounder = args['_ec'].bounder
      try:
          values = bounder.values
      except AttributeError:
          values = None
      if values is not None:
          rate = args.setdefault('mutation_rate', 0.1)
          mutant = copy.copy(candidate)
          for i, m in enumerate(mutant):
              if random.random() < rate:
                  mutant[i] = random.choice(values)
          return mutant
      else:
          return candidate