优化算法——人工蜂群算法(ABC)

优化算法——人工蜂群算法(ABC)

一、人工蜂群算法的介绍       人工蜂群算法(Artificial Bee Colony, ABC)是由Karaboga于2005年提出的一种新颖的基于群智能的全局优化算法,其直观背景来源于蜂群的采蜜行为,蜜蜂根据各自的分工进行不同的活动,并实现蜂群信息的共享和交流,从而找到问题的最优解。人工蜂群算法属于群智能算法的一种。

二、人工蜂群算法的原理

1、原理           标准的ABC算法通过模拟实际蜜蜂的采蜜机制将人工蜂群分为3类: 采蜜蜂、观察蜂和侦察蜂。整个蜂群的目标是寻找花蜜量最大的蜜源。在标准的ABC算法中,采蜜蜂利用先前的蜜源信息寻找新的蜜源并与观察蜂分享蜜源信息;观察蜂在蜂房中等待并依据采蜜蜂分享的信息寻找新的蜜源;侦查蜂的任务是寻找一个新的有价值的蜜源,它们在蜂房附近随机地寻找蜜源。            假设问题的解空间是

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

维的,采蜜蜂与观察蜂的个数都是

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

,采蜜蜂的个数或观察蜂的个数与蜜源的数量相等。则标准的ABC算法将优化问题的求解过程看成是在

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

维搜索空间中进行搜索。每个蜜源的位置代表问题的一个可能解,蜜源的花蜜量对应于相应的解的适应度。一个采蜜蜂与一个蜜源是相对应的。与第

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

个蜜源相对应的采蜜蜂依据如下公式寻找新的蜜源:

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

其中,

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

是区间

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

上的随机数,

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

。标准的ABC算法将新生成的可能解

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

与原来的解

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

作比较,并采用贪婪选择策略保留较好的解。每一个观察蜂依据概率选择一个蜜源,概率公式为

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

其中,

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

是可能解

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

的适应值。对于被选择的蜜源,观察蜂根据上面概率公式搜寻新的可能解。当所有的采蜜蜂和观察蜂都搜索完整个搜索空间时,如果一个蜜源的适应值在给定的步骤内(定义为控制参数“limit”) 没有被提高, 则丢弃该蜜源,而与该蜜源相对应的采蜜蜂变成侦查蜂,侦查蜂通过已下公式搜索新的可能解。

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

其中,

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

是区间

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

上的随机数,

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

是第

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

维的下界和上界。

2、流程

  • 初始化;
  • 重复以下过程:
  • 将采蜜蜂与蜜源一一对应,根据上面第一个公式更新蜜源信息,同时确定蜜源的花蜜量;
  • 观察蜂根据采蜜蜂所提供的信息采用一定的选择策略选择蜜源,根据第一个公式更新蜜源信息,同时确定蜜源的花蜜量;
  • 确定侦查蜂,并根据第三个公式寻找新的蜜源;
  • 记忆迄今为止最好的蜜源;
  • 判断终止条件是否成立;

三、人工蜂群算法用于求解函数优化问题       对于函数

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

其中

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

。    代码:

#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<cmath>
#include<fstream>
#include<iomanip>
using namespace std;

const int NP=40;//种群的规模,采蜜蜂+观察蜂
const int FoodNumber=NP/2;//食物的数量,为采蜜蜂的数量
const int limit=20;//限度,超过这个限度没有更新采蜜蜂变成侦查蜂
const int maxCycle=10000;//停止条件

/*****函数的特定参数*****/
const int D=2;//函数的参数个数
const double lb=-100;//函数的下界 
const double ub=100;//函数的上界

double result[maxCycle]={0};

/*****种群的定义****/
struct BeeGroup
{
	double code[D];//函数的维数
	double trueFit;//记录真实的最小值
	double fitness;
	double rfitness;//相对适应值比例
	int trail;//表示实验的次数,用于与limit作比较
}Bee[FoodNumber];

BeeGroup NectarSource[FoodNumber];//蜜源,注意:一切的修改都是针对蜜源而言的
BeeGroup EmployedBee[FoodNumber];//采蜜蜂
BeeGroup OnLooker[FoodNumber];//观察蜂
BeeGroup BestSource;//记录最好蜜源

