C#利用粒子群算法实现求一元函数最小值

粒子群算法是一种人工智能算法,它模拟自然界中鸟类觅食的规律,被广泛用于优化领域。出于学习的目的,笔者用C#写了一个求函数y=x*2+1/x的最小值的示例,并利用TeeChart绘图控件,将求解最小值的过程形象地表示出来。

算法的思路:

1.指定一定规模的鸟群(笔者只使用了10只鸟作为搜索),每只鸟Bird都有三个属性:X、V、Best

public class Bird
{
    public double X { get; set; }
    public double V { get; set; }
    public double Best { get; set; }
}

其中,X代表鸟Bird的当前位置,V代表鸟当前的移动方向和移动速度,由于本文研究的是一元函数,所以X和V都是一维的,读者可以根据所研究问题的领域设计搜索空间的维度。Best代表当前这只鸟目前所找到的最小值。

2.按照将每只鸟按照b.V = (w * b.V + c1 * rand1 * (b.Best - b.X) + c2 * rand2 * (gBest - b.X));更新鸟的位置,即让每只鸟飞行一段距离。其中w代表惯性指数,这是代表该鸟对其移动方向的自信程度,c1代表该鸟对自己之前找到的最小值的信任程度,c2代表该鸟对整个种群的最小值的信任程度。

public void run()
{
    int count = 0;
    double rand1 = rand.NextDouble();
    double rand2 = rand.NextDouble();
    //根据标准差(种群中粒子的分布的离散程度)和最大迭代次数进行收敛判断
    while (count < 50000 && stdd > 0.0001)
    {
        Thread.Sleep(100);

        foreach (Bird b in birds)
        {
            double oldValue = F1(b.Best);
            b.V = (w * b.V + c1 * rand1 * (b.Best - b.X) + c2 * rand2 * (gBest - b.X));
            if ((b.X + b.V) > Double.Parse(txtXStart.Text) && (b.X + b.V) < Double.Parse(txtXEnd.Text))
            {
                b.X = b.X + b.V;
            }
            else if((b.X + b.V) < Double.Parse(txtXStart.Text))
            {
                b.X = Double.Parse(txtXStart.Text);
            }
            else
            {
                b.X = Double.Parse(txtXEnd.Text);
            }
            if (F1(b.X) < oldValue)
            {
                b.Best = b.X;
            }
            if (F1(b.X) < F1(gBest))
            {
                gBest = b.X;
            }
        }

        ShowSwarm(birds);

        double[] x = new double[birdnum];
        //计算种群的离散程度
        for (int i = 0; i < birds.Count; i++)
        {
            x[i] = birds[i].X;
        }
        stdd = StDev(x);

        count++;
    }
}
需要特别注意的是,笔者采用鸟群分布的离散程度作为收敛条件,读者也可以自己定义其他的指标判断收敛。其他的具体细节可以参考 项目github地址(vs2015)



猜你喜欢

转载自blog.csdn.net/zyxhangiian123456789/article/details/80736297
今日推荐