遗传算法简单介绍与MATLAB实现(一)

遗传算法简单介绍与MATLAB实现(一)

一点前奏

第一次听说遗传算法是在高三晚上放学回家的路上,同行的小伙伴问我:你知道遗传算法么?我自然没听说过,于是追问细节。

“听说遗传算法能够自我迭代,让他本身系统内的东西进行优胜劣汰的自然选择,把好的保留下来,次一点的东西就排除掉。是不是特别像人工智能的那种感觉?”

这么高端的么?那时候我就对这个算法产生了一点兴趣,毕竟一个算法是如何做到自我判断什么是好什么是坏。

因为如此,在我接触到编程以后,我终于有能力去深入研究一下遗传算法了。最后觉得,其实这个算法也没有当初想得那么玄乎。

当初年轻不懂事时,对未知的事物有着天然的好奇,自然会把遗传算法想的无限大,甚至认为可以自我淘汰不好的代码,学习优秀的代码等。

其实现在再看过来,遗传算法的本质始终没变,依旧是优胜劣汰,选出最优秀的个体。只不过它的作用被我规划成了“求一个系统/模型的最优解”。

遗传算法简介

顾名思义,学过高中生物的都应该可以理解“遗传”是什么,染色体变异、染色体交叉等术语应该也能够大概知道是什么意思。其实遗传算法主要就是模拟这一个过程。

不过我也不是专业搞生物的,高中的知识细节部分我早都忘光了,因此抛开其他的,接下来我用我的理解来定义一下遗传算法的过程。

遗传算法四个基础概念

遗传算法中,一个基本单位为“个体”,一个种群(系统)中拥有好多个体。每个个体携带两个内容:染色体与适应度。

为了形象起见,我们可以把一个个体比喻成一头羊,一堆羊聚集在一起就成了一个种群。每一只羊长的(肥瘦程度)都不同,有的很肥,有的很瘦。我们作为一个牧场的牧场主,最终目的是养出最肥的羊。而我们的羊比较奇葩,每天都会产仔,并且产完仔就会死去,令我们牧场羊的数量保持在一个确定的数量上。

为了逼迫羊们越来越肥,我们每天杀死最瘦的羊,然后越肥的羊就越有几率交配生孩子,生出的孩子有可能变肥,也有可能变瘦。这样长此以往下去,我们羊群的羊将会越来越肥,而我们也达到了我们的目的。

所以简单的总结一下,上面每一头羊都是一个“个体”,整个牧场就是一个种群。每一头羊有“决定肥瘦程度的染色体”与“肥瘦程度”。这个肥瘦程度就是我们要说的遗传算法的“适应度”。每一天我们将其称之为迭代一次,也就是换一批新羊。

或者用生物上的话来说,每一头羊都有染色体,染色体决定了他们表现出来的性状是怎样的。所以说,染色体决定了每一头羊的肥瘦程度。

因此我们建立以下对应关系:

  • 整个牧场 -> 一个种群
  • 一头羊->一个个体
  • 某头羊决定肥瘦程度的染色体->该个体的染色体
  • 肥瘦程度->适应度

明确了上面四个基础概念以后,我们就可以引出他们之间的相互关系。

种群中包含了若干个个体,每个个体都拥有两个属性:染色体与适应度。每一次迭代中,种群中的个体数量不变。

染色体

其实需要细讲的主要还是染色体。

染色体是遗传算法与“被求最优解模型”直接相关之处。通常来说一个模型想要求最优解,那么就肯定会存在变量,通过控制变量的值让模型的最终值达到最优。

所以在这里,模型中所有变量就构成了一条染色体。其中每一个变量称之为染色体上的一个基因。

比如说我们这里有一个多元函数 f=f(x,y) ,这个函数拥有最大值 fmax ,但是对应的最大值点 (xmax,ymax) 我们并不知道,用通常方法也十分难求出来,所以我们可以利用遗传算法来简单求解一下。所以就将染色体设定为两个节点(基因),第一个节点为 x ,第二个节点为y