/*****函数的声明*****/
double random(double, double);//产生区间上的随机数
void initilize();//初始化参数
double calculationTruefit(BeeGroup);//计算真实的函数值
double calculationFitness(double);//计算适应值
void CalculateProbabilities();//计算轮盘赌的概率
void evalueSource();//评价蜜源
void sendEmployedBees();
void sendOnlookerBees();
void sendScoutBees();
void MemorizeBestSource();


/*******主函数*******/
int main()
{
	ofstream output;
	output.open("dataABC.txt");

	srand((unsigned)time(NULL));
	initilize();//初始化
	MemorizeBestSource();//保存最好的蜜源
		
	//主要的循环
	int gen=0;
	while(gen<maxCycle)
	{
		sendEmployedBees();
			
		CalculateProbabilities();
			
		sendOnlookerBees();
			
		MemorizeBestSource();
			
		sendScoutBees();
			
		MemorizeBestSource();

		output<<setprecision(30)<<BestSource.trueFit<<endl;
			
		gen++;
	}
	
	output.close();
	cout<<"运行结束!!"<<endl;
	return 0;
}

/*****函数的实现****/
double random(double start, double end)//随机产生区间内的随机数
{	
	return start+(end-start)*rand()/(RAND_MAX + 1.0);
}

void initilize()//初始化参数
{
	int i,j;
	for (i=0;i<FoodNumber;i++)
	{
		for (j=0;j<D;j++)
		{
			NectarSource[i].code[j]=random(lb,ub);
			EmployedBee[i].code[j]=NectarSource[i].code[j];
			OnLooker[i].code[j]=NectarSource[i].code[j];
			BestSource.code[j]=NectarSource[0].code[j];
		}
		/****蜜源的初始化*****/
		NectarSource[i].trueFit=calculationTruefit(NectarSource[i]);
		NectarSource[i].fitness=calculationFitness(NectarSource[i].trueFit);
		NectarSource[i].rfitness=0;
		NectarSource[i].trail=0;
		/****采蜜蜂的初始化*****/
		EmployedBee[i].trueFit=NectarSource[i].trueFit;
		EmployedBee[i].fitness=NectarSource[i].fitness;
		EmployedBee[i].rfitness=NectarSource[i].rfitness;
		EmployedBee[i].trail=NectarSource[i].trail;
		/****观察蜂的初始化****/
		OnLooker[i].trueFit=NectarSource[i].trueFit;
		OnLooker[i].fitness=NectarSource[i].fitness;
		OnLooker[i].rfitness=NectarSource[i].rfitness;
		OnLooker[i].trail=NectarSource[i].trail;
	}
	/*****最优蜜源的初始化*****/
	BestSource.trueFit=NectarSource[0].trueFit;
	BestSource.fitness=NectarSource[0].fitness;
	BestSource.rfitness=NectarSource[0].rfitness;
	BestSource.trail=NectarSource[0].trail;
}

double calculationTruefit(BeeGroup bee)//计算真实的函数值
{
	double truefit=0;
	/******测试函数1******/
	truefit=0.5+(sin(sqrt(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))*sin(sqrt(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))-0.5)
		/((1+0.001*(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1]))*(1+0.001*(bee.code[0]*bee.code[0]+bee.code[1]*bee.code[1])));

	return truefit;
}

double calculationFitness(double truefit)//计算适应值
{
	double fitnessResult=0;
	if (truefit>=0)
	{
		fitnessResult=1/(truefit+1);
	}else
	{
		fitnessResult=1+abs(truefit);
	}
	return fitnessResult;
}

void sendEmployedBees()//修改采蜜蜂的函数
{
	int i,j,k;
	int param2change;//需要改变的维数
	double Rij;//[-1,1]之间的随机数
	for (i=0;i<FoodNumber;i++)
	{
		
		param2change=(int)random(0,D);//随机选取需要改变的维数

		/******选取不等于i的k********/
		while (1)
		{
			k=(int)random(0,FoodNumber);
			if (k!=i)
			{
				break;
			}
		}

		for (j=0;j<D;j++)
		{
			EmployedBee[i].code[j]=NectarSource[i].code[j];
		}

		/*******采蜜蜂去更新信息*******/
		Rij=random(-1,1);
		EmployedBee[i].code[param2change]=NectarSource[i].code[param2change]+Rij*(NectarSource[i].code[param2change]-NectarSource[k].code[param2change]);
		/*******判断是否越界********/
		if (EmployedBee[i].code[param2change]>ub)
		{
			EmployedBee[i].code[param2change]=ub;
		}
		if (EmployedBee[i].code[param2change]<lb)
		{
			EmployedBee[i].code[param2change]=lb;
		}
		EmployedBee[i].trueFit=calculationTruefit(EmployedBee[i]);
		EmployedBee[i].fitness=calculationFitness(EmployedBee[i].trueFit);

		/******贪婪选择策略*******/
 		if (EmployedBee[i].trueFit<NectarSource[i].trueFit)
 		{
 			for (j=0;j<D;j++)
 			{
 				NectarSource[i].code[j]=EmployedBee[i].code[j];
 			}
			NectarSource[i].trail=0;
			NectarSource[i].trueFit=EmployedBee[i].trueFit;
			NectarSource[i].fitness=EmployedBee[i].fitness;
 		}else
		{
			NectarSource[i].trail++;
		}
	}
}

