头脑风暴过程

头脑风暴法经常被用来解决创新问题。它可以解决很多通常不能由一个人解决的难题。在头脑风暴过程中,一群背景不同的人聚集在一起进行讨论。引导者通常会参与这个过程,但不会直接参与想法的产生。引导者通常应该有足够的引导者经验,但对要解决的问题的了解较少,这样产生的想法就会较少受到来自引导者的认知的影响。头脑风暴的过程是用来产生尽可能多的想法,这样就可以从这些想法中得到解决问题的好办法。

头脑风暴的过程通常包括几轮想法的产生。在每一轮的想法生成中,头脑风暴小组都被要求提出很多想法。在每一轮的想法生成过程结束时,比较好的想法会被挑选出来,作为下一轮创意生成过程中产生想法的线索。在头脑风暴的过程中,还有另外一群人,他们的目的是从每一轮的想法产生过程中挑选出比较好的想法,通过头脑风暴的过程,由人类的集体智慧,往往会产生伟大的解决方案,并且我们的问题通常能够以很高的概率得到解决。

头脑风暴流程建模如下

头脑风暴(BSO)算法简介

受人类创造性解决问题过程——头脑风暴会议的启发, 2011年史玉回老师在第二次群体智能国际会议 (The Second International Conference on Swarm Intelligence(ICSI11)) 中提出一种新的群智能优化算法——头脑风暴优化算法,算法采用聚 类思想搜索局部最优,通过局部最优的比较得到全局最优;采用变异思想增加了算法的多 样性,避免算法陷入局部最优,在这聚与散相辅相承的过程中搜索最优解,思想新颖,适合于解决多峰高维函数问题。

算法流程建模如下

算法步骤描述(流程纯Word手打,转载请注明出处!):

使用Java实现BSO算法

注:为了演示效果,本示例选择Sphere函数作为适应值函数来评价个体。维度设置为2维,且迭代次数仅仅设定20代。

Sphere函数定义如下:

