基因遗传进化算法-找最优路径

news2024/11/16 11:27:02

在这里插入图片描述
在这里插入图片描述

import random
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题


# 创建初始种群
def create_initial_population():
    population = []
    for _ in range(population_size):
        chromosome = list(cities.keys())
        random.shuffle(chromosome)
        population.append(chromosome)
    return population


# 计算两个城市之间的距离
def distance(city1, city2):
    x1, y1 = cities[city1]
    x2, y2 = cities[city2]
    return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5


# 计算适应度(路径长度)
def calculate_fitness(chromosome):
    total_distance = 0
    for i in range(len(chromosome) - 1):
        city1, city2 = chromosome[i], chromosome[i + 1]
        total_distance += distance(city1, city2)
    return total_distance


# 选择精英个体
def select_elite(population):
    elite = []
    sorted_population = sorted(population, key=lambda chromosome: calculate_fitness(chromosome))
    for i in range(elite_size):
        elite.append(sorted_population[i])
    return elite


# 进化过程(交叉和变异)
def evolve_population(population):
    # 选择精英种群
    elite = select_elite(population)
    new_population = elite.copy()
    # 初始种群数量, population_size = 50
    while len(new_population) < population_size:
        parent1 = random.choice(elite)
        parent2 = random.choice(elite)
        # 交叉操作
        child = crossover(parent1, parent2)
        mutate(child)
        # 交叉操作后的种群添加到新的种群里面去
        new_population.append(child)
    # 返回新的种群
    return new_population


# 交叉操作
def crossover(parent1, parent2):
    child = ['-'] * len(parent1)
    start = random.randint(0, len(parent1) - 1)
    end = random.randint(start, len(parent1) - 1)
    child[start:end+1] = parent1[start:end+1]
    for city in parent2:
        if city not in child:
            index = child.index('-')
            child[index] = city
    return child


# 变异操作
def mutate(chromosome):
    for i in range(len(chromosome)):
        if random.random() < mutation_rate:
            j = random.randint(0, len(chromosome) - 1)
            # 染色体的两个片段进行交互
            chromosome[i], chromosome[j] = chromosome[j], chromosome[i]


# 主函数
def run():
    # 创建初始种群, 随机生成n个种群
    population = create_initial_population()
    best_distance = float('inf')
    best_chromosome = []

    # 进化一百次
    for _ in range(generations):
        # 把随机生成的种群放进去进化
        population = evolve_population(population)
        # 计算当前的适应度,并选出最小的(路径)的一组
        current_best = min(population, key=lambda chromosome: calculate_fitness(chromosome))
        current_distance = calculate_fitness(current_best)
        # 比较当前的最小距离和全局最优的距离
        if current_distance < best_distance:
            best_distance = current_distance
            best_chromosome = current_best

    print("最短路径:", best_chromosome)
    print("最短路径长度:", best_distance)
    return best_chromosome


# 运行主函数
if __name__ == "__main__":
    # 城市坐标
    cities = {
        '城市A': (3, 7),
        '城市B': (1, 5),
        '城市C': (9, 9),
        '城市D': (0, 0),
        '城市E': (8, 3),
        '城市F': (5, 1)
    }

    x = [cities[k][0] for k in cities]
    y = [cities[k][1] for k in cities]
    fig, ax = plt.subplots()
    scatter = ax.scatter(x, y)
    ax.set_xlabel('X轴')
    ax.set_ylabel('Y轴')
    ax.set_title('城市分布图')
    for i, txt in enumerate(cities.keys()):
        ax.annotate(txt, (x[i], y[i]), textcoords='offset points', xytext=(0, 10), ha='center')
    # 显示图形
    plt.show()

    # 遗传算法参数
    # 初始种群数量
    population_size = 50
    # 精英个体数量,即每次进化,筛选出来的数量
    elite_size = 10
    # mutation_rate(变异率),表示在交叉操作后发生基因变异的概率
    mutation_rate = 0.01
    # 进化次数
    generations = 100
    res = run()

    res_x = [cities[r][0] for r in res]
    res_y = [cities[r][1] for r in res]
    fig, ax = plt.subplots()
    scatter = ax.scatter(res_x, res_y)
    path = ax.plot(res_x, res_y, '--', color='gray')
    ax.set_xlabel('X轴')
    ax.set_ylabel('Y轴')
    ax.set_title('路径图')
    for i, txt in enumerate(res):
        ax.annotate(txt, (res_x[i], res_y[i]), textcoords='offset points', xytext=(0, 10), ha='center')
    plt.show()



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/711231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1024天,CSDN上的时间之旅

