diff --git a/README.md b/README.md index 59a7fc1..c7e68e0 100644 --- a/README.md +++ b/README.md @@ -125,8 +125,9 @@ Calling `(-main)` will run the default genetic programming problem. ## Description -Propel is an implementation of the Push programming -language and the PushGP genetic programming system in Clojure. +Propeller is an implementation of the Push programming +language and the PushGP genetic programming system in Clojure, based +on Tom Helmuth's little PushGP implementation [propel](https://github.com/thelmuth/propel). For more information on Push and PushGP see [http://pushlanguage.org](http://pushlanguage.org). diff --git a/src/propeller/gp.cljc b/src/propeller/gp.cljc index 852b26a..9b1d3a5 100644 --- a/src/propeller/gp.cljc +++ b/src/propeller/gp.cljc @@ -1,7 +1,6 @@ (ns propeller.gp "Main genetic programming loop." (:require [clojure.string] - [clojure.pprint] [propeller.genome :as genome] [propeller.simplification :as simplification] [propeller.variation :as variation] @@ -22,20 +21,21 @@ "Reports information each generation." [evaluations pop generation argmap training-data] (let [best (first pop)] - (clojure.pprint/pprint + (utils/pretty-map-println {: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) + :ds-indices (if (:downsample? argmap) + (map #(:index %) training-data) + nil) :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)))}) - (println))) + :average-total-error (float (/ (reduce + (map :total-error pop)) (count pop)))}))) (defn cleanup [] diff --git a/src/propeller/push/instructions/numeric.cljc b/src/propeller/push/instructions/numeric.cljc index ff47336..7de1e3c 100755 --- a/src/propeller/push/instructions/numeric.cljc +++ b/src/propeller/push/instructions/numeric.cljc @@ -183,6 +183,14 @@ Otherwise, acts as a NOOP" ;; FLOAT Instructions only ;; ============================================================================= +;; Divides the top two items on the float stack +;; If denominator is 0, returns 1.0 +(def-instruction + :float_div + ^{:stacks #{:float}} + (fn [state] + (make-instruction state #(float (if (zero? %2) 1 (/ %1 %2))) [:float :float] :float))) + ;; Pushes the cosine of the top FLOAT (def-instruction :float_cos diff --git a/src/propeller/utils.cljc b/src/propeller/utils.cljc index ea03d29..afc2faf 100755 --- a/src/propeller/utils.cljc +++ b/src/propeller/utils.cljc @@ -151,3 +151,14 @@ (if (coll? thing-or-collection) (rand-nth thing-or-collection) thing-or-collection)) + +(defn pretty-map-println + "Takes a map and prints it, with each key/value pair on its own line." + [mp] + (print "{") + (let [mp-seq (seq mp) + [first-key first-val] (first mp-seq)] + (println (pr-str first-key first-val)) + (doseq [[k v] (rest mp-seq)] + (println (str " " (pr-str k v))))) + (println "}"))