001 (ns nature.monitors
002 "Helper functions to inspect generations and return run-time information, statistics, etc.")
003
004 (defn apply-monitors
005 "Apply each function in `monitors` against `population` and `current-generation`"
006 [monitors population current-generation]
007 (let [fns (apply juxt monitors)]
008 (do (fns population current-generation))))
009
010 (defn mk-monitor
011 "Apply `monitor-fn` to the `population` and `current-generation`, and print the result.
012 If a `format-fn` has been supplied, modify the output before printing.
013 This is useful for separating the monitor code into a separate testable function."
014 ([monitor-fn population current-generation]
015 (println (monitor-fn population current-generation)))
016
017 ([monitor-fn population current-generation format-fn]
018 (println (format-fn (monitor-fn population current-generation)))))
019
020 (defn print-best-solution*
021 "Finds the individual with the highest fitness in `population`"
022 [population current-generation]
023 (first (sort-by :fitness-score #(> %1 %2) population)))
024
025 (defn print-best-solution
026 "Finds the individual with the highest fitness in `population`, and prints it to std-out"
027 [population current-generation]
028 (mk-monitor print-best-solution* population current-generation))
029
030 (defn print-worst-solution*
031 "Finds the individual with the lowest fitness in `population`"
032 [population current-generation]
033 (first (sort-by :fitness-score #(> %2 %1) population)))
034
035 (defn print-worst-solution
036 "Finds the individual with the lowest fitness in `population`, and prints it to std-out"
037 [population current-generation]
038 (mk-monitor print-worst-solution* population current-generation))
039
040 (defn print-solution-frequencies*
041 "Finds how frequently each genetic sequence is repeated across the `population`"
042 [population current-generation]
043 (frequencies (map :genetic-sequence population)))
044
045 (defn print-solution-frequencies
046 "Finds how frequently each genetic sequence is repeated across the `population`, and prints it to std-out"
047 [population current-generation]
048 (mk-monitor print-solution-frequencies* population current-generation))
049
050 (defn print-fitness-score-frequencies*
051 "Finds how frequently each fitness score is repeated across the `population`"
052 [population current-generation]
053 (frequencies (map :fitness-score population)))
054
055 (defn print-fitness-score-frequencies
056 "Finds how frequently each fitness score is repeated across the `population`, and prints it to std-out"
057 [population current-generation]
058 (mk-monitor print-fitness-score-frequencies* population current-generation))