void CalculateProbabilities()//计算轮盘赌的选择概率
{
	int i;
	double maxfit;
	maxfit=NectarSource[0].fitness;
	for (i=1;i<FoodNumber;i++)
	{
		if (NectarSource[i].fitness>maxfit)
			maxfit=NectarSource[i].fitness;
	}
	
	for (i=0;i<FoodNumber;i++)
	{
		NectarSource[i].rfitness=(0.9*(NectarSource[i].fitness/maxfit))+0.1;
    }
}

void sendOnlookerBees()//采蜜蜂与观察蜂交流信息,观察蜂更改信息
{
	int i,j,t,k;
	double R_choosed;//被选中的概率
	int param2change;//需要被改变的维数
	double Rij;//[-1,1]之间的随机数
	i=0;
	t=0;
	while(t<FoodNumber)
	{
		
        R_choosed=random(0,1);
        if(R_choosed<NectarSource[i].rfitness)//根据被选择的概率选择
        {        
			t++;
			param2change=(int)random(0,D);
			
			/******选取不等于i的k********/
			while (1)
			{
				k=(int)random(0,FoodNumber);
				if (k!=i)
				{
					break;
				}
			}

			for(j=0;j<D;j++)
			{
				OnLooker[i].code[j]=NectarSource[i].code[j];
			}
			
			/****更新******/
			Rij=random(-1,1);
			OnLooker[i].code[param2change]=NectarSource[i].code[param2change]+Rij*(NectarSource[i].code[param2change]-NectarSource[k].code[param2change]);
			
			/*******判断是否越界*******/
			if (OnLooker[i].code[param2change]<lb)
			{
				OnLooker[i].code[param2change]=lb;
			}
			if (OnLooker[i].code[param2change]>ub)
			{	
				OnLooker[i].code[param2change]=ub;
			}
			OnLooker[i].trueFit=calculationTruefit(OnLooker[i]);
			OnLooker[i].fitness=calculationFitness(OnLooker[i].trueFit);
			
			/****贪婪选择策略******/
			if (OnLooker[i].trueFit<NectarSource[i].trueFit)
			{
				for (j=0;j<D;j++)
				{
					NectarSource[i].code[j]=OnLooker[i].code[j];
				}
				NectarSource[i].trail=0;
				NectarSource[i].trueFit=OnLooker[i].trueFit;
				NectarSource[i].fitness=OnLooker[i].fitness;
			}else
			{
				NectarSource[i].trail++;
			}
        } 
        i++;
        if (i==FoodNumber)
		{
			i=0;
		}
	}
}


/*******只有一只侦查蜂**********/
void sendScoutBees()//判断是否有侦查蜂的出现,有则重新生成蜜源
{
	int maxtrialindex,i,j;
	double R;//[0,1]之间的随机数
	maxtrialindex=0;
	for (i=1;i<FoodNumber;i++)
	{
		if (NectarSource[i].trail>NectarSource[maxtrialindex].trail)
		{
			maxtrialindex=i;
		}
	}
	if(NectarSource[maxtrialindex].trail>=limit)
	{
		/*******重新初始化*********/
		for (j=0;j<D;j++)
		{
			R=random(0,1);
			NectarSource[maxtrialindex].code[j]=lb+R*(ub-lb);
		}
		NectarSource[maxtrialindex].trail=0;
		NectarSource[maxtrialindex].trueFit=calculationTruefit(NectarSource[maxtrialindex]);
		NectarSource[maxtrialindex].fitness=calculationFitness(NectarSource[maxtrialindex].trueFit);
	}
}

