算法背景
混合蛙跳算法的运行原理从仿生上来说可以这么认为:
在一个池塘,有若干块石头,青蛙可以落在石头上,每块石头上可以获取到的食物数量是不同的,在池塘中有很多只青蛙,也有很多块石头,青蛙间可以交流,这样所有青蛙就都会往自己所在蛙群中所知道的最多食物的方向跳,或往全部青蛙中食物最多的方向跳,最终在池塘中找到最多食物的石头。
算法原理
不作赘述。(主要懒得写,而且功力不够写不好~)
实现步骤
- 初始化参数
- 随机生成青蛙
- 划分蛙群
- 蛙群内进行局部搜索
- 重新排序(按适应度排序)后回到步骤3,直到达到条件输出
可以看出,第5步和第三步就是全局搜索,将蛙群里的信息通过排序后重新划分来实现蛙群间的信息共享
解决负载均衡调度问题
问题:现在有若干个任务,并有若干台处理任务的机器,每台机器处理任务的速度不同,找出最好的安排方案
比如任务有长度为1,2,3的三个任务,而机器也有每单位时间可以处理的任务长度为1,2,3的三台机器,那么最优方案是显而易见的,时间也只需要1个单位时间。
代码需改进的地方很多,但思路可供参考
import matplotlib.pyplot as plt
import numpy as np
import random
import operator
# 适应度函数
def F(plan):
sum = []
for i in range(d):
sum.append(0)
for i in range(d):
if(plan[i]<0|plan[i]>nodes.__len__()):
return 100
sum[plan[i]] += round(tasks[i]/nodes[plan[i]],3)
sum.sort(reverse=True)
return sum[0]
# 初始化
tasks = [1, 2, 3, 4, 5,6,7,8,9] # 任务长度
nodes = [1, 2, 3] # 节点
# SFLA参数
N = 100
n = 10
d = tasks.__len__()
m = N//n
L = 5
G = 100
D_max = 10
P = []
# step1 生成蛙群
for i in range(N):
t = [[], 0]
for j in range(d):
t[0].append(random.randint(0, 2))
t[0] = np.array(t[0])
t[1] = F(t[0])
P.append(t)
# sorted(P,key=lambda P:P[1])
P.sort(key=operator.itemgetter(1))
Xg = P[0]
for k in range(G):
#step2 划分子群
M=[]
for i in range(m):
M.append([])
for i in range(N):
M[i%m].append(P[i])
Xb=[]
Xw=[]
for i in range(m):
Xb.append(M[i][0])
Xw.append(M[i][M[i].__len__()-1])
#step3 局部搜索
for i in range(m):
for j in range(L):
D = random.randint(0,1)*(Xb[i][0]-Xw[i][0])
temp = Xw[i][0]+D
if(F(temp) < F(Xw[i][0])):
f = 0
Xw[i][0] = temp
Xw[i][1] = F(temp)
M[i][M[i].__len__()-1]=Xw[i]
else:
Xb[i] = Xg
f=2
if(f==2):
t = [[], 0]
for j in range(d):
t[0].append(random.randint(0, 2))
t[0] = np.array(t[0])
t[1] = F(t[0])
Xw[i] = t
P = []
for i in range(m):
for j in range(n):
P.append(M[i][j])
# sorted(P,key=lambda P:P[1])
P.sort(key=operator.itemgetter(1))
Xg = P[0]
x=[]
y=[]
for i in range(P.__len__()):
x.append(k)
y.append(P[i][1])
plt.scatter(x,y,s=5)
print(P[0])
plt.show()
可以看出蛙群很快就收敛到最优解了(横轴是全局搜索次数,纵轴是计划所需时间)