Skip to content

Commit

Permalink
Encoding floating point NTTPs
Browse files Browse the repository at this point in the history
  • Loading branch information
kataklinger committed Mar 5, 2024
1 parent b18e4dd commit d8b79da
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 65 deletions.
18 changes: 9 additions & 9 deletions sample/simple/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void simple() {
.stop(criteria::generation_limit{100})
//.select(select::random{select::unique<4>, rng})
.select(select::roulette_raw{select::unique<4>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::worst_raw{})
.observe(observe{generation_event, f1::observe{}})
.build<soo::algo>()
Expand Down Expand Up @@ -161,7 +161,7 @@ void nsga() {
.prune(prune::none{})
.project(project::factory<project::scale, int_rank_t>{})
.select(select::roulette_scaled{select::unique<4>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::total{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down Expand Up @@ -198,7 +198,7 @@ void nsga_ii() {
.project(project::factory<project::merge, int_rank_t>{})
.select(
select::tournament_scaled{select::unique<2>, select::rounds<2>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::append{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down Expand Up @@ -233,7 +233,7 @@ void spea() {
.prune(prune::cluster_edge{})
.project(project::factory<project::truncate, real_rank_t>{})
.select(select::roulette_scaled{select::unique<4>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::append{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down Expand Up @@ -268,7 +268,7 @@ void spea_ii() {
.prune(prune::global_worst<int_rank_t>{})
.project(project::factory<project::translate, int_rank_t>{})
.select(select::roulette_scaled{select::unique<4>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::append{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down Expand Up @@ -303,7 +303,7 @@ void rdga() {
.prune(prune::none{})
.project(project::factory<project::alternate, int_rank_t>{})
.select(select::roulette_scaled{select::unique<4>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::nondominating_parents_raw{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down Expand Up @@ -342,7 +342,7 @@ void pesa() {
.prune(prune::cluster_random{rng})
.project(project::factory<project::truncate, crowd_density_t>{})
.select(select::roulette_scaled{select::unique<4>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::append{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down Expand Up @@ -378,7 +378,7 @@ void pesa_ii() {
.project(project::factory<project::none>{})
.select(select::cluster{
gal::select::shared<cluster_label>, select::unique<4>, rng})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::append{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down Expand Up @@ -418,7 +418,7 @@ void paes() {
.prune(prune::cluster_random{rng})
.project(project::factory<project::truncate, crowd_density_t>{})
.select(select::lineal_scaled{})
.couple(couple::parametrize<couple::exclusive, 0.8f, 0.2f, true>(rng))
.couple(couple::parametrize<couple::exclusive, 0.8, 0.2, true>(rng))
.replace(replace::append{})
.observe(observe{generation_event, f1f2::observe{}})
.build<moo::algo>()
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ list(APPEND HEADER_LIST
elitism.hpp
fitness.hpp
individual.hpp
literals.hpp
moo.hpp
multiobjective.hpp
mutation.hpp
Expand Down
2 changes: 1 addition & 1 deletion src/inc/chromosome.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ concept matcher =
Operation,
std::add_lvalue_reference_t<std::add_const_t<Chromosome>>,
std::add_lvalue_reference_t<std::add_const_t<Chromosome>>> &&
util::arithmetic<std::invoke_result_t<
util::runtime_arithmetic<std::invoke_result_t<
Operation,
std::add_lvalue_reference_t<std::add_const_t<Chromosome>>,
std::add_lvalue_reference_t<std::add_const_t<Chromosome>>>>;
Expand Down
16 changes: 8 additions & 8 deletions src/inc/coupling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@

namespace gal::couple {

template<auto Crossover,
auto Mutation,
template<literals::fp_const Crossover,
literals::fp_const Mutation,
util::boolean_flag MutationImproveOnly,
typename Generator>
requires(probability<Crossover> && probability<Mutation>)
requires(execution_probability<Crossover> && execution_probability<Mutation>)
class reproduction_params {
public:
using generator_t = Generator;
using mutation_improve_only_t = MutationImproveOnly;

inline static constexpr auto crossover_probability = Crossover;
inline static constexpr auto mutation_probability = Mutation;
inline static constexpr double crossover_probability = Crossover;
inline static constexpr double mutation_probability = Mutation;

public:
inline explicit reproduction_params(generator_t& generator) noexcept
Expand Down Expand Up @@ -415,12 +415,12 @@ inline constexpr auto parametrize(Params const& params) {
}

template<template<typename, typename> class Coupling,
auto Crossover,
auto Mutation,
literals::fp_const Crossover,
literals::fp_const Mutation,
bool MutationImproveOnly,
typename Generator>
inline constexpr auto parametrize(Generator& generator)
requires(probability<Crossover> && probability<Mutation>)
requires(execution_probability<Crossover> && execution_probability<Mutation>)
{
using params_t = reproduction_params<Crossover,
Mutation,
Expand Down
2 changes: 1 addition & 1 deletion src/inc/crowding.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ class neighbor {
};

// cell-sharing (rdga, pesa, paes)
template<double Alpha = 1.>
template<literals::fp_const Alpha = 1.>
class cluster {
public:
template<crowded_population Population, typename Preserved>
Expand Down
30 changes: 30 additions & 0 deletions src/inc/literals.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <bit>
#include <cstddef>

namespace gal::literals {

struct fp_const {
fp_const() = default;

inline constexpr fp_const(double value) noexcept
: rep_{std::bit_cast<std::size_t>(value)} {
}

inline constexpr double value() const noexcept {
return std::bit_cast<double>(rep_);
}

inline constexpr operator double() const noexcept {
return value();
}

std::size_t rep_{};
};

inline constexpr fp_const operator""_fc(long double value) noexcept {
return fp_const{static_cast<double>(value)};
}

} // namespace gal::literals
17 changes: 8 additions & 9 deletions src/inc/operation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,31 +152,30 @@ concept coupling_factory =
typename Context::population_t,
Parents>;

template<auto Probability>
concept probability = Probability >= 0.f && Probability <= 1.f &&
std::floating_point<decltype(Probability)>;
template<literals::fp_const Probability>
concept execution_probability = Probability >= 0. && Probability <= 1.;

template<typename Generator, auto Probability>
requires(probability<Probability>)
template<typename Generator, literals::fp_const Probability>
requires(execution_probability<Probability>)
struct probabilistic_operation {
public:
using generator_t = Generator;
using distribution_t = std::uniform_real_distribution<decltype(Probability)>;
using distribution_t = std::uniform_real_distribution<double>;

public:
inline explicit probabilistic_operation(generator_t& generator) noexcept
: generator_{&generator} {
}

inline bool operator()() const {
if constexpr (Probability == 0.f) {
if constexpr (Probability == 0.) {
return false;
}
else if constexpr (Probability == 1.f) {
else if constexpr (Probability == 1.) {
return true;
}

return distribution_t{0.f, 1.f}(*generator_) < Probability;
return distribution_t{0., 1.}(*generator_) < Probability;
}

private:
Expand Down
44 changes: 20 additions & 24 deletions src/inc/scaling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

namespace gal::scale {

template<auto Constant>
concept scaling_constant = util::arithmetic<decltype(Constant)>;

namespace details {

using linear_coefficients = std::pair<double, double>;
Expand All @@ -17,7 +14,7 @@ namespace details {
return std::fabs(delta) < 0.00001;
}

template<auto Preassure, fitness Fitness>
template<literals::fp_const Preassure, fitness Fitness>
linear_coefficients caclulate_linear_coefficients(Fitness const& fmin,
Fitness const& favg,
Fitness const& fmax) {
Expand Down Expand Up @@ -67,8 +64,7 @@ concept linear_context =
stats::extreme_fitness<raw_fitness_tag>,
stats::average_fitness<raw_fitness_tag>>;

template<linear_context Context, auto Preassure>
requires(scaling_constant<Preassure>)
template<linear_context Context, literals::fp_const Preassure>
class linear {
public:
using is_stable_t = std::true_type;
Expand Down Expand Up @@ -203,8 +199,7 @@ concept ranked_context =
sortable_population<typename Context::population_t, raw_fitness_tag> &&
details::scalable_from<Context, double>;

template<ranked_context Context, auto Preassure>
requires(scaling_constant<Preassure>)
template<ranked_context Context, literals::fp_const Preassure>
class ranked {
public:
using is_stable_t = std::true_type;
Expand Down Expand Up @@ -239,14 +234,12 @@ class ranked {
population_t* population_;
};

template<typename Context, typename Base>
template<typename Context>
concept exponential_context =
sortable_population<typename Context::population_t, raw_fitness_tag> &&
details::scalable_from<Context, Base>;
details::scalable_from<Context, double>;

template<typename Context, auto Base>
requires(exponential_context<Context, decltype(Base)> &&
scaling_constant<Base>)
template<exponential_context Context, literals::fp_const Base>
class exponential {
public:
using is_stable_t = std::true_type;
Expand All @@ -272,7 +265,8 @@ class exponential {
inline void operator()(ordinal_t ordinal, individual_t& individual) const {
auto& eval = individual.eval();

auto power = population_->current_size() - *ordinal - 1;
auto power =
static_cast<double>(population_->current_size() - *ordinal - 1);
eval.set_scaled(scaled_fitness_t{std::pow(Base, power)});
}

Expand All @@ -285,17 +279,17 @@ concept proportional_fitness = requires(Fitness f, Proportion p) {
{ p* f } -> std::convertible_to<Output>;
};

template<typename Context, typename Proportion>
template<typename Context>
concept proportional_context =
sortable_population<typename Context::population_t, raw_fitness_tag> &&
proportional_fitness<typename Context::population_t::raw_fitness_t,
Proportion,
double,
typename Context::population_t::scaled_fitness_t>;

template<typename Context, auto OrdinalCutoff, auto Proportion>
requires(proportional_context<Context, decltype(Proportion)> &&
std::integral<decltype(OrdinalCutoff)> && OrdinalCutoff > 0 &&
scaling_constant<Proportion>)
template<proportional_context Context,
auto OrdinalCutoff,
literals::fp_const Proportion>
requires(std::integral<decltype(OrdinalCutoff)> && OrdinalCutoff > 0)
class top {
public:
using is_stable_t = std::true_type;
Expand Down Expand Up @@ -335,14 +329,13 @@ concept power_fitness = requires(Fitness f, Power p) {
{ std::pow(f, p) } -> std::convertible_to<Output>;
};

template<typename Context, typename Power>
template<typename Context>
concept power_context =
power_fitness<typename Context::population_t::raw_fitness_t,
Power,
double,
typename Context::population_t::scaled_fitness_t>;

template<typename Context, auto Power>
requires(power_context<Context, decltype(Power)> && scaling_constant<Power>)
template<power_context Context, literals::fp_const Power>
class power {
public:
using is_stable_t = std::true_type;
Expand Down Expand Up @@ -412,6 +405,9 @@ class window {
stats::history<statistics_t>* statistics_;
};

template<auto Constant>
concept scaling_constant = util::compile_arithmetic<decltype(Constant)>;

template<template<typename, auto...> class Scaling, auto... Parameters>
requires(scaling_constant<Parameters> && ...)
struct factory {
Expand Down
4 changes: 2 additions & 2 deletions src/inc/statistics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ using average_fitness_scaled = average_fitness<scaled_fitness_tag>;
template<typename Value>
struct square_power;

template<util::arithmetic Value>
template<util::runtime_arithmetic Value>
struct square_power<Value> {
using result_t = Value;

Expand All @@ -430,7 +430,7 @@ using square_power_result_t = typename square_power<Value>::result_t;
template<typename Value>
struct square_root;

template<util::arithmetic Value>
template<util::runtime_arithmetic Value>
struct square_root<Value> {
using result_t = Value;

Expand Down
9 changes: 8 additions & 1 deletion src/inc/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <concepts>
#include <type_traits>

#include "literals.hpp"

namespace gal::util {

template<typename Ref, typename Decayed>
Expand Down Expand Up @@ -57,7 +59,12 @@ template<typename From, typename To>
concept decays_to = std::same_as<std::decay_t<From>, To>;

template<typename Value>
concept arithmetic = std::integral<Value> || std::floating_point<Value>;
concept runtime_arithmetic = std::integral<Value> || std::floating_point<Value>;

template<typename Value>
concept compile_arithmetic =
std::integral<Value> ||
std::same_as<Value, std::remove_const_t<literals::fp_const>>;

template<typename Ty, boolean_flag Condition>
inline decltype(auto) move_if(Ty&& value, Condition /*unused*/) noexcept {
Expand Down
Loading

0 comments on commit d8b79da

Please sign in to comment.