这是对于一个个体来说的,也就是对于单个个体,他的染色体值我可以写成一个向量为

chrom=[x,y]

适应度

那么得到了染色体,模型的最优解如何评价呢?就是利用适应度来寻找最优解。

每个个体的适应度就相当于这个模型在“这个染色体的变量的值下的解”。也就是说这个个体的染色体值为 chrom=[x1,y1] ,所以我们把 (x1,y1) 带入到之前的多元函数中,可以得到这个函数的一个解为 f1=f(x1,y1) ,解 f1 就是这一条染色体(个体)的适应度。

寻找最优解

对于整个种群,我们假设有 N 个个体,所以对应的,也就有N条染色体, N 个适应度。因此可以写成以下形式

Chrom=x1x2xNy1y2xN

Fitness=[f1,f2,,fN]T

其中每一行都代表着一个个体。

我们在这里假设每个个体的染色体的值各不相同,因此适应度(模型的解)也就各不相同。所以我们就可以从中挑出来最大的适应度,它就是在当前情况下的最优解,但不一定是真正的最大值 fmax

所以接下来的就是开始寻找真正的最大值(最优解)。

遗传算法流程

一次迭代包括以下几个过程:

  1. 染色体变异。即改变某个染色体的值;
  2. 染色体交叉。任意选择两个染色体交换部分基因;
  3. 计算适应度。计算每个染色体在当前迭代下对应的适应度。
  4. 优胜劣汰。选出最劣适应度的染色体,并将其用最优适应度染色体替换。
染色体变异

染色体变异作用于每一个个体,目的就是修改当前染色体,从而让其变得“更好”,也有可能变得“更坏”。

为了能够让已经就很优的个体不要贸然的跌下神坛,让不算特别好的个体突破阶级限制进入最优,我们可以做出以下规定:

  • 适应度越优的个体染色体变化范围越小;
  • 适应度越劣的个体染色体变化范围越大。

这样子就能够令整个种群的阶级随时保持流动。

假设某个个体的染色体的某个节点 x 要发生变异,我们现在必须已知:当前迭代下种群中的最优适应度fbest;当前个体的适应度 f

然后我们产生一个随机数rand,就是这个节点的变化值,所以通过公式

xnew=x[1±rand(1ffbest)2]

可以得到新的染色体节点值 xnew .其中,正负号随机决定,代表着当前染色体节点值应该变大还是变小。

这个式子代表着,当 f 越趋近于fbest时, (1ffbest)2 就趋近于0,说明对原 x 的改变越小(变化量几乎为0);当f远离 fbest 时, (1ffbest)2 越趋近于1,说明对原 x 的改变越大。

染色体交叉

染色体交叉比较容易,随机选择两个染色体,在随机选择一对节点,相互交换对应的值即可。

比如有两个个体的染色体为chromm=[xm,ym],chromn=[xn,yn],我们选择将其第一个节点上的两个节点进行交叉互换,得到新的两个染色体值为 chromm=[xn,ym],chromn=[xm,yn]

计算适应度

计算适应度其实就是将每个个体的染色体带入到模型中进行计算,计算出来其对应的适应度。

优胜劣汰

为了让我们种群的适应度整体水平上升,我们必须杀死排名最后的那个个体。

杀死之后种群数量就变少了,所以就必须要让比较优良的个体多生点来把种群数量补回来。在这里我为了方便,直接把最劣的个体的染色体替换成了最优个体的染色体。

这样子就是优胜劣汰,略微的把整体适应度水平提升了一点。


小结

以上就是遗传算法的大概流程。因为遗传算法的实现方法较多,所以这是按照我个人习惯整合成的一个遗传算法。一般来说,遗传算法的染色体还可以由二进制表示,优胜劣汰的方法也有其他方法,在这里我们就不多赘述。

