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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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