code: def operator_cross(self, graph, solution, op_diff_round_digits):
          # TODO: check docstring
          
  
          # shorter var names for loop
          dm = graph._matrix
          dn = graph._nodes
docs: applies Cross inter-route operator to solution
  
          Takes every node from every route and calculates savings when inserted
          into all possible positions in other routes. Insertion is done at
          position with max. saving and procedure starts over again with newly
          created graph as input. Stops when no improvement is found.
          
          Args
          ----
          graph: :networkx:`NetworkX Graph Obj< >`
              Descr
          solution: BaseSolution
              Descr
          op_diff_round_digits: float
              Precision (floating point digits) for rounding route length differences.
              
              *Details*: In some cases when an exchange is performed on two routes with one node each,
              the difference between the both solutions (before and after the exchange) is not zero.
              This is due to internal rounding errors of float type. So the loop won't break
              (alternating between these two solutions), we need an additional criterion to avoid
              this behaviour: A threshold to handle values very close to zero as if they were zero
              (for a more detaisled description of the matter see http://floating-point-gui.de or
              https://docs.python.org/3.5/tutorial/floatingpoint.html)
          
          Returns
          -------
          LocalSearchSolution
             A solution (LocalSearchSolution class)
  
          Todo
          ----
          * allow moves of a 2-node chain
          * Remove ugly nested loops, convert to more efficient matrix operations