下一章将会引入MATLAB代码,引入实际模型来进行一个具体的计算。

  • 94
    点赞
  • 348
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
以下是神经网络与遗传算法结合的 MATLAB 代码示例: ```matlab % 定义神经网络类 classdef NeuralNetwork < handle properties weights1 weights2 end methods % 初始化权重 function obj = NeuralNetwork(input_size, hidden_size, output_size) obj.weights1 = randn(input_size, hidden_size); obj.weights2 = randn(hidden_size, output_size); end % 前向传播计算输出 function output = forward(obj, inputs) hidden = inputs * obj.weights1; hidden = tanh(hidden); output = hidden * obj.weights2; end end end % 定义遗传算法类 classdef GeneticAlgorithm < handle properties population_size gene_length mutation_rate fitness_function elitism population fitness end methods % 初始化种群 function obj = GeneticAlgorithm(population_size, gene_length, mutation_rate, fitness_function, elitism) obj.population_size = population_size; obj.gene_length = gene_length; obj.mutation_rate = mutation_rate; obj.fitness_function = fitness_function; obj.elitism = elitism; obj.population = randi([0, 1], population_size, gene_length); obj.fitness = zeros(population_size, 1); end % 选择操作 function parents = selection(obj) % 使用轮盘赌选择算法 fitness_sum = sum(obj.fitness); selection_prob = obj.fitness / fitness_sum; selected_indices = randsample(obj.population_size, 2, true, selection_prob); parents = obj.population(selected_indices, :); end % 交叉操作 function offspring = crossover(obj, parents) % 使用单点交叉算法 crossover_point = randi(obj.gene_length - 1); offspring = [parents(1, 1:crossover_point), parents(2, crossover_point+1:end)]; end % 变异操作 function mutated_offspring = mutation(obj, offspring) % 使用随机单点变异算法 for i = 1:length(offspring) if rand() < obj.mutation_rate offspring(i) = ~offspring(i); end end mutated_offspring = offspring; end % 进化操作 function evolve(obj) % 计算适应度 for i = 1:obj.population_size obj.fitness(i) = obj.fitness_function(obj.population(i, :)); end % 计算精英个体 if obj.elitism [~, elite_index] = max(obj.fitness); elite = obj.population(elite_index, :); end % 创建新种群 new_population = zeros(obj.population_size, obj.gene_length); for i = 1:obj.population_size parents = obj.selection(); offspring = obj.crossover(parents); mutated_offspring = obj.mutation(offspring); new_population(i, :) = mutated_offspring; end % 保留精英个体 if obj.elitism new_population(1, :) = elite; end % 更新种群 obj.population = new_population; end end end % 定义适应度函数 function fitness = fitness_function(gene) % 将二进制基因转换为实数 x = bi2de(gene) / (2^length(gene) - 1); % 计算目标函数值 y = sin(10 * pi * x) / x + 5; % 返回适应度 fitness = y; end % 初始化遗传算法和神经网络 population_size = 20; gene_length = 20; mutation_rate = 0.01; elitism = true; ga = GeneticAlgorithm(population_size, gene_length, mutation_rate, @fitness_function, elitism); nn = NeuralNetwork(1, 3, 1); % 训练神经网络 max_generation = 100; for i = 1:max_generation % 获取当前种群的最优个体 [~, best_index] = max(ga.fitness); best_gene = ga.population(best_index, :); % 将二进制基因转换为实数 x = bi2de(best_gene) / (2^length(best_gene) - 1); % 使用最优个体来训练神经网络 nn.weights1 = x * nn.weights1; nn.weights2 = x * nn.weights2; % 进化种群 ga.evolve(); end % 测试神经网络 input = 0.5; output = nn.forward(input); disp(output); ``` 在这个示例,我们使用遗传算法来优化神经网络的权重。我们首先定义了一个包含一个隐藏层的神经网络,以及一个遗传算法类。遗传算法类包含了种群初始化、选择、交叉、变异和进化等操作,并使用适应度函数来评估个体的适应度。然后,我们定义了一个简单的目标函数,用于测试遗传算法和神经网络的性能。最后,我们初始化遗传算法和神经网络,并使用遗传算法来优化神经网络的权重。在每一代进化,我们使用当前种群的最优个体来训练神经网络。完成进化后,我们使用训练好的神经网络来测试输入的输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值