python pygad保证约束内的唯一点

dtcbnfnu  于 2023-04-19  发布在  Python
关注(0)|答案(1)|浏览(121)

对于HPC上的一个项目,我想使用pygad来生成一组点,然后可以将这些点传递给集群上的作业:因此,我希望种群中的所有点都是唯一的(在集群上的时间是昂贵的,所以我希望最佳地使用我提交的作业,而不是重复的)。此外,由于作业模拟物理,我需要限制我的值,因为有些值在物理上没有任何意义(例如,粒子的负数或负长度)。
pygad似乎有两个参数allow_duplicate_genesgene_space,根据我对文档的理解,它们似乎正是我想要的。
然而,这段代码:

import pygad
import numpy
import itertools

def mock_function(solution, sol_idx):
    return -1 * (solution[0] ** 2 + solution[1] ** 2)
range = [.1, 1.]
param_values = numpy.linspace(range[0], range[1], 10).tolist()
initial_population = list(itertools.product(param_values, param_values))

ga = pygad.GA(num_generations=100,
              num_parents_mating=10,
              gene_type=float,
              gene_space={'low': range[0], 'high': range[1]},
              fitness_func=mock_function,
              initial_population=initial_population,
              mutation_probability=0.2,
              allow_duplicate_genes=False,
              )
ga.run()

new_points = ga.population
unique_points = set([tuple(x) for x in new_points])
print(len(initial_population), len(new_points), len(unique_points))
print(f"Best solution is {ga.best_solution()[0]}.")
for point in new_points:
    for x in point:
        if not range[0] <= x <= range[1]:
            print(f"Point {point} is outside gene_space.")

两者都产生了大量的非唯一点,偶尔也会产生gene_space之外的点。
提前感谢您的帮助,让我知道如果你需要更多的细节。

**编辑:**在github repo中有一个关于这个see here的(公开)问题,声称最新版本应该修复唯一性问题。然而,在这个例子中,它仍然没有。它仍然产生gene_space之外的点。

v1l68za4

v1l68za41#

这段代码解决了任何重复的基因。变化是:
1.从通过的初始群体中删除重复项。
1.设置mutation_by_replacement=True
代码还设置save_solutions=True以验证在任何代中生成的解都没有重复。打印所有探索的解中的最小和最大基因值,以确保没有基因超出范围[.1, 1.]

import pygad
import numpy
import itertools

def mock_function(ga_instance, solution, sol_idx):
    return -1 * (solution[0] ** 2 + solution[1] ** 2)
range = [.1, 1.]
param_values = numpy.linspace(range[0], range[1], 10).tolist()
initial_population = list(itertools.product(param_values, param_values))

## Remove duplicates from the initial population.
for idx, sol in enumerate(initial_population):
    sol = list(sol)
    if sol[0] == sol[1]:
        if sol[1] < 0.101:
            sol[1] = sol[1] + 0.001
        else:
            sol[1] = sol[1] - 0.001
    initial_population[idx] = sol.copy()

ga = pygad.GA(num_generations=100,
              num_parents_mating=10,
              gene_type=float,
              gene_space={'low': range[0], 'high': range[1]},
              fitness_func=mock_function,
              initial_population=initial_population,
              mutation_probability=0.2,
              allow_duplicate_genes=False,
              save_solutions=True,
              suppress_warnings=True,
              mutation_by_replacement=True
              )
ga.run()

new_points = ga.population
unique_points = set([tuple(x) for x in new_points])
print(len(initial_population), len(new_points), len(unique_points))
print(f"Best solution is {ga.best_solution()[0]}.")
for point in ga.solutions:
    for x in point:
        if not range[0] <= x <= range[1]:
            print(f"Point {point} is outside gene_space.")

print("Maximum gene value found", numpy.max(ga.solutions))
print("Maximum gene value found", numpy.min(ga.solutions))

相关问题