class_docstr: A GSGP class, inherited from GP.
  
  This is the designed class to define GSGP-related
  variables and methods.
  
  References:
      A. Moraglio, K. Krawiec, and C. G. Johnson.
      Geometric semantic genetic programming.
      Lecture Notes in Computer Science (2012).
  
      G. H. de Rosa, J. P. Papa, and L. P. Papa.
      Feature selection using geometric semantic genetic programming.
      Proceedings of the Genetic and Evolutionary Computation Conference Companion (2017).
class_docstr_tok: ["A","GSGP","class",",","inherited","from","GP",".","This","is","the","designed","class","to","define","GSGP-related","variables","and","methods",".","References",":","A.","Moraglio",",","K.","Krawiec",",","and","C.","G.","Johnson",".","Geometric","semantic","genetic","programming",".","Lecture","Notes","in","Computer","Science","(","2012",")",".","G.","H.","de","Rosa",",","J.","P.","Papa",",","and","L.","P.","Papa",".","Feature","selection","using","geometric","semantic","genetic","programming",".","Proceedings","of","the","Genetic","and","Evolutionary","Computation","Conference","Companion","(","2017",")","."]
docstr: Actually performs the crossover over a father and mother nodes.
  
  Args:
      father: A father's node to be crossed.
      mother: A mother's node to be crossed.
      n_variables: Number of variables.
      max_father: Maximum of nodes from father to be used.
      max_mother: Maximum of nodes from mother to be used.
  
  Returns:
      (Node): Single offspring based on the crossover operator.
docstr_tok: ["Actually","performs","the","crossover","over","a","father","and","mother","nodes",".","Args",":","father",":","A","father","'s","node","to","be","crossed",".","mother",":","A","mother","'s","node","to","be","crossed",".","n_variables",":","Number","of","variables",".","max_father",":","Maximum","of","nodes","from","father","to","be","used",".","max_mother",":","Maximum","of","nodes","from","mother","to","be","used",".","Returns",":","(","Node",")",":","Single","offspring","based","on","the","crossover","operator","."]
code: def _cross(
      self,
      father: Node,
      mother: Node,
      n_variables: int,
      max_father: int,
      max_mother: int,
  ) -> Node:
      """Actually performs the crossover over a father and mother nodes.
  
      Args:
          father: A father's node to be crossed.
          mother: A mother's node to be crossed.
          n_variables: Number of variables.
          max_father: Maximum of nodes from father to be used.
          max_mother: Maximum of nodes from mother to be used.
  
      Returns:
          (Node): Single offspring based on the crossover operator.
  
      """
  
      father_offspring = copy.deepcopy(father)
      father_point = int(
          r.generate_uniform_random_number(2, max_father)
      )
      sub_father, _ = father_offspring.find_node(father_point)
  
      mother_offspring = copy.deepcopy(mother)
      mother_point = int(
          r.generate_uniform_random_number(2, max_mother)
      )
      sub_mother, _ = mother_offspring.find_node(mother_point)
  
      if sub_father and sub_mother:
          position = r.generate_uniform_random_number(size=n_variables)
          position_hash = sha1(
              repr(position).encode("ascii")
          ).hexdigest()[:4]
  
          terminal = Node(position_hash, "TERMINAL", position)
          not_terminal = Node(
              "~" + position_hash, "TERMINAL", 1 - terminal.value
          )
  
          root = Node("SUM", "FUNCTION")
          left_node = Node("MUL", "FUNCTION")
          right_node = Node("MUL", "FUNCTION")
  
          root.parent = None
          root.left = left_node
          root.right = right_node
  
          sub_father.parent = left_node
          sub_mother.parent = right_node
          sub_mother.flag = False
  
          left_node.parent = root
          left_node.left = sub_father
          left_node.right = terminal
  
          not_terminal.parent = right_node
          terminal.parent = left_node
          terminal.flag = False
  
          right_node.parent = root
          right_node.left = not_terminal
          right_node.right = sub_mother
          right_node.flag = False
  
          return root
  
      return father_offspring
  
file_path: opytimizer/opytimizer/optimizers/evolutionary/gsgp.py
imports: import copy
  from hashlib import sha1
  from typing import Any, Dict, Optional
  import numpy
  import opytimizer.math.general
  import opytimizer.math.random
  from opytimizer.core.node import Node
  from opytimizer.optimizers.evolutionary.gp import GP
  from opytimizer.spaces.tree import TreeSpace
  from opytimizer.utils import logging
label_desc: Use image node_id 5 for calling the GSGP obj's underlying member method code with example usage: obj._cross(father, mother, n_variables, max_father, max_mother) and returns: father_offspring, root