class_docstr: Customed Graph class.
docstr: Mutation for a graph
docstr_tok: ["Mutation","for","a","graph"]
code: def mutation(self, only_add=False):
      """
      Mutation for a graph
      """
      types = []
      if self.layer_num() < self.max_layer_num:
          types.append(0)
          types.append(1)
      if self.layer_num() > 5 and only_add is False:
          types.append(2)
          types.append(3)
      # 0 : add a layer , delete a edge
      # 1 : add a layer , change a edge
      # 2 : delete a layer, delete a edge
      # 3 : delete a layer, change a edge
      graph_type = random.choice(types)
      layer_type = random.choice(
          [
              LayerType.attention.value,
              LayerType.self_attention.value,
              LayerType.rnn.value,
          ]
      )
      layers = copy.deepcopy(self.layers)
      cnt_try = 0
      while True:
          layers_in = []
          layers_out = []
          layers_del = []
          for i, layer in enumerate(layers):
              if layer.is_delete is False:
                  if layer.graph_type != LayerType.output.value:
                      layers_in.append(i)
                  if layer.graph_type != LayerType.input.value:
                      layers_out.append(i)
                  if (
                      layer.graph_type != LayerType.output.value
                      and layer.graph_type != LayerType.input.value
                  ):
                      layers_del.append(i)
          if graph_type <= 1:
              new_id = len(layers)
              out = random.choice(layers_out)
              inputs = []
              output = [out]
              pos = random.randint(0, len(layers[out].input) - 1)
              last_in = layers[out].input[pos]
              layers[out].input[pos] = new_id
              if graph_type == 0:
                  layers[last_in].output.remove(out)
              if graph_type == 1:
                  layers[last_in].output.remove(out)
                  layers[last_in].output.append(new_id)
                  inputs = [last_in]
              lay = Layer(
                  graph_type=layer_type, inputs=inputs, output=output
              )
              while len(inputs) < lay.input_size:
                  layer1 = random.choice(layers_in)
                  inputs.append(layer1)
                  layers[layer1].output.append(new_id)
              lay.input = inputs
              layers.append(lay)
          else:
              layer1 = random.choice(layers_del)
              for layer2 in layers[layer1].output:
                  layers[layer2].input.remove(layer1)
                  if graph_type == 2:
                      random_in = random.choice(layers_in)
                  else:
                      random_in = random.choice(layers[layer1].input)
                  layers[layer2].input.append(random_in)
                  layers[random_in].output.append(layer2)
              for layer2 in layers[layer1].input:
                  layers[layer2].output.remove(layer1)
              layers[layer1].is_delete = True
  
          if self.is_legal(layers):
              self.layers = layers
              break
          else:
              layers = copy.deepcopy(self.layers)
              cnt_try += 1
  
imports: import copy
  import json
  import random
  from enum import Enum, unique
label_desc: Use image node_id 5 for calling the Graph obj's underlying member method code with example usage: obj.mutation(only_add) without return types