问题描述
我编写了一个简单的遗传算法,旨在执行拟合。也就是说,给定一些输入 f(x)
,我可以在不知道 x
的情况下求解 f
(而且,实际上,f(x)
并不有 甚至存在)。我的流程如下:
-
我生成了一些初始点,均匀分布在已知的求解区间
0,1
上。 -
然后我进行迭代,直到达到某个最大代数。每次迭代,我:
a) 按最小误差(RSS 误差)对当前点集进行排序,将它们存储在
parents
列表中c)
parents
列表中的 1/2 点我“涂抹”,通过生成从高斯分布中提取的新点,其均值由所选点给出d) 我现在通过生成“孩子”来填充
parents
列表中剩余的“空位”。通过从parents
列表中随机选择两个点并取其平均值 ((male + female)/2
) 来生成子项。e) 最后,我将初始列表设置为与父母列表相等,然后跳回到 a)
最后,我最后一次对列表进行排序,并选择第一个元素作为解决方案。
查看下面的代码
我最终得到了一个还不错的解决方案。它似乎以惊人的速度跳到解决方案的附近,但随后未能取得太大进展。我仍然使用蛮力获得更好(并且更快)的结果。所以,我想改进我的算法。
一些注意事项:
我很清楚这在某种程度上取决于我将算法应用于的问题。我有兴趣将它用于一些不同的事情。忽略这个问题,我可以用我所拥有的做什么来改善这个问题?
我也知道更好/更容易/更快/等方法(可能)存在。我只是对这个话题感兴趣。
我的代码:
initial = []
# Generate random initial test points
for i in range(5000):
initial.append(random.uniform(0,1))
for i in range(max_generations):
# Sort according to some error function
initial.sort(key = error_func)
# Keep the "best" 500
parents = initial[:500]
# Throw in a few random points
for i in range(randint(10,100)):
parents.append(initial[randint(0,len(parents) - 1)])
# "Mutate" half the parents
for individual in parents:
if randint(0,1):
individual = random.gauss(individual,1E-5)
children = []
while len(children) < (5000 - len(parents)):
# Randomly pick a male and female
male = parents[randint(0,len(parents) - 1)]
female = parents[randint(0,len(parents) - 1)]
# Produce a child
children.append((male + female) / 2)
parents.extend(children)
initial = parents
initial.sort(key = error_func)
print(initial[0])
我正在考虑的几点:
目标
#1:提高准确度和精确度 #2:提高找到“好的”解决方案的速度
解决方法
遗传算法必须在系统中运行。因此,您必须在实施之前指定一些关键点。它们是:
- 种群大小(每一代的染色体数量)
- 选择运算符
- 交叉运算符
- 上榜率
- 变异政策
- 终止条件(基于适应度或基于代)
与问题完全相关的决定尝试解决(适应度函数)。
遗传算法的主要问题是单调的。如果你不能提供多样性,你很可能会陷入局部最优点。解决方案是选择方便的“选择”和“交叉”运算符。
这可能是你的起点,comparison of selection operators 和 comparion of crossover operators。此外,还有implementation ways of lots crossovers。同样,它们只是介绍。您可以找到更多资源,只需 google 即可。