N 皇后问题与进化算法

我试图使用进化算法解决N皇后问题,但无法得到我图表中期望的输出结果。

以下是我编写的代码

import matplotlib.pyplot as pltimport randomimport numpy as np# ConstantsN = 8  # Size of the N-Queens problemPOP_SIZE = 100  # Population sizeGENERATIONS = 1000  # Number of generationsMUTATION_PROBABILITIES = [0.6, 0.8, 1.0]  # Mutation probabilities# Fitness function to maximize non-attacking pairs  def fitness(solution):    non_attacking_pairs = 0    for i in range(N):        for j in range(i + 1, N):            if solution[i] != solution[j] and abs(i - j) != abs(solution[i] - solution[j]):                non_attacking_pairs += 1    return non_attacking_pairs  # Return the number of non-attacking pairsdef generate_population():    return [random.sample(range(N), N) for _ in range(POP_SIZE)]def select_parents(population):    # Tournament selection for parents    tournament = random.sample(population, 5)    parent = max(tournament, key=fitness)  # Maximizing fitness    return parentdef crossover(parent1, parent2):    point = random.randint(1, N - 1)    child1 = parent1[:point] + [x for x in parent2 if x not in parent1[:point]]    child2 = parent2[:point] + [x for x in parent1 if x not in parent2[:point]]    return child1, child2def mutate(solution, mutation_rate):    if random.random() < mutation_rate:        i, j = random.sample(range(N), 2)        solution[i], solution[j] = solution[j], solution[i]    return solutiondef next_generation(population, mutation_rate):    new_population = []        # Sort the population by fitness in descending order    sorted_population = sorted(population, key=fitness, reverse=True)    # Select parents and create the new population    while len(new_population) < POP_SIZE:        parent1 = select_parents(sorted_population)        parent2 = select_parents(sorted_population)        child1, child2 = crossover(parent1, parent2)                # Mutate the children        new_population.append(mutate(child1, mutation_rate))        new_population.append(mutate(child2, mutation_rate))    return new_population# Evolutionary Algorithm with tracking of fitness valuesdef evolutionary_algorithm(mutation_rate):    population = generate_population()    best_fitness_values = []    average_fitness_values = []    for generation in range(GENERATIONS):        # Evaluate fitness of current population        fitness_values = [fitness(individual) for individual in population]        best_fitness = max(fitness_values)  # Maximization        average_fitness = np.mean(fitness_values)        # Record best and average fitness        best_fitness_values.append(float(best_fitness))  # Keep as float        average_fitness_values.append(float(average_fitness))  # Keep as float        # Generate the next generation        population = next_generation(population, mutation_rate)    return best_fitness_values, average_fitness_values# Store average fitness values across mutation ratesoverall_average_fitness = np.zeros(GENERATIONS)# Run the evolutionary algorithm for each mutation probabilityfor mutation_rate in MUTATION_PROBABILITIES:    best_fitness, average_fitness = evolutionary_algorithm(mutation_rate)    # Accumulate average fitness values    overall_average_fitness += np.array(average_fitness)# Calculate the overall average fitness across mutation ratesoverall_average_fitness /= len(MUTATION_PROBABILITIES)# overall_average_fitness = np.round(overall_average_fitness)# Plotting the resultsplt.figure(figsize=(12, 6))plt.plot(range(GENERATIONS), overall_average_fitness, label='Overall Average Fitness', color='blue')plt.title('Overall Average Non-Attacking Pairs Fitness Over Generations')plt.xlabel('Generation')plt.ylabel('Fitness (Number of Non-Attacking Pairs)')plt.xticks(ticks=np.arange(0, GENERATIONS + 1, 100))  # Set x-axis ticks at intervals of 10plt.grid()plt.axhline(y=N * (N - 1) / 2 + 0.001, color='black', linewidth=0.1, linestyle='--', label='Max Non-Attacking Pairs')  # Max pairs lineplt.legend()plt.show()

我尝试更改了种群大小和代数值,但仍然无法得到平滑的曲线。我的输出:我的输出

期望的输出适应度随代数变化:期望的输出曲线

如何使该曲线看起来平滑?


回答:

为什么要对不同突变率(特别是较大的突变率)进行平均处理?如果你想要一条平滑的曲线,你需要一个较大的种群大小来减少统计噪声,同时你还希望采取小的步骤,因此需要一个较小的突变率,最后你不需要太多的代数,只需要足够达到最大适应度即可:

POP_SIZE = 1000  # Population sizeGENERATIONS = 50  # Number of generationsMUTATION_PROBABILITIES = [0.001]  # Mutation probabilities

enter image description here

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注