1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-04-09 21:50:45 +01:00

Hadrons: a bit of cleaning in the scheduler

This commit is contained in:
Antonin Portelli 2016-12-10 21:14:13 +01:00
parent 51322da6f8
commit 4a87486365

View File

@ -40,7 +40,9 @@ template <typename T>
class GeneticScheduler class GeneticScheduler
{ {
public: public:
typedef std::function<int(const std::vector<T> &)> ObjFunc; typedef std::vector<T> Gene;
typedef std::pair<Gene *, Gene *> GenePair;
typedef std::function<int(const Gene &)> ObjFunc;
struct Parameters struct Parameters
{ {
double mutationRate; double mutationRate;
@ -53,8 +55,8 @@ public:
// destructor // destructor
virtual ~GeneticScheduler(void) = default; virtual ~GeneticScheduler(void) = default;
// access // access
const std::vector<T> & getMinSchedule(void); const Gene & getMinSchedule(void);
int getMinValue(void); int getMinValue(void);
// breed a new generation // breed a new generation
void nextGeneration(void); void nextGeneration(void);
// print population // print population
@ -71,19 +73,20 @@ public:
return out; return out;
} }
private: private:
// randomly initialize population // evolution steps
void initPopulation(void); void initPopulation(void);
void doCrossover(void);
void doMutation(void);
// genetic operators // genetic operators
std::vector<T> * select1(void); GenePair selectPair(void);
std::pair<std::vector<T> *, std::vector<T> *> select2(void); void crossover(Gene &c, const Gene &p1, const Gene &p2);
void crossover(void); void mutation(Gene &m, const Gene &c);
void mutation(void);
private: private:
Graph<T> &graph_; Graph<T> &graph_;
const ObjFunc &func_; const ObjFunc &func_;
const Parameters par_; const Parameters par_;
std::multimap<int, std::vector<T>> population_; std::multimap<int, Gene> population_;
std::mt19937 gen_; std::mt19937 gen_;
}; };
/****************************************************************************** /******************************************************************************
@ -102,7 +105,8 @@ GeneticScheduler<T>::GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
// access ////////////////////////////////////////////////////////////////////// // access //////////////////////////////////////////////////////////////////////
template <typename T> template <typename T>
const std::vector<T> & GeneticScheduler<T>::getMinSchedule(void) const typename GeneticScheduler<T>::Gene &
GeneticScheduler<T>::getMinSchedule(void)
{ {
return population_.begin()->second; return population_.begin()->second;
} }
@ -128,7 +132,7 @@ void GeneticScheduler<T>::nextGeneration(void)
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for (unsigned int i = 0; i < par_.popSize; ++i) for (unsigned int i = 0; i < par_.popSize; ++i)
{ {
mutation(); doMutation();
} }
LOG(Debug) << "After mutations:\n" << *this << std::endl; LOG(Debug) << "After mutations:\n" << *this << std::endl;
@ -136,7 +140,7 @@ void GeneticScheduler<T>::nextGeneration(void)
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for (unsigned int i = 0; i < par_.popSize/2; ++i) for (unsigned int i = 0; i < par_.popSize/2; ++i)
{ {
crossover(); doCrossover();
} }
LOG(Debug) << "After mating:\n" << *this << std::endl; LOG(Debug) << "After mating:\n" << *this << std::endl;
@ -148,7 +152,7 @@ void GeneticScheduler<T>::nextGeneration(void)
LOG(Debug) << "After grim reaper:\n" << *this << std::endl; LOG(Debug) << "After grim reaper:\n" << *this << std::endl;
} }
// randomly initialize population ////////////////////////////////////////////// // evolution steps /////////////////////////////////////////////////////////////
template <typename T> template <typename T>
void GeneticScheduler<T>::initPopulation(void) void GeneticScheduler<T>::initPopulation(void)
{ {
@ -161,24 +165,50 @@ void GeneticScheduler<T>::initPopulation(void)
} }
} }
// genetic operators ///////////////////////////////////////////////////////////
template <typename T> template <typename T>
std::vector<T> * GeneticScheduler<T>::select1(void) void GeneticScheduler<T>::doCrossover(void)
{ {
std::uniform_int_distribution<unsigned int> pdis(0, population_.size() - 1); auto p = selectPair();
auto &p1 = *(p.first), &p2 = *(p.second);
Gene c1, c2;
auto it = population_.begin(); crossover(c1, p1, p2);
std::advance(it, pdis(gen_)); crossover(c2, p2, p1);
PARALLEL_CRITICAL
return &(it->second); {
population_.emplace(func_(c1), c1);
population_.emplace(func_(c2), c2);
}
} }
template <typename T> template <typename T>
std::pair<std::vector<T> *, std::vector<T> *> GeneticScheduler<T>::select2(void) void GeneticScheduler<T>::doMutation(void)
{
std::uniform_real_distribution<double> mdis(0., 1.);
std::uniform_int_distribution<unsigned int> pdis(0, population_.size() - 1);
if (mdis(gen_) < par_.mutationRate)
{
Gene m;
auto it = population_.begin();
std::advance(it, pdis(gen_));
mutation(m, it->second);
PARALLEL_CRITICAL
{
population_.erase(it);
population_.emplace(func_(m), m);
}
}
}
// genetic operators ///////////////////////////////////////////////////////////
template <typename T>
typename GeneticScheduler<T>::GenePair GeneticScheduler<T>::selectPair(void)
{ {
std::vector<double> prob; std::vector<double> prob;
unsigned int ind; unsigned int ind;
std::vector<T> *p1, *p2; Gene *p1, *p2;
for (auto &c: population_) for (auto &c: population_)
{ {
@ -206,76 +236,52 @@ std::pair<std::vector<T> *, std::vector<T> *> GeneticScheduler<T>::select2(void)
} }
template <typename T> template <typename T>
void GeneticScheduler<T>::crossover(void) void GeneticScheduler<T>::crossover(Gene &c, const Gene &p1, const Gene &p2)
{ {
auto p = select2(); Gene buf;
auto &p1 = *(p.first), std::uniform_int_distribution<unsigned int> dis(0, p1.size() - 1);
&p2 = *(p.second); unsigned int cut = dis(gen_);
std::uniform_int_distribution<unsigned int> dis2(0, p1.size() - 1);
unsigned int cut = dis2(gen_);
std::vector<T> c1, c2, buf;
auto cross = [&buf, cut](std::vector<T> &c, const std::vector<T> &p1, c.clear();
const std::vector<T> &p2) buf = p1;
for (unsigned int i = 0; i < cut; ++i)
{ {
buf = p1; c.push_back(p2[i]);
for (unsigned int i = 0; i < cut; ++i) buf.erase(std::find(buf.begin(), buf.end(), p2[i]));
{ }
c.push_back(p2[i]); for (unsigned int i = 0; i < buf.size(); ++i)
buf.erase(std::find(buf.begin(), buf.end(), p2[i]));
}
for (unsigned int i = 0; i < buf.size(); ++i)
{
c.push_back(buf[i]);
}
};
cross(c1, p1, p2);
cross(c2, p2, p1);
PARALLEL_CRITICAL
{ {
population_.emplace(func_(c1), c1); c.push_back(buf[i]);
population_.emplace(func_(c2), c2);
} }
} }
template <typename T> template <typename T>
void GeneticScheduler<T>::mutation(void) void GeneticScheduler<T>::mutation(Gene &m, const Gene &c)
{ {
std::uniform_real_distribution<double> mdis(0., 1.); Gene buf;
std::uniform_int_distribution<unsigned int> dis(0, c.size() - 1);
unsigned int cut = dis(gen_);
Graph<T> g1 = graph_, g2 = graph_;
if (mdis(gen_) < par_.mutationRate) for (unsigned int i = 0; i < cut; ++i)
{ {
auto &c = *select1(); g1.removeVertex(c[i]);
std::uniform_int_distribution<unsigned int> cdis(0, c.size() - 1); }
unsigned int cut = cdis(gen_); for (unsigned int i = cut; i < c.size(); ++i)
std::vector<T> buf1, buf2; {
Graph<T> g1 = graph_, g2 = graph_; g2.removeVertex(c[i]);
}
for (unsigned int i = 0; i < cut; ++i) if (g1.size() > 0)
{ {
g1.removeVertex(c[i]); buf = g1.topoSort(gen_);
} }
for (unsigned int i = cut; i < c.size(); ++i) if (g2.size() > 0)
{ {
g2.removeVertex(c[i]); m = g2.topoSort(gen_);
} }
if (g1.size() > 0) for (unsigned int i = cut; i < c.size(); ++i)
{ {
buf1 = g1.topoSort(gen_); m.push_back(buf[i - cut]);
}
if (g2.size() > 0)
{
buf2 = g2.topoSort(gen_);
}
for (unsigned int i = cut; i < c.size(); ++i)
{
buf2.push_back(buf1[i - cut]);
}
PARALLEL_CRITICAL
{
population_.emplace(func_(buf2), buf2);
}
} }
} }