例子种群算法

1. 概念

    粒子群优化算法(PSO:Particle swarm optimization) 是一种进化计算技术(evolutionary computation)。

    源于对鸟群捕食的行为研究。粒子群优化算法的基本思想:是通过群体中个体之间的协作和信息共享来寻找最优解.

    PSO的优势:在于简单容易实现并且没有许多参数的调节。目前已被广泛应用于函数优化、神经网络训练、模糊系统控制以及其他遗传算法的应用领域。 

2. 算法

 

2.1 问题抽象

      鸟被抽象为没有质量和体积的微粒(点),并延伸到N维空间,粒子i在N维空间的位置表示为矢量Xi=(x1,x2,…,xN),飞行速度表示为矢量Vi=(v1,v2,…,vN)。每个粒子都有一个由目标函数决定的适应值(fitness value),并且知道自己到目前为止发现的最好位置(pbest)和现在的位置Xi。这个可以看作是粒子自己的飞行经验。除此之外,每个粒子还知道到目前为止整个群体中所有粒子发现的最好位置(gbest)(gbest是pbest中的最好值),这个可以看作是粒子同伴的经验。粒子就是通过自己的经验和同伴中最好的经验来决定下一步的运动。 

 

2.2 更新规则

      PSO初始化为一群随机粒子(随机解)。然后通过迭代找到最优解。在每一次的迭代中,粒子通过跟踪两个“极值”(pbest,gbest)来更新自己。在找到这两个最优值后,粒子通过下面的公式来更新自己的速度和位置。

     

      公式(1)的第一部分称为【记忆项】,表示上次速度大小和方向的影响;公式(1)的第二部分称为【自身认知项】,是从当前点指向粒子自身最好点的一个矢量,表示粒子的动作来源于自己经验的部分;公式(1)的第三部分称为【群体认知项】,是一个从当前点指向种群最好点的矢量,反映了粒子间的协同合作和知识共享。粒子就是通过自己的经验和同伴中最好的经验来决定下一步的运动。

     以上面两个公式为基础,形成了PSO的标准形式。

     

     公式(2)和 公式(3)被视为标准PSO算法。

3.算法 C++实现

/***
 *  计算y=-x(x-1)的最大值
 *  取值范围x--[-2,2]
 * @author BreezeDust
 *
 */
public class PSOTest {
    int n=2; //粒子个数,这里为了方便演示,我们只取两个,观察其运动方向
    double[] y;
    double[] x;
    double[] v;
    double c1=2;
    double c2=2;
    double pbest[];
    double gbest;
    double vmax=0.1;
    public void fitnessFunction(){//适应函数
        for(int i=0;i<n;i++){
            y[i]=-1*x[i]*(x[i]-2);
        }
    }
    public void init(){ //初始化
        x=new double[n];
        v=new double[n];
        y=new double[n];
        pbest=new double[n];
        /***
         * 本来是应该随机产生的,为了方便演示,我这里手动随机落两个点,分别落在最大值两边
         */
        x[0]=-0.5;
        x[1]=2.6;
        v[0]=0.01;
        v[1]=0.02;
        fitnessFunction();
        //初始化当前个体极值,并找到群体极值
        for(int i=0;i<n;i++){
            pbest[i]=y[i];
            if(y[i]>gbest) gbest=y[i];
        }
        System.out.println("start gbest:"+gbest);
    }
    public double getMAX(double a,double b){
        return a>b?a:b;
    }
    //粒子群算法
    public void PSO(int max){
        for(int i=0;i<max;i++){
            double w=0.4;
            for(int j=0;j<n;j++){
                //更新位置和速度
                v[j]=w*v[j]+c1*Math.random()*(pbest[j]-x[j])+c2*Math.random()*(gbest-x[j]);
                if(v[j]>vmax) v[j]=vmax;
                x[j]+=v[j];
                //越界判断
                if(x[j]>2) x[j]=2;
                if(x[j]<-2) x[j]=-2;
                
            }
            fitnessFunction();
            //更新个体极值和群体极值
            for(int j=0;j<n;j++){
                pbest[j]=getMAX(y[j],pbest[j]);
                if(pbest[j]>gbest) gbest=pbest[j];
                System.out.println(x[j]+"  "+v[j]);
            }
            System.out.println("======"+(i+1)+"======gbest:"+gbest);
        }
        
        
    }
    public static void main(String[] args){
        PSOTest ts=new PSOTest();
        ts.init();
        ts.PSO(100);
    }
}

输出结果

