Merge branch 'master'
This commit is contained in:
commit
fbf77cdb90
46
README.md
46
README.md
@ -10,23 +10,29 @@ If you are working in a Clojure IDE with an integrated REPL, the first
|
||||
thing you may want to do is to open `src/propeller/session.cljc` and
|
||||
evaluate the namespace declaration and the commented-out expressions
|
||||
therein. These demonstrate core components of Propeller including
|
||||
complete genetic programming runs.
|
||||
complete genetic programming runs. When conducting complete genetic
|
||||
programming runs this way (using `gp/gp`), depending on your IDE you
|
||||
may need to explicitly open and load the problem file before evaluating
|
||||
the calls to `require` and `gp/gp`.
|
||||
|
||||
To run Propeller from the command line, on a genetic programming problem
|
||||
that is defined within this project, you will probably want to use either
|
||||
the Clojure [CLI tools](https://clojure.org/guides/deps_and_cli) or
|
||||
[leiningen](https://leiningen.org).
|
||||
[leiningen](https://leiningen.org). In the examples below, the leiningen
|
||||
and CLI commands are identical except that the former begin with
|
||||
`lein run -m`, while the latter begin with `clj -M -m`.
|
||||
|
||||
The instructions below are written for leiningen. If you are using
|
||||
the CLI tools instead, then replace `lein run -m` in each command
|
||||
with `clj -M -m`.
|
||||
|
||||
If you are using leiningen, then you can start a run with the command
|
||||
To start a run use `clj -M -m <namespace>` or
|
||||
`lein run -m <namespace>`, replacing `<namespace>`
|
||||
with the actual namespace that you will find at the top of the problem file.
|
||||
|
||||
For example, you can run the simple-regression genetic programming problem with:
|
||||
|
||||
```
|
||||
clj -M -m propeller.problems.simple-regression
|
||||
```
|
||||
or
|
||||
|
||||
```
|
||||
lein run -m propeller.problems.simple-regression
|
||||
```
|
||||
@ -35,6 +41,11 @@ Additional command-line arguments may
|
||||
be provided to override the default key/value pairs specified in the
|
||||
problem file, for example:
|
||||
|
||||
```
|
||||
clj -M -m propeller.problems.simple-regression :population-size 100
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
lein run -m propeller.problems.simple-regression :population-size 100
|
||||
@ -44,6 +55,13 @@ On Unix operating systems, including MacOS, you can use something
|
||||
like the following to send output both to the terminal
|
||||
and to a text file (called `outfile` in this example):
|
||||
|
||||
|
||||
```
|
||||
clj -M -m propeller.problems.simple-regression | tee outfile
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
lein run -m propeller.problems.simple-regression | tee outfile
|
||||
```
|
||||
@ -55,10 +73,24 @@ quotes, like in this example that provides a non-default
|
||||
value for the `:variation` argument, which is a clojure map
|
||||
containing curly brackets that may confuse your shell:
|
||||
|
||||
```
|
||||
clj -M -m propeller.problems.simple-regression :variation "{:umad 1.0}"
|
||||
```
|
||||
|
||||
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`.
|
||||
Threads are not available in Javascript, so no processes are run concurrnetly
|
||||
when Propeller is run in Clojurescript.
|
||||
|
||||
|
||||
## CLJS Usage
|
||||
|
||||
|
2
deps.edn
2
deps.edn
@ -3,7 +3,7 @@
|
||||
{org.clojure/clojure #:mvn{:version "1.10.0"},
|
||||
org.clojure/clojurescript #:mvn{:version "1.9.946"},
|
||||
org.clojure/test.check #:mvn{:version "1.1.0"},
|
||||
net.clojars.schneau/psb2 #:mvn{:version "1.1.0"}},
|
||||
net.clojars.schneau/psb2 #:mvn{:version "1.1.1"}},
|
||||
:mvn/repos {}
|
||||
:codox {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
|
||||
:exec-fn codox.main/generate-docs
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB1.count-odds.html
Normal file
11
docs/propeller.problems.PSB1.count-odds.html
Normal file
File diff suppressed because one or more lines are too long
13
docs/propeller.problems.PSB1.grade.html
Normal file
13
docs/propeller.problems.PSB1.grade.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB1.scrabble-score.html
Normal file
11
docs/propeller.problems.PSB1.scrabble-score.html
Normal file
File diff suppressed because one or more lines are too long
11
docs/propeller.problems.PSB1.small-or-large.html
Normal file
11
docs/propeller.problems.PSB1.small-or-large.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
docs/propeller.problems.complex-regression.html
Normal file
8
docs/propeller.problems.complex-regression.html
Normal file
File diff suppressed because one or more lines are too long
8
docs/propeller.problems.float-regression.html
Normal file
8
docs/propeller.problems.float-regression.html
Normal file
File diff suppressed because one or more lines are too long
8
docs/propeller.problems.integer-regression.html
Normal file
8
docs/propeller.problems.integer-regression.html
Normal file
File diff suppressed because one or more lines are too long
8
docs/propeller.problems.simple-classification.html
Normal file
8
docs/propeller.problems.simple-classification.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
(defproject net.clojars.lspector/propeller "0.3.0"
|
||||
(defproject net.clojars.lspector/propeller "0.3.2"
|
||||
:description "Yet another Push-based genetic programming system in Clojure."
|
||||
:url "https://github.com/lspector/propeller"
|
||||
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
|
||||
|
1
scripts/GenerateDocs.sh
Normal file → Executable file
1
scripts/GenerateDocs.sh
Normal file → Executable file
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
pip install mdutils
|
||||
lein codox
|
||||
python3 FunctionsToMD.py
|
||||
python3 HTMLFix.py
|
||||
|
@ -39,9 +39,9 @@ line with the command `lein run -m <namespace>`, replacing `<namespace>`
|
||||
with the actual namespace that you will find at the top of the problem file.
|
||||
|
||||
If you have installed [Clojure](https://clojure.org/guides/install_clojure#java), you can run Propeller on a genetic programming
|
||||
problem with the command `clj --main <namespace>`, replacing `<namespace>` with
|
||||
problem with the command `clj -M -m <namespace>`, replacing `<namespace>` with
|
||||
the actual namespace that you will find at the top of the problem file.
|
||||
The examples below use leiningen, but you can replace `lein run -m` with `clj --main` to run the same problem.
|
||||
The examples below use leiningen, but you can replace `lein run -m` with `clj -M -m` to run the same problem.
|
||||
|
||||
A specific example is provided later below.
|
||||
|
||||
|
@ -116,7 +116,6 @@ instructions from `push/instructions`, input instructions, close, and constants
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
||||
```
|
@ -7,6 +7,7 @@ Table of contents
|
||||
|
||||
* [Additional Instructions](#additional-instructions)
|
||||
* [input_output.cljc](#input_outputcljc)
|
||||
* [.DS_Store](#ds_store)
|
||||
* [numeric.cljc](#numericcljc)
|
||||
* [string.cljc](#stringcljc)
|
||||
* [character.cljc](#charactercljc)
|
||||
@ -19,6 +20,8 @@ Table of contents
|
||||
|
||||
## :print_newline
|
||||
Prints new line
|
||||
# .DS_Store
|
||||
|
||||
# numeric.cljc
|
||||
|
||||
## :float_cos
|
||||
|
@ -1,6 +1,9 @@
|
||||
# Generating Documentation for Propeller
|
||||
|
||||
To generate documentation with [codox](https://github.com/weavejester/codox), run `scripts/GenerateDocs.sh`in the command line.
|
||||
In order to generate documentation, you'll need Python and `pip` installed.
|
||||
|
||||
To generate documentation with [codox](https://github.com/weavejester/codox), run `scripts/GenerateDocs.sh` in the command line from the `scripts` directory.
|
||||
To make the script executable, you may need to first run `chmod +x GenerateDocs.sh`.
|
||||
This will run "lein codox" on the command line to generate first batch of HTMl files.
|
||||
Then, it runs FunctionsToMD to take Push instructions generated by `def-instruction` and spit it out to a Markdown file.
|
||||
Then, it runs HTMLFix to fix the ordered lists in `Adding_Genetic_Operators.md`, `Adding_Problem.md`, and
|
||||
|
@ -22,6 +22,9 @@ They hold the genetic material for an `individual`. In the initial population, w
|
||||
([plushy] (plushy->push plushy {}))
|
||||
([plushy argmap]
|
||||
(let [plushy (if (:diploid argmap) (map first (partition 2 plushy)) plushy)
|
||||
plushy (if (> (or (:ah-umad (:variation argmap)) 0) 0) ;; strip :vary and :protect if using :ah-umad
|
||||
(filter (complement #{:vary :protect}) plushy)
|
||||
plushy)
|
||||
opener? #(and (vector? %) (= (first %) 'open))] ;; [open <n>] marks opens
|
||||
(loop [push () ;; iteratively build the Push program from the plushy
|
||||
plushy (mapcat #(let [n (get instructions/opens %)]
|
||||
|
@ -15,46 +15,41 @@
|
||||
[propeller.push.instructions.polymorphic]
|
||||
[propeller.push.instructions.string]
|
||||
[propeller.push.instructions.vector]
|
||||
[propeller.selection :as selection]))
|
||||
[propeller.selection :as selection]
|
||||
[propeller.utils :as utils]))
|
||||
|
||||
(defn report
|
||||
"Reports information each generation."
|
||||
[evaluations pop generation argmap training-data]
|
||||
(let [best (first pop)]
|
||||
(clojure.pprint/pprint {:generation generation
|
||||
:best-plushy (:plushy best)
|
||||
:best-program (genome/plushy->push (:plushy best) argmap)
|
||||
:best-total-error (:total-error best)
|
||||
:evaluations evaluations
|
||||
:ds-indices (map #(:index %) training-data)
|
||||
:best-errors (:errors best)
|
||||
:best-behaviors (:behaviors best)
|
||||
:genotypic-diversity (float (/ (count (distinct (map :plushy pop))) (count pop)))
|
||||
:behavioral-diversity (float (/ (count (distinct (map :behaviors pop))) (count pop)))
|
||||
:average-genome-length (float (/ (reduce + (map count (map :plushy pop))) (count pop)))
|
||||
:average-total-error (float (/ (reduce + (map :total-error pop)) (count pop)))})
|
||||
(clojure.pprint/pprint
|
||||
(merge {:generation generation
|
||||
:best-plushy (:plushy best)
|
||||
:best-program (genome/plushy->push (:plushy best) argmap)
|
||||
:best-total-error (:total-error best)
|
||||
:evaluations evaluations
|
||||
:ds-indices (map #(:index %) training-data)
|
||||
:best-errors (:errors best)
|
||||
:best-behaviors (:behaviors best)
|
||||
:genotypic-diversity (float (/ (count (distinct (map :plushy pop))) (count pop)))
|
||||
:behavioral-diversity (float (/ (count (distinct (map :behaviors pop))) (count pop)))
|
||||
:average-genome-length (float (/ (reduce + (map count (map :plushy pop))) (count pop)))
|
||||
:average-total-error (float (/ (reduce + (map :total-error pop)) (count pop)))}
|
||||
(if (> (or (:ah-umad (:variation argmap)) 0) 0) ;; using autoconstructive hypervariability
|
||||
{:average-hypervariability
|
||||
(let [variabilities (map (fn [i]
|
||||
(let [p (:plushy i)]
|
||||
(if (empty? p)
|
||||
0
|
||||
(/ (reduce + (variation/ah-rates p 0 1))
|
||||
(count p)))))
|
||||
pop)]
|
||||
(float (/ (reduce + variabilities) (count variabilities))))}
|
||||
{})))
|
||||
(println)))
|
||||
|
||||
(defn gp
|
||||
"Main GP loop.
|
||||
|
||||
On each iteration, it creates a population of random plushies using a mapper
|
||||
function and genome/make-random-plushy function,
|
||||
then it sorts the population by the total error using the error-function
|
||||
and sort-by function. It then takes the best individual from the sorted population,
|
||||
and if the parent selection is set to epsilon-lexicase, it adds the epsilons to the argmap.
|
||||
|
||||
The function then checks if the custom-report argument is set,
|
||||
if so it calls that function passing the evaluated population,
|
||||
current generation and argmap. If not, it calls the report function
|
||||
passing the evaluated population, current generation and argmap.
|
||||
|
||||
Then, it checks if the total error of the best individual is less than or equal
|
||||
to the solution-error-threshold or if the current generation is greater than or
|
||||
equal to the max-generations specified. If either is true, the function
|
||||
exits with the best individual or nil. If not, it creates new individuals
|
||||
for the next generation using the variation/new-individual function and the
|
||||
repeatedly function, and then continues to the next iteration of the loop. "
|
||||
"Main GP loop."
|
||||
[{:keys [population-size max-generations error-function instructions
|
||||
max-initial-plushy-size solution-error-threshold mapper ds-parent-rate ds-parent-gens dont-end ids-type downsample?]
|
||||
:or {solution-error-threshold 0.0
|
||||
@ -73,9 +68,11 @@ repeatedly function, and then continues to the next iteration of the loop. "
|
||||
;;
|
||||
(loop [generation 0
|
||||
evaluations 0
|
||||
population (mapper
|
||||
(fn [_] {:plushy (genome/make-random-plushy instructions max-initial-plushy-size)})
|
||||
(range population-size))
|
||||
population (utils/pmapallv
|
||||
(fn [_] {:plushy (let [plushy (genome/make-random-plushy instructions max-initial-plushy-size)]
|
||||
(if (:diploid argmap)
|
||||
(interleave plushy plushy)
|
||||
plushy))}) (range population-size) argmap)
|
||||
indexed-training-data (downsample/assign-indices-to-data (downsample/initialize-case-distances argmap))]
|
||||
(let [training-data (if downsample?
|
||||
(case (:ds-function argmap)
|
||||
@ -89,21 +86,24 @@ repeatedly function, and then continues to the next iteration of the loop. "
|
||||
(zero? (mod generation ds-parent-gens))) ;every ds-parent-gens generations
|
||||
(take (* ds-parent-rate (count population)) (shuffle population))
|
||||
'()) ;else just empty list
|
||||
; parent representatives for down-sampling
|
||||
rep-evaluated-pop (if downsample?
|
||||
(sort-by :total-error
|
||||
(mapper
|
||||
(utils/pmapallv
|
||||
(partial error-function argmap indexed-training-data)
|
||||
parent-reps))
|
||||
parent-reps
|
||||
argmap))
|
||||
'())
|
||||
evaluated-pop (sort-by :total-error
|
||||
(mapper
|
||||
(utils/pmapallv
|
||||
(partial error-function argmap training-data)
|
||||
population))
|
||||
population
|
||||
argmap))
|
||||
best-individual (first evaluated-pop)
|
||||
best-individual-passes-ds (and downsample? (<= (:total-error best-individual) solution-error-threshold))
|
||||
argmap (if (= (:parent-selection argmap) :epsilon-lexicase)
|
||||
(assoc argmap :epsilons (selection/epsilon-list evaluated-pop))
|
||||
argmap)] ;adds :epsilons if using epsilon-lexicase
|
||||
argmap)] ; epsilons
|
||||
(if (:custom-report argmap)
|
||||
((:custom-report argmap) evaluations evaluated-pop generation argmap)
|
||||
(report evaluations evaluated-pop generation argmap training-data))
|
||||
|
@ -77,5 +77,4 @@
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -96,4 +96,4 @@
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(#?(:clj shutdown-agents)))
|
||||
|
@ -146,5 +146,4 @@
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -78,5 +78,4 @@
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -85,5 +85,4 @@
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -96,5 +96,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -85,5 +85,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -119,5 +119,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -93,5 +93,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -100,5 +100,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -101,5 +101,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -102,5 +102,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -87,5 +87,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -83,5 +83,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -84,5 +84,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -96,5 +96,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -98,5 +98,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -88,5 +88,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -112,5 +112,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -85,5 +85,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -95,5 +95,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -87,5 +87,4 @@ Source: https://arxiv.org/pdf/2106.06086.pdf"
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
341
src/propeller/problems/boolean/mul3.cljc
Normal file
341
src/propeller/problems/boolean/mul3.cljc
Normal file
@ -0,0 +1,341 @@
|
||||
(ns propeller.problems.boolean.mul3
|
||||
(:require [propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.gp :as gp]
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
make-instruction]]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
||||
(defn target-function
|
||||
"Returns a vector of 8 bits (booleans) for the product of the numbers
|
||||
a and b, which should be provided as 3 booleans each."
|
||||
[a2 a1 a0 b2 b1 b0]
|
||||
(let [a (+ (if a2 4 0)
|
||||
(if a1 2 0)
|
||||
(if a0 1 0))
|
||||
b (+ (if b2 4 0)
|
||||
(if b1 2 0)
|
||||
(if b0 1 0))
|
||||
product (* a b)]
|
||||
(loop [bit-index 5
|
||||
product-bits {}
|
||||
remainder product]
|
||||
(if (< bit-index 0)
|
||||
product-bits
|
||||
(let [pow2 (bit-shift-left 1 bit-index)
|
||||
this-bit (>= remainder pow2)]
|
||||
(recur (dec bit-index)
|
||||
(assoc product-bits (keyword (str "c" bit-index)) this-bit)
|
||||
(- remainder (* (if this-bit 1 0) pow2))))))))
|
||||
|
||||
#_(target-function false true false false false true)
|
||||
#_(target-function true true true true true)
|
||||
|
||||
(def train-and-test-data
|
||||
(let [bools [false true]]
|
||||
{:train (for [a2 bools
|
||||
a1 bools
|
||||
a0 bools
|
||||
b2 bools
|
||||
b1 bools
|
||||
b0 bools]
|
||||
{:inputs {:a2 a2 :a1 a1 :a0 a0 :b2 b2 :b1 b1 :b0 b0}
|
||||
:outputs (target-function a2 a1 a0 b2 b1 b0)})
|
||||
:test []}))
|
||||
|
||||
(def-instruction
|
||||
:set-c5
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c5]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c4
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c4]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c3
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c3]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c2
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c2]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c1
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c1]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c0
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c0]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
|
||||
(def-instruction
|
||||
:c5
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(let [val (:c5 (:output state))]
|
||||
(if (boolean? val)
|
||||
(state/push-to-stack state :boolean val)
|
||||
state))))
|
||||
|
||||
(def-instruction
|
||||
:c4
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(let [val (:c4 (:output state))]
|
||||
(if (boolean? val)
|
||||
(state/push-to-stack state :boolean val)
|
||||
state))))
|
||||
|
||||
(def-instruction
|
||||
:c3
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(let [val (:c3 (:output state))]
|
||||
(if (boolean? val)
|
||||
(state/push-to-stack state :boolean val)
|
||||
state))))
|
||||
|
||||
(def-instruction
|
||||
:c2
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(let [val (:c2 (:output state))]
|
||||
(if (boolean? val)
|
||||
(state/push-to-stack state :boolean val)
|
||||
state))))
|
||||
|
||||
(def-instruction
|
||||
:c1
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(let [val (:c1 (:output state))]
|
||||
(if (boolean? val)
|
||||
(state/push-to-stack state :boolean val)
|
||||
state))))
|
||||
|
||||
(def-instruction
|
||||
:c0
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(let [val (:c0 (:output state))]
|
||||
(if (boolean? val)
|
||||
(state/push-to-stack state :boolean val)
|
||||
state))))
|
||||
|
||||
(def-instruction
|
||||
:boolean_bufa
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] b1)
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
(def-instruction
|
||||
:boolean_nota
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (not b1))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
|
||||
(def-instruction
|
||||
:boolean_nand
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (not (and b1 b2)))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
(def-instruction
|
||||
:boolean_nor
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (not (or b1 b2)))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
(def-instruction
|
||||
:boolean_xnor
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (= b1 b2))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
(def instructions
|
||||
(list :a2
|
||||
:a1
|
||||
:a0
|
||||
:b2
|
||||
:b1
|
||||
:b0
|
||||
:set-c5 ;; defined here
|
||||
:set-c4 ;; defined here
|
||||
:set-c3 ;; defined here
|
||||
:set-c2 ;; defined here
|
||||
:set-c1 ;; defined here
|
||||
:set-c0 ;; defined here
|
||||
:c5 ;; defined here
|
||||
:c4 ;; defined here
|
||||
:c3 ;; defined here
|
||||
:c2 ;; defined here
|
||||
:c1 ;; defined here
|
||||
:c0 ;; defined here
|
||||
|
||||
;; BOOLEAN TAGGING?
|
||||
|
||||
;; Recommended by Kalkreuth et al: BUFa, NOTa, AND, OR, XOR, NAND, NOR, XNOR
|
||||
;:boolean_bufa ;; defined here
|
||||
;:boolean_nota ;; defined here
|
||||
:boolean_and
|
||||
:boolean_or
|
||||
:boolean_xor
|
||||
:boolean_nand ;; defined here
|
||||
:boolean_nor ;; defined here
|
||||
:boolean_xnor ;; defined here
|
||||
|
||||
:boolean_not ;; added to compensate for commenting out :boolean_nota
|
||||
|
||||
;:boolean_pop
|
||||
:boolean_dup
|
||||
:boolean_swap
|
||||
:boolean_rot
|
||||
|
||||
;:exec_pop
|
||||
;:exec_dup
|
||||
;:exec_swap
|
||||
;:exec_rot
|
||||
;'close
|
||||
|
||||
;true
|
||||
;false
|
||||
))
|
||||
|
||||
|
||||
|
||||
(defn error-function
|
||||
[argmap data individual]
|
||||
(let [program (genome/plushy->push (:plushy individual) argmap)
|
||||
input-maps (mapv :inputs data)
|
||||
correct-output-maps (mapv :outputs data)
|
||||
output-maps (mapv (fn [input-map]
|
||||
(:output
|
||||
(interpreter/interpret-program
|
||||
program
|
||||
(assoc state/empty-state
|
||||
:input input-map
|
||||
:output {:c5 :unset
|
||||
:c4 :unset
|
||||
:c3 :unset
|
||||
:c2 :unset
|
||||
:c1 :unset
|
||||
:c0 :unset})
|
||||
(:step-limit argmap))))
|
||||
input-maps)
|
||||
errors (flatten (map (fn [correct-output-map output-map]
|
||||
(mapv (fn [k]
|
||||
; no answer same as wrong answer
|
||||
(if (= (k correct-output-map)
|
||||
(k output-map))
|
||||
0
|
||||
1))
|
||||
[:c5 :c4 :c3 :c2 :c1 :c0]))
|
||||
correct-output-maps
|
||||
output-maps))]
|
||||
(assoc individual
|
||||
:behaviors output-maps
|
||||
:errors errors
|
||||
:total-error #?(:clj (apply +' errors)
|
||||
:cljs (apply + errors)))))
|
||||
|
||||
(defn -main
|
||||
"Runs the top-level genetic programming function, giving it a map of
|
||||
arguments with defaults that can be overridden from the command line
|
||||
or through a passed map."
|
||||
[& args]
|
||||
(gp/gp
|
||||
(merge
|
||||
{:instructions (concat instructions [:vary :protect]) ;; ah-umad
|
||||
:error-function error-function
|
||||
:training-data (:train train-and-test-data)
|
||||
:testing-data (:test train-and-test-data)
|
||||
:max-generations 1000
|
||||
:population-size 100
|
||||
:max-initial-plushy-size 100
|
||||
:step-limit 1000
|
||||
:parent-selection :lexicase
|
||||
;:parent-selection :tournament
|
||||
;:parent-selection :motley-batch-lexicase
|
||||
;:max-batch-size [1 2 4 8 16 32 64 128 256]
|
||||
;:tournament-size 5
|
||||
;:umad-rate 0.09
|
||||
:ah-umad-protect-rate 0.001 ;; ah-umad
|
||||
:ah-umad-vary-rate 0.1 ;; ah-umad
|
||||
:ah-umad-tournament-size 2 ;; ah-umad
|
||||
;:umad-rate [1/2
|
||||
; 1/4 1/4
|
||||
; 1/8 1/8 1/8
|
||||
; 1/16 1/16 1/16 1/16
|
||||
; 1/32 1/32 1/32 1/32 1/32
|
||||
; 1/64 1/64 1/64 1/64 1/64 1/64
|
||||
; 1/128 1/128 1/128 1/128 1/128 1/128 1/128
|
||||
; 1/256 1/256 1/256 1/256 1/256 1/256 1/256 1/256]
|
||||
;: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 1 ;; ah-umad
|
||||
:umad 0
|
||||
:alternation 0
|
||||
:reproduction 0
|
||||
:tail-aligned-crossover 0}
|
||||
;:diploid true
|
||||
;:variation {:diploid-vumad 0.8
|
||||
; :diploid-uniform-silent-replacement 0.1
|
||||
; :diploid-flip 0.1}
|
||||
;:replacement-rate 0.01
|
||||
;:diploid-flip-rate 0.01
|
||||
:elitism false
|
||||
:single-thread-mode false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
278
src/propeller/problems/boolean/mul4.cljc
Normal file
278
src/propeller/problems/boolean/mul4.cljc
Normal file
@ -0,0 +1,278 @@
|
||||
(ns propeller.problems.boolean.mul4
|
||||
(:require [propeller.genome :as genome]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.push.state :as state]
|
||||
[propeller.gp :as gp]
|
||||
[propeller.push.instructions :refer [def-instruction
|
||||
make-instruction]]
|
||||
#?(:cljs [cljs.reader :refer [read-string]])))
|
||||
|
||||
(defn target-function
|
||||
"Returns a vector of 8 bits (booleans) for the product of the numbers
|
||||
a and b, which should be provided as 4 booleans each."
|
||||
[a3 a2 a1 a0 b3 b2 b1 b0]
|
||||
(let [a (+ (if a3 8 0)
|
||||
(if a2 4 0)
|
||||
(if a1 2 0)
|
||||
(if a0 1 0))
|
||||
b (+ (if b3 8 0)
|
||||
(if b2 4 0)
|
||||
(if b1 2 0)
|
||||
(if b0 1 0))
|
||||
product (* a b)]
|
||||
(loop [bit-index 7
|
||||
product-bits {}
|
||||
remainder product]
|
||||
(if (< bit-index 0)
|
||||
product-bits
|
||||
(let [pow2 (bit-shift-left 1 bit-index)
|
||||
this-bit (>= remainder pow2)]
|
||||
(recur (dec bit-index)
|
||||
(assoc product-bits (keyword (str "c" bit-index)) this-bit)
|
||||
(- remainder (* (if this-bit 1 0) pow2))))))))
|
||||
|
||||
#_(target-function false true false false false true false false)
|
||||
#_(target-function true true true true true true true true)
|
||||
|
||||
(def train-and-test-data
|
||||
(let [bools [false true]]
|
||||
{:train (for [a3 bools
|
||||
a2 bools
|
||||
a1 bools
|
||||
a0 bools
|
||||
b3 bools
|
||||
b2 bools
|
||||
b1 bools
|
||||
b0 bools]
|
||||
{:inputs {:a3 a3 :a2 a2 :a1 a1 :a0 a0 :b3 b3 :b2 b2 :b1 b1 :b0 b0}
|
||||
:outputs (target-function a3 a2 a1 a0 b3 b2 b1 b0)})
|
||||
:test []}))
|
||||
|
||||
(def-instruction
|
||||
:set-c7
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c7]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
#_(interpreter/interpret-program
|
||||
'(:set-c7) (assoc state/empty-state :output {:c7 :unset}) 1000)
|
||||
|
||||
#_(interpreter/interpret-program
|
||||
'(true :set-c7) (assoc state/empty-state :output {:c7 :unset}) 1000)
|
||||
|
||||
(def-instruction
|
||||
:set-c6
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c6]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c5
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c5]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c4
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c4]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c3
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c3]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c2
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c2]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c1
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c1]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:set-c0
|
||||
^{:stacks [:boolean :output]}
|
||||
(fn [state]
|
||||
(if (state/empty-stack? state :boolean)
|
||||
state
|
||||
(assoc-in (state/pop-stack state :boolean)
|
||||
[:output :c0]
|
||||
(state/peek-stack state :boolean)))))
|
||||
|
||||
(def-instruction
|
||||
:boolean_bufa
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] b1)
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
|
||||
(def-instruction
|
||||
:boolean_nota
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (not b1))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
|
||||
(def-instruction
|
||||
:boolean_nand
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (not (and b1 b2)))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
(def-instruction
|
||||
:boolean_nor
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (not (or b1 b2)))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
(def-instruction
|
||||
:boolean_xnor
|
||||
^{:stacks #{:boolean}}
|
||||
(fn [state]
|
||||
(make-instruction state
|
||||
(fn [b1 b2] (= b1 b2))
|
||||
[:boolean :boolean]
|
||||
:boolean)))
|
||||
|
||||
(def instructions
|
||||
(list :a3
|
||||
:a2
|
||||
:a1
|
||||
:a0
|
||||
:b3
|
||||
:b2
|
||||
:b1
|
||||
:b0
|
||||
:set-c7 ;; defined here
|
||||
:set-c6 ;; defined here
|
||||
:set-c5 ;; defined here
|
||||
:set-c4 ;; defined here
|
||||
:set-c3 ;; defined here
|
||||
:set-c2 ;; defined here
|
||||
:set-c1 ;; defined here
|
||||
:set-c0 ;; defined here
|
||||
;; Recommended by Kalkreuth et al: BUFa, NOTa, AND, OR, XOR, NAND, NOR, XNOR
|
||||
:boolean_bufa ;; defined here
|
||||
:boolean_nota ;; defined here
|
||||
:boolean_and
|
||||
:boolean_or
|
||||
:boolean_xor
|
||||
:boolean_nand ;; defined here
|
||||
:boolean_nor ;; defined here
|
||||
:boolean_xnor ;; defined here
|
||||
:boolean_dup
|
||||
:boolean_swap
|
||||
:boolean_rot
|
||||
:boolean_pop
|
||||
:integer_dup ;; will be a noop
|
||||
:exec_pop
|
||||
true
|
||||
false))
|
||||
|
||||
|
||||
|
||||
(defn error-function
|
||||
[argmap data individual]
|
||||
(let [program (genome/plushy->push (:plushy individual) argmap)
|
||||
input-maps (mapv :inputs data)
|
||||
correct-output-maps (mapv :outputs data)
|
||||
output-maps (mapv (fn [input-map]
|
||||
(:output
|
||||
(interpreter/interpret-program
|
||||
program
|
||||
(assoc state/empty-state
|
||||
:input input-map
|
||||
:output {:c7 :unset
|
||||
:c6 :unset
|
||||
:c5 :unset
|
||||
:c4 :unset
|
||||
:c3 :unset
|
||||
:c2 :unset
|
||||
:c1 :unset
|
||||
:c0 :unset})
|
||||
(:step-limit argmap))))
|
||||
input-maps)
|
||||
errors (flatten (map (fn [correct-output-map output-map]
|
||||
(mapv (fn [k]
|
||||
; no answer same as wrong answer
|
||||
(if (= (k correct-output-map)
|
||||
(k output-map))
|
||||
0
|
||||
1))
|
||||
[:c7 :c6 :c5 :c4 :c3 :c2 :c1 :c0]))
|
||||
correct-output-maps
|
||||
output-maps))]
|
||||
(assoc individual
|
||||
:behaviors output-maps
|
||||
:errors errors
|
||||
:total-error #?(:clj (apply +' errors)
|
||||
:cljs (apply + errors)))))
|
||||
|
||||
(defn -main
|
||||
"Runs the top-level genetic programming function, giving it a map of
|
||||
arguments with defaults that can be overridden from the command line
|
||||
or through a passed map."
|
||||
[& 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 100
|
||||
:population-size 100
|
||||
:max-initial-plushy-size 10
|
||||
:step-limit 1000
|
||||
:parent-selection :lexicase
|
||||
:tournament-size 5
|
||||
:umad-rate 0.01
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
@ -83,5 +83,4 @@
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -80,5 +80,4 @@
|
||||
:solution-error-threshold 0.5
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -82,5 +82,4 @@
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -101,5 +101,4 @@
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 1.0 :crossover 0.0}
|
||||
:elitism false}
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
|
||||
(#?(:clj shutdown-agents)))
|
||||
(apply hash-map (map #(if (string? %) (read-string %) %) args)))))
|
||||
|
@ -1,15 +0,0 @@
|
||||
(ns ^:no-doc propeller.problems.software.fizz-buzz
|
||||
(:require [psb2.core :as psb2]))
|
||||
|
||||
;; @todo This namespace is never used an it isn't a complete problem. Furthermore fizz-buzz exists in the PSB2 folder.
|
||||
;; Consider removing this file.
|
||||
|
||||
;; NOTE: Need to change directory below to location of the PSB2 files
|
||||
(def train-and-test (psb2/fetch-examples "PSB2/directory/path/goes/here/" "fizz-buzz" 200 2000))
|
||||
|
||||
(comment
|
||||
|
||||
train-and-test
|
||||
|
||||
problems
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user