DeveloperPaul123 / genetic

A performant and flexible genetic algorithm implemented in C++20/23.
MIT License
18 stars 1 forks source link

Make selection strategy configurable #1

Open DeveloperPaul123 opened 1 year ago

DeveloperPaul123 commented 1 year ago

Currently it's not possible to customize the selection strategy via the dp::genetic::params object. This should be addressed with roulette_selection being the default.

DeveloperPaul123 commented 1 year ago

For the solve() function, I moved to using this:

template <typename PopulationType,
          dp::genetic::concepts::fitness_operator<ChromosomeType> FitnessOperator =
              dp::genetic::accumulation_fitness,
          dp::genetic::concepts::crossover_operator<ChromosomeType> CrossoverOperator =
              dp::genetic::default_crossover,
          dp::genetic::concepts::mutation_operator<ChromosomeType> MutationOperator =
              dp::genetic::noop_mutator,
          dp::genetic::concepts::termination_operator<
              ChromosomeType, std::invoke_result_t<FitnessOperator, ChromosomeType>>
              TerminationOperator = dp::genetic::generations_termination_criteria,
          dp::genetic::concepts::selection_operator<ChromosomeType, PopulationType,
                                                    FitnessOperator>
              SelectionOperator = dp::genetic::roulette_selection,
          typename IterationCallback = std::function<void(const iteration_statistics&)>>
    requires dp::genetic::concepts::population<PopulationType, ChromosomeType> &&
             std::invocable<IterationCallback, const iteration_statistics&>
[[nodiscard]] results solve(
            const PopulationType& initial_population,
            const IterationCallback& callback = [](const iteration_statistics&) {},
            FitnessOperator fitness = FitnessOperator{},
            MutationOperator mutator = MutationOperator{},
            CrossoverOperator crossover = CrossoverOperator{},
            TerminationOperator termination = TerminationOperator{},
            SelectionOperator selector = SelectionOperator{}) 

Which is honestly quite ridiculous.

It would be ideal to have a parameter object that can be passed in with sensible default and then we can use designated initializers to customize it.