mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Hadrons: genetic scheduler improvement
This commit is contained in:
		@@ -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();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    LOG(Debug) << "After mutations:\n" << *this << std::endl;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // mating
 | 
				
			||||||
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
					    for (unsigned int i = 0; i < par_.popSize/2; ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
            mutation(c.second);
 | 
					        crossover();
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        population_.emplace(func_(c.second), c.second);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    return rIt->second;
 | 
					        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 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);
 | 
				
			||||||
 | 
					    PARALLEL_CRITICAL
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        population_.emplace(func_(c1), c1);
 | 
					        population_.emplace(func_(c1), c1);
 | 
				
			||||||
        population_.emplace(func_(c2), c2);
 | 
					        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);
 | 
				
			||||||
    if (g.size() > 0)
 | 
					        unsigned int                                cut = cdis(gen_);
 | 
				
			||||||
 | 
					        std::vector<T>                              buf1, buf2;
 | 
				
			||||||
 | 
					        Graph<T>                                    g1 = graph_, g2 = graph_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (unsigned int i = 0; i < cut; ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        buf = g.topoSort(gen_);
 | 
					            g1.removeVertex(c[i]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (unsigned int i = cut; i < c.size(); ++i)
 | 
					        for (unsigned int i = cut; i < c.size(); ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
        buf.push_back(c[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);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    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 {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user