有没有办法避免在遗传算法中选择两个相同的parents?
Is there a way to aviod picking two same parents in genetic aglorithm?
我正在 GA 中选择两个 parents,问题是当我实现“tournament_selection”函数时,它总是 returns 两个相同的 parents.
初始人口为:
num_emitter_coefficients = 782
sol_per_pop_1=1
sol_per_pop_2=3
sol_per_pop=sol_per_pop_1+sol_per_pop_2
pop_size_1 = [sol_per_pop_1, num_emitter_coefficients]
pop_size_2 = [sol_per_pop_2, num_emitter_coefficients]
initial_population_1 = np.random.uniform(low=0.0, high=0.0, size=pop_size_1)
initial_population_2 = np.random.uniform(low=0.0, high=0.0, size=pop_size_2)
for row in initial_population_2:
locations_used_in_this_row = 0
while locations_used_in_this_row != 5:
column = np.random.randint(num_emitter_coefficients)
if row[column] == 0.0:
row[column] = np.random.rand()*10
locations_used_in_this_row += 1
population=np.vstack([initial_population_1, initial_population_2])
print('Population: ',population)
假设每个人的分数是:
[44,56,63,34]
而在我的项目中,每个人的得分越高,每个人的适应度就越低。
parents选择功能如下图:
def tournament_selection(population, scores, k=4):
first_pick = np.random.randint(0,len(population))
for second_pick in np.random.randint(0,len(population),k-1):
if scores[second_pick] < scores[first_pick]:
winner = second_pick
else:
winner = first_pick
return population[winner,:]
当我实现功能时,
for i in range(0, len(population),2):
parent_1 = tournament_selection(population, scores)
parent_2 = tournament_selection(population, scores)
它总是返回两个相同的 parents。
你能告诉我如何避免这个问题吗?
也许如果我可以从人口列表中排除'winner',可以解决选择两个相同parents的问题,但我不知道如何用代码实现它,你能请给我想法?非常感谢。
我认为列表理解是你的答案,无需任何更多信息(我知道遗传分析会变得很麻烦)。
我在您的函数开头添加了列表理解,以从您的主列表中过滤掉以前的获胜者。请记住 .index() 只会 select 在列表中第一次出现,所以如果你有很长的列表并且可能有重复项,你将需要另一种方法来
import numpy as np
num_emitter_coefficients = 782
sol_per_pop_1=1
sol_per_pop_2=3
sol_per_pop=sol_per_pop_1+sol_per_pop_2
pop_size_1 = [sol_per_pop_1, num_emitter_coefficients]
pop_size_2 = [sol_per_pop_2, num_emitter_coefficients]
initial_population_1 = np.random.uniform(low=0.0, high=0.0, size=pop_size_1)
initial_population_2 = np.random.uniform(low=0.0, high=0.0, size=pop_size_2)
for row in initial_population_2:
locations_used_in_this_row = 0
while locations_used_in_this_row != 5:
column = np.random.randint(num_emitter_coefficients)
if row[column] == 0.0:
row[column] = np.random.rand()*10
locations_used_in_this_row += 1
population=np.vstack([initial_population_1, initial_population_2]).tolist()
prevwinner = []
scores = [44,56,63,34]
def tournament_selection(population, scores, k=4):
# filter previous winners out
selectable_parents = [nonwinner for nonwinner in population if nonwinner not in prevwinner]
if len(selectable_parents) > 1:
first_pick, second_pick = np.random.randint(len(selectable_parents), size=2)
first_pick_score = scores[population.index(selectable_parents[first_pick])]
while second_pick == first_pick:
second_pick = np.random.randint(0,len(selectable_parents))
second_pick_score = scores[population.index(selectable_parents[second_pick])]
if second_pick_score < first_pick_score:
winner = second_pick
loser = first_pick
else:
winner = first_pick
loser = second_pick
# append winner to prevwinner list
prevwinner.append(population[population.index(selectable_parents[winner])])
prevwinner.append(population[population.index(selectable_parents[loser])])
return population[population.index(selectable_parents[winner])], population[population.index(selectable_parents[loser])]
else:
# there is one parent left
return selectable_parents[0]
for i in range(0, len(population),2):
parent_1, parent_2 = tournament_selection(population, scores)
print('parent_1: ', np.unique(np.array(parent_1)))
print('parent_2: ', np.unique(np.array(parent_2)))
与其从总体中随机选择两次,不如使用 np.random.choice
和 replace=False
。
但貌似 random.choice 在 numpy 中只支持一维数组,所以你必须在 np.random.randint. See Numpy: Get random set of rows from 2D array
中使用大小参数
import numpy as np
population= [[0., 1., 0., 0., 0., 0.],
[0., 0., 0., 0., 1., 0.],
[0., 0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.]]
parent_1, parent_2 = np.random.randint(len(population), size=2)
我正在 GA 中选择两个 parents,问题是当我实现“tournament_selection”函数时,它总是 returns 两个相同的 parents.
初始人口为:
num_emitter_coefficients = 782
sol_per_pop_1=1
sol_per_pop_2=3
sol_per_pop=sol_per_pop_1+sol_per_pop_2
pop_size_1 = [sol_per_pop_1, num_emitter_coefficients]
pop_size_2 = [sol_per_pop_2, num_emitter_coefficients]
initial_population_1 = np.random.uniform(low=0.0, high=0.0, size=pop_size_1)
initial_population_2 = np.random.uniform(low=0.0, high=0.0, size=pop_size_2)
for row in initial_population_2:
locations_used_in_this_row = 0
while locations_used_in_this_row != 5:
column = np.random.randint(num_emitter_coefficients)
if row[column] == 0.0:
row[column] = np.random.rand()*10
locations_used_in_this_row += 1
population=np.vstack([initial_population_1, initial_population_2])
print('Population: ',population)
假设每个人的分数是:
[44,56,63,34]
而在我的项目中,每个人的得分越高,每个人的适应度就越低。 parents选择功能如下图:
def tournament_selection(population, scores, k=4):
first_pick = np.random.randint(0,len(population))
for second_pick in np.random.randint(0,len(population),k-1):
if scores[second_pick] < scores[first_pick]:
winner = second_pick
else:
winner = first_pick
return population[winner,:]
当我实现功能时,
for i in range(0, len(population),2):
parent_1 = tournament_selection(population, scores)
parent_2 = tournament_selection(population, scores)
它总是返回两个相同的 parents。 你能告诉我如何避免这个问题吗?
也许如果我可以从人口列表中排除'winner',可以解决选择两个相同parents的问题,但我不知道如何用代码实现它,你能请给我想法?非常感谢。
我认为列表理解是你的答案,无需任何更多信息(我知道遗传分析会变得很麻烦)。
我在您的函数开头添加了列表理解,以从您的主列表中过滤掉以前的获胜者。请记住 .index() 只会 select 在列表中第一次出现,所以如果你有很长的列表并且可能有重复项,你将需要另一种方法来
import numpy as np
num_emitter_coefficients = 782
sol_per_pop_1=1
sol_per_pop_2=3
sol_per_pop=sol_per_pop_1+sol_per_pop_2
pop_size_1 = [sol_per_pop_1, num_emitter_coefficients]
pop_size_2 = [sol_per_pop_2, num_emitter_coefficients]
initial_population_1 = np.random.uniform(low=0.0, high=0.0, size=pop_size_1)
initial_population_2 = np.random.uniform(low=0.0, high=0.0, size=pop_size_2)
for row in initial_population_2:
locations_used_in_this_row = 0
while locations_used_in_this_row != 5:
column = np.random.randint(num_emitter_coefficients)
if row[column] == 0.0:
row[column] = np.random.rand()*10
locations_used_in_this_row += 1
population=np.vstack([initial_population_1, initial_population_2]).tolist()
prevwinner = []
scores = [44,56,63,34]
def tournament_selection(population, scores, k=4):
# filter previous winners out
selectable_parents = [nonwinner for nonwinner in population if nonwinner not in prevwinner]
if len(selectable_parents) > 1:
first_pick, second_pick = np.random.randint(len(selectable_parents), size=2)
first_pick_score = scores[population.index(selectable_parents[first_pick])]
while second_pick == first_pick:
second_pick = np.random.randint(0,len(selectable_parents))
second_pick_score = scores[population.index(selectable_parents[second_pick])]
if second_pick_score < first_pick_score:
winner = second_pick
loser = first_pick
else:
winner = first_pick
loser = second_pick
# append winner to prevwinner list
prevwinner.append(population[population.index(selectable_parents[winner])])
prevwinner.append(population[population.index(selectable_parents[loser])])
return population[population.index(selectable_parents[winner])], population[population.index(selectable_parents[loser])]
else:
# there is one parent left
return selectable_parents[0]
for i in range(0, len(population),2):
parent_1, parent_2 = tournament_selection(population, scores)
print('parent_1: ', np.unique(np.array(parent_1)))
print('parent_2: ', np.unique(np.array(parent_2)))
与其从总体中随机选择两次,不如使用 np.random.choice
和 replace=False
。
但貌似 random.choice 在 numpy 中只支持一维数组,所以你必须在 np.random.randint. See Numpy: Get random set of rows from 2D array
中使用大小参数import numpy as np
population= [[0., 1., 0., 0., 0., 0.],
[0., 0., 0., 0., 1., 0.],
[0., 0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.]]
parent_1, parent_2 = np.random.randint(len(population), size=2)