欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-08 18:40:41
...

粒子群算法是一种人工智能算法,它模拟自然界中鸟类觅食的规律,被广泛用于优化领域。出于学习的目的,笔者用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)

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

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