code: def get_subtree(self, random_state, program=None):
          
          if program is None:
              program = self.program
          # Choice of crossover points follows Koza's (1992) widely used approach
          # of choosing functions 90% of the time and leaves 10% of the time.
          probs = np.array([0.9 if isinstance(node, _Function) else 0.1
                            for node in program])
          probs = np.cumsum(probs / probs.sum())
          start = np.searchsorted(probs, random_state.uniform())
  
          stack = 1
          end = start
          while stack > end - start:
              node = program[end]
              if isinstance(node, _Function):
                  stack += node.arity
              end += 1
  
          return start, end
docs: Get a random subtree from the program.
  
          Parameters
          ----------
          random_state : RandomState instance
              The random number generator.
  
          program : list, optional (default=None)
              The flattened tree representation of the program. If None, the
              embedded tree in the object will be used.
  
          Returns
          -------
          start, end : tuple of two ints
              The indices of the start and end of the random subtree.