diff --git a/src/propeller/variation.cljc b/src/propeller/variation.cljc index 1a077a9..05f5302 100644 --- a/src/propeller/variation.cljc +++ b/src/propeller/variation.cljc @@ -173,6 +173,18 @@ The function `new-individual` returns a new individual produced by selection and (+ (* 0.5 (metrics/multiset-distance p1 p2)) (math/abs (- (count p1) (count p2))))) +(defn fill-empty-genes + "A utility function for bmx-related genetic operators. Returns the provided + plushy with any empty genes (regions before/between/after instances of :gap) + filled with a new random instruction." + [plushy instructions] + (flatten (interpose :gap + (mapv (fn [gene] + (if (empty? gene) + (utils/random-instruction instructions) + gene)) + (utils/extract-genes plushy))))) + (defn bmx "Crosses over two plushies using best match crossover (bmx)." [plushy-a plushy-b rate max-distance argmap] @@ -250,7 +262,8 @@ The function `new-individual` returns a new individual produced by selection and max-distance (utils/onenum (:bmx-maximum-distance argmap))] (-> (bmx plushy1 plushy2 bmx-exchange-rate max-distance argmap) (uniform-gap-addition gap-change-prob) - (uniform-gap-deletion gap-change-prob))) + (uniform-gap-deletion gap-change-prob) + (fill-empty-genes (:instructions argmap)))) ; :umad ;; uniform mutation by addition and deletion, see uniform-deletion for the ;; adjustment that makes this size neutral on average @@ -281,7 +294,8 @@ The function `new-individual` returns a new individual produced by selection and (uniform-gap-addition gap-change-prob) (uniform-gap-deletion gap-change-prob) (uniform-addition (:instructions argmap) umad-rate) - (uniform-deletion umad-rate))) + (uniform-deletion umad-rate) + (fill-empty-genes (:instructions argmap)))) ; :rumad ;; responsive UMAD, uses a deletion rate computed from the actual ;; number of additions made