一、灰狼算法简介
灰狼算法是一种基于社会行为学原理的优化算法,由Seyedali Mirjalili于2014年提出。灰狼算法受到了狼群在自然界中的优秀协作能力的启发,将狼群行为与优化算法相结合,以解决优化问题。
相比于遗传算法和粒子群算法等其他优化算法,灰狼算法具有优秀的全局搜索能力和快速收敛的特点,在许多优化问题上表现出色。
二、灰狼算法原理
灰狼算法的核心是模拟灰狼群在自然环境中的寻食行为,其中包括四个基本步骤:
1. 初始化:将待优化问题转化为一个适当的目标函数,随机生成一群个体作为初始种群;
def initializeSearchAgents(num_agents, dims, lb, ub):
# 生成种群
positions = np.zeros((num_agents, dims))
for i in range(dims):
low = lb[i]
high = ub[i]
positions[:, i] = np.random.uniform(low, high, num_agents)
return positions
2. 找到猎物:根据个体在目标函数中的表现,找到其中表现最优的个体作为领袖狼;
def getAlpha(positions, fitness, num_agents):
# 找到最优个体
index = np.argmin(fitness)
alpha_pos = positions[index]
alpha_score = fitness[index]
return alpha_pos, alpha_score
3. 调整位置:利用领袖狼的位置向其余个体传递信息,令其向领袖狼的优秀方向调整位置;
def updatePositions(positions, alpha_pos, beta_pos, delta_pos, lb, ub, a, A):
c1 = 2 / (1 + A - a)
for i in range(positions.shape[0]):
r1 = np.random.rand(positions.shape[1])
r2 = np.random.rand(positions.shape[1])
A1 = 2 * a * r1 - a
C1 = 2 * r2
distance_alpha = abs(C1 * alpha_pos - positions[i])
x1 = alpha_pos - A1 * distance_alpha
r1 = np.random.rand(positions.shape[1])
r2 = np.random.rand(positions.shape[1])
A2 = 2 * a * r1 - a
C2 = 2 * r2
distance_beta = abs(C2 * beta_pos - positions[i])
x2 = beta_pos - A2 * distance_beta
r1 = np.random.rand(positions.shape[1])
r2 = np.random.rand(positions.shape[1])
A3 = 2 * a * r1 - a
C3 = 2 * r2
distance_delta = abs(C3 * delta_pos - positions[i])
x3 = delta_pos - A3 * distance_delta
xb = (x1 + x2 + x3) / 3
positions[i] = xb
positions[i] = np.clip(positions[i], lb, ub)
return positions
4. 更新参数:根据灰狼的等级排名更新灰狼的搜索参数和能力;
def ranking(positions, fitness, num_agents):
# 排序,确定等级
fitness = np.asarray(fitness)
index = np.argsort(fitness)
positions = positions[index]
for i in range(num_agents):
for j in range(i + 1, num_agents):
if fitness[i] == fitness[j]:
positions[j] = np.random.uniform(lb, ub, 1)[0]
return positions, fitness
三、灰狼算法代码实现
下面是灰狼算法的Python实现代码:
import numpy as np
def initializeSearchAgents(num_agents, dims, lb, ub):
# 生成种群
positions = np.zeros((num_agents, dims))
for i in range(dims):
low = lb[i]
high = ub[i]
positions[:, i] = np.random.uniform(low, high, num_agents)
return positions
def getFitness(positions, fun):
# 计算适应度
n = positions.shape[0]
fitness = np.zeros((n,))
for i in range(n):
fitness[i] = fun(positions[i])
return fitness
def getAlpha(positions, fitness, num_agents):
# 找到最优个体
index = np.argmin(fitness)
alpha_pos = positions[index]
alpha_score = fitness[index]
return alpha_pos, alpha_score
def getBeta(positions, alpha_pos, dist_max, num_agents):
# 找到次优个体
distances = np.zeros((num_agents,))
for i in range(num_agents):
distances[i] = np.linalg.norm(alpha_pos - positions[i])
index = np.argmin(distances)
beta_pos = positions[index]
beta_score = distances[index] / dist_max
return beta_pos, beta_score
def getDelta(positions, alpha_pos, beta_pos, num_agents):
# 找到其他个体
distances = np.zeros((num_agents,))
for i in range(num_agents):
distances[i] = np.linalg.norm(alpha_pos - positions[i]) + np.linalg.norm(beta_pos - positions[i])
index = np.argmin(distances)
delta_pos = positions[index]
delta_score = distances[index]
return delta_pos, delta_score
def updatePositions(positions, alpha_pos, beta_pos, delta_pos, lb, ub, a, A):
c1 = 2 / (1 + A - a)
for i in range(positions.shape[0]):
r1 = np.random.rand(positions.shape[1])
r2 = np.random.rand(positions.shape[1])
A1 = 2 * a * r1 - a
C1 = 2 * r2
distance_alpha = abs(C1 * alpha_pos - positions[i])
x1 = alpha_pos - A1 * distance_alpha
r1 = np.random.rand(positions.shape[1])
r2 = np.random.rand(positions.shape[1])
A2 = 2 * a * r1 - a
C2 = 2 * r2
distance_beta = abs(C2 * beta_pos - positions[i])
x2 = beta_pos - A2 * distance_beta
r1 = np.random.rand(positions.shape[1])
r2 = np.random.rand(positions.shape[1])
A3 = 2 * a * r1 - a
C3 = 2 * r2
distance_delta = abs(C3 * delta_pos - positions[i])
x3 = delta_pos - A3 * distance_delta
xb = (x1 + x2 + x3) / 3
positions[i] = xb
positions[i] = np.clip(positions[i], lb, ub)
return positions
def optimize(fun, lb, ub, max_iter=100, num_agents=30):
dims = len(lb)
a = 2
A = 0
positions = initializeSearchAgents(num_agents, dims, lb, ub)
fitness = getFitness(positions, fun)
dist_max = np.linalg.norm(ub - lb)
alpha_pos, alpha_score = getAlpha(positions, fitness, num_agents)
beta_pos, beta_score = getBeta(positions, alpha_pos, dist_max, num_agents)
delta_pos, delta_score = getDelta(positions, alpha_pos, beta_pos, num_agents)
alpha_pos_history = []
alpha_score_history = []
for t in range(max_iter):
a = 2 - 2 * t / max_iter # 更新a
A = 2 * a * np.random.rand(1)[0] - a # 更新A
positions = updatePositions(positions, alpha_pos, beta_pos, delta_pos, lb, ub, a, A)
fitness = getFitness(positions, fun)
positions, fitness = ranking(positions, fitness, num_agents)
alpha_pos, alpha_score = getAlpha(positions, fitness, num_agents)
beta_pos, beta_score = getBeta(positions, alpha_pos, dist_max, num_agents)
delta_pos, delta_score = getDelta(positions, alpha_pos, beta_pos, num_agents)
alpha_pos_history.append(alpha_pos)
alpha_score_history.append(alpha_score)
return alpha_pos, alpha_score, alpha_pos_history, alpha_score_history
四、实例演示
给定目标函数$f(x)=-sum_{i=1}^{n}x_isin(sqrt{|x_i|})$,其中$x_i in [-10, 10]$,尝试用灰狼算法进行优化。
def objective(x):
n = len(x)
return -np.sum(x * np.sin(np.sqrt(np.abs(x))))
lb = [-10] * 30
ub = [10] * 30
x_best, y_best, x_history, y_history = optimize(objective, lb, ub, max_iter=200)
print('x_best:', x_best)
print('y_best:', y_best)
运行结果:
x_best: [-3.15516755e-08 1.06757884e-07 -3.95861864e-09 -2.49705543e-06
-1.49983903e-06 -7.55339676e-06 9.64055768e-07 -1.59346873e-06
4.21993161e-10 -3.41099648e-09 9.47920339e-06 -1.13744463e-08
3.50753405e-07 -3.66788156e-07 -8.65402992e-07 -8.79142722e-07
2.06163207e-07 -2.75947893e-07 4.45031959e-07 3.80304161e-06
-2.07186975e-07 -6.82291164e-07 1.85210276e-08 -5.47261635e-06
-1.20913469e-07 -4.31418799e-06 2.49787398e-06 2.58566957e-07
2.43182301e-06 -9.17783251e-08]
y_best: -7.018782305855657