[アルゴリズム]遺伝アルゴリズム局所最値を求める

24836 ワード

#include <iostream>

#include <algorithm>

#include <string>

#include <vector>

#include <cmath>

#include <ctime>

using namespace std;

void decode(double xBegin, double yBegin,pair<string, string> sample,double& x, double& y);

double targetFun(double xBegin, double yBegin,pair<string, string>& sample);

void randomInit(double xBegin,double xEnd, double yBegin, double yEnd,vector< pair<string,string> > &group,unsigned int nGroup, double error=0.125);

double maxOfGroup(vector< pair<string, string> >&group, pair<string, string>& solution, double xBegin, double yBegin,double& sum);

void genPopulation(vector< pair<string, string> >&group,double sum,double xBegin, double yBegin,double matingProb = 1.0,double mutateProb = 0.001);

void singularMating(pair<string, string>& sample1,pair<string, string>& sample2);

void mutate(pair<string, string>& sample);

void groupMating(vector< pair<string, string> >&group,double matingProb = 1.0);

void groupMutate(vector< pair<string, string> >&group,double mutateProb = 0.001);

int main()

{

    vector< pair<string,string> > group;

    pair<string,string> solution,tempSolution;

    double sum,epsilon = 0.01,matingProb = 1.0, mutateProb = 0.001;

    //sum           ,epsilon       ,matingProb    ,mutateProb    

    double xBegin = 1, xEnd = 2, yBegin = 1, yEnd = 2;

    unsigned int nGroup = 16;

    randomInit(xBegin,xEnd,yBegin,yEnd,group,nGroup);

    double preMax = maxOfGroup(group,solution,xBegin,yBegin,sum);

    genPopulation(group,sum,xBegin,yBegin);

    double currentMax = maxOfGroup(group,tempSolution,xBegin,yBegin,sum);

    unsigned int i = 0;

    while (abs(preMax-currentMax) > epsilon && i++ < nGroup*nGroup)

    {

        if (currentMax > preMax)

        {

            preMax = currentMax;

            solution = tempSolution;

        }

        genPopulation(group,sum,xBegin,yBegin);

        currentMax = maxOfGroup(group,tempSolution,xBegin,yBegin,sum);

    }

    cout<<""<<preMax<<endl;

    cin.get();

    return 0;

}



void decode(double xBegin, double yBegin,pair<string, string> sample,double& x, double& y)

{

    x = xBegin,y = yBegin;

    double base= 0.5;

    string first,second;

    first = sample.first;

    second = sample.second;

    for (unsigned int i = 0; i < first.size(); ++i)

    {

        if ('1' == first.at(i))

        {

            x += base;

        }

        base /=2;

    }

    base = 0.5;

    for (unsigned int i = 0; i < second.size(); ++i)

    {

        if ('1' == second.at(i))

        {

            y += base;

        }

        base /=2;

    }

}



double targetFun(double xBegin, double yBegin,pair<string, string>& sample)

{

    const double matingProb = 1.0;

    const double mutateProb = 0.001;

    double x,y;

    decode(xBegin,yBegin,sample,x,y);

    return x*sin(6*y)+y*cos(8*x);

}



void randomInit(double xBegin,double xEnd, double yBegin, double yEnd,vector< pair<string,string> > &group,unsigned int nGroup, double error)

{

    unsigned int xLen, yLen;

    xLen = ceil(log((xEnd-xBegin)/error + 1)/log(2));

    yLen = ceil(log((yEnd-yBegin)/error + 1)/log(2));

    string x, y;

    pair<string, string> sample;

    srand(unsigned (time(0)));

    for (unsigned int i = 0; i < nGroup ;++i)

    {

        for (unsigned int j = 0; j < xLen; ++j)

        {

            x.push_back(rand()%2 + '0');

        }

        for (unsigned int k = 0; k < xLen; ++k)

        {

            y.push_back(rand()%2 + '0');

        }

        sample.first = x;

        sample.second = y;

        group.push_back(sample);

        x.clear();

        y.clear();

    }    

}



void singularMating(pair<string, string>& sample1,pair<string, string>& sample2)