package BSO_Code;import java.util.ArrayList;
import java.util.Random;/*** 头脑风暴智能优化算法实现* @author xudaxia0610*/
public class BSO {//个体数量public int number_of_individuals;//聚类个数public int number_of_clusters;//种群public ArrayList<Cindividual> population;//类簇public ArrayList<ArrayList<Integer>> cluster;//质心集合public ArrayList<Cindividual> meansList;//存放类中心所在下标的集合public ArrayList<Integer> clusterCenterIndex;//新解集合public ArrayList<Cindividual> nSolutions;//最优个体public Cindividual bestIndividual;//下面四个为预先决定的概率public float p_clustering;public float p_generation;public float p_oneCluster;public float p_twoCluster;//下面四个为算法执行过程中生成的比例public float r_clustering;public float r_generation;public float r_oneCluster;public float r_twoCluster;//个体的维数public int dimension;// 迭代次数public int total_evolve_times;// 当前迭代的次数public int current_evolve_times;//随机数生成器public Random random = new Random();//参数k,此k非聚类k的个数,而是新个体产生的公式中变异系数中那个控制斜率的Kpublic int k;//交叉生成新个体时,父母的权重比例public float weight1;public float weight2;//参数初始化public void initParameters() {//解的维数dimension = 2;//个体数量(种群大小)number_of_individuals = 100;//聚类个数number_of_clusters = 5;//初始化各个集合cluster = new ArrayList<>();clusterCenterIndex = new ArrayList<>();nSolutions = new ArrayList<>();meansList = new ArrayList<>();//决定是否需要替换一个类中心的概率p_clustering = 0.2f;//决定新个体产生是由一个还是两个老个体所决定的概率p_generation = 0.8f; //决定由一个类中心还是其它普通个体来生成新个体的概率p_oneCluster = 0.4f;//决定由两个类中心还是其它两个普通个体来生成新个体的概率p_twoCluster = 0.5f;//总迭代次数total_evolve_times = 20;//当前迭代次数current_evolve_times = 0;//初始化k,变异操作控制斜率的参数k = 25;//初始化权重weight1 = 0.5f;weight2 = 0.5f;//初始化最优个体bestIndividual = new Cindividual();bestIndividual.lChromosome = new ArrayList<>();for(int i = 0; i < dimension; i++) {bestIndividual.lChromosome.add(1.0f);}//将初始化的最优个体的Object_value设为最大值,因为object_value越小越好bestIndividual.objectValue = Float.MAX_VALUE;}//种群初始化public void initPopulation() {population = new ArrayList<>();for(int i = 0;i < number_of_individuals;i++) {//生成一个新个体Cindividual t = new Cindividual();t.lChromosome = new ArrayList<>();//随机初始化这个个体initIndividual(t);//根据适应值函数评价该个体evaluate(t);//更新最优个体updateBestIndividual(t);//将该个体的引用置入种群中population.add(t);}}//初始化一个个体public void initIndividual(Cindividual t) {for(int i = 0;i < dimension;i++) {t.lChromosome.add(random.nextFloat() * 200.0f - 100.0f);}}//适应值函数评价个体public void evaluate(Cindividual t) {//此处实现的是最简单的Sphere函数(单峰函数)t.objectValue = 0.0f;float cur = 0.0f;for(int i = 0; i < dimension; i++) {cur = t.lChromosome.get(i);t.objectValue = t.objectValue + cur * cur;}}//更新最优个体public void updateBestIndividual(Cindividual t) {//objectValue值越小越好if (t.objectValue < bestIndividual.objectValue) {bestIndividual.objectValue = t.objectValue;}}//K-Means聚类算法过程public void clustering() {//清空上次聚类的残留结果clusterCenterIndex.clear();cluster.clear();for (int i = 0; i < number_of_clusters; i++){//将类中心数组初始化clusterCenterIndex.add(-1);//生成k个空簇cluster.add(new ArrayList<>());}//随机挑选k个个体作为初始类中心for(int i = 0;i < number_of_clusters;i++) {int centerIndex = -1;while(true) {//flag为标识位,标识挑选的类中心是否距离已经挑选好的类中心距离太近boolean flag = false;//随机挑选一个个体centerIndex = random.nextInt(number_of_individuals);//确保不会出现重复的类中心if (clusterCenterIndex.contains(centerIndex)) {//重复了就重来continue;}//确保随机挑选的类中心之间相距不会太近if (i != 0){for (int j = i - 1; j >= 0; j--){if (getDistance(population.get(centerIndex), population.get(clusterCenterIndex.get(j))) < 1.0f) {//距离小于2,判定初始类中心相距太近flag = true;break;}}}//如果距离太近,那么就重新生成if (flag) {continue;}//如果类中心既未重复也未距离其他类中心太近,跳出循环break;}clusterCenterIndex.set(i, centerIndex);}//第一次聚类for (int i = 0; i < number_of_individuals; i++) {Cindividual tCindividual = population.get(i);//获取该个体所属簇编号int label = getIndividualOfCluster(tCindividual);//将该个体的下标添加到对应的簇中cluster.get(label).add(i);}float oldVar = -1.0f;float newVar = getVar();//当新旧方差值相差不到1即准则函数值不发生明显变化时,聚类算法终止while(Math.abs(newVar - oldVar) >= 1.0f) {//更新类中心getCenter();//使用质心//getMeans();oldVar = newVar;//清空每个簇for (int i = 0; i < number_of_clusters; i++){cluster.get(i).clear();;}//根据新的聚类中心去获取新的聚类结果for (int i = 0; i < number_of_individuals; i++){//遍历每一个个体Cindividual t = population.get(i);//获取该个体所属簇编号int label = getIndividualOfCluster(t);//将该个体的下标添加到对应的簇中cluster.get(label).add(i);}//计算新的簇内方差值newVar = getVar();}}//获取两个个体之间的欧式距离public float getDistance(Cindividual t1,Cindividual t2) {float res = 0.0f;for(int i = 0;i < dimension;i++) {res += (t1.lChromosome.get(i) - t2.lChromosome.get(i)) * (t1.lChromosome.get(i) - t2.lChromosome.get(i));}return (float) Math.sqrt(res);}//查看当前个体属于哪个类中public int getIndividualOfCluster(Cindividual t) {int label = 0;float minDistance = getDistance(t, population.get(clusterCenterIndex.get(0)));for(int i = 1;i < number_of_clusters;i++) {float anotherDistance = getDistance(t, population.get(clusterCenterIndex.get(i)));if (anotherDistance < minDistance) {minDistance = anotherDistance;label = i;}}return label;}//获得簇集的平方差public float getVar() {float var = 0.0f;for(int i = 0;i < number_of_clusters; i++) {ArrayList<Integer> list = cluster.get(i);for(int j = 0; j < list.size(); j++) {var += getDistance(population.get(clusterCenterIndex.get(i)), population.get(list.get(j)));}}return var;}//将质心作为聚类中心public void getMeans() {//清空上次聚类的质心残留meansList.clear();for(int i = 0;i < number_of_clusters ; i++) {Cindividual cindividual = new Cindividual();cindividual.lChromosome = new ArrayList<>();int clusterSize = cluster.get(i).size();for(int k = 0;k < dimension; k++) {float means = 0.0f;for(int j = 0;j < clusterSize;j++) {means += population.get(cluster.get(i).get(j)).lChromosome.get(k);}means /= clusterSize;cindividual.lChromosome.add(means);}meansList.add(cindividual);}}//确定类中心//下面的实现是基于挑选类中最优个体作为类中心的//如果最终算法收敛效果不好,那么可以尝试一下使用质心作为类中心public void getCenter() {for(int i = 0;i < number_of_clusters;i++) {//定义一个初始的最优值float bestValue = Float.MAX_VALUE;//定义类中心的索引int centerIndex = -1;ArrayList<Integer> list = cluster.get(i);for(int j = 0; j < list.size(); j++) {float curValue = population.get(list.get(j)).objectValue;if (curValue < bestValue) {bestValue = curValue;centerIndex = list.get(j);}}//更新类中心的索引clusterCenterIndex.set(i, centerIndex);}}//新个体生成的过程public void newIndividualGenerate() {//清空新解集合nSolutions.clear();//由单个类生成新个体所需下标参数int clusterIndex = -1, individualIndex = -1;//由两个类生成新个体所需下标参数int clusterIndex1 = -1, clusterIndex2 = -1, individualIndex1 = -1, individualIndex2 = -1;//簇大小int clusterSize1 = -1;int clusterSize2 = -1;//判断是否需要随机挑选出来一个类中心去替换掉//这是一种发散操作r_clustering = random.nextFloat();if (r_clustering < p_clustering) {//随机获取一个类的索引clusterIndex = random.nextInt(number_of_clusters);//随机生成一个新个体Cindividual newObject = new Cindividual();newObject.lChromosome = new ArrayList<>();initIndividual(newObject);//替换刚才选中的那个类中心int replacedObjectIndex = clusterCenterIndex.get(clusterIndex);population.set(replacedObjectIndex, newObject);}//新个体生成的过程for(int i = 0;i < number_of_individuals; i++) {Cindividual newObject = new Cindividual();r_generation = random.nextFloat();//r_generation < p_generation --》 随机挑选一个类去生成新个体     else 随机挑选两个类去生成新个体if (r_generation < p_generation) {r_oneCluster = random.nextFloat();//随机获取一个簇clusterIndex = random.nextInt(number_of_clusters);if (r_oneCluster < p_oneCluster) {//根据刚刚获得的随机类索引,拿到该类的类中心//根据该类中心加入噪声以生成新的个体individualIndex = clusterCenterIndex.get(clusterIndex);Cindividual center = population.get(individualIndex);//根据类中心执行变异操作mutation(center,newObject);//评价新个体evaluate(newObject);//更新最优个体updateBestIndividual(newObject);//加入新个体集合nSolutions.add(newObject);}else {//在随机选取的类中我们随机选取一个普通个体,以该个体为根据,加入噪声生成新个体clusterSize1 = cluster.get(clusterIndex).size();//随机选取一个个体individualIndex = cluster.get(clusterIndex).get(random.nextInt(clusterSize1));//避免随机到类中心while(cluster.get(clusterIndex).size() != 1 && individualIndex == clusterCenterIndex.get(clusterIndex)) {individualIndex = cluster.get(clusterIndex).get(random.nextInt(clusterSize1));}Cindividual commonObj = population.get(individualIndex);//根据普通个体执行变异操作mutation(commonObj,newObject);//评价新个体evaluate(newObject);//更新最优个体updateBestIndividual(newObject);//加入新个体集合nSolutions.add(newObject);}}else {r_twoCluster = random.nextFloat();//随机选取两个类clusterIndex1 = random.nextInt(number_of_clusters);clusterIndex2 = random.nextInt(number_of_clusters);while(clusterIndex1 == clusterIndex2) {clusterIndex2 = random.nextInt(number_of_clusters);}//r_twoCluster < p_twoCluster --> 由两个类中心结合,加入噪声去生成新个体//r_twoCluster >= p_twoCluster --> 有两个类中的普通个体交叉,加入噪声去生成新个体if (r_twoCluster < p_twoCluster) {individualIndex1 = clusterCenterIndex.get(clusterIndex1);individualIndex2 = clusterCenterIndex.get(clusterIndex2);//取两个类的类中心作为双亲Cindividual father = population.get(individualIndex1);Cindividual mother = population.get(individualIndex2);//交叉生成crossover(father,mother,newObject);//评价新个体evaluate(newObject);//更新最优个体updateBestIndividual(newObject);//加入新个体集合nSolutions.add(newObject);}else {clusterSize1 = cluster.get(clusterIndex1).size();clusterSize2 = cluster.get(clusterIndex2).size();//去获取两个类中的两个普通个体individualIndex1 = cluster.get(clusterIndex1).get(random.nextInt(clusterSize1));individualIndex2 = cluster.get(clusterIndex2).get(random.nextInt(clusterSize2));//避免随机到类中心while(cluster.get(clusterIndex1).size() != 1 && individualIndex1 == clusterCenterIndex.get(clusterIndex1)) {individualIndex1 = cluster.get(clusterIndex1).get(random.nextInt(clusterSize1));}//避免随机到类中心while(cluster.get(clusterIndex2).size() != 1 && individualIndex2 == clusterCenterIndex.get(clusterIndex2)) {individualIndex2 = cluster.get(clusterIndex2).get(random.nextInt(clusterSize2));}//取两个类中的普通个体作为双亲Cindividual father = population.get(individualIndex1);Cindividual mother = population.get(individualIndex2);//交叉生成crossover(father,mother,newObject);//评价新个体evaluate(newObject);//更新最优个体updateBestIndividual(newObject);//加入新个体集合nSolutions.add(newObject);}}}System.out.println();}//个体变异操作public void mutation(Cindividual center,Cindividual newObj) {//定义传递函数的指数部分float j = (0.5f * total_evolve_times - current_evolve_times) / k;newObj.lChromosome = new ArrayList<>();for(int i = 0;i < dimension; i++) {float r1 = random.nextFloat();float r2 = random.nextFloat();newObj.lChromosome.add((float) (center.lChromosome.get(i) + (r1 * r2)/(1 + Math.exp(-j))));}}//交叉生成public void crossover(Cindividual father,Cindividual mother,Cindividual newObj) {// 定义传递函数的指数部分float j = (0.5f * total_evolve_times - current_evolve_times) / k;newObj.lChromosome = new ArrayList<>();for(int i = 0;i < dimension; i++) {float r1 = random.nextFloat();float r2 = random.nextFloat();newObj.lChromosome.add((float) (weight1*father.lChromosome.get(i) + weight2*mother.lChromosome.get(i) + (r1 * r2)/(1 + Math.exp(-j))));}}//挑选过程,对同一下标的新老个体进行对比,好的留下,坏的淘汰public void selection() {for(int i = 0;i < number_of_individuals;i++) {if (nSolutions.get(i).objectValue < population.get(i).objectValue) {population.set(i, nSolutions.get(i));}}}//进化函数public void evolve() {//参数初始化initParameters();//种群初始化initPopulation();//迭代开始while (current_evolve_times < total_evolve_times) {//先聚类clustering();//生成新个体newIndividualGenerate();//挑选selection();System.out.println("当前迭代次数:"+current_evolve_times + "次,本次最优个体值为:"+bestIndividual.objectValue);current_evolve_times++;}}public static void main(String[] args) {BSO bso = new BSO();bso.evolve();}}

Sphere函数的最优解非常直观,就是0,我们来观察一下算法的效果.

当前迭代次数:0次,本次最优个体值为:146.48228
当前迭代次数:1次,本次最优个体值为:21.945087
当前迭代次数:2次,本次最优个体值为:20.831068
当前迭代次数:3次,本次最优个体值为:6.7565203
当前迭代次数:4次,本次最优个体值为:0.6902876
当前迭代次数:5次,本次最优个体值为:0.19008647
当前迭代次数:6次,本次最优个体值为:0.015031425
当前迭代次数:7次,本次最优个体值为:0.010165354
当前迭代次数:8次,本次最优个体值为:0.0011416364
当前迭代次数:9次,本次最优个体值为:0.0011416364
当前迭代次数:10次,本次最优个体值为:0.0011416364
当前迭代次数:11次,本次最优个体值为:0.0011416364
当前迭代次数:12次,本次最优个体值为:3.4804514E-4
当前迭代次数:13次,本次最优个体值为:2.8302986E-4
当前迭代次数:14次,本次最优个体值为:2.8302986E-4
当前迭代次数:15次,本次最优个体值为:2.8302986E-4
当前迭代次数:16次,本次最优个体值为:2.8302986E-4
当前迭代次数:17次,本次最优个体值为:2.8302986E-4
当前迭代次数:18次,本次最优个体值为:1.7496837E-4
当前迭代次数:19次,本次最优个体值为:1.7496837E-4

BSO算法介绍及Java实现相关推荐

