Allow collections for genetic operator hyperparameters

This commit is contained in:
Lee Spector 2023-09-03 21:40:02 -04:00
parent 875c0b8e73
commit a27c7f8477
3 changed files with 52 additions and 48 deletions

View File

@ -83,6 +83,8 @@ or
lein run -m propeller.problems.simple-regression :variation "{:umad 1.0}"
```
For many genetic operator hyperparameters, collections may be provided in place of single values. When this is done, a random element of the collection will be chosen (with each being equally likely) each time the operator is used. When specied at the command line, these collections will also have to be quoted, for example with `:umad-rate "[0.01 0.05 0.1]"` to mean that UMAD rates of 0.01, 0.05, and 0.1 can be used.
By default, Propeller will conduct many processes concurrently on multiple
cores using threads. If you want to disable this behavior (for example, during
debugging) then provide the argument `:single-thread-mode` with the value `true`.

View File

@ -303,19 +303,19 @@
:training-data (:train train-and-test-data)
:testing-data (:test train-and-test-data)
:max-generations 1000
:population-size 1000
:population-size 100
:max-initial-plushy-size 100
:step-limit 1000
;:parent-selection :lexicase
:parent-selection :lexicase
;:parent-selection :tournament
:parent-selection :motley-batch-lexicase
;:parent-selection :motley-batch-lexicase
:max-batch-size 16
:tournament-size 5
:umad-rate 0.05
:alternation-rate 0.05
:alignment-deviation 1
:variation {:umad 0.5
:alternation 0.5
:umad-rate [1/8 1/16 1/32 1/64 1/128 1/256]
:alternation-rate [1/8 1/16 1/32 1/64 1/128 1/256]
:alignment-deviation [1 2 4 8 16 32 64 128 256]
:variation {:umad 1
:alternation 0
:reproduction 0
:tail-aligned-crossover 0
}

View File

@ -53,9 +53,6 @@ The function `new-individual` returns a new individual produced by selection and
(:require [propeller.selection :as selection]
[propeller.utils :as utils]))
(defn crossover
"Crosses over two individuals using uniform crossover, one Push instruction at a time.
Pads shorter one from the end of the list of instructions."
@ -73,26 +70,24 @@ The function `new-individual` returns a new individual produced by selection and
(defn alternation
"Alternates between the two parent genomes."
[genome1 genome2 {:keys [alternation-rate alignment-deviation] :as argmap}]
(let [alternation-rate (or alternation-rate 0)
alignment-deviation (or alignment-deviation 0)]
(loop [i 0
use-genome1 (rand-nth [true false])
result-genome []
iteration-budget (+ (count genome1) (count genome2))]
(if (or (>= i (count (if use-genome1 genome1 genome2))) ;; finished current program
(<= iteration-budget 0)) ;; looping too long
result-genome ;; Return
(if (< (rand) alternation-rate)
(recur (max 0 (+ i (utils/round (* alignment-deviation
(utils/gaussian-noise-factor)))))
(not use-genome1)
result-genome
(dec iteration-budget))
(recur (inc i)
use-genome1
(conj result-genome (nth (if use-genome1 genome1 genome2) i))
(dec iteration-budget)))))))
[genome1 genome2 alternation-rate alignment-deviation]
(loop [i 0
use-genome1 (rand-nth [true false])
result-genome []
iteration-budget (+ (count genome1) (count genome2))]
(if (or (>= i (count (if use-genome1 genome1 genome2))) ;; finished current program
(<= iteration-budget 0)) ;; looping too long
result-genome ;; Return
(if (< (rand) alternation-rate)
(recur (max 0 (+ i (utils/round (* alignment-deviation
(utils/gaussian-noise-factor)))))
(not use-genome1)
result-genome
(dec iteration-budget))
(recur (inc i)
use-genome1
(conj result-genome (nth (if use-genome1 genome1 genome2) i))
(dec iteration-budget))))))
(defn tail-aligned-crossover
"Crosses over two individuals using uniform crossover, one Push instruction at a time.
@ -234,9 +229,10 @@ The function `new-individual` returns a new individual produced by selection and
(:plushy (selection/select-parent pop argmap)))
;
:umad
(-> (:plushy (selection/select-parent pop argmap))
(uniform-addition (:instructions argmap) (:umad-rate argmap))
(uniform-deletion (:umad-rate argmap)))
(let [rate (utils/onenum (:umad-rate argmap))]
(-> (:plushy (selection/select-parent pop argmap))
(uniform-addition (:instructions argmap) rate)
(uniform-deletion rate)))
; uniform mutation by addition and deletion is a uniform mutation operator which
;first adds genes with some probability before or after every existing gene and then
;deletes random genes from the resulting genome
@ -245,7 +241,7 @@ The function `new-individual` returns a new individual produced by selection and
(let [parent-genome (:plushy (selection/select-parent pop argmap))
after-addition (uniform-addition parent-genome
(:instructions argmap)
(:umad-rate argmap))
(utils/onenum (:umad-rate argmap)))
effective-addition-rate (/ (- (count after-addition)
(count parent-genome))
(count parent-genome))]
@ -253,26 +249,29 @@ The function `new-individual` returns a new individual produced by selection and
; Adds and deletes instructions in the parent genome with the same rate
;
:vumad ;; variable umad: :umad-rate is interpreted as max, actual uniform 0-max
(let [rate (rand (:umad-rate argmap))]
(let [rate (rand (utils/onenum (:umad-rate argmap)))]
(-> (:plushy (selection/select-parent pop argmap))
(uniform-addition (:instructions argmap) rate)
(uniform-deletion rate)))
;
:uniform-addition
(-> (:plushy (selection/select-parent pop argmap))
(uniform-addition (:instructions argmap) (:umad-rate argmap)))
(uniform-addition (:instructions argmap)
(utils/onenum (:umad-rate argmap))))
;
:uniform-replacement
(-> (:plushy (selection/select-parent pop argmap))
(uniform-replacement (:instructions argmap) (:replacement-rate argmap)))
(uniform-replacement (:instructions argmap)
(utils/onenum (:replacement-rate argmap))))
;
:diploid-uniform-silent-replacement
(-> (:plushy (selection/select-parent pop argmap))
(diploid-uniform-silent-replacement (:instructions argmap) (:replacement-rate argmap)))
(diploid-uniform-silent-replacement (:instructions argmap)
(utils/onenum (:replacement-rate argmap))))
;
:uniform-deletion
(-> (:plushy (selection/select-parent pop argmap))
(uniform-deletion (:umad-rate argmap)))
(uniform-deletion (utils/onenum (:umad-rate argmap))))
;
:diploid-crossover
(diploid-crossover
@ -285,32 +284,35 @@ The function `new-individual` returns a new individual produced by selection and
(:plushy (selection/select-parent pop argmap)))
;
:diploid-umad
(-> (:plushy (selection/select-parent pop argmap))
(diploid-uniform-addition (:instructions argmap) (:umad-rate argmap))
(diploid-uniform-deletion (:umad-rate argmap)))
(let [rate (utils/onenum (:umad-rate argmap))]
(-> (:plushy (selection/select-parent pop argmap))
(diploid-uniform-addition (:instructions argmap) rate)
(diploid-uniform-deletion rate)))
;
:diploid-vumad ;; variable umad: :umad-rate is interpreted as max, actual uniform 0-max
(let [rate (rand (:umad-rate argmap))]
(let [rate (rand (utils/onenum (:umad-rate argmap)))]
(-> (:plushy (selection/select-parent pop argmap))
(diploid-uniform-addition (:instructions argmap) rate)
(diploid-uniform-deletion rate)))
;
:diploid-uniform-addition
(-> (:plushy (selection/select-parent pop argmap))
(diploid-uniform-addition (:instructions argmap) (:umad-rate argmap)))
(diploid-uniform-addition (:instructions argmap)
(utils/onenum (:umad-rate argmap))))
;
:diploid-uniform-deletion
(-> (:plushy (selection/select-parent pop argmap))
(diploid-uniform-deletion (:umad-rate argmap)))
(diploid-uniform-deletion (utils/onenum (:umad-rate argmap))))
;
:diploid-flip
(-> (:plushy (selection/select-parent pop argmap))
(diploid-flip (:diploid-flip-rate argmap)))
(diploid-flip (utils/onenum (:diploid-flip-rate argmap))))
;
:alternation
(alternation (:plushy (selection/select-parent pop argmap))
(:plushy (selection/select-parent pop argmap))
argmap)
(utils/onenum (or (:alternation-rate argmap) 0))
(utils/onenum (or (:alignment-deviation argmap) 0)))
;
:reproduction
(:plushy (selection/select-parent pop argmap))