start gbest:0.0
-0.4  0.1
0.0  -10.751668729351186
======1======gbest:0.0
-0.6822365786740794  -0.2822365786740793
0.0  -5.375834364675593
======2======gbest:0.0
-0.5822365786740794  0.1
0.0  -2.6879171823377965
======3======gbest:0.0
-0.48223657867407943  0.1
-1.3439585911688983  -1.3439585911688983
======4======gbest:0.0
-0.38223657867407945  0.1
-1.2439585911688982  0.1
======5======gbest:0.0
-0.47659030560462123  -0.09435372693054181
-1.143958591168898  0.1
======6======gbest:0.0
-0.37659030560462126  0.1
-1.043958591168898  0.1
======7======gbest:0.0
-0.2765903056046213  0.1
-0.943958591168898  0.1
======8======gbest:0.0
-0.27903394174424034  -0.0024436361396190653
-0.843958591168898  0.1
======9======gbest:0.0
-0.38899022876058803  -0.10995628701634769
-0.7439585911688981  0.1
======10======gbest:0.0
-0.35250959144436234  0.03648063731622572
-0.6439585911688981  0.1
======11======gbest:0.0
........
........
........
........
0.9999990975760489  -1.556071309835406E-6
======98======gbest:1.0
1.0000000029937202  4.411275849326098E-9
1.0000001827158205  1.085139771533034E-6
======99======gbest:1.0
0.9999999993730952  -3.6206249540206964E-9
1.0000001197322141  -6.298360633295484E-8
======100======gbest:1.0

结果分析

我们可以从打印的数据看出来,刚开始x[0]和x[1]分散在最大值两边,然后x[0]和x[1]逐渐聚集到1的周围,这里,我们已经收敛到x=1这个地方了,这正是我们要求的最大值,其最大值为1,下面是图解过程。

    1.初始状态

    2.第二次x[1]向左边移动了

   3.最后,两点聚集在1上,上面多个圈是他们聚集的过程,可以看出来,聚集过程是个越来越密集的过程。

转载原文链接1:https://blog.csdn.net/qq_34504481/article/details/79763824

转载原文链接2:http://www.cnblogs.com/BreezeDust/p/3354769.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
遗传算法的编码方式有多种,其中二进制编码是最常用的一种。下面是一个使用二进制编码的遗传算法Python示例: ```python import random # 定义目标函数 def fitness_func(chromosome): x = decode(chromosome[:10], -5, 5) y = decode(chromosome[10:], -5, 5) return x**2 + y**2 # 定义解码函数 def decode(binary, a, b): x = int(''.join(str(i) for i in binary), 2) return a + (b - a) * x / (2**len(binary) - 1) # 定义交叉函数 def crossover(parent1, parent2): point = random.randint(1, len(parent1) - 1) child1 = parent1[:point] + parent2[point:] child2 = parent2[:point] + parent1[point:] return child1, child2 # 定义变异函数 def mutation(chromosome, p): for i in range(len(chromosome)): if random.random() < p: chromosome[i] = 1 - chromosome[i] return chromosome # 初始化种群 population_size = 50 chromosome_length = 20 population = [[random.randint(0, 1) for j in range(chromosome_length)] for i in range(population_size)] # 开始迭代 max_generation = 100 crossover_rate = 0.8 mutation_rate = 0.01 for generation in range(max_generation): # 计算适应度 fitness = [fitness_func(chromosome) for chromosome in population] # 选择 parents = [] for i in range(population_size): parent1 = population[roulette_wheel_selection(fitness)] parent2 = population[roulette_wheel_selection(fitness)] parents.append((parent1, parent2)) # 交叉 offspring = [] for parent1, parent2 in parents: if random.random() < crossover_rate: child1, child2 = crossover(parent1, parent2) offspring.append(child1) offspring.append(child2) else: offspring.append(parent1) offspring.append(parent2) # 变异 population = [mutation(chromosome, mutation_rate) for chromosome in offspring] # 输出最优解 best_chromosome = population[0] best_fitness = fitness_func(best_chromosome) for chromosome in population: fitness = fitness_func(chromosome) if fitness < best_fitness: best_chromosome = chromosome best_fitness = fitness x = decode(best_chromosome[:10], -5, 5) y = decode(best_chromosome[10:], -5, 5) print("x =", x) print("y =", y) print("f(x,y) =", best_fitness) ``` 在这个例子中,我们使用二进制编码来表示自变量x和y。每个染色体由20个基因组成,前10个基因表示x,后10个基因表示y。解码函数decode将二进制编码转换为实数值。交叉函数crossover和变异函数mutation用于产生新的染色体。选择函数roulette_wheel_selection使用轮盘赌算法来选择父代。最终,我们得到了最优解x、y和目标函数的最小值f(x,y)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值