diff --git a/src/propeller/gp.cljc b/src/propeller/gp.cljc index 9ea78d6..ae738bf 100644 --- a/src/propeller/gp.cljc +++ b/src/propeller/gp.cljc @@ -42,7 +42,7 @@ dont-end false ds-parent-rate 0 ds-parent-gens 1 - ids-type :solved ; :solved or :elite + ids-type :solved ; :solved or :elite or :soft downsample? false ;; The `mapper` will perform a `map`-like operation to apply a function to every individual ;; in the population. The default is `map` but other options include `mapv`, or `pmap`. @@ -126,6 +126,6 @@ #(variation/new-individual reindexed-pop argmap))))) (if downsample? (if (zero? (mod generation ds-parent-gens)) - (downsample/update-case-distances rep-evaluated-pop indexed-training-data indexed-training-data ids-type) ; update distances every ds-parent-gens generations + (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 diff --git a/src/propeller/problems/float_regression.cljc b/src/propeller/problems/float_regression.cljc new file mode 100644 index 0000000..f7c8ca4 --- /dev/null +++ b/src/propeller/problems/float_regression.cljc @@ -0,0 +1,82 @@ +(ns propeller.problems.float-regression + (:require [propeller.genome :as genome] + [propeller.push.interpreter :as interpreter] + [propeller.push.state :as state] + [propeller.tools.math :as math] + [propeller.gp :as gp] + #?(:cljs [cljs.reader :refer [read-string]]))) + +(defn- target-function + "Target function: f(x) = (1+ x^3)^3 + 1" + [x] + (inc (* (inc (* x x x)) (inc (* x x x)) (inc (* x x x))))) + +(def train-and-test-data + (let [train-inputs (range -1.5 1.5 0.1) + test-inputs (range -1.75 1.75 0.05)] + {:train (map (fn [x] {:input1 (vector x) :output1 (vector (target-function x))}) train-inputs) + :test (map (fn [x] {:input1 (vector x) :output1 (vector (target-function x))}) test-inputs)})) + +(def instructions + (list :in1 + :float_add + :float_subtract + :float_mult + :float_quot + :float_eq + :exec_dup + :exec_if + 'close + 0 + 1)) + +(defn error-function + "Finds the behaviors and errors of an individual. The error is the absolute + deviation between the target output value and the program's selected behavior, + or 1000000 if no behavior is produced. The behavior is here defined as the + final top item on the FLOAT stack." + ([argmap data individual] + (let [program (genome/plushy->push (:plushy individual) argmap) + inputs (map (fn [x] (first (:input1 x))) data) + correct-outputs (map (fn [x] (first (:output1 x))) data) + outputs (map (fn [input] + (state/peek-stack + (interpreter/interpret-program + program + (assoc state/empty-state :input {:in1 input}) + (:step-limit argmap)) + :float)) + inputs) + errors (map (fn [correct-output output] + (if (= output :no-stack-item) + 1000000 + (math/abs (- correct-output output)))) + correct-outputs + outputs)] + (assoc individual + :behaviors outputs + :errors errors + :total-error #?(:clj (apply +' errors) + :cljs (apply + errors)))))) + +(defn -main + "Runs propel-gp, giving it a map of arguments." + [& args] + (gp/gp + (merge + {:instructions instructions + :error-function error-function + :training-data (:train train-and-test-data) + :testing-data (:test train-and-test-data) + :max-generations 300 + :population-size 1000 + :max-initial-plushy-size 100 + :step-limit 200 + :parent-selection :lexicase + :tournament-size 5 + :umad-rate 0.1 + :solution-error-treshold 0.5 + :variation {:umad 1.0 :crossover 0.0} + :elitism false} + (apply hash-map (map #(if (string? %) (read-string %) %) args)))) + (#?(:clj shutdown-agents))) diff --git a/src/propeller/problems/simple_regression.cljc b/src/propeller/problems/integer_regression.cljc old mode 100755 new mode 100644 similarity index 93% rename from src/propeller/problems/simple_regression.cljc rename to src/propeller/problems/integer_regression.cljc index 3f84e9f..ff60213 --- a/src/propeller/problems/simple_regression.cljc +++ b/src/propeller/problems/integer_regression.cljc @@ -1,4 +1,4 @@ -(ns propeller.problems.simple-regression +(ns propeller.problems.integer-regression (:require [propeller.genome :as genome] [propeller.push.interpreter :as interpreter] [propeller.push.state :as state] @@ -7,9 +7,9 @@ #?(:cljs [cljs.reader :refer [read-string]]))) (defn- target-function - "Target function: f(x) = x^3 + x + 3" + "Target function: f(x) = x^3 + 2*x^2 + x + 3" [x] - (+ (* x x x) x 3)) + (+ (* x x x) (* 2 x x) x 3)) (def train-and-test-data (let [train-inputs (range -10 11) @@ -68,8 +68,8 @@ :error-function error-function :training-data (:train train-and-test-data) :testing-data (:test train-and-test-data) - :max-generations 500 - :population-size 500 + :max-generations 300 + :population-size 1000 :max-initial-plushy-size 100 :step-limit 200 :parent-selection :lexicase