  1. Sunday算法介绍及Java实现

    前言 最初想写这篇文章的原因是在LeetCode上看到了一道实现strStr函数的题: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haysta ...

  2. sunday算法特征码_Sunday算法介绍及Java实现

    前言 最初想写这篇文章的原因是在LeetCode上看到了一道实现strStr函数的题: 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haysta ...

  3. apriori java_频繁模式挖掘apriori算法介绍及Java实现

    频繁模式是频繁地出如今数据集中的模式(如项集.子序列或者子结构).比如.频繁地同一时候出如今交易数据集中的商品(如牛奶和面包)的集合是频繁项集. 一些基本概念 支持度:support(A=>B) ...

  4. pca算法介绍及java实现_PCA算法原理及实现

    众所周知,PCA(principal component analysis)是一种数据降维的方式,能够有效的将高维数据转换为低维数据,进而降低模型训练所需要的计算资源. 以上是比较官方的说法,下面是人 ...

  5. pca算法介绍及java实现_PCA实现教程

    摘要: 手把手教你PCA降维技术!(有案例) 数据是机器学习模型的生命燃料.对于特定的问题,总有很多机器学习技术可供选择,但如果没有很多好的数据,问题将不能很好的解决.数据通常是大部分机器学习应用程序 ...

  6. mllib协同过滤 java实现_协同过滤(ALS)算法介绍及Spark MLlib调用实例(Scala/Java/Python)...