1024天&#xff0c;CSDN上的时间之旅 感想收获未来规划职业规划创作规划 感想 今天是在CSDN这个博客上成为博主已经迈入了1024天。这个数字对于计算机领域来说&#xff0c;具有特殊的含义和重要性。 在计算机科学中&#xff0c;1024是2的十次方&#xff0c;也就是2^10。这意味…

rt-thread------串口V1(三)接收

系列文章目录 rt-thread 之 fal移植 rt-thread 之 生成工程模板 STM32------串口理论篇 rt-thread------串口V1版本&#xff08;一&#xff09;配置 rt-thread------串口V1版本&#xff08;二&#xff09;发送篇 文章目录 系列文章目录一、串口的接收中断接收DMA接收 一、串口…

从一次netty分享漫谈

从一次netty分享漫谈 1.前言 上周五&#xff0c;笔者所在的开发小组&#xff0c;组织了一场分享&#xff0c;内容是netty的入门。笔者所在的团队&#xff0c;基本上就是在各条业务线中活蹦乱跳&#xff0c;有经验的看官&#xff0c;到这里已经可以给出分享效果的总体预测&…

Gradle 各个版本下载

每次都要找下载地址&#xff0c;还是记录一下好找点。 http://services.gradle.org/distributions

Unreal 5 官方在Niagara里模拟大型群体笔记

官方视频地址&#xff1a;https://www.bilibili.com/video/BV1FX4y1T7z2/ 如果需要&#xff0c;请查看官方视频。 性能测试 在讲解Niagara之前&#xff0c;视频首先做了一个性能测试&#xff0c;首先放置了100个AI角色&#xff0c;可以想目标角色移动的ai&#xff0c;然后测试…

C语言:猜凶手

题目&#xff1a; 日本某地发生了一件谋杀案&#xff0c;警察通过排查确定杀人凶手必为4个嫌疑犯的一个。 以下为4个嫌疑犯的供词: A说&#xff1a;不是我。 B说&#xff1a;是C。 C说&#xff1a;是D。 D说&#xff1a;C在胡说 已知3个人说了真话&#xff0c;1个人说的是假话。…

山西电力市场日前价格预测【2023-07-03】

日前价格预测 预测明日&#xff08;2023-07-03&#xff09;山西电力市场全天平均日前电价为333.50元/MWh。其中&#xff0c;最高日前电价为398.66元/MWh&#xff0c;预计出现在15: 15。最低日前电价为280.73元/MWh&#xff0c;预计出现在24: 00。 以上预测仅供学习参考&#x…

Spring第一讲:Spring基础概念和环境搭建

一、Spring是什么 Spring 是 Java EE 编程领域的一款轻量级的开源框架&#xff0c;由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立&#xff0c;它的目标就是要简化 Java 企业级应用程序的开发难度和周期。 Spring 自诞生以来备受青睐&#xff0c;一直被广大开发…

二叉树各种函数的实现

如果你觉得迷茫&#xff0c;那就尽可能选择比较困难的路。 目录 前言&#xff1a; &#x1f340;一.通过前序遍历创建二叉树 &#x1f341;二.二叉树的四种遍历 &#x1f342;1.二叉树的前序遍历 &#x1f33c;2.二叉树的中序遍历 &#x1f34c;3.二叉树的后序遍历 …

