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:
parent
51322da6f8
commit
4a87486365
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user