void MemorizeBestSource()//保存最优的蜜源
{
	int i,j;
	for (i=1;i<FoodNumber;i++)
	{
		if (NectarSource[i].trueFit<BestSource.trueFit)
		{
			for (j=0;j<D;j++)
			{
				BestSource.code[j]=NectarSource[i].code[j];
			}
			BestSource.trueFit=NectarSource[i].trueFit;
		}
	}
}


收敛曲线:

www.zeeklog.com  - 优化算法——人工蜂群算法(ABC)

Read more

国产FPGA在海上风电设备中的应用

国产FPGA在海上风电设备中的应用

针对海上风电并网系统频繁遇到的谐波谐振问题,研制海上风电信息处理板,可以有效地减小谐波谐振对海上风电设备的影响,保证海上风电并网系统的安全稳定运行。 图 海上风电信息处理板 本方案主要负责三相电压电流信号的的采集和信号处理,采用双FPGA+DSP架构,主要由FPGA处理单元、DSP处理单元、光纤接口单元、ADC接口单元以及DAC接口单元组成。FPGA处理单元选用中科亿海微的EQ6HL130和EQ6HL9型FPGA。EQ6HL130负责对外接口,包括千兆以太网接口、AD/DA接口、GPS授时接口、变流器数字量接口、USB-C接口实现。EQ6HL9负责上电控制、电压电流监控、信号处理流程监控管理、故障上报等功能。DSP负责信号处理算法。本方案具有接口丰富可扩展、信号处理性能高、全链路延时低、高可靠高可用的特点。 方案优势 1、基于FPGA+DSP异构架构,主FPGA负责对外接口,DSP负责核心处理算法,从FPGA进行整板自检和监控管理,功能划分清晰; 2、对外接口丰富 * 六路ADC采样电路,可实现三相电压、三相电流的同时采样; * 八路DAC模数转换电路,可实现将原始或处

By Ne0inhk
docker容器安装vim

docker容器安装vim

起因是rancher安装jenkins的时候,需要改一些配置文件,突然发现没有vi命令 jenkins@jenkins-ci-jenkins-primary-1:/$ vim bash: vim: command not found 现在但是进去docker容器里面发现没有vi或者vim。于是想要安装 jenkins@jenkins-ci-jenkins-primary-1:/$ apt-get install vi E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied) E: Unable to lock the administration directory (/var/lib/dpkg/), are you root? jenkins@jenkins-ci-jenkins-primary-1:/$ 安装的时候发现没有root 权限,

By Ne0inhk
在centos安装jenkins

在centos安装jenkins

基于RPM分发包,如:RHEL, CentOS, Fedora 等linux .你可以通过yum安装jenkins ,在yum仓库里有最近的版本,你可以下载它. 安装 安装最近一周的版本 在yum repo添加jenkins地址,然后可以从那里安装它 • sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo • sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key • sudo yum install jenkins 安装LTS版本 你也可以安装 LTS Release Line • sudo

By Ne0inhk
海灵犀FPGA基础研学实验箱

海灵犀FPGA基础研学实验箱

海灵犀FPGA基础研学实验箱(EDU_H6_01_1V0)是由中科亿海微电子科技(苏州)有限公司(简称:中科亿海微)自主研发设计的教学用具,由箱体、FPGA开发卡、LCD屏、USB下载线及相关实验配件组成,提供Verilog语言的实验例程,产品具有实用性高、案例丰富、国产化程度高等特点,满足教学机构微电子、电子工程等相关专业基础研学实验需要。 图 海灵犀FPGA基础研学实验箱 1、实验箱概述 · 海灵犀FPGA基础研学实验箱由箱体、FPGA开发板、LCD屏、USB下载线、资料U盘及相关实验配件组成; · 基于中科亿海微全国产全正向的FPGA芯片和配套的EDA软件进行设计。FPGA芯片为EQ6HL9-TQG144,具有高性能低功耗特定,可编程逻辑单元数量为8.64K; · FPGA板卡资源有:8位LED数码管、USB转UART/JTAG口、蜂鸣器、4.3寸LCD、两路2.54mm间距的40PIN标准IO扩展口; · 根据实际课程教学要求,提供Verilog语言的实验例程; · 实验指导手册非常注重实验过程的深度讲解,包括开发板简介、实验环境搭建、实验简介、

By Ne0inhk