Mac VSCode配置运行单个C++文件

题外话&#xff1a;VSCode一键整理代码快捷键&#xff1a;ShiftoptionF 方法一&#xff1a;命令行直接编译 g -o 想创建的可执行文件名 ./cpp文件名 ./可执行文件名 以test.cpp为例&#xff0c;我创建的可执行文件名为test&#xff0c;运行结果如下&#xff1a; 方法二&#…

SpringCloud-Nacos配置管理

文章目录 Nacos配置管理统一配置管理在nacos中添加配置文件从微服务拉取配置 配置热更新方式一方式二 配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两个UserApplication&#xff0c;使用不同的profile3&#xff09;运…

React教程(由浅到深)

文章目录 1. 基本语法1.1 初体验Hello React1.2 JSX语法的基本使用1.2.1 语句与表达式说明 1.3. React面向组件编程1.3.1 函数组件与类组件 1.4 组件实例的三大特性1.4.1 state数据存储状态1.4.2 props的使用1.4.2.1基本使用1.4.2.2 做限制类型&#xff0c;默认值使用1.4.2.3 简…

2、boostrap 多数据类型表单

fileinput 视频图片文本数据表单 插件下载地址&#xff1a;https://github.com/kartik-v/bootstrap-fileinput/ 1、多类型数据from测试 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</tit…

Jeston Xavier NX 模块将系统迁移到NVME存储

大家好&#xff0c;我是虎哥&#xff0c;最近完成了自己设计的第一个Xavier NX的载板设计和打样&#xff0c;虽然还有一些小的不完善的地方&#xff0c;但是可以正常使用&#xff0c;这里记录和分享一下我自己设计的载板上如何实现系统迁移。 我自己使用SDK Manager 安装了所有…

c# Invoke使用

在多线程编程中&#xff0c;我们经常要在工作线程中去更新界面显示&#xff0c;而在多线程中直接调用界面控件的方法是错误的做法&#xff0c;Invoke 和 BeginInvoke 就是为了解决这个问题而出现的&#xff0c;使你在多线程中安全的更新界面显示。 正确的做法是将工作线程中涉…

青少年机器人技术一级考试备考重点(三):简单机械

随着机器人技术的飞速发展&#xff0c;越来越多的青少年开始关注并参与其中。青少年机器人技术考试作为一项评估学生机器人技术水平的重要考试&#xff0c;备受广大青少年和家长的关注。为了更好地备战青少年机器人技术一级考试&#xff0c;了解考试的学习要点和备考重点是非常…

【C++初阶】11. list的使用及模拟实现

1. list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。list与…

清华青年AI自强作业hw5:基于CNN实现CIFAR10分类任务

清华青年AI自强作业hw5&#xff1a;基于CNN实现CIFAR10分类任务 简述作业实现遇到的问题相关链接 一起学AI系列博客&#xff1a;目录索引 简述 hw5作业为利用深度卷积神经网络实现CIFAR_10数据集十分类问题&#xff0c;帮助理解CNN的前向传播结构。 CIFAR-10是一个常用的彩色图…

现代处理器结构

本文翻译自&#xff1a;Modern Microprocessors A 90-Minute Guide!&#xff0c;&#xff0c;我认为原文是相当好的计算机体系结构方面的概述&#xff0c;与时代相结合是国内计算机课本普遍缺失的一环&#xff0c;本文可作为一个有效的补充&#xff0c;向原作者和其他译者表示感…

青岛大学_王卓老师【数据结构与算法】Week03_09_线性表的链式表示和实现9_学习笔记

本文是个人学习笔记&#xff0c;素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享&#xff0c;另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权&#xff0c;请留言作删文处理。 课程视频链接&#xff1a; 数据结构与算法基础–…