我是python新手,我觉得我在python编程中使用了完全错误的策略。举个例子:
我有这样一个清单:
selected_parents =
[array([[4, 6, 3, 1, 0, 7, 5, 2]]), array([[0, 2, 7, 3, 5, 4, 1, 6]])]
现在我想对列表中的元素应用交叉(请参见p.S.了解我所说的交叉是什么意思以及它是如何实现的,但我的问题是,我应该如何避免在python编程时使用这么多索引):
crossed_p1 = np.zeros((len(selected_parents[0][0]))).astype(int)
crossed_p2 = np.zeros((len(selected_parents[0][0]))).astype(int)
co_point = rd.sample(range(len(selected_parents[0][0])),1)
if co_point[0] >= len(selected_parents[0][0])/2:
crossed_p1[0:co_point[0]] = selected_parents[0][0][0:co_point[0]]
indeces = []
for i in range(co_point[0],len(selected_parents[0][0])):
a = np.where(selected_parents[1][0] == selected_parents[0][0][i])
indeces.append(a)
indeces = sorted(indeces)
for i in range(len(indeces)):
crossed_p1[i + co_point[0]] = selected_parents[1][0][indeces[i][0][0]]
crossed_p2[0:co_point[0]] = selected_parents[1][0][0:co_point[0]]
indeces = []
for i in range(co_point[0],len(selected_parents[0][0])):
a = np.where(selected_parents[0][0] == selected_parents[1][0][i])
indeces.append(a)
indeces = sorted(indeces)
for i in range(len(indeces)):
crossed_p2[i + co_point[0]] = selected_parents[0][0][indeces[i][0][0]]
else:
crossed_p1[co_point[0]:] = selected_parents[0][0][co_point[0]:]
indeces = []
for i in range(co_point[0]):
a = np.where(selected_parents[1][0] == selected_parents[0][0][i])
indeces.append(a)
indeces = sorted(indeces)
for i in range(len(indeces)):
crossed_p1[i] = selected_parents[1][0][indeces[i][0][0]]
crossed_p2[co_point[0]:] = selected_parents[1][0][co_point[0]:]
indeces = []
for i in range(co_point[0]):
a = np.where(selected_parents[0][0] == selected_parents[1][0][i])
indeces.append(a)
indeces = sorted(indeces)
for i in range(len(indeces)):
crossed_p2[i] = selected_parents[0][0][indeces[i][0][0]]
代码就像一个魅力,但我讨厌我写它的方式!就像我一直在问自己一样,我真的要写selected_parents[0][0][indeces[i][0][0]]
这样的东西吗?!有没有更好的方法来做我正在做的事?!你知道吗
p.S.这是遗传算法的一个例子,我将selected_parents
中的两个数组作为第一代父代。现在我想应用交叉,这意味着:随机选择一个切割点(即代码中的co_point
),它是1和父长度(这里是8)之间的随机整数;第一个子代(即crossed_p1
)从第一个父代继承一个较长的子串,并按出现的数字顺序替换较短子串的数字在第二个家长。对第二个后代(即crossed_p2
)重复类似的过程。例如,基于当前的selected_parents
列表,对于co_point = 5
,第一子代(即crossed_p1
)从第一个父代继承46310
的子串,并且752
的剩余子串被275
替换,这是第二个父代中出现的数字顺序。因此,第一个后代(即crossed_p1
)是46310275
,第二个后代(即crossed_p2
)将是02735461
。你知道吗
这是你代码的矢量化版本。矢量化的一个令人愉快的副作用是它通常会去掉大多数索引。你知道吗
这段代码假设父向量是
0, 1, 2, ...
的乱序。如果不是这样,还需要做更多的工作:大多数索引都指向
selected_parents
列表的元素,这些元素是二维数组:数组可以用一组[]索引:
注意,可以方便地“命名”列表中的2个元素(解包):
一般来说,在数组上使用
shape
比使用len
更好。替换与
p1.shape
是(1,8)看起来
p1, p2
有相同的形状。在那种情况下应该生成一个(2,1,8)数组,该数组可以重新调整为(2,8)。或者
产生(2,8)数组。你知道吗
如果你的氏族是1D列表,这似乎是最简单的交叉方式:
让我们创建两个parant,并选择交叉点:
第一个孩子和第二个孩子是两个单子的结合体
如果你需要numpy,这不是问题。同样的想法如下:
相关问题 更多 >
编程相关推荐