IAtari
Genetic algorithm generating AI capable to play Atari2600 games.
fitness.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "message.hpp"
4 #include "master.hpp"
5 #include <boost/asio/spawn.hpp>
6 #include <boost/interprocess/sync/interprocess_semaphore.hpp>
7 #include <vector>
8 #include <memory>
9 #include <functional>
10 #include <atomic>
11 #include <thread>
12 #include <numeric>
13 
15 {
16  template <typename Res, typename Params>
18  {
19  std::function<Res(const std::list<Res>&)> accumulate;
20  std::vector<Params> params;
21  std::vector<std::list<Res>> results;
22  boost::interprocess::interprocess_semaphore ready;
23  boost::interprocess::interprocess_semaphore processed;
24  bool stop = false;
25  std::atomic<bool> last;
26  public:
27  distributed_fitness(std::function<Res(const std::list<Res>&)> accumulate);
28  bool finished();
29  std::vector<Params> get_parameters(boost::asio::yield_context yield);
30  void set_results(std::vector<std::list<Res>> res,
31  boost::asio::yield_context yield);
32  void run(int i, int nb_iterations,
33  const std::vector<Params>& population,
34  std::vector<Res>& results);
35  };
36 
37  template <typename Res, typename Params>
38  distributed_fitness<Res, Params>::distributed_fitness(std::function<Res(const std::list<Res>&)> accumulate)
39  : accumulate(accumulate),
40  ready(0), processed(0), last(false)
41  {
42  }
43 
44  template <typename Res, typename Params>
46  {
47  return stop;
48  }
49 
50  template <typename Res, typename Params>
51  std::vector<Params> distributed_fitness<Res, Params>::get_parameters(boost::asio::yield_context)
52  {
53  ready.wait();
54  return params;
55  }
56 
57  template <typename Res, typename Params>
58  void distributed_fitness<Res, Params>::set_results(std::vector<std::list<Res>> res,
59  boost::asio::yield_context)
60  {
61  results = res;
62  processed.post();
63  if (last) stop = true;
64  }
65 
66  template <typename Res, typename Params>
67  void distributed_fitness<Res, Params>::run(int i, int nb_iterations,
68  const std::vector<Params>& population,
69  std::vector<Res>& res)
70  {
71  params.clear();
72  for (const auto& p : population)
73  {
74  params.emplace_back(p);
75  }
76  ready.post();
77  if (i == nb_iterations) last = true;
78  processed.wait();
79  for (unsigned int i = 0; i < results.size(); ++i)
80  {
81  res[i] = accumulate(results[i]);
82  }
83  }
84 
85  template <typename Res, typename Params>
86  std::shared_ptr<distributed_fitness<Res, Params>> make_distributed_fitness(int port,
87  std::function<Res(const std::list<Res>&)> accumulate,
88  int nb_eval_by_parameter = 1, int nb_eval_by_slave = 1)
89  {
90  auto fitness = std::make_shared<distributed_fitness<Res, Params>>(accumulate);
91  std::thread t([=]{ master<Res, Params>(port, nb_eval_by_parameter, nb_eval_by_slave).run(fitness); });
92  t.detach();
93  return fitness;
94  }
95 
96  namespace accumulate
97  {
98  template <typename T>
99  double mean_score(const std::list<T>& l)
100  {
101  return std::accumulate(l.begin(), l.end(), T{}, std::plus<T>()) / (double)l.size();
102  }
103  }
104 }
void set_results(std::vector< std::list< Res >> res, boost::asio::yield_context yield)
Definition: fitness.hpp:58
Definition: fitness.hpp:14
void run(Client client)
Definition: master.hpp:159
Definition: fitness.hpp:17
bool finished()
Definition: fitness.hpp:45
std::vector< Params > get_parameters(boost::asio::yield_context yield)
Definition: fitness.hpp:51
void run(int i, int nb_iterations, const std::vector< Params > &population, std::vector< Res > &results)
Definition: fitness.hpp:67
Definition: master.hpp:15
double mean_score(const std::list< T > &l)
Definition: fitness.hpp:99
std::shared_ptr< distributed_fitness< Res, Params > > make_distributed_fitness(int port, std::function< Res(const std::list< Res > &)> accumulate, int nb_eval_by_parameter=1, int nb_eval_by_slave=1)
Definition: fitness.hpp:86
distributed_fitness(std::function< Res(const std::list< Res > &)> accumulate)
Definition: fitness.hpp:38