python - 遗传算法-无序可变长度染色体-交叉策略?

标签 python algorithm genetic-algorithm genetic-programming

我正在研究一种遗传算法。染色体没有排列顺序,这意味着它们在一个成员中出现的顺序并不影响该成员的得分。染色体数目也不固定。一个成员可能有一个染色体,另一个可能有超过100个。
我在Python中工作,染色体存储在列表中下面是结构的简化示例:

member = [{"key1":"value","key2":"value"},{"key1":"value","key2":"value"},{"key1":"value","key2":"value"}]

两个示例成员(简化)可能是:
member1 = [{"a":1.5,"b":2.334563},{"a":769.0003413,"b":0.00023}]
member2 = [{"a":7,"b":432.993246927},{"a":99,"b":532.234},{"a":21,"b":712.2},{"a":432,"b":999.9999},{"a":932,"b":12}]

在应用程序中,重复出现无序的染色体是可以的:
member3 = [{"a":1,"b":1},{"a":2,"b":2},{"a":2,"b":2},{"a":1,"b":1}]

成员
成员中的每个染色体都是一个数学函数,它以unix epoc时间戳作为输入,并输出一个值。这允许我使用该成员的函数随时获取“值”。染色体中的键总是相同的,但是在初始播种值范围从0到100,小数点后100位之间随机生成值。
评分系统
我正在根据sql数据库中的实时时间序列数据对函数进行分级。时间序列数据每1到3秒不断更新一次新值。当我对这些数据进行选择时,我选择epoc值大于当前epoc的位置-5秒并按降序排列,并将输出限制为1行。我取实际返回的epoc值,这是我评分的依据之一。
我取所有的点(epoc:value对)并用它们来打分,给成员函数输入epoc,得到成员的值,然后从实际值中减去该值,然后取其绝对值。
看起来有点像这样:
total = 0
for chromosome in member[chromosomes]:
    for epoc in epocs:
        thisValue = Calc(epoc,chromosome)
        total = total + abs(thisValue - getRealValue(epoc))

函数Calc获取染色体和epoc值并输出浮点值。
零是一个完美的分数分数越高,队员就越差。我平均所有会员的分数,去掉低于平均分的。
我试着对数据库中的一组静态数据进行分级,也试着对过去的24小时进行动态分级——这意味着过去的24小时总是随着时间的推移而不同。我也试过最后4个小时,最后一个小时,最后3天。
突变系统
我已经把我的突变率定为2%,但我一直在玩更高的百分比和更差的结果。独生子女有潜在的变异,而不是现存的人口(想要留住精英)。当选择一个孩子进行突变时,其染色体中的值会随机移动(随机加减)一个小数点,在0到1之间,最多100个小数点这对孩子的价值观提供了微小的改变,因为一个非常微小的改变会彻底改变染色体功能的输出。
我的问题
我现在使用的交叉方法会导致过早收敛。
我试过的交叉策略
我试着从每个父母身上随机抽取一些染色体。我试过把第一任父母的上半部分和第二任父母的上半部分带走。
到目前为止,我已经尝试过这些方法:
# Number of chromosomes from parent 1.
parent1chromosomes = randomNumber(0,len(parent1['chromosomes']))

# Number of chromosomes from parent 2.
parent2chromosomes = randomNumber(0,len(parent2['chromosomes']))

child = {}
child['chromosomes'] = []

# Get parent 1 chromosomes into child.
for i in range(0,parent1chromosomes):
    child['chromosomes'].append(random.choice(parent1['chromosomes']))

# Get parent 2 chromosomes into child.
for i in range(0,parent2chromosomes):
    child['chromosomes'].append(random.choice(parent2['chromosomes']))

注意:randomNumber是一个函数,它返回指定范围之间的随机整数。
两种尝试都导致了早期的融合。我试图解决的问题是非常复杂的-我已经试过人口规模从10000到1000000到目前为止。
示例性能
这是最近一次跑步的截图。我正在绘制最好的分数(最低的)和平均分数。在这张照片中,它描绘了五种不同人群的最佳和平均值这5个特定的群体是每10000个成员,使用3秒的真实数据采样,并根据最后一个小时的真实数据动态评分-这就是为什么最好的成员会变得更差-因为它的真实数据的评分变化的方式,使最好的成员更差。最好的分数减少了几千分,这是完全不准确的。较小的种群导致更快的早期收敛。
enter image description here
我的问题
在染色体顺序无关紧要、重复染色体无关紧要的情况下,还有什么方法可以更好地处理与可变长度成员的交叉?

最佳答案

而不是:

for i in range(0,parent1chromosomes):
    child['chromosomes'].append(random.choice(parent1['chromosomes']))

也许:
child['chromosomes'].extend(random.sample(parent1['chromosomes'], parent1chromosomes))

这意味着你只能从一个父母那里得到重复的染色体,或者从双亲那里得到一个。

关于python - 遗传算法-无序可变长度染色体-交叉策略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48773854/

相关文章:

algorithm - 如何在DP表中实现这个递归算法?

algorithm - 采样信号的相似度算法(数学)

algorithm - 我应该为 "genetic AI improvement"使用什么算法

python - 在 Python 2.7 中创建套接字时出错

algorithm - 从图表创建 "pairing"?

c++ - 如何使用遗传算法求解线性方程组?

algorithm - 缺乏多样化,真的是遗传算法的缺点吗?

python - 如何在 Flask 中进行首次迁移?

如果导入 PySide,python 子进程会在 numpy 点上崩溃

python - 使用 Xcode 在 Mac OSX 上使用 pip 安装 lxml 时出现 GCC 错误