<commit_before>(ns evolution-programs.core
  (:require [clj-genetic.core :as ga]
            [clj-genetic.objective :as objective]
            [clj-genetic.selection :as selection]
            [clj-genetic.recombination :as recombination]
            [clj-genetic.mutation :as mutation]
            [clj-genetic.crossover :as crossover]
            [clj-genetic.random-generators :as random-generators]
            [evolution-programs.console :as console]
            [evolution-programs.chart :as chart]))

(defn- spread-logger [& loggers]
  (fn [p g]
    (doseq [l loggers] (l p g))))

(defn- preserving-fittest [f]
  (fn [& args]
    (let [population (last args)
          fittest (apply max-key #(:fitness (meta %)) population)
          new-pop (apply f args)]
      (if (.contains new-pop fittest)
        new-pop
        (cons fittest (rest new-pop))))))

(defn run
  ([objective limits]
   (run objective limits (spread-logger (console/logger) (chart/logger))))
  ([objective limits logger]
   (let [max-generations 50]
     (ga/run
       objective
       (preserving-fittest selection/binary-tournament-without-replacement)
       (preserving-fittest (partial recombination/crossover-mutation
                                    (partial crossover/simulated-binary-with-limits limits)
                                    (partial mutation/parameter-based-with-limits limits max-generations)))
       (ga/terminate-max-generations? max-generations)
       (random-generators/generate-population 30 limits)
       logger))))

(defn maximize [f & options] (apply run (cons (objective/maximize f) options)))<commit_msg>Update core; add helper for minimize function<commit_after>(ns evolution-programs.core
  (:require [clj-genetic.core :as ga]
            [clj-genetic.objective :as objective]
            [clj-genetic.selection :as selection]
            [clj-genetic.recombination :as recombination]
            [clj-genetic.mutation :as mutation]
            [clj-genetic.crossover :as crossover]
            [clj-genetic.random-generators :as random-generators]
            [evolution-programs.console :as console]
            [evolution-programs.chart :as chart]))

(defn- spread-logger [& loggers]
  (fn [p g]
    (doseq [l loggers] (l p g))))

(defn- preserving-fittest [f]
  (fn [& args]
    (let [population (last args)
          fittest (apply max-key #(:fitness (meta %)) population)
          new-pop (apply f args)]
      (if (.contains new-pop fittest)
        new-pop
        (cons fittest (rest new-pop))))))

(defn run
  ([objective limits]
   (run objective limits (spread-logger (console/logger) (chart/logger))))
  ([objective limits logger]
   (let [max-generations 50]
     (ga/run
       objective
       (preserving-fittest selection/binary-tournament-without-replacement)
       (preserving-fittest (partial recombination/crossover-mutation
                                    (partial crossover/simulated-binary-with-limits limits)
                                    (partial mutation/parameter-based-with-limits limits max-generations)))
       (ga/terminate-max-generations? max-generations)
       (random-generators/generate-population 30 limits)
       logger))))

(defn maximize [f & options] (apply run (cons (objective/maximize f) options)))
(defn minimize [f & options] (apply run (cons (objective/minimize f) options)))
{'fraction_non_alphanumeric': 0.12046400951814396, 'fraction_numerical': 0.002379535990481856, 'mean_word_length': 2.5362776025236595, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '511784', 'n_tokens_mistral': 1062, 'n_tokens_neox': 992, 'n_words': 247}