Skip to content

Commit

Permalink
Merge pull request #231 from thelmuth/experiment/epsilon-lexicase
Browse files Browse the repository at this point in the history
Experiment/epsilon lexicase; lein release :minor
  • Loading branch information
lspector committed Feb 19, 2017
2 parents 1a36f63 + 70e2928 commit 0fac591
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 33 deletions.
17 changes: 0 additions & 17 deletions src/clojush/args.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
;; gorilla-repl.fileformat = 1

;; @@
(ns clojush.args
(:require [clj-random.core :as random])
(:use [clojush globals random util pushstate]
Expand Down Expand Up @@ -556,17 +553,3 @@
([argmap]
(load-push-argmap argmap)
(reset-globals)))













;; @@
1 change: 1 addition & 0 deletions src/clojush/globals.clj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
(def timing-map (atom {:initialization 0 :reproduction 0 :report 0 :fitness 0 :other 0})) ;; Used for timing of different parts of pushgp
(def solution-rates (atom (repeat 0))) ;; Used in historically-assessed hardness
(def elitegroups (atom ())) ;; Used for elitegroup lexicase selection (will only work if lexicase-selection is off)
(def epsilons-for-epsilon-lexicase (atom ())) ;; Used in epsilon lexicase. Only calculated once per population
(def population-behaviors (atom ())) ;; Used to store the behaviors of the population for use in tracking behavioral diversity
(def selection-counts (atom {})) ;; Used to store the number of selections for each individual, indexed by UUIDs

Expand Down
5 changes: 0 additions & 5 deletions src/clojush/pushgp/breed.clj
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,3 @@
(<= prob (second (first vectored-go-probabilities))))
(perform-genetic-operator (first (first vectored-go-probabilities)) population location rand-gen argmap)
(recur (rest vectored-go-probabilities)))))))





28 changes: 19 additions & 9 deletions src/clojush/pushgp/parent_selection.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

(ns clojush.pushgp.parent-selection
(:use [clojush random globals util])
(:require [clojure.set :as set]))
Expand Down Expand Up @@ -71,6 +70,9 @@
survivors)
(rest cases)))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; epsilon lexicase selection

(defn mad
"returns median absolute deviation (MAD)"
[x]
Expand All @@ -81,8 +83,21 @@
x)]
(median dev)))

(defn calculate-epsilons-for-epsilon-lexicase
"Calculates the epsilon values for epsilon lexicase selection. Only runs once
per generation. "
[pop-agents {:keys [epsilon-lexicase-epsilon]}]
(when (not epsilon-lexicase-epsilon)
(let [pop (map deref pop-agents)
test-case-errors (apply map list (map :errors pop))
meta-case-errors (apply map list (map :meta-errors pop))
all-errors (concat test-case-errors meta-case-errors)
epsilons (map mad all-errors)]
(println "Epsilons for epsilon lexicase:" epsilons)
(reset! epsilons-for-epsilon-lexicase epsilons))))

(defn epsilon-lexicase-selection
"Returns an individual that does within epsilon of the best on the fitness cases when considered one at a
"Returns an individual that does within epsilon of the best on the fitness cases when considered one at a
time in random order. If trivial-geography-radius is non-zero, selection is limited to parents within +/- r of location"
[pop location {:keys [trivial-geography-radius epsilon-lexicase-epsilon]}]
(let [lower (mod (- location trivial-geography-radius) (count pop))
Expand All @@ -100,12 +115,10 @@
(empty? (rest survivors)))
(lrand-nth survivors)
(let [; If epsilon-lexicase-epsilon is set in the argmap, use it for epsilon.
; Otherwise, use automatic epsilon selections. aka use MAD for epsilon.
; Otherwise, use automatic epsilon selections, which are calculated once per generation.
epsilon (if epsilon-lexicase-epsilon
epsilon-lexicase-epsilon
(mad (map #(nth (:errors %)
(first cases))
survivors)))
(nth @epsilons-for-epsilon-lexicase (first cases)))
min-err-for-case (apply min (map #(nth % (first cases))
(map #(:errors %) survivors)))]
(recur (filter #(<= (nth (:errors %)
Expand Down Expand Up @@ -236,6 +249,3 @@
1
(inc sel-count)))))
selected))



5 changes: 3 additions & 2 deletions src/clojush/pushgp/pushgp.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

(ns clojush.pushgp.pushgp
(:require [clojure.java.io :as io]
[clj-random.core :as random]
Expand Down Expand Up @@ -170,6 +169,9 @@
;; calculate implicit fitness sharing fitness for population
(when (= (:total-error-method @push-argmap) :ifs)
(calculate-implicit-fitness-sharing pop-agents @push-argmap))
;; calculate epsilons for epsilon lexicase selection
(when (= (:parent-selection @push-argmap) :epsilon-lexicase)
(calculate-epsilons-for-epsilon-lexicase pop-agents @push-argmap))
(timer @push-argmap :other)
;; report and check for success
(let [[outcome best] (report-and-check-for-success (vec (doall (map deref pop-agents)))
Expand All @@ -185,4 +187,3 @@
(install-next-generation pop-agents child-agents @push-argmap)
(recur (inc generation)))
:else (final-report generation best @push-argmap))))))))

0 comments on commit 0fac591

Please sign in to comment.