def set_gene_subtree(self,
                         g_parent: Gene,
                         x_id,
                         trunk: dict,
                         subtree: dict,
                         depth=1):
        """ 部分木を接ぎ木する """
        # 左側の処理
        self.g_len += 1
        if self.g_len - 1 < x_id or self.g_len - 1 > x_id + len(subtree) - 1:
            g_id = g_parent.arg1_id
            g_child = copy.deepcopy(trunk[g_id])
        else:
            st_id = subtree[self.g_len - x_id - 1].g_id
            g_child = copy.deepcopy(subtree[st_id])

        g_child.g_id = self.g_len - 1
        g_parent.arg1_id = self.g_len - 1

        self.chrom_dict[g_child.g_id] = g_child

        if g_child.node_type == Gene.NODE_ARITHMETIC:
            self.set_gene_subtree(g_parent=g_child,
                                  x_id=x_id,
                                  trunk=trunk,
                                  subtree=subtree,
                                  depth=depth + 1)

        # 右側の処理
        self.g_len += 1
        if self.g_len - 1 < x_id or self.g_len - 1 > x_id + len(subtree) - 1:
            g_id = g_parent.arg2_id
            g_child = copy.deepcopy(trunk[g_id])
        else:
            st_id = subtree[self.g_len - x_id - 1].g_id
            g_child = copy.deepcopy(subtree[st_id])

        g_child.g_id = self.g_len - 1
        g_parent.arg2_id = self.g_len - 1

        self.chrom_dict[g_child.g_id] = g_child

        if g_child.node_type == Gene.NODE_ARITHMETIC:
            self.set_gene_subtree(g_parent=g_child,
                                  x_id=x_id,
                                  trunk=trunk,
                                  subtree=subtree,
                                  depth=depth + 1)

        # ルートの場合、chrom_dictのarg1, 2が未更新なのでここで更新
        if depth == 1:
            self.chrom_dict[0] = g_parent

        # DEBUG
        """
    def append_gene(self, g_parent: Gene, depth, is_mutant=False):
        """ 指定した遺伝子に再帰的に遺伝子を追加していく """
        """ g_anc: 追加対象に指定した遺伝子, d: 追加する階層の深さ """

        max_depth = GP.MAX_DEPTH if is_mutant is False else GP.MAX_MUTANT_DEPTH

        # 左側引数
        self.g_len += 1
        if depth < GP.MIN_DEPTH:
            # 最小深さ未満なら演算子
            g_child1 = Gene(g_id=self.g_len - 1,
                            node_type=Gene.NODE_ARITHMETIC)
        elif depth < max_depth:
            # 最大深さ未満ならランダムで演算子かオペランド
            g_child1 = Gene(g_id=self.g_len - 1)
        else:
            # 最大深度に到達していればオペランド
            g_child1 = Gene(g_id=self.g_len - 1, node_type=Gene.NODE_OPERAND)

        g_parent.arg1_id = g_child1.g_id
        self.chrom_dict[g_child1.g_id] = g_child1

        if g_child1.node_type == Gene.NODE_ARITHMETIC:
            # 演算子ノードなら再帰的にオペランドを追加する
            self.append_gene(g_parent=g_child1,
                             depth=depth + 1,
                             is_mutant=is_mutant)

        # 右側引数 左とやること同じ
        self.g_len += 1
        if depth < GP.MIN_DEPTH:
            # 最小深さ未満なら演算子
            g_child2 = Gene(g_id=self.g_len - 1,
                            node_type=Gene.NODE_ARITHMETIC)
        elif depth < max_depth:
            g_child2 = Gene(g_id=self.g_len - 1)
        else:
            g_child2 = Gene(g_id=self.g_len - 1, node_type=Gene.NODE_OPERAND)

        g_parent.arg2_id = g_child2.g_id
        self.chrom_dict[g_child2.g_id] = g_child2

        if g_child2.node_type == Gene.NODE_ARITHMETIC:
            self.append_gene(g_parent=g_child2,
                             depth=depth + 1,
                             is_mutant=is_mutant)

        return