    协同过滤 算法介绍: 协同过滤常被用于推荐系统.这类技术目标在于填充"用户-商品"联系矩阵中的缺失项.Spark.ml目前支持基于模型的协同过滤,其中用户和商品以少量的潜在因子来描 ...

  7. java和c 的rsa加密算法_RSA算法签名技术Java与C++统一(加密解密结果一样)

    RSA算法签名技术Java与C++统一 (加密解密结果一样) 源代码下载地址:http://www.doczj.com/doc/64f44a94a0116c175f0e484d.html/produc ...

  8. 一致性哈希算法学习及JAVA代码实现分析

    1,对于待存储的海量数据,如何将它们分配到各个机器中去?---数据分片与路由 当数据量很大时,通过改善单机硬件资源的纵向扩充方式来存储数据变得越来越不适用,而通过增加机器数目来获得水平横向扩展的方式则 ...

  9. 递归算法介绍及Java应用实战

    转载自 递归算法介绍及Java应用实战 什么是递归算法 递归算法是把问题转化为规模缩小了的同类问题的子问题,然后递归调用函数(或过程)来表示问题的解.一个过程(或函数)直接或间接调用自己本身,这种过程 ...

最新文章

  1. c语言产生一m序列,其特征多相式:1+x^3+x^5,M序列伪随机码在测距回答概率控制中的 - FPGA/ASIC技术 - 电子发烧友网...
  2. 卡尔曼滤波器中的Q,R
  3. git如何查看sshkey_Jenkins配置SSH Key下载代码
  4. 解决go get 下载慢的问题
  5. Spring Roo开发初评
  6. 多个project[项目]共享session
  7. ThreadPoolExcutor 线程池 异常处理 (上篇)
  8. nginx优化配置选项
  9. Docker学习总结(66)—— Docker 的三大基石:Namespace、Cgroup 和 rootfs
  10. 最简单的DX窗口程序
  11. 话题热议:有没有能替代Excel的数据处理软件?
  12. Myeclipse8.5 cn 序列号
  13. OCR 常用软件对比
  14. 【抓否】哪来的“独角兽”——360私有化,富士康开飞机上市,宁德时代、药明康德这一系列闪电过会
  15. B站评论区抽奖[python]
  16. 计算机数据采集 的优点,数据采集器的作用_数据采集器硬件特点
  17. python基础语法测评_Python基础语法测评(A1卷)
  18. 深度学习Python环境打包到另外一台电脑(详细教程)
  19. 3.9使用ValidationSummary控件
  20. make menuconfig 添加新选项

热门文章

  1. spring boot+iview 前后端分离架构之用户管理的实现(三十)
  2. C语言程序设计之平面连杆机构解析法函数版
  3. 死磕算法真的有必要吗?
  4. matlab提取海岸线,遥感自动提取海岸线方法.PDF
  5. 杭电电子考研经验交流
  6. 淘宝教育浏览器无法观看
  7. Portal的简单介绍
  8. 关于PIC18F25K80串口收发问题
  9. html5 见缝插针,HTML5见缝插针小游戏
  10. python压缩包zip下载后解压使用(安装pip)