ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 20705|回复: 47

[分享] 【遗传算法】简单实例

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2015-12-23 22:37 | 显示全部楼层 |阅读模式
遗传算法是模仿生物种群通过几代、几十代的遗传进化、依靠环境选择进行优胜劣汰,从中筛选得到最接近最优解的模糊算法。

当无法进行穷举遍历时,采用遗传算法可以很快地得到较优解。

具体过程比较复杂一些,所以一般VBA中很少使用。

但是,有简单的例子,可以给大家做个参考。

请看附件。

遗传算法实例.rar

49.71 KB, 下载次数: 1149

评分

8

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-12-23 22:39 | 显示全部楼层
  1. Option Base 1
  2. Dim binVal, pop, popVal, newPop, maxPop
  3. Dim popSize&, chromLen&, maxNum&, maxVal, maxCnt&, maxB&, maxX, fitM&, fitSum, pC, pM, cCnt&, mCnt&
  4. Sub MainSub() 'by kagawa 2015/12/23
  5.     Dim j&, maxY
  6.     maxY = 16.9996092520257 'x=161
  7.     fitM = 20
  8.    
  9.     maxNum = 10 'x∈[0,10) x最大值范围
  10.     chromLen = 10 'x=b/1024*maxNum 染色体长度(二进制位数)
  11.     pC = 0.85 '交叉概率
  12.     pM = 0.005 '变异概率
  13.     popSize = 20 '样本种群大小
  14.    
  15.     ReDim binVal(0 To chromLen) '生成二进制Decode计算常量
  16.     For j = 0 To chromLen
  17.         binVal(j) = 2 ^ (chromLen - j)
  18.     Next
  19.    
  20.     maxVal = 0 '记录最大值初始化
  21.     cCnt = 0 '记录交叉实施次数
  22.     mCnt = 0 '记录变异实施次数
  23.    
  24.     Call InitPop '随机生成初始种群
  25.     For j = 1 To 10 '遗传迭代次数
  26.         Call decodeBin '解码计算x、y=f(x)、z=fit(y)
  27.         Call SortPop '对fit结果排序
  28.         If popVal(2, popSize) - fitM > maxVal Then
  29. '        If popVal(2, popSize) > maxVal Then
  30.             maxCnt = j '最大值时的迭代次数
  31.             maxB = decodeBinX(popVal(1, popSize), 1) '最大时的十进制值
  32.             maxX = decodeBinX(popVal(1, popSize)) '最大时的x值
  33.             maxVal = calObjVal(maxX) '更新最大记录y值
  34.             maxPop = Application.Index(pop, popVal(1, popSize)) '最大时的二进制值
  35.         End If
  36.         Call CrossPop '交叉遗传
  37.         Call MutationPop '变异遗传
  38.     Next
  39.     Debug.Print Join(maxPop, ""); maxB; maxX; maxVal; Format(maxVal / maxY, "0.0000%"); maxCnt; cCnt; mCnt
  40. '    Stop
  41. End Sub
  42. Sub InitPop() '样本种群初始化 随机赋值
  43.     Dim i&, j&
  44.     ReDim pop(popSize, chromLen)
  45.     Randomize
  46.     For i = 1 To popSize
  47.         For j = 1 To chromLen
  48.             pop(i, j) = Int(Rnd * 2)
  49.         Next
  50.     Next
  51. End Sub
  52. Sub decodeBin() '对种群进行解码计算
  53.     Dim i&, j&, x, y, z
  54.     ReDim popVal(3, popSize)
  55.     fitSum = 0
  56.     For i = 1 To popSize
  57.         x = decodeBinX(i)
  58.         y = calObjVal(x)
  59.         z = calFitVal(y)
  60.         fitSum = fitSum + z
  61.         popVal(1, i) = i
  62.         popVal(2, i) = z
  63.     Next
  64. End Sub
  65. Function decodeBinX(i, Optional k = 0) '逐行解码计算得到x值
  66.     Dim binSum, j&
  67.     binSum = 0
  68.     For j = 1 To chromLen
  69.         If pop(i, j) Then binSum = binSum + binVal(j)
  70.     Next
  71.     If k Then decodeBinX = binSum Else decodeBinX = binSum / binVal(0) * maxNum '二进制binSum 或转为x=[0,10)内实数值
  72. End Function
  73. Function calObjVal(x) 'f(x)=10*sin(5x)+7*cos(4x) x∈[0,10] '目标计算函数
  74.     calObjVal = 10 * Sin(5 * x) + 7 * Cos(4 * x)
  75. End Function
  76. Function calFitVal(y) '适度评价函数
  77. '    calFitVal = fitM - y '求最小值
  78. '    calFitVal = fitM - Abs(y) '最接近0值
  79.     If fitM + y > 0 Then calFitVal = fitM + y Else calFitVal = 0 '求最大值
  80. End Function
  81. Sub SortPop() '解码计算结果排序、并得到累计占比
  82.     Dim i&, j&, t, popSum
  83.     For i = popSize To 2 Step -1 '冒泡排序
  84.         For j = 1 To i - 1
  85.             If popVal(2, j) > popVal(2, j + 1) Then '按适度值A-Z升序排序
  86.                 t = popVal(1, j): popVal(1, j) = popVal(1, j + 1): popVal(1, j + 1) = t '索引值
  87.                 t = popVal(2, j): popVal(2, j) = popVal(2, j + 1): popVal(2, j + 1) = t '适度值z值
  88.             End If
  89.         Next
  90.     Next
  91.     '计算累计占比
  92.     popSum = popVal(2, 1): popVal(3, 1) = popSum / fitSum
  93.     For i = 2 To popSize
  94.         popSum = popSum + popVal(2, i): popVal(3, i) = popSum / fitSum
  95.     Next
  96. End Sub
  97. Sub CrossPop() '交叉遗传复制
  98.     Dim i1&, i2&, j&, j2&, k&, l&, r, t
  99.     ReDim newPop(popSize, chromLen)
  100.     Randomize
  101.     For k = 1 To popSize Step 2
  102.         Do
  103.             r = Rnd '随机1
  104.             For i1 = 1 To popSize
  105.                 If r < popVal(3, i1) Then i1 = popVal(1, i1): Exit For
  106.             Next
  107.             r = Rnd '随机2
  108.             For i2 = 1 To popSize
  109.                 If r < popVal(3, i2) Then i2 = popVal(1, i2): Exit For
  110.             Next
  111.             If i1 <> i2 Then Exit Do
  112.         Loop
  113.         '首先确定需要复制的2个父本的随机位置i1/i2
  114.         
  115.         If Rnd < pC Then '如果满足交叉概率 则进行随机交叉
  116.             cCnt = cCnt + 1 '记录交叉实施次数
  117.             
  118.             '随机得到交叉起始位置j 以及交叉长度l
  119.             j = Int(Rnd * chromLen) + 1 '交叉起始位置j
  120.             l = Int(Rnd * (chromLen - j + 1)) '交叉长度l
  121.             For j2 = 1 To j - 1 'DNA仅复制
  122.                 newPop(k, j2) = pop(i1, j2)
  123.                 newPop(k + 1, j2) = pop(i2, j2)
  124.             Next
  125.             For j2 = j To j + l '此区域进行DNA交叉
  126.                 newPop(k, j2) = pop(i2, j2)
  127.                 newPop(k + 1, j2) = pop(i1, j2)
  128.             Next
  129.             For j2 = j2 To chromLen 'DNA仅复制
  130.                 newPop(k, j2) = pop(i1, j2)
  131.                 newPop(k + 1, j2) = pop(i2, j2)
  132.             Next
  133.         End If
  134.     Next
  135.     pop = newPop '处理完成后,更新pop种群
  136. End Sub
  137. Sub MutationPop() '变异遗传计算
  138.     Dim i&, j&
  139.     For i = 1 To popSize
  140.         If Rnd < pM Then '如果满足变异概率 则进行随机位置变异
  141.             mCnt = mCnt + 1 '记录变异实施次数
  142.             j = Int(Rnd * chromLen) + 1 '确定随机变异位置j
  143.             If pop(i, j) Then pop(i, j) = 0 Else pop(i, j) = 1 '进行0/1互换变异(只1位)
  144.         End If
  145.     Next
  146. End Sub
复制代码

评分

5

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-12-23 22:41 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
离楼主这么近,爽呀,支持下下,谢谢分享

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2015-12-23 22:55 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-12-24 10:18 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2015-12-24 10:35 | 显示全部楼层
说实话,算法没太看明白,俺数学渣。很敬佩群子女侠的钻研精神,努力扣代码中......

TA的精华主题

TA的得分主题

发表于 2015-12-24 12:22 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
算法概述可以看看这个文章,讲得很有趣。http://songshuhui.net/archives/10462

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-12-24 17:24 | 显示全部楼层
遗传算法 一个未知数x的优化版本,加了一些过程数据分析。

GeneticAlgorithm-1 (x).zip

112 KB, 下载次数: 314

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-12-24 17:25 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
遗传算法 2个未知数x1、先的最新版本。

计算过程比1个未知数稍有变化,但总体算法结构是一样的。

GeneticAlgorithm-2 (x1x2).zip

79.94 KB, 下载次数: 691

TA的精华主题

TA的得分主题

发表于 2015-12-24 21:56 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-19 16:38 , Processed in 0.044278 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表