added fitness proportionate selection + tests
This commit is contained in:
parent
2a76d32479
commit
c40f1f70f4
@ -21,9 +21,27 @@
|
||||
survivors)
|
||||
(rest cases))))))
|
||||
|
||||
(defn fitness-proportionate-selection
|
||||
"Selects an individual from the population using a fitness proportionate selection."
|
||||
[pop argmap]
|
||||
(let [pop-fits (->> pop ;convert from error to fitness, where fitness (probability) is (1/ (1+ tot_err))
|
||||
(map #(assoc % :fitness (/ 1 (inc (:total-error %))))))
|
||||
pop-total-fit (->> pop-fits
|
||||
(map :fitness)
|
||||
(reduce +))
|
||||
random-num (* (rand) pop-total-fit)
|
||||
sorted-by-fitness (->> pop-fits
|
||||
(sort-by :fitness)
|
||||
(reverse))]
|
||||
(loop [tot (:fitness (first sorted-by-fitness)) individuals sorted-by-fitness]
|
||||
(if (< random-num tot)
|
||||
(first individuals)
|
||||
(recur (+ tot (:fitness (first (rest individuals)))) (rest individuals))))))
|
||||
|
||||
(defn select-parent
|
||||
"Selects a parent from the population using the specified method."
|
||||
[pop argmap]
|
||||
(case (:parent-selection argmap)
|
||||
:tournament (tournament-selection pop argmap)
|
||||
:lexicase (lexicase-selection pop argmap)))
|
||||
:lexicase (lexicase-selection pop argmap)
|
||||
:roulette (fitness-proportionate-selection pop argmap)))
|
23
test/propeller/selection_test.cljc
Normal file
23
test/propeller/selection_test.cljc
Normal file
@ -0,0 +1,23 @@
|
||||
(ns propeller.selection-test
|
||||
(:require [clojure.test :as t]
|
||||
[propeller.selection :as s]))
|
||||
|
||||
|
||||
(t/deftest roulette-selection-test
|
||||
(t/testing "fitness proportionate selection"
|
||||
(t/testing "should correctly define the probabilities of selection"
|
||||
(t/is (let [ret (s/fitness-proportionate-selection '({:index 0 :total-error 0}
|
||||
{:index 1 :total-error 1}
|
||||
{:index 2 :total-error 1}
|
||||
{:index 3 :total-error 1}) {:empty :argmap})]
|
||||
(case (:index ret)
|
||||
0 (= (:fitness ret) 1) ;if we selected index 0, check that fitness is correctly calculated to 1
|
||||
(= (:fitness ret) 1/2)
|
||||
))))
|
||||
(t/testing "should always return the same individual if there is only one"
|
||||
(t/testing "desipte it having bad error"
|
||||
(t/is (= (:index (s/fitness-proportionate-selection '({:index 99 :total-error 109012390123}) {:empty :argmap}))
|
||||
99)))
|
||||
(t/testing "when it has low error"
|
||||
(t/is (= (:index (s/fitness-proportionate-selection '({:index 22 :total-error 0}) {:empty :argmap}))
|
||||
22))))))
|
Loading…
x
Reference in New Issue
Block a user