mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-09 21:50:45 +01:00
Hadrons: genetic scheduler improvement
This commit is contained in:
parent
49c3eeb378
commit
51322da6f8
@ -61,10 +61,12 @@ public:
|
|||||||
friend std::ostream & operator<<(std::ostream &out,
|
friend std::ostream & operator<<(std::ostream &out,
|
||||||
const GeneticScheduler<T> &s)
|
const GeneticScheduler<T> &s)
|
||||||
{
|
{
|
||||||
|
out << "[";
|
||||||
for (auto &p: s.population_)
|
for (auto &p: s.population_)
|
||||||
{
|
{
|
||||||
out << p.second << ": " << p.first << std::endl;
|
out << p.first << ", ";
|
||||||
}
|
}
|
||||||
|
out << "\b\b]";
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -72,10 +74,10 @@ private:
|
|||||||
// randomly initialize population
|
// randomly initialize population
|
||||||
void initPopulation(void);
|
void initPopulation(void);
|
||||||
// genetic operators
|
// genetic operators
|
||||||
const std::vector<T> & selection(void);
|
std::vector<T> * select1(void);
|
||||||
void crossover(const std::vector<T> &c1,
|
std::pair<std::vector<T> *, std::vector<T> *> select2(void);
|
||||||
const std::vector<T> &c2);
|
void crossover(void);
|
||||||
void mutation(std::vector<T> &c);
|
void mutation(void);
|
||||||
private:
|
private:
|
||||||
Graph<T> &graph_;
|
Graph<T> &graph_;
|
||||||
const ObjFunc &func_;
|
const ObjFunc &func_;
|
||||||
@ -115,38 +117,35 @@ int GeneticScheduler<T>::getMinValue(void)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void GeneticScheduler<T>::nextGeneration(void)
|
void GeneticScheduler<T>::nextGeneration(void)
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<double> dis(0., 1.);
|
|
||||||
|
|
||||||
// random initialization of the population if necessary
|
// random initialization of the population if necessary
|
||||||
if (population_.size() != par_.popSize)
|
if (population_.size() != par_.popSize)
|
||||||
{
|
{
|
||||||
initPopulation();
|
initPopulation();
|
||||||
}
|
}
|
||||||
|
LOG(Debug) << "Starting population:\n" << *this << std::endl;
|
||||||
// mating
|
|
||||||
for (unsigned int i = 0; i < par_.popSize/2; ++i)
|
|
||||||
{
|
|
||||||
auto &p1 = selection(), &p2 = selection();
|
|
||||||
crossover(p1, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// random mutations
|
// random mutations
|
||||||
auto buf = population_;
|
PARALLEL_FOR_LOOP
|
||||||
population_.clear();
|
for (unsigned int i = 0; i < par_.popSize; ++i)
|
||||||
for (auto &c: buf)
|
|
||||||
{
|
{
|
||||||
if (dis(gen_) < par_.mutationRate)
|
mutation();
|
||||||
{
|
|
||||||
mutation(c.second);
|
|
||||||
}
|
|
||||||
population_.emplace(func_(c.second), c.second);
|
|
||||||
}
|
}
|
||||||
|
LOG(Debug) << "After mutations:\n" << *this << std::endl;
|
||||||
|
|
||||||
|
// mating
|
||||||
|
PARALLEL_FOR_LOOP
|
||||||
|
for (unsigned int i = 0; i < par_.popSize/2; ++i)
|
||||||
|
{
|
||||||
|
crossover();
|
||||||
|
}
|
||||||
|
LOG(Debug) << "After mating:\n" << *this << std::endl;
|
||||||
|
|
||||||
// grim reaper
|
// grim reaper
|
||||||
auto it = population_.begin();
|
auto it = population_.begin();
|
||||||
|
|
||||||
std::advance(it, par_.popSize);
|
std::advance(it, par_.popSize);
|
||||||
population_.erase(it, population_.end());
|
population_.erase(it, population_.end());
|
||||||
|
LOG(Debug) << "After grim reaper:\n" << *this << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// randomly initialize population //////////////////////////////////////////////
|
// randomly initialize population //////////////////////////////////////////////
|
||||||
@ -164,37 +163,66 @@ void GeneticScheduler<T>::initPopulation(void)
|
|||||||
|
|
||||||
// genetic operators ///////////////////////////////////////////////////////////
|
// genetic operators ///////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const std::vector<T> & GeneticScheduler<T>::selection(void)
|
std::vector<T> * GeneticScheduler<T>::select1(void)
|
||||||
|
{
|
||||||
|
std::uniform_int_distribution<unsigned int> pdis(0, population_.size() - 1);
|
||||||
|
|
||||||
|
auto it = population_.begin();
|
||||||
|
std::advance(it, pdis(gen_));
|
||||||
|
|
||||||
|
return &(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::pair<std::vector<T> *, std::vector<T> *> GeneticScheduler<T>::select2(void)
|
||||||
{
|
{
|
||||||
std::vector<double> prob;
|
std::vector<double> prob;
|
||||||
|
unsigned int ind;
|
||||||
|
std::vector<T> *p1, *p2;
|
||||||
|
|
||||||
for (auto &c: population_)
|
for (auto &c: population_)
|
||||||
{
|
{
|
||||||
prob.push_back(1./c.first);
|
prob.push_back(1./c.first);
|
||||||
}
|
}
|
||||||
std::discrete_distribution<unsigned int> dis(prob.begin(), prob.end());
|
do
|
||||||
auto rIt = population_.begin();
|
{
|
||||||
std::advance(rIt, dis(gen_));
|
double probCpy;
|
||||||
|
|
||||||
|
std::discrete_distribution<unsigned int> dis1(prob.begin(), prob.end());
|
||||||
|
auto rIt = population_.begin();
|
||||||
|
ind = dis1(gen_);
|
||||||
|
std::advance(rIt, ind);
|
||||||
|
p1 = &(rIt->second);
|
||||||
|
probCpy = prob[ind];
|
||||||
|
prob[ind] = 0.;
|
||||||
|
std::discrete_distribution<unsigned int> dis2(prob.begin(), prob.end());
|
||||||
|
rIt = population_.begin();
|
||||||
|
std::advance(rIt, dis2(gen_));
|
||||||
|
p2 = &(rIt->second);
|
||||||
|
prob[ind] = probCpy;
|
||||||
|
} while (p1 == p2);
|
||||||
|
|
||||||
return rIt->second;
|
return std::make_pair(p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void GeneticScheduler<T>::crossover(const std::vector<T> &p1,
|
void GeneticScheduler<T>::crossover(void)
|
||||||
const std::vector<T> &p2)
|
|
||||||
{
|
{
|
||||||
std::uniform_int_distribution<unsigned int> dis(0, p1.size() - 1);
|
auto p = select2();
|
||||||
unsigned int cut = dis(gen_);
|
auto &p1 = *(p.first),
|
||||||
|
&p2 = *(p.second);
|
||||||
|
std::uniform_int_distribution<unsigned int> dis2(0, p1.size() - 1);
|
||||||
|
unsigned int cut = dis2(gen_);
|
||||||
std::vector<T> c1, c2, buf;
|
std::vector<T> c1, c2, buf;
|
||||||
|
|
||||||
auto cross = [&buf, cut](std::vector<T> &c, const std::vector<T> &p1,
|
auto cross = [&buf, cut](std::vector<T> &c, const std::vector<T> &p1,
|
||||||
const std::vector<T> &p2)
|
const std::vector<T> &p2)
|
||||||
{
|
{
|
||||||
buf = p2;
|
buf = p1;
|
||||||
for (unsigned int i = 0; i < cut; ++i)
|
for (unsigned int i = 0; i < cut; ++i)
|
||||||
{
|
{
|
||||||
c.push_back(p1[i]);
|
c.push_back(p2[i]);
|
||||||
buf.erase(std::find(buf.begin(), buf.end(), p1[i]));
|
buf.erase(std::find(buf.begin(), buf.end(), p2[i]));
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < buf.size(); ++i)
|
for (unsigned int i = 0; i < buf.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -204,31 +232,51 @@ void GeneticScheduler<T>::crossover(const std::vector<T> &p1,
|
|||||||
|
|
||||||
cross(c1, p1, p2);
|
cross(c1, p1, p2);
|
||||||
cross(c2, p2, p1);
|
cross(c2, p2, p1);
|
||||||
population_.emplace(func_(c1), c1);
|
PARALLEL_CRITICAL
|
||||||
population_.emplace(func_(c2), c2);
|
{
|
||||||
|
population_.emplace(func_(c1), c1);
|
||||||
|
population_.emplace(func_(c2), c2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void GeneticScheduler<T>::mutation(std::vector<T> &c)
|
void GeneticScheduler<T>::mutation(void)
|
||||||
{
|
{
|
||||||
std::uniform_int_distribution<unsigned int> dis(0, c.size() - 1);
|
std::uniform_real_distribution<double> mdis(0., 1.);
|
||||||
unsigned int cut = dis(gen_);
|
|
||||||
Graph<T> g = graph_;
|
|
||||||
std::vector<T> buf;
|
|
||||||
|
|
||||||
for (unsigned int i = cut; i < c.size(); ++i)
|
if (mdis(gen_) < par_.mutationRate)
|
||||||
{
|
{
|
||||||
g.removeVertex(c[i]);
|
auto &c = *select1();
|
||||||
|
std::uniform_int_distribution<unsigned int> cdis(0, c.size() - 1);
|
||||||
|
unsigned int cut = cdis(gen_);
|
||||||
|
std::vector<T> buf1, buf2;
|
||||||
|
Graph<T> g1 = graph_, g2 = graph_;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < cut; ++i)
|
||||||
|
{
|
||||||
|
g1.removeVertex(c[i]);
|
||||||
|
}
|
||||||
|
for (unsigned int i = cut; i < c.size(); ++i)
|
||||||
|
{
|
||||||
|
g2.removeVertex(c[i]);
|
||||||
|
}
|
||||||
|
if (g1.size() > 0)
|
||||||
|
{
|
||||||
|
buf1 = g1.topoSort(gen_);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (g.size() > 0)
|
|
||||||
{
|
|
||||||
buf = g.topoSort(gen_);
|
|
||||||
}
|
|
||||||
for (unsigned int i = cut; i < c.size(); ++i)
|
|
||||||
{
|
|
||||||
buf.push_back(c[i]);
|
|
||||||
}
|
|
||||||
c = buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
END_HADRONS_NAMESPACE
|
END_HADRONS_NAMESPACE
|
||||||
|
@ -46,11 +46,13 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
#endif
|
#endif
|
||||||
#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)")
|
#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)")
|
||||||
#define PARALLEL_REGION _Pragma("omp parallel")
|
#define PARALLEL_REGION _Pragma("omp parallel")
|
||||||
|
#define PARALLEL_CRITICAL _Pragma("omp critical")
|
||||||
#else
|
#else
|
||||||
#define PARALLEL_FOR_LOOP
|
#define PARALLEL_FOR_LOOP
|
||||||
#define PARALLEL_FOR_LOOP_INTERN
|
#define PARALLEL_FOR_LOOP_INTERN
|
||||||
#define PARALLEL_NESTED_LOOP2
|
#define PARALLEL_NESTED_LOOP2
|
||||||
#define PARALLEL_REGION
|
#define PARALLEL_REGION
|
||||||
|
#define PARALLEL_CRITICAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user