赞
踩
粒子群算法是一种启发式优化算法,1995年由Eberhart和kennedy提出。该算法起源于鸟群捕食的启发,进而利用群体智能在解空间中不断搜索取得最优解。
在粒子群算法中,每个解空间中的点被抽想成为一个d维的粒子,且每一个粒子对应着由目标函数决定的适应度(fitness)。同时每一个粒子对应着解空间中的位置以及各自拥有一个速度,它们在解空间中不断搜索问题的最优解的同时收到各自变化以及当前全局最优解的影响。粒子的速度以及位置更新公式如下:
其中参数
做过一些简单是实验以及一些比赛,发现要用好一些启发式算法,包括模拟退火,粒子群算法,遗传算法还是很不容易的,经常发现到最后还不如xjbs……总结经验如下:
/*
寻找函数y = sum(Xi - 0.5)^2的最优值,维输1000
*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define num_particle 100 //粒子个数
#define dim 1000 //粒子维数
#define low 0 //搜索域范围,即每个维度的最大最小可能值
#define high 1
#define num_iter 5000 //迭代次数
#define c1 2 //参数初始化
#define c2 2
#define w 0.5
#define v_max 0.03
double particle[num_particle][dim]; //粒子群集合
double particle_local_best[num_particle][dim]; //每个粒子的局部最优位置
double particle_local_fit[num_particle]; //每个粒子的局部最优适应度
double particle_global_best[dim]; //粒子群的全局最优位置
double particle_global_fit; //粒子群的全局最优适应度
double particle_v[num_particle][dim]; //每个粒子的当前速度
double particle_fit[num_particle]; //每个粒子的当前适应度
//定义适应度函数(cost)为向量的长度平方
double fitness(double a[]){
int i;
double sum = 0.0;
for(i = 0; i < dim; i++){
sum += (a[i] - 0.5) * (a[i] - 0.5);
}
return sum;
}
//初始化粒子群
void initial(){
int i, j;
for(i = 0; i < num_particle; i++){
for(j = 0; j < dim; j++){
particle[i][j] = low + (high - low)*1.0*rand()/RAND_MAX; //初始化粒子群位置
particle_local_best[i][j] = particle[i][j]; //初始局部最优即为初始位置
particle_v[i][j] = 0.2*rand()/RAND_MAX; //初始化粒子速度
}
}
for(i = 0; i < num_particle; i++){
particle_fit[i] = fitness(particle[i]); //计算每个粒子的初始适应度
particle_local_fit[i] = particle_fit[i]; //每个粒子的初始局部最优适应度即为初始位置的适应度
}
particle_global_fit = particle_local_fit[0]; //初始化全局最优适应度
j = 0;
for(i = 0; i < num_particle; i++){ //寻找全局最优位置
if(particle_local_fit[i] < particle_global_fit){
particle_global_fit = particle_local_fit[i];
j = i;
}
}
for(i = 0; i < dim; i++){ //更新全局最优位置
particle_global_best[i] = particle_local_best[j][i];
}
}
//迭代更新粒子群位置
void renew_particle(){
int i, j;
for(i = 0; i < num_particle; i++){
for(j = 0; j < dim; j++){
particle[i][j] += particle_v[i][j];
if(particle[i][j] > high){ //位置不能超过设定的最大最小值
particle[i][j] = high;
}
if(particle[i][j] < low){
particle[i][j] =low;
}
}
}
}
//迭代后更新粒子群速度
void renew_v(){
int i, j;
for(i = 0; i < num_particle; i++){
particle_fit[i] = fitness(particle[i]); //计算每个粒子的适应度
if(particle_fit[i] < particle_local_fit[i]){ //更新个体局部最优适应度
particle_local_fit[i] = particle_fit[i];
for(j = 0; j < dim; j++){ // 更新个体局部最优位置
particle_local_best[i][j] = particle[i][j];
}
}
}
j = -1;
for(i = 0; i < num_particle; i++){ //更新全局最优适应度
if(particle_local_fit[i] < particle_global_fit){
particle_global_fit = particle_local_fit[i];
j = i;
}
}
if(j != -1){ //若该次迭代产生全局最优,更新全局最优位置
for(i = 0; i < dim; i++){
particle_global_best[i] = particle_local_best[j][i];
}
}
for(i = 0; i < num_particle; i++){
for(j = 0; j < dim; j++){
particle_v[i][j] = w * particle_v[i][j] + c1 * 1.0 * rand() / RAND_MAX * (particle_local_best[i][j] - particle[i][j])+ c2 * 1.0 * rand() / RAND_MAX * (particle_global_best[j] - particle[i][j]);
if(particle_v[i][j] > v_max){
particle_v[i][j] = v_max;
}
if(particle_v[i][j] < -v_max){
particle_v[i][j] = -v_max;
}
}
}
}
int main(){
int i = 0;
initial();
srand((unsigned)time(NULL));
while(i < num_iter){ //进行1000次迭代
renew_particle();
renew_v();
i++;
}
printf("粒子群个数:%d\n", num_particle);
printf("每个粒子群维度:%d\n", dim);
printf("迭代次数:%d\n", num_iter);
//printf("最优位置:%f\n", particle_global_best);
printf("最优适应度:%f\n", particle_global_fit);
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。