差异进化算法C#实现

差异进化(Differential Evolution)是一种全局最优化的算法。它是一种随机直接搜索方法,通过参数向量集的随机扰动实现并行计算,通过自组织的方式减少用户参数输入。

差异进化算法算法本身输入遗传类算法,包含杂交、变异和竞争等基本特点。在遗传算法的基础上,差异进化借用了Nelder and Mead算法的优点。Nelder and Mead(Bunday et tal,1987)是一种好的自组织最小化器,假如它的损失函数(cost function)有D个参数,它用D+1的顶点的多面体定义目前的搜索空间,每个顶点由一个D维参数向量表示,计算损失函数。新的参数向量集通过映射函数产生,映射函数由最大值和最小值作为限制。如果新的目标函数值有所减小,则接受新的参数向量集。这种策略允许搜索范围,也称多面体,不断扩展,但不需要用户设置参数。遗憾的是,Nelder & Mead方法是局部最优方法,经过实验,发现它不足以解决全局最优问题,尽管也引入了退火的概念。但是把Nelder & Mead方法的优势,从向量集中获取信息并更新搜索空间,这个观点借用过来,加入到差异演化方法中。差异演化的搜索控制自组织策略是从选取的向量集中随机选择向量对已有向量进行扰动,这个扰动对向量集中的每个向量都执行一次。这种方法区别与传统的差异演化方法,它需要预先定义不同的概率扰动向量。

差异演化的具体方法如下:

差异演化通过给两个参数向量不同的权重得到第三个参数向量,这种操作称为变异(mutation),变异后的向量与已有向量,也称目标向量,进行混合得到新的向量称为尝试向量,参数混合过程称为杂交(crossover)。如果尝试向量得到的损失函数的值更小,则在下一次的更新中把用尝试向量代替目标向量。最后的操作是选择,向量集中所有向量都要与目标向量比较,使得在一次更新(一代种群)中发生完全的竞争,即选择。

差异演化的代码如下:



public void search(int gen_max, double CR, doubleF, double[,]x1)

{

    intcout=0;

    intNP = x1.GetLength(0);   //number of populations

    intparaD = x1.GetLength(1);     //numberof parameters, parameter dimension

    Random rand = newRandom();

    double[]cost = newdouble[NP];

    cost[0] = double.MaxValue;

    double[,]x2 = newdouble[NP, paraD];

    while(cout< gen_max)   //haltafter gen_max generations

    {

        for(inti=0;i<NP;i++)       //startloop through population

        {

            //mutateand recombine

            inta,b,c;

            do

            {

                a =rand.Next(0, NP);

                b =rand.Next(0, NP);

                c = rand.Next(0,NP);

            }

            while(a == i || b==i || c==i);

            //load D parameters into trial[]

            double[]trial = newdouble[paraD];

            intj = rand.Next(0,paraD);

            for(intk=1;k<=paraD;k++)

            {

                if(rand.NextDouble()<CR || k==paraD)

                {

                   trial[j] = x1[c, j] + F * (x1[a, j] - x1[b, j]);

                }

                else

                {

                   trial[j] = x1[i, j];

                }

                j =(j + 1) % paraD;

            }

            //Evaluate  select

            doublescore = evaluate(trial);     //evaluate tria with your function

            if(score<= cost[i])

            {

                for(j=0;j<paraD;j++)

                {

                   x2[i, j] = trial[j];

                }

               cost[i] = score;

            }

            else

            {

                for(j= 0;j<paraD;j++)

                {

                   x2[i, j] = x1[i, j];

                }

            }

        }

        //endof population loop, swap arrays

        for(inti=0;i<NP;i++)

        {

            for(intj=0;j<paraD;j++)

            {

               x1[i, j] = x2[i, j];

            }

        }

        cout++;

        //endof generation...increment counter

    }

    //endof main loop

}

参考文献:

Storn R, Price K. Differential Evolution – A Simple and Efficient Heuristic for global Optimization over Continuous Spaces[J]. Journal of Global Optimization, 1997, 11(4):341-359

posted @ 2022-08-21 10:13  Oliver2022  阅读(96)  评论(0编辑  收藏  举报