From 25e8efe255f4695763445f5bbc528e4d84cdda91 Mon Sep 17 00:00:00 2001
From: Lee Spector <lspector@hampshire.edu>
Date: Wed, 8 Nov 2023 18:53:58 -0500
Subject: [PATCH] Handle argmap adjustments outside of gp loop; add :gene when
 using autoconstructive crossover

---
 src/propeller/gp.cljc                    | 17 +++++++++++++++--
 src/propeller/problems/boolean/mul3.cljc | 15 ++++++++-------
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/src/propeller/gp.cljc b/src/propeller/gp.cljc
index 7c74af6..1749ba6 100644
--- a/src/propeller/gp.cljc
+++ b/src/propeller/gp.cljc
@@ -41,7 +41,7 @@
   #?(:clj (shutdown-agents))
   nil)
 
-(defn gp
+(defn gp-loop
   "Main GP loop."
   [{:keys [population-size max-generations error-function instructions
            max-initial-plushy-size solution-error-threshold ds-parent-rate ds-parent-gens dont-end ids-type downsample?]
@@ -137,4 +137,17 @@
                        (if (zero? (mod generation ds-parent-gens))
                          (downsample/update-case-distances rep-evaluated-pop indexed-training-data indexed-training-data ids-type (/ solution-error-threshold (count indexed-training-data))) ; update distances every ds-parent-gens generations
                          indexed-training-data)
-                       indexed-training-data))))))
\ No newline at end of file
+                       indexed-training-data))))))
+
+(defn gp
+  "Top-level gp function. Calls gp-loop with possibly-adjusted arguments."
+  [argmap]
+  (let [adjust-for-autoconstructive-crossover
+        (fn [args]
+          (let [prob (:autoconstructive-crossover (:variation args))
+                n (:autoconstructive-crossover-enrichment args)]
+            (if (and prob (> prob 0))
+              (update args :instructions concat (repeat (or n 1) :gene))
+              args)))]
+    (gp-loop (-> argmap
+                 (adjust-for-autoconstructive-crossover)))))
\ No newline at end of file
diff --git a/src/propeller/problems/boolean/mul3.cljc b/src/propeller/problems/boolean/mul3.cljc
index b027808..5822a75 100644
--- a/src/propeller/problems/boolean/mul3.cljc
+++ b/src/propeller/problems/boolean/mul3.cljc
@@ -300,7 +300,7 @@
   [& args]
   (gp/gp
    (merge
-    {:instructions             (concat instructions [:gene]) ;; autox
+    {:instructions             instructions
      :error-function           error-function
      :training-data            (:train train-and-test-data)
      :testing-data             (:test train-and-test-data)
@@ -309,9 +309,9 @@
      :max-initial-plushy-size  100
      :step-limit               10000
      :parent-selection         :lexicase
-     ;:downsample?              true
-     ;:ds-function              :case-rand
-     ;:downsample-rate          0.5
+     :downsample?              true
+     :ds-function              :case-rand
+     :downsample-rate          0.1
      ;:parent-selection         :tournament
      ;:parent-selection         :motley-batch-lexicase
      ;:max-batch-size           [1 2 4 8 16 32 64 128 256]
@@ -331,12 +331,13 @@
      ;:alternation-rate         [1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256]
      ;:alignment-deviation      [0 1 2 4 8 16 32 64 128]
      :variation                {:ah-umad 0
-                                :umad 0.5 ;autox
-                                :autoconstructive-crossover 0.5 ;autox
+                                :umad 0.5
+                                :autoconstructive-crossover 0.5
                                 :alternation 0
                                 :reproduction 0
                                 :tail-aligned-crossover 0}
      ;:replacement-rate         0.01
      :elitism                  false
-     :single-thread-mode       false}
+     :single-thread-mode       false
+     :autoconstructive-crossover-enrichment 10}
     (apply hash-map (map #(if (string? %) (read-string %) %) args)))))