1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use gp::*;
use rand::Rng;

/// The mutation mode in use. See `Mutation`.
#[derive(PartialEq, Clone, Copy, Debug)]
enum MutationMode {
    /// Corresponds to `Mutation::shrink`.
    Shrink,
    /// Corresponds to `Mutation::uniform`.
    Uniform,
    /// Corresponds to `Mutation::node_replacement`.
    NodeReplacement,
    /// Corresponds to `Mutation::ephemeral_one` and `Mutation::ephemeral_all`.
    Ephemeral(EphemeralMode),
    /// Corresponds to `Mutation::insert`.
    Insert,
}

/// Modes of ephemeral mutation. See `MutationMode::Ephemeral`.
#[derive(PartialEq, Clone, Copy, Debug)]
enum EphemeralMode {
    One,
    All,
}

/// Configures crossover (mating) on GP individuals.
#[derive(PartialEq, Clone, Copy, Debug)]
pub struct Mutation {
    mode: MutationMode,
}

impl Mutation {
    /// Perform mutation by randomly replacing a node with one of its children.
    #[doc(hidden)]
    pub fn shrink() -> Mutation {
        Mutation { mode: MutationMode::Shrink }
    }

    /// Perform mutation by randomly replacing a node with a new subtree.
    pub fn uniform() -> Mutation {
        Mutation { mode: MutationMode::Uniform }
    }

    /// Perform mutation by randomly replacing a node with a new subtree. The replacement
    /// node will have the same number of children.
    #[doc(hidden)]
    pub fn node_replacement() -> Mutation {
        Mutation { mode: MutationMode::NodeReplacement }
    }

    /// Randomly replace a constant value in the tree with another value.
    #[doc(hidden)]
    pub fn ephemeral_one() -> Mutation {
        Mutation { mode: MutationMode::Ephemeral(EphemeralMode::One) }
    }

    /// Randomly replace all constant values in the tree.
    #[doc(hidden)]
    pub fn ephemeral_all() -> Mutation {
        Mutation { mode: MutationMode::Ephemeral(EphemeralMode::All) }
    }

    /// Insert a new node at a randomly chosen position. The existing node and its children
    /// will be a child of the new node.
    #[doc(hidden)]
    pub fn insert() -> Mutation {
        Mutation { mode: MutationMode::Insert }
    }

    /// Mutate an individual according to the configured mutation mode.
    pub fn mutate<T, R>(&self, indv: &mut Individual<T>, tg: &mut TreeGen<R>)
        where T: Tree,
              R: Rng
    {
        match self.mode {
            MutationMode::Shrink => self.mutate_shrink(indv, tg),
            MutationMode::Uniform => self.mutate_uniform(indv, tg),
            MutationMode::NodeReplacement => self.mutate_node_replacement(indv, tg),
            MutationMode::Ephemeral(EphemeralMode::One) => self.mutate_ephemeral_one(indv, tg),
            MutationMode::Ephemeral(EphemeralMode::All) => self.mutate_ephemeral_all(indv, tg),
            MutationMode::Insert => self.mutate_insert(indv, tg),
        }
    }

    fn mutate_shrink<T, R>(&self, _: &mut Individual<T>, _: &mut TreeGen<R>)
        where T: Tree,
              R: Rng
    {
        unimplemented!();
    }

    fn mutate_uniform<T, R>(&self, indv: &mut Individual<T>, tg: &mut TreeGen<R>)
        where T: Tree,
              R: Rng
    {
        let target_index = tg.gen_range(0, indv.nodes_count());
        indv.tree.map_while(|node, index, _| if index == target_index {
            *node = T::tree(tg).inner();
            false
        } else {
            true
        });
    }

    fn mutate_node_replacement<T, R>(&self, _: &mut Individual<T>, _: &mut TreeGen<R>)
        where T: Tree,
              R: Rng
    {
        unimplemented!();
    }

    fn mutate_ephemeral_one<T, R>(&self, _: &mut Individual<T>, _: &mut TreeGen<R>)
        where T: Tree,
              R: Rng
    {
        unimplemented!();
    }

    fn mutate_ephemeral_all<T, R>(&self, _: &mut Individual<T>, _: &mut TreeGen<R>)
        where T: Tree,
              R: Rng
    {
        unimplemented!();
    }

    fn mutate_insert<T, R>(&self, _: &mut Individual<T>, _: &mut TreeGen<R>)
        where T: Tree,
              R: Rng
    {
        unimplemented!();
    }
}