第5章 进化计算与群体智能
5.1 遗传算法理论与实现
5.1.1 遗传算法
遗传算法被广泛应用于大规模的优化问题,例如非线性规划,离散优化,TSP 问题,VRP 问题,车间调度问题等。
遗传算法通过遗传和变异生成一批候选解,然后在逐代进化的过程中一步步逼近最优解。这里补充几个概念定义:
- 染色体:遗传物质的主要载体,是多个遗传因子的集合。
- 基因:遗传操作的最小单元,以一定排列方式构成染色体。
- 个体:染色体带有特征的实体。
- 种群:多个个体组成群体,进化之初的原始群体被称为初始种群。
- 适应度:用于评价个体适应环境程度的函数值。
- 编码:二进制或十进制去表示研究问题的过程。
- 解码:将二进制或十进制还原为原始问题的过程。
- 选择:以一定概率从种群中选择若干个体的过程,选择的基准方法有很多,常见的有适应度比例法、期望值法、轮盘赌法等。
- 交叉:将两个染色体换组的操作,又称重组。
- 变异:遗传因子按一定概率变化的操作。
遗传算法首先需要对问题进行编码,通常是将函数编码为二进制代码以后,随机产生初始种群作为初始解。随后是遗传算法的核心操作之一——选择,通常选择首先要计算出个体的适应度,根据适应度不同来采取不同选择方法进行选择,常用方法有适应度比例法、期望值法、排位次法、轮盘赌法等。
5.1.2 遗传算法的实现
我们以一个二元函数的寻优为例介绍如何实现遗传算法。
例 5.1 求下面这个函数的极值:
定义函数并给出绘图方法
def F(x, y):
return 100.0 * (y - x ** 2.0) ** 2.0 + (1 - x) ** 2.0 # 以香蕉函数为例
def plot_3d(ax):
X = np.linspace(*X_BOUND, 100)
Y = np.linspace(*Y_BOUND, 100)
X, Y = np.meshgrid(X, Y)
Z = F(X, Y)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.pause(3)
plt.show()
函数图像如图所示:
解码方法和适应度评估函数:
def get_fitness(pop):
x, y = translateDNA(pop)
pred = F(x, y)
return pred
# return pred - np.min(pred)+1e-3 # 求最大值时的适应度
# return np.max(pred) - pred + 1e-3 # 求最小值时的适应度,通过这一步 fitness 的范围为[0, np.max(pred)-np.min(pred)]
def translateDNA(pop):
# pop 表示种群矩阵,一行表示一个二进制编码表示的 DNA,矩阵的行数为种群数目
x_pop = pop[:, 0:DNA_SIZE] # 前 DNA_SIZE 位表示 X
y_pop = pop[:, DNA_SIZE:] # 后 DNA_SIZE 位表示