code: def benchmark_operator_order(self, graph, solution, op_diff_round_digits):
          
          
          operators = {self.operator_exchange: 'exchange',
                       self.operator_relocate: 'relocate',
                       self.operator_oropt: 'oropt'}
                       
          for op in it.permutations(operators):
              solution = solution.clone()
              solution = op[0](graph, solution, op_diff_round_digits)
              solution = op[1](graph, solution, op_diff_round_digits)
              solution = op[2](graph, solution, op_diff_round_digits)
              logger.info("{0} {1} {2} => Length: {3}".format(
                  operators[op[0]],
                  operators[op[1]],
                  operators[op[2]],
                  solution.length()))
docs: performs all possible permutations of route improvement and prints graph length
          
          Args
          ----
          graph: :networkx:`NetworkX Graph Obj< >`
              A NetworkX graaph is used.
          solution: BaseSolution
              BaseSolution instance
          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 detailed description of the matter see http://floating-point-gui.de or
              https://docs.python.org/3.5/tutorial/floatingpoint.html)