粒子群算法

来源:互联网 发布:局域网每台机器端口 编辑:程序博客网 时间:2024/06/03 19:40

1、 概述

粒子群算法作为一种优化算法,在很多领域都有应用。所谓优化,我的理解是对一个问题求出它足够好的解,目前的优化算法有很多,如蚁群算法、遗传算法等。粒子群算法相对于这些算法来说,它更简单,而且有很快的收敛速度。

2、 算法描述

举一个优化问题的例子,若求的最小值,当然可以通过数学手段求出当向量时的最小值为0 ,但是对于更复杂的函数表达式来说,运用数学手段求解是复杂的,而且在实际应用中,并不一定要求出它的精确解,只要是满足足够精度的精确解就够了,这时通过一定的优化算法求解就很方便。

粒子群算法思想来源于实际生活中鸟捕食的过程。假设在一个n维的空间中,有一群鸟(m只)在捕食,食物位于n维空间的某个点上,对于第i只鸟某一时刻来说,有两个向量描述,一个是鸟的位置向量,第二个是鸟的速度i=1,2...m)。假设鸟能够判断一个位置的好坏,所谓“好坏”,就是离食物更近了还是更远了。鸟在捕食的过程中会根据自己的经验以及鸟群中的其他鸟的位置决定自己的速度,根据当前的位置和速度,可以得到下一刻的位置,这样每只鸟通过向自己和鸟群学习不断的更新自己的速度位置,最终找到食物,或者离食物足够近的点。更新速度和位置的表达式如下。

更新速度:


对应的python实现如下:

[python] view plain copy
  1. import random  
  2. import copy  
  3.   
  4. birds=int(raw_input('Enter count of bird: '))  
  5. xcount=int(raw_input('Enter count of x: '))  
  6. pos=[]  
  7. speed=[]  
  8. bestpos=[]  
  9. birdsbestpos=[]  
  10. w=0.8  
  11. c1=2   
  12. c2=2  
  13. r1=0.6  
  14. r2=0.3  
  15. for i in range(birds):  
  16.     pos.append([])  
  17.     speed.append([])  
  18.     bestpos.append([])  
  19.   
  20. def GenerateRandVec(list):  
  21.     for i in range(xcount):  
  22.         list.append(random.randrange(1,100))  
  23.           
  24. def CalDis(list):  
  25.     dis=0.0  
  26.     for i in list:  
  27.         dis+=i**2  
  28.     return dis  
  29.   
  30. for i in range(birds):          #initial all birds' pos,speed  
  31.     GenerateRandVec(pos[i])  
  32.     GenerateRandVec(speed[i])  
  33.     bestpos[i]=copy.deepcopy(pos[i])  
  34.   
  35. def FindBirdsMostPos():  
  36.     best=CalDis(bestpos[0])  
  37.     index=0  
  38.     for i in range(birds):  
  39.         temp=CalDis(bestpos[i])  
  40.         if temp<best:  
  41.             best=temp  
  42.             index=i  
  43.     return bestpos[index]  
  44.   
  45. birdsbestpos=FindBirdsMostPos()   #initial birdsbestpos  
  46.   
  47. def NumMulVec(num,list):         #result is in list  
  48.     for i in range(len(list)):  
  49.         list[i]*=num  
  50.     return list  
  51.   
  52. def VecSubVec(list1,list2):   #result is in list1  
  53.     for i in range(len(list1)):  
  54.         list1[i]-=list2[i]  
  55.     return list1  
  56.   
  57. def VecAddVec(list1,list2):      #result is in list1  
  58.     for i in range(len(list1)):  
  59.         list1[i]+=list2[i]  
  60.     return list1  
  61.   
  62. def UpdateSpeed():  
  63.     #global speed  
  64.     for i in range(birds):  
  65.         temp1=NumMulVec(w,speed[i][:])  
  66.         temp2=VecSubVec(bestpos[i][:],pos[i])  
  67.         temp2=NumMulVec(c1*r1,temp2[:])  
  68.         temp1=VecAddVec(temp1[:],temp2)  
  69.         temp2=VecSubVec(birdsbestpos[:],pos[i])  
  70.         temp2=NumMulVec(c2*r2,temp2[:])  
  71.         speed[i]=VecAddVec(temp1,temp2)  
  72.           
  73. def UpdatePos():  
  74.     global bestpos,birdsbestpos  
  75.     for i in range(birds):  
  76.         VecAddVec(pos[i],speed[i])  
  77.         if CalDis(pos[i])<CalDis(bestpos[i]):  
  78.             bestpos[i]=copy.deepcopy(pos[i])  
  79.     birdsbestpos=FindBirdsMostPos()  
  80.       
  81. for i in range(100):  
  82.     #print birdsbestpos  
  83.     print CalDis(birdsbestpos)  
  84.     UpdateSpeed()  
  85.     UpdatePos()  
  86.                   
  87.   
  88. raw_input()  

若搜索空间鸟群中鸟的个数为30,问题规模x的个数为5个,100次迭代运行的结果如下,可以看到最终的值已经非常接近0这个最优解了。

Enter count of bird: 10

Enter count of x: 3

2921.0
2921.0
2921.0
468.3536
468.3536
330.4208
129.954472858
39.5341538959
39.5341538959
24.3882545449
24.3882545449
24.3882545449
24.3882545449
24.3882545449
24.3882545449
24.3414689425
24.3414689425
24.3414689425
24.3414689425
24.3396167276
24.3396167276
24.3396167276
24.3396167276
24.3396167276
24.3396167276
24.3396167276
24.3396167276
24.3396167276
24.3396167276
23.5885921317
15.7786497355
14.9316544734
9.46790752591
7.88590666461
6.70016643479
6.4934163887
4.72599645949
4.2514104093
4.05931397099
2.21436861265
2.21436861265
1.85332969683
1.7204846408
1.46608673028
0.839916173527
0.549995816894
0.453109828398
0.234947853329
0.117666669432
0.117666669432
0.103001164371
0.0989092532996
0.0596320222454
0.0391304232586
0.0364979613238
0.0282282591672
0.0282282591672
0.0233945770492
0.0233945770492
0.0233945770492
0.0233945770492
0.0233945770492
0.0197848989618
0.0195625784869
0.00395786591507
0.000655153734194
0.000446409849472
0.000285134802229
0.000285134802229
0.000285134802229
0.000285134802229
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.000246247594479
0.00016180105607
0.000154900780521
9.81866807502e-06
9.81866807502e-06


#注意:python所用版本为2.7