template<typename ProblemType>
class Experimenter#

A Class used for running experiments.

Template Parameters:

ProblemType – The type of the problems used in the experiments, needs to be a subclass of ioh::problem::Problem.

Public Types

using Algorithm = std::function<void(std::shared_ptr<ProblemType>)>#

A typedef for an optimizer; a function which takes a ioh::problem::Problem.

Public Functions

Experimenter() = delete#
Experimenter(const Experimenter&) = delete#
Experimenter(const Experimenter&&) = delete#
Experimenter &operator=(const Experimenter&) = delete#
Experimenter &operator=(const Experimenter&&) = delete#
~Experimenter() = default#
inline Experimenter(std::shared_ptr<suite::Suite<ProblemType>> suite, std::shared_ptr<Logger> logger, Algorithm algorithm = nullptr, const int independent_runs = 1)#

Constructs an Experimenter object from a Suite object and an Logger object.

  • suite – A suite object

  • logger – A csv logger object

  • algorithm – a function pointer of type Algorithm

  • independent_runs – the number of repetitions default = 1

inline void run()#

Runs the experiment; Evaluates algorithm_ on all problems X instances X dimensions, for N = independent_runs_ repeated runs.

inline void independent_runs(const int n)#

Set’s the number of independent runs to be used in run.


n – The number of runs

inline int independent_runs() const#

Get’s the number of independent runs to be used in run.

inline std::shared_ptr<suite::Suite<ProblemType>> suite() const#

Get method for suite_


Private suite_

inline std::shared_ptr<Logger> logger() const#

Get method for.



Private Members

std::shared_ptr<suite::Suite<ProblemType>> suite_#

The benchmark suite used in the Experiment.

std::shared_ptr<Logger> logger_#

A pointer to the logger.

Algorithm algorithm_#

A function pointer of type Algorithm.

int independent_runs_ = 1#

The number of independent runs to be performed.


inline friend std::ostream &operator<<(std::ostream &os, const Experimenter &obj)#

Prints a verbose representation of an Experimenter object to an output stream.


The output steam


class Logger#

Interface of loggers.

A logger is a class that has a log(log_info) function called by the problem and hosts a set of Trigger that determine when a log event should be handled (or silently passed).

By default, the Logger calls a log event if any of the triggers are fired, but you can use your own way to combine triggers if necessary.

If you need to handle any property, consider sub-classing logger::Watcher.

If not, the design enforces your subclass to declare which property it needs. Then, you can easily access them by their name through"name").


Using the call functions without having been attached to a problem first will results in an assert failure.

Subclassed by ioh::logger::Combine, ioh::logger::EAH, ioh::logger::Watcher

Public Functions

inline Logger(std::vector<std::reference_wrapper<logger::Trigger>> triggers, std::vector<std::reference_wrapper<logger::Property>> properties)#

Use this constructor if you just need to trigger a log event if ANY of the triggers are fired.


Do not pass references to members of your derived class, as this would pass a reference to an unitiliazed member, the base class constructor being always called first. Instead, use the empty Logger() constructor and then add the triggers manually in your own constructor.

inline Logger(trigger::Set &triggers, std::vector<std::reference_wrapper<logger::Property>> properties)#

Use this constructor if you want to combine triggers differently.

You can for instance combine your triggers in a trigger::All, so that the log event would be triggered only if ALL triggers are fired at once.

inline Logger()#

Use this constructor if you just need the interface without triggers or properties, for instance if you define default triggers/properties in your constructor.

Used by logger::Combine, for instance.


If you manage your own default triggers/properties, use _properties.insert_or_assign(name, std::ref(tp)); instead of classical access operators.

inline void trigger(logger::Trigger &when)#

Add the given trigger to the list.

inline virtual void log(const logger::Info &log_info)#

Check if the logger should be triggered and if so, call call(log_info).

inline virtual void attach_problem(const problem::MetaData &problem)#

Starts a new session for the given problem/instance/dimension/run.

This is called automatically by the Problem (or Suite) to which the Logger is attached, each time a change occurs (be it a new run, or a new problem instance).


If you override this function, do not forget to call the base class’ one.

virtual void attach_suite(const std::string &suite_name) = 0#

Starts a new session for the given Suite name.

virtual void call(const logger::Info &log_info) = 0#

Main entry point, called everytime a Trigger is true.

inline virtual void reset()#

Optional actions when the logger is detached from a suite/problem or the problem is reset.

Useful if you want to flush data, for instance, and/or start a new run of the linked algorithm.


You most probably don’t want to call this directly, but should call the Problem::reset() instead, which will call this anyway.


If you override this function, do not forget to call the base class’ one.

inline virtual void close()#

Shutdown behaviour.

virtual ~Logger() = default#
inline std::optional<problem::MetaData> problem() const#

Access the attached problem’s metadata.

Protected Functions

inline bool consistent_properties()#

Check that there is no duplicated properties (only in Debug builds).

inline void store_properties(std::vector<std::reference_wrapper<logger::Property>> &properties)#

Convert a vector of properties in a map of {name => property}.

Protected Attributes

trigger::Any any_#

Default combination of triggers instance.

trigger::Set &triggers_#

Lower-level interface.

std::optional<problem::MetaData> problem_#

Access to the problem.

std::map<std::string, std::reference_wrapper<logger::Property>> properties_#

Map property names to property references.

If your logger is handling any property, you can just iterate over them, if you need specific ones, you can call them by their name.

This holds reference to optionals, so to get the actual value of a property, you should:

  1. use at(…) and not operator[],

  2. use get() on the returned element,

  3. ensure that there actually is a valid value,

  4. use value() to get it.

    // With its name:"name").get().value()
    // If your iterating over the map:
    for(auto& p : _properties) { p.second.get().value();}

You can directly test if the property actually has a valid value:

if("name").get()) {...}

logger::Properties properties_vector_ = {}#

A vector with all the properties.