Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into track-selection-counts
- Loading branch information
Showing
18 changed files
with
1,101 additions
and
606 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,4 @@ lib/ | |
/bin | ||
*.csv | ||
*.json | ||
.lein-failures |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
src/clojush/pushgp/report.clj: (map-indexed (fn [location individual] | ||
src/clojush/pushgp/report.clj~: (doseq [[ind p] (map-indexed vector population)] | ||
src/clojush/pushgp/report.clj~: (doseq [[ind p] (map-indexed vector population)] | ||
src/clojush/pushstate.clj:(let [empty-state (map->PushState {})] |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
;; the_idea_of_numbers.clj | ||
;; Bill Tozier, bill@vagueinnovation.com | ||
;; | ||
;; This implements a common pedagogic demonstration from classes I | ||
;; teach in GP. The objective is a simple symbolic regression problem | ||
;; except there are no numeric ERCs. | ||
;; | ||
;; Input and output are given as integers using the integer stack. | ||
|
||
(ns clojush.problems.tozier.the-idea-of-numbers | ||
(:use clojush.pushgp.pushgp | ||
[clojush pushstate interpreter random util] | ||
[clojure.math.numeric-tower] | ||
)) | ||
|
||
|
||
(defn birthday-polynomial | ||
"Returns a polynomial y = YYYY + MM * x * DD * x * x" | ||
[x year month day] | ||
(+ year (* month x) (* day x x)) | ||
) | ||
|
||
|
||
(defn missing-numbers-error-function | ||
"Returns the absolute error." | ||
[number-test-cases] | ||
(fn [program] | ||
(doall | ||
(for [input (range 0 number-test-cases)] | ||
(let [final-state (run-push program | ||
(push-item input :input | ||
(make-push-state))) | ||
result-output (top-item :integer final-state)] | ||
(if (and (number? result-output)) | ||
(abs (- result-output (birthday-polynomial input 1964 9 11))) ;; edit this so it's your birthday | ||
1000000000) | ||
))))) | ||
|
||
; Atom generators | ||
(def missing-numbers-atom-generators | ||
(cons 'in1 | ||
(registered-for-stacks [:integer :code :boolean :exec :char :string :float]))) | ||
|
||
|
||
|
||
; Define the argmap | ||
(def argmap | ||
{:error-function (missing-numbers-error-function 20) | ||
:atom-generators missing-numbers-atom-generators | ||
:max-points 500 | ||
:max-genome-size-in-initial-program 300 | ||
:evalpush-limit 1000 | ||
:population-size 1000 | ||
:max-generations 300 | ||
:parent-selection :lexicase | ||
:final-report-simplifications 1000 | ||
:genetic-operator-probabilities { | ||
:alternation 0.5 | ||
:uniform-mutation 0.5} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
;; winkler01.clj | ||
;; Bill Tozier, bill@vagueinnovation.com | ||
;; | ||
;; This is code for running Tozier's variant on Winkler's Zeros-and-Ones puzzle: | ||
;; For any positive (non-zero) integer input, return a strictly positive integer which | ||
;; when multiplied by the input value produces a result which contains only the | ||
;; digits 0 and 1 (in base 10 notation) | ||
;; | ||
;; Input and output are given as integers using the integer stack. | ||
|
||
(ns clojush.problems.tozier.winkler01 | ||
(:use clojush.pushgp.pushgp | ||
[clojush pushstate interpreter random util] | ||
[clojure.math.numeric-tower] | ||
)) | ||
|
||
; Create the error function | ||
(defn count-digits [num] (count (re-seq #"\d" (str num)))) | ||
|
||
|
||
(defn proportion-not-01 | ||
"Returns the proportion of digits in the argument integer which are not 0 or 1" | ||
[num] | ||
(let [counts (frequencies (re-seq #"\d" (str num)))] | ||
(- 1 | ||
(/ (+ (get counts "0" 0) | ||
(get counts "1" 0)) | ||
(count-digits num))))) | ||
|
||
|
||
(defn kill-trailing-zeros | ||
"Returns an integer with all trailing zeros stripped off" | ||
[num] | ||
(read-string (clojure.string/replace (str num) #"(0+)$" "")) | ||
) | ||
|
||
|
||
;; "obvious" first attempt at an error function | ||
(defn winkler-error-function-01 | ||
"Returns the proportion of digits in the product of input * output that are not 0 or 1." | ||
[number-test-cases] | ||
(fn [program] | ||
(doall | ||
(for [input (range 1 number-test-cases)] | ||
(let [final-state (run-push program | ||
(push-item input :input | ||
(make-push-state))) | ||
result-output (top-item :integer final-state)] | ||
(when false (println ;; change to true to print every result (which is awful) | ||
(if (and (number? result-output) (pos? result-output)) | ||
(* input result-output) | ||
"N/A"))) | ||
(if (and (number? result-output) (pos? result-output)) | ||
(proportion-not-01 (* input result-output)) | ||
100) | ||
))))) | ||
|
||
|
||
;; "obvious" second attempt at an error function; | ||
;; accommodation to trivial strategy of multiplying by 10000000... | ||
(defn winkler-error-function-02 | ||
"Returns the proportion of digits in the product of input * output that are not 0 or 1, after trimming trailing zeros." | ||
[number-test-cases] | ||
(fn [program] | ||
(doall | ||
(for [input (range 1 number-test-cases)] | ||
(let [final-state (run-push program | ||
(push-item input :input | ||
(make-push-state))) | ||
result-output (top-item :integer final-state)] | ||
(when false (println ;; change to true to print every result (which is awful) | ||
(if (and (number? result-output) (pos? result-output)) | ||
(* input result-output) | ||
"N/A"))) | ||
(if (and (number? result-output) (pos? result-output)) | ||
(proportion-not-01 (kill-trailing-zeros (* input result-output))) | ||
100) | ||
))))) | ||
|
||
|
||
;; trying to give it some raw materials it might want to use | ||
|
||
(defn prime-factors | ||
"Return a vector of the prime factors of the argument integer; cadged from http://rosettacode.org/wiki/Prime_decomposition#Clojure" | ||
([num] | ||
(prime-factors num 2 ())) | ||
([num k acc] | ||
(if (= 1 num) | ||
acc | ||
(if (= 0 (rem num k)) | ||
(recur (quot num k) k (cons k acc)) | ||
(recur num (inc k) acc))))) | ||
|
||
|
||
(defn prime-factors-as-sorted-vector | ||
"Return the argument's prime factors as a sorted vector of integers; if the argument is 0, it returns (0); if the argument is negative, it returns the factors of the positive number with -1 added to the list;" | ||
[num] | ||
(cond | ||
(pos? num) (into [] (sort (prime-factors num))) | ||
(neg? num) (into [] (cons -1 (sort (prime-factors (abs num))))) | ||
:else [0] | ||
)) | ||
|
||
|
||
; Define new instructions | ||
(define-registered | ||
integer_factors | ||
^{:stack-types [:integer :vector_integer]} | ||
(fn [state] | ||
(if (not (empty? (:integer state))) | ||
(push-item (prime-factors-as-sorted-vector (stack-ref :integer 0 state)) | ||
:vector_integer | ||
(pop-item :integer state)) | ||
state))) | ||
|
||
|
||
; Atom generators | ||
(def winkler-atom-generators | ||
(concat (take 100 (repeat 'in1)) | ||
(take 50 (repeat (fn [] (lrand-int 65536)))) ;Integer ERC [0,65536] | ||
(registered-for-stacks [:integer :code :boolean :exec :vector_integer :char :string :float]))) | ||
|
||
|
||
|
||
; Define the argmap | ||
(def argmap | ||
{:error-function (winkler-error-function-02 44) ;; change the error function to follow along... | ||
:atom-generators winkler-atom-generators | ||
:max-points 1000 | ||
:print-csv-logs true | ||
:csv-columns [:generation :location :parent-uuids :genetic-operators :push-program-size :push-program :total-error :test-case-errors] | ||
:csv-log-filename "log.csv" | ||
:max-genome-size-in-initial-program 500 | ||
:evalpush-limit 1000 | ||
:population-size 1000 | ||
:max-generations 1000 | ||
:parent-selection :lexicase | ||
:final-report-simplifications 1000 | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
; To run these tests with autotest use: | ||
; | ||
; lein midje :autotest test | ||
; | ||
; This runs everything in the test sub-directory but | ||
; _doesn't_ run all the stuff in src, which midje tries | ||
; to run by default, which breaks the world. | ||
|
||
(ns clojush.midje.interpreter.literal-handling | ||
(:use clojure.test | ||
midje.sweet | ||
clojush.interpreter | ||
clojush.pushstate)) | ||
|
||
(fact "Evaluating a null instruction returns the same state" | ||
(execute-instruction nil :test-state) => :test-state) | ||
|
||
(fact "Evaluating an integer constant as an instruction adds that value to the integer stack" | ||
(let [test-state (make-push-state) | ||
value 8] | ||
(:integer (execute-instruction value (make-push-state))) => (list value))) |
46 changes: 46 additions & 0 deletions
46
test/clojush/midje/problems/tozier/the_idea_of_numbers.clj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
; To run these tests with autotest use: | ||
; | ||
; lein midje :autotest test | ||
; | ||
; This runs everything in the test sub-directory but | ||
; _doesn't_ run all the stuff in src, which midje tries | ||
; to run by default, which breaks the world. | ||
|
||
(ns clojush.midje.problems.tozier.the-idea-of-numbers | ||
(:use clojure.test | ||
clojush.pushstate | ||
clojush.interpreter | ||
midje.sweet | ||
clojush.problems.tozier.the-idea-of-numbers)) | ||
|
||
(facts "birthday-polynomial works as expected" | ||
(birthday-polynomial 0 0 0 0) => 0 | ||
(birthday-polynomial 1 1 1 1) => 3 ;; 1 + 1*1 + 1*1*1 | ||
(birthday-polynomial 2 3 4 5) => 31 ;; 3 + 4*2 + 5*2*2 | ||
(birthday-polynomial 0 1988 9 12) => 1988 | ||
) | ||
|
||
;; checking error function | ||
;; | ||
|
||
(fact "missing-numbers-error-function responds with the number of cases indicated by the argument" | ||
(count ((missing-numbers-error-function 5) '())) => 5 ;; (tests on 0,1,2,3,4) | ||
) | ||
|
||
(fact "missing-numbers-error-function produces the expected penalties when no answer is returned" | ||
((missing-numbers-error-function 2) '()) => (just 1000000000 1000000000) ;; empty program | ||
) | ||
|
||
(fact "missing-numbers-error-function produces the expected scores" | ||
((missing-numbers-error-function 3) '(0)) => (just 1964 1984 2026) ;; 1964+0; 1964+9+11; 1964+18+36 | ||
((missing-numbers-error-function 3) '(1000)) => (just 964 984 1026) ;; 1000 closer! | ||
((missing-numbers-error-function 3) | ||
'(1964 9 in1 integer_mult 11 in1 in1 integer_mult integer_mult integer_add integer_add)) => (just 0 0 0) ;; the right answer | ||
) | ||
|
||
;; check atom-generators | ||
(fact "atom-generators have no numbers" | ||
missing-numbers-atom-generators => (has not-any? integer?)) | ||
|
||
(fact "atom-generators does include the input (always good to check)" | ||
missing-numbers-atom-generators => (contains ['in1])) |
Oops, something went wrong.