Skip to content

Commit 24daa7d

Browse files
committed
Document source for saini-modular problem
1 parent 95d47d6 commit 24daa7d

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
;; This file implements a the symbolic regression problem described:
2+
;;
3+
;; Saini, A.K., Spector, L. (2020). Using Modularity Metrics as
4+
;; Design Features to Guide Evolution in Genetic Programming.
5+
;; In: Banzhaf, W., Goodman, E., Sheneman, L., Trujillo, L.,
6+
;; Worzel, B. (eds) Genetic Programming Theory and Practice XVII.
7+
;; Genetic and Evolutionary Computation. Springer, Cham.
8+
;; https://doi.org/10.1007/978-3-030-39958-0_9
9+
10+
(ns propeller.problems.regression.saini-modular
11+
(:require [propeller.genome :as genome]
12+
[propeller.push.interpreter :as interpreter]
13+
[propeller.push.state :as state]
14+
[propeller.tools.math :as math]
15+
[propeller.gp :as gp]
16+
#?(:cljs [cljs.reader :refer [read-string]])))
17+
18+
(defn- target-function
19+
"Saini modular = (x^3 + 1)^3 + 1"
20+
[x]
21+
(+ (* (+ (* x x x) 1)
22+
(+ (* x x x) 1)
23+
(+ (* x x x) 1))
24+
1))
25+
26+
(def train-and-test-data
27+
(let [train-inputs (range -4.0 4.0 0.1)
28+
test-inputs (range -4.0 4.0 0.05)]
29+
{:train (map (fn [x] {:input1 (vector x) :output1 (vector (target-function x))}) train-inputs)
30+
:test (map (fn [x] {:input1 (vector x) :output1 (vector (target-function x))}) test-inputs)}))
31+
32+
(def instructions
33+
(list :in1
34+
:float_add
35+
:float_subtract
36+
:float_mult
37+
:float_div
38+
:float_sin
39+
:float_cos
40+
:float_tan
41+
0.0
42+
1.0))
43+
44+
(defn error-function
45+
"Finds the behaviors and errors of an individual. The error is the absolute
46+
deviation between the target output value and the program's selected behavior,
47+
or 1000000 if no behavior is produced. The behavior is here defined as the
48+
final top item on the FLOAT stack."
49+
([argmap data individual]
50+
(let [program (genome/plushy->push (:plushy individual) argmap)
51+
inputs (map (fn [x] (first (:input1 x))) data)
52+
correct-outputs (map (fn [x] (first (:output1 x))) data)
53+
outputs (map (fn [input]
54+
(state/peek-stack
55+
(interpreter/interpret-program
56+
program
57+
(assoc state/empty-state :input {:in1 input})
58+
(:step-limit argmap))
59+
:float))
60+
inputs)
61+
errors (map (fn [correct-output output]
62+
(if (= output :no-stack-item)
63+
1000000
64+
(math/abs (- correct-output output))))
65+
correct-outputs
66+
outputs)]
67+
(assoc individual
68+
:behaviors outputs
69+
:errors errors
70+
:total-error #?(:clj (apply +' errors)
71+
:cljs (apply + errors))))))
72+
73+
(defn -main
74+
"Runs the top-level genetic programming function, giving it a map of
75+
arguments with defaults that can be overridden from the command line
76+
or through a passed map."
77+
[& args]
78+
(gp/gp
79+
(merge
80+
{:instructions instructions
81+
:error-function error-function
82+
:training-data (:train train-and-test-data)
83+
:testing-data (:test train-and-test-data)
84+
:downsample? false
85+
:solution-error-threshold 0.1
86+
:max-generations 300
87+
:population-size 1000
88+
:max-initial-plushy-size 50
89+
:step-limit 100
90+
:parent-selection :epsilon-lexicase
91+
:umad-rate 0.05
92+
:variation {:umad 1.0}
93+
:simplification? true}
94+
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))

0 commit comments

Comments
 (0)