{

    unsigned matingPoint = rand()%(sample1.first.size()+sample1.second.size()-1)+1;

    string temp;

    if (matingPoint <= sample1.first.size())

    {

        temp = sample1.second;

        sample1.second = sample2.second;

        sample2.second = temp;

        temp.clear();

        temp.assign(sample1.first.begin()+matingPoint,sample1.first.end());

        sample1.first.insert(sample1.first.begin()+matingPoint,sample2.first.begin()+matingPoint,sample2.first.end());

        sample1.first.resize(sample2.first.size());

        sample2.first.insert(sample2.first.begin()+matingPoint,temp.begin(),temp.end());

        sample2.first.resize(sample1.first.size());

    }

    else

    {

        matingPoint -= sample1.first.size();

        temp.assign(sample1.second.begin()+matingPoint,sample1.second.end());

        sample1.second.insert(sample1.second.begin()+matingPoint,sample2.second.begin()+matingPoint,sample2.second.end());

        sample1.second.resize(sample2.second.size());

        sample2.second.insert(sample2.second.begin()+matingPoint,temp.begin(),temp.end());

        sample2.second.resize(sample1.second.size());

    }

}



void groupMating(vector< pair<string, string> >&group,double matingProb)

{

    unsigned int i = 0;

    while (i < group.size()-1)

    {

        if (rand()/(double)RAND_MAX < matingProb)

        {

            singularMating(group.at(i),group.at(i+1));

        }

        i += 2;

    }

}

void groupMutate(vector< pair<string, string> >&group,double mutateProb)

{

    vector< pair<string, string> >::iterator iter = group.begin();

    while (group.end() != iter)

    {

        if (rand()/double(RAND_MAX) < mutateProb)

        {

            mutate(*iter);

        }

        ++iter;

    }

}

void mutate(pair<string, string>& sample)

{

    unsigned mutatePoint = rand() % (sample.first.size() + sample.second.size());

    if (mutatePoint < sample.first.size())

    {

        if (sample.first.at(mutatePoint) == '0')

        {

            sample.first.at(mutatePoint)='1';

        }

        else

        {

            sample.first.at(mutatePoint)='0';

        }

    }

    else

    {

        mutatePoint -= sample.first.size();

        if (sample.second.at(mutatePoint) == '0')

        {

            sample.second.at(mutatePoint) = '1';

        } 

        else

        {

            sample.second.at(mutatePoint) = '0';

        }

    }

}



double maxOfGroup(vector< pair<string, string> >&group, pair<string, string>& solution, double xBegin, double yBegin,double& sum)

{

    vector< pair<string, string> >::iterator iter = group.begin();

    double currentMax = targetFun(xBegin,yBegin,*iter),temp; 

    sum = currentMax;

    solution = *iter;

    ++iter;

    while (group.end() != iter)

    {

        temp = targetFun(xBegin,yBegin,*iter);

        sum += temp;

        if (temp > currentMax)

        {

            currentMax = temp;

            solution = *iter;

        }

        ++iter;

    }

    return currentMax;

}



void genPopulation(vector< pair<string, string> >&group,double sum,double xBegin, double yBegin,double matingProb,double mutateProb)

{

    unsigned int n = group.size();

    double* ProbSection = new double[n+1];//       

    unsigned int* individual = new unsigned int[n];//         

    ProbSection[0] = 0.0;

    unsigned int i = 0;

    while (i < n)

    {

        ProbSection[i+1] = ProbSection[i] + targetFun(xBegin,yBegin,group.at(i))/sum;

        individual[i] = 0;

        ++i;

    }

    i = 0;

    double r;

    unsigned int times;

    while (i < n)

    {

        times = 0;

        r = rand()/(double)RAND_MAX;

        for (unsigned int j = 0; j < n; ++j)

        {

            if (r > ProbSection[j])

            {

                ++times;

            }

        }

        ++individual[times-1];

        ++i;

    }

    i = 0;

    while (i < n)

    {

        while (individual[i]-- > 0)

        {

            group.push_back(group.at(i));

        }

        ++i;

    }

    reverse(group.begin(),group.end());

    group.resize(n);

    delete ProbSection;

    delete individual;

}

 
 
本明細書は、知識共有署名-非商業的使用3.0ライセンス契約に基づいて許可される.転载、演繹を歓迎して、しかし本文の署名林が舞い上がるを保留しなければならなくて、もしコンサルティングが必要ならば、手紙を出してください。