Perform the point mutation operation on the program. Point mutation selects random nodes from the embedded program to be replaced. Terminals are replaced by other terminals and functions are replaced by other functions that require the same number of arguments as
(self, random_state)
| 705 | return self.program[:start] + hoist + self.program[end:], removed |
| 706 | |
| 707 | def point_mutation(self, random_state): |
| 708 | """Perform the point mutation operation on the program. |
| 709 | |
| 710 | Point mutation selects random nodes from the embedded program to be |
| 711 | replaced. Terminals are replaced by other terminals and functions are |
| 712 | replaced by other functions that require the same number of arguments |
| 713 | as the original node. The resulting tree forms an offspring. |
| 714 | |
| 715 | Parameters |
| 716 | ---------- |
| 717 | random_state : RandomState instance |
| 718 | The random number generator. |
| 719 | |
| 720 | Returns |
| 721 | ------- |
| 722 | program : list |
| 723 | The flattened tree representation of the program. |
| 724 | |
| 725 | """ |
| 726 | program = self.program.copy() |
| 727 | |
| 728 | # Get the nodes to modify |
| 729 | mutate = np.where(random_state.uniform(size=len(program)) < |
| 730 | self.p_point_replace)[0] |
| 731 | |
| 732 | for node in mutate: |
| 733 | if isinstance(program[node], _Function): |
| 734 | |
| 735 | if not (program[node].para is None): |
| 736 | para = program[node].para.copy() |
| 737 | para = [str(p) for p in para] |
| 738 | para = ''.join(para) |
| 739 | else: |
| 740 | para = None |
| 741 | # Find a valid replacement with same arity |
| 742 | replacement = len(self.paras[para]) |
| 743 | # replacement = len(self.arities[arity]) |
| 744 | replacement = random_state.randint(replacement) |
| 745 | replacement = list(self.paras[para])[replacement] |
| 746 | program[node] = replacement |
| 747 | elif isinstance(program[node], int): |
| 748 | # We've got a terminal, add variable |
| 749 | #if self.const_range is not None: |
| 750 | terminal = random_state.randint(self.n_features) |
| 751 | program[node] = terminal |
| 752 | else: |
| 753 | #terminal = random_state.randint(self.n_features) |
| 754 | #if terminal == self.n_features: |
| 755 | terminal = float(random_state.randint(*self.const_range)) |
| 756 | if self.const_range is None: |
| 757 | # We should never get here |
| 758 | raise ValueError('A constant was produced with ' |
| 759 | 'const_range=None.') |
| 760 | program[node] = terminal |
| 761 | |
| 762 | return program, list(mutate) |
| 763 | |
| 764 | depth_ = property(_depth) |