数学建模学习(1)遗传算法

news2024/11/24 9:01:04

一、简介

        遗传算法(Genetic Algorithm, GA)是一种用于解决优化搜索问题的进化算法。它基于自然选择和遗传学原理,通过模拟生物进化过程来寻找最优解。

        以下是遗传算法的主要步骤和概念:

  • 初始化种群(Initialization):随机生成一组可能的解(个体),形成初始种群。

  • 适应度评估(Fitness Evaluation):根据适应度函数评估每个个体的质量,即其解问题的效果。

  • 选择(Selection):根据适应度选择较优的个体进行繁殖。常见的选择方法包括轮盘赌选择锦标赛选择排序选择

  • 交叉(Crossover):将两个个体的部分基因组合生成新的个体(子代)。交叉操作模拟生物的基因重组,常见的交叉方法有单点交叉和多点交叉。

  • 变异(Mutation):随机改变个体的部分基因,以增加种群的多样性,防止算法陷入局部最优。变异操作模拟生物的基因突变。

  • 替换(Replacement):将子代个体加入种群中,通常会替换掉适应度较低的个体,以保持种群规模恒定。

  • 终止条件(Termination Condition):当达到预定的终止条件时(如运行一定代数、适应度达到某个阈值),算法停止,输出最优解。

        遗传算法通常用于解决以下类型的问题:

  • 优化问题,例如函数优化、路径优化(如旅行商问题)。
  • 搜索问题,例如求解数独、密码破解。
  • 机器学习中的参数优化,例如神经网络权重优化。

优点

  • 遗传算法具有全局搜索能力,能够在较大的搜索空间中找到全局最优解。
  • 适用于复杂的、多维的、非线性的优化问题。
  • 不依赖于问题的具体数学性质,可以处理各种类型的目标函数和约束条件。

缺点

  • 计算代价较高,尤其是适应度评估过程可能耗时。
  • 需要精心设计适应度函数、选择方法、交叉和变异操作,才能获得好的效果。
  • 对于某些问题,可能会收敛到局部最优解,而非全局最优解。

二、算法介绍 

(1)适应度函数

(2)轮盘赌选择

(3)锦标赛选择

(4)排序选择

 

(5)单点交叉 

应用场景

        单点交叉适用于问题规模较小或基因序列较短的情况。

        对于复杂问题或基因序列较长的情况,可以考虑多点交叉均匀交叉等更复杂的交叉方法,以提高解的多样性和质量。

(6) 多点交叉

(7)均匀交叉 

 

 

(8)变异 

        通常设置较低的变异率(如 0.1% 到 1%)

三、遗传算法解TSP 

import copy
import random
import math
import numpy as np
import matplotlib.pyplot as plt

N = 20000  # 最大迭代次数
city_num = 31
pop_size = 100  # 种群数量
pc = 0.8  # 交叉概率
pm = 0.05  # 变异概率

# 城市坐标
city_position = [(1304, 2312), (3639, 1315), (4177, 2244), (3712, 1399), (3488, 1535),
                 (3326, 1556), (3238, 1229), (4196, 1004), (4312, 790), (4380, 570),
                 (3007, 1970), (2562, 1756), (2788, 1491), (2381, 1676), (1332, 695),
                 (3715, 1678), (3918, 2179), (4061, 2370), (3780, 2212), (3676, 2578),
                 (4029, 2838), (4263, 2931), (3429, 1908), (3507, 2367), (3394, 2643),
                 (3439, 3201), (2935, 3240), (3140, 3550), (2545, 2357), (2778, 2826), (2370, 2975)]

# 距离矩阵,城市之间的距离
dis = np.zeros((31, 31))
for i in range(31):
    for j in range(31):
        if i != j:
            dis[i][j] = ((city_position[i][0] - city_position[j][0]) ** 2 + (city_position[i][1] - city_position[j][1]) ** 2) ** 0.5

# 初始化种群并去重
def init(pop_size, city_num):
    population = []
    while len(population) < pop_size:
        temp = random.sample(range(city_num), city_num)
        if temp not in population:
            population.append((temp))
    return population

# 适应度函数
def fitness(population, dis):
    fitness = []
    for i in range(len(population)):
        distance = 0
        for j in range(city_num - 1):
            distance += dis[population[i][j]][population[i][j + 1]]
        distance += dis[population[i][-1]][population[i][0]]
        if distance == 0:
            f = float('inf')
        else:
            f = 1 / (distance ** 2)
        fitness.append(f)
    return fitness

# 选择函数:轮盘赌选择
def select(population, fitness):
    index = random.randint(0, pop_size - 1)
    num = 0
    r = random.uniform(0, sum(fitness))
    for i in range(len(population)):
        num += fitness[i]
        if num >= r:
            index = i
            break
    return population[index]

# 交叉函数
def cross(fa1, fa2):
    if random.random() < pc:
        chrom1 = fa1[:]
        chrom2 = fa2[:]
        cpoint1 = random.randint(0, city_num - 1)
        cpoint2 = random.randint(0, city_num - 1)
        if cpoint1 > cpoint2:
            temp = cpoint1
            cpoint1 = cpoint2
            cpoint2 = temp
        temp1 = []
        temp2 = []
        for i in range(cpoint1, len(chrom1)):
            temp1.append(chrom1[i])
            temp2.append(chrom2[i])
        for i in range(cpoint1, cpoint2 + 1):
            chrom1[i] = fa2[i]
            chrom2[i] = fa1[i]
        new_chrom1 = []
        new_chrom2 = []
        for i in range(cpoint2 + 1):
            new_chrom1.append(chrom1[i])
            new_chrom2.append(chrom2[i])
        new_chrom1.extend(temp1)
        new_chrom2.extend(temp2)

        ans1 = []
        ans2 = []
        for i in range(len(new_chrom1)):
            if new_chrom1[i] not in ans1:
                ans1.append(new_chrom1[i])
        for i in range(len(new_chrom2)):
            if new_chrom2[i] not in ans2:
                ans2.append(new_chrom2[i])
        return ans1, ans2
    else:
        return fa1[:], fa2[:]

# 变异函数
def mutate(chrom):
    if random.random() < pm:
        mpoint1 = random.randint(0, city_num - 1)
        mpoint2 = random.randint(0, city_num - 1)
        temp = chrom[mpoint1]
        chrom[mpoint1] = chrom[mpoint2]
        chrom[mpoint2] = temp
    return chrom


def show(lx, ly, fit_history):
    # 画出每代最好适应值的图像
    plt.plot(range(len(fit_history)), fit_history)
    plt.xlabel("Generation")
    plt.ylabel("Fitness")
    plt.show()
    # 画出最短路径大小的变化图
    a = []
    for i in range(len(fit_history)):
        a.append(math.sqrt(1 / fit_history[i]))
    plt.plot(range(len(a)), a)
    plt.xlabel("Generation")
    plt.ylabel("Best_path_size")
    plt.show()


def best_show(x, y, Best_Fitness):
    # 定义两个子图
    fig, ax = plt.subplots(1, 2, figsize=(12, 5), facecolor='#ccddef')
    # 定义子图1标题
    ax[0].set_title("Best route")
    # 定义子图2标题
    ax[1].set_title("Best_Fitness Change Procession")
    # 画线
    ax[0].plot(x, y)
    # 画点(第一个子图)
    ax[0].scatter(x, y, color='r')
    # 画线(第二个子图)
    ax[1].plot(range(len(Best_Fitness)), [Best_Fitness[i] for i in range(len(Best_Fitness))])
    plt.show()

# 主程序
if __name__ == '__main__':
    best_fit = 0.0
    ans = []
    best_path = []
    population = init(pop_size, city_num)  # 初始化种群,pop_size:种群个数
    for i in range(N):
        fit = fitness(population, dis)  # 计算适应度列表
        max_fit = max(fit)  # 因为适应度是采用距离和的平方的倒数,故最大的适应度代表距离最小
        max_index = fit.index(max_fit)  # 最大适应度的方案索引
        lx = []
        ly = []
        for j in population[max_index][:]:
            j = int(j)  # 保证整数
            lx.append(city_position[j][0])
            ly.append(city_position[j][1])
        if max_fit > best_fit:  # 假如路径更短
            best_fit = max_fit  # 修正了这里的错别字
            ans = population[max_index][:]
            x = copy.copy(lx)
            y = copy.copy(ly)
        best_path.append(best_fit)  # 记录适应度变化,为画图准备
        # 变异、交叉
        new_population = []
        n = 0
        while n < pop_size:
            p1 = select(population, fit)
            p2 = select(population, fit)
            while p2 == p1:
                p2 = select(population, fit)
            # 交叉
            chrom1, chrom2 = cross(p1, p2)
            # 变异
            chrom1 = mutate(chrom1)
            chrom2 = mutate(chrom2)
            new_population.append(chrom1)
            new_population.append(chrom2)
            n += 2
        population = new_population
        print("######################################################")
        print(f"第{i + 1}代的最优路径为:", ans)
        print("最短路径为:", (1 / best_fit) ** 0.5)
    show(lx,ly,best_path)
    x.append(x[0])
    y.append(y[0])
    best_show(x,y,best_path)

结果:

 

 

对比模拟退火算法的结果:

(以下是模拟退火算法的结果) 

 

 

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

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

相关文章

react中嵌套路由以及默认显示二级路由

1.安装插件 npm install react-router-dom 2.新建文件及页面 在scr/page下新建layout、about、home文件夹&#xff0c;分别在对应的文件夹下新建入口文件index.js&#xff1b;src下新建router文件夹&#xff0c;该文件夹下新建入口文件index.js 3.配置路由 如何配置路由&am…

昇思学习打卡-25-自然语言处理/RNN实现情感分类

文章目录 数据下载加载预训练词向量数据集预处理模型构建损失函数与优化器训练逻辑评估指标和逻辑模型训练与保存模型加载与测试自定义输入测试测试 情感分类是自然语言处理中的经典任务&#xff0c;是典型的分类问题。本节使用MindSpore实现一个基于RNN网络的情感分类模型&…

android audio不同音频流,(六)settings内音频流音量调整

&#xff08;1&#xff09;settings内&#xff0c;可设置音频流音量&#xff0c;如下图&#xff1a; &#xff08;2&#xff09;settings调整音量条进度&#xff0c;会触发SeekBarVolumizer对象&#xff1a; SeekBarVolumizer文件路径&#xff1a; frameworks/base/core/java/…

设计模式13-单件模式

设计模式13-单件模式 写在前面对象性能模式典型模式1. 单例模式&#xff08;Singleton Pattern&#xff09;2. 享元模式&#xff08;Flyweight Pattern&#xff09;3. 原型模式&#xff08;Prototype Pattern&#xff09;4. 对象池模式&#xff08;Object Pool Pattern&#xf…

WebRTC QoS方法十三.2(Jitter延时的计算)

一、背景介绍 一些报文在网络传输中&#xff0c;会存在丢包重传和延时的情况。渲染时需要进行适当缓存&#xff0c;等待丢失被重传的报文或者正在路上传输的报文。 jitter延时计算是确认需要缓存的时间 另外&#xff0c;在检测到帧有重传情况时&#xff0c;也可适当在渲染时…

无人机图像目标检测技术详解

当前研究领域的热点之一。无人机搭载的高清摄像头能够实时捕获大量图像数据&#xff0c;对这些数据进行有效的目标检测对于军事侦察、环境监测、灾害救援等领域具有重要意义。本文将对无人机图像目标检测技术进行详解&#xff0c;包括图像处理技术、目标检测算法、关键技术应用…

LoFTR关键点特征匹配算法环境构建与图像匹配测试Demo

0&#xff0c;LoFTR CVPR 2021论文《LoFTR: Detector-Free Local Feature Matching with Transformers》开源代码 1&#xff0c;项目主页 LoFTR: Detector-Free Local Feature Matching with Transformers 2&#xff0c;GItHub主页 GitHub - zju3dv/LoFTR: Code for "…

Gen AI核心技术发展趋势分析

Gen AI核心技术解析及发展趋势 判别式模型&#xff0c;适用于处理回归与分类任务&#xff0c;其核心在于精准区分各类数据。与生成模型的生成新数据不同&#xff0c;判别模型专注于揭示输入特征与输出标签之间的紧密联系&#xff0c;从而实现准确分类或预测。在众多应用领域&am…

VS Code打开新文件会覆盖之前的窗口,解决办法

当我在VS Code中打开文件夹时&#xff0c;文件夹中只有一个文件能展示在窗口中&#xff0c;如果点击打开另外一个文件&#xff0c;之前打开的文件又会被覆盖。这样是无法进行文件之间的关联查找的。 要保证窗口可以打开多个文件&#xff0c;有不同的tab显示&#xff0c;设置如下…

好用的电脑屏幕监控软件推荐,什么软件能够监控电脑?

在当今信息化时代&#xff0c;电脑屏幕监控软件成为了企业管理、家长监管以及教育培训等领域的必备工具。通过实时监控电脑屏幕&#xff0c;这类软件可以有效提高工作效率&#xff0c;防止信息泄露&#xff0c;保障网络安全。本文将详细盘点几款主流的电脑屏幕监控软件&#xf…

PHP基础语法(四)

一、字符串类型 1、字符串定义语法 1&#xff09;单引号字符串&#xff1a;在单引号内部&#xff0c;所有的字符都会按照字面意义解释&#xff0c;不会进行变量替换或转义处理&#xff0c;除了 \ 表示单引号本身。 $str1 Hello, World!;2&#xff09;双引号字符串&#xff…

【机器学习算法基础】(基础机器学习课程)-08-决策树和随机森林-笔记

一、决策树之信息论基础 决策树是一种用来做决策的工具&#xff0c;就像我们生活中的选择树。例如&#xff0c;你在选择今天穿什么衣服时&#xff0c;会根据天气情况、出行活动等进行判断。决策树的构建过程涉及一些信息论的概念&#xff0c;用来衡量和选择最好的“分叉点”来进…

Unity打包设置

1.Resolution and Presentation (分辨率和显示) Fullscreen Window (全屏窗口): 应用程序将以全屏窗口模式运行&#xff0c;但不会独占屏幕。适用于想要全屏显示但仍需访问其他窗口的情况。 Resizable Window (可调整大小的窗口): 允许用户调整应用程序窗口的大小。适用于窗口…

Action通信 实践案例

Action通信 Server端实现 创建服务端功能包&#xff08;注意目录层级&#xff09;&#xff1a; ros2 pkg create my_exer05_action_server --build-type ament_cmake --node-name nav_server --dependencies rclcpp rclcpp_action my_exer_interfaces nav_msgs /*需求&#x…

【vim】ubuntu20-server 安装配置 vim 最新最详细

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【vim】ubuntu20-server 安装配置 vim 最新最详细 开发环境一、vim github二、安装必…

基于SpringBoot实现验证码功能

目录 一 实现思路 二 代码实现 三 代码汇总 现在的登录都需要输入验证码用来检测是否是真人登录&#xff0c;所以验证码功能在现在是非常普遍的&#xff0c;那么接下来我们就基于springboot来实现验证码功能。 一 实现思路 今天我们介绍的是两种主流的验证码&#xff0c;一…

IP地址专用SSL/https证书——10分钟签发

一般常用的SSL证书多为域名型SSL证书&#xff0c;即需要提供准确的域名。如果不能提供域名&#xff0c;只能提供IP地址&#xff0c;则需要一种特殊的SSL证书——IP地址证书。下面是IP地址证书的申请教程 IP地址专用SSL证书获取链接https://www.joyssl.com/certificate/select/…

SQL中的LEFT JOIN、RIGHT JOIN和INNER JOIN

在SQL中&#xff0c;JOIN操作是连接两个或多个数据库表&#xff0c;并根据两个表之间的共同列&#xff08;通常是主键和外键&#xff09;返回数据的重要方法。其中&#xff0c;LEFT JOIN&#xff08;左连接&#xff09;、RIGHT JOIN&#xff08;右连接&#xff09;和INNER JOIN…

Open3D 将点云投影到球面

目录 一、概述 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2投影后点云 前期试读&#xff0c;后续会将博客加入下列链接的专栏&#xff0c;欢迎订阅 Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSDN博客 一、概述…

【表单组件】地址组件新增精简模式

07/17 主要更新模块概览 快速筛选 精简模式 触发条件 自定义域名 01 表单管理 1.1 【表单组件】-数据关联组件新增快速筛选功能 说明&#xff1a; 数据关联组件新增快速筛选功能&#xff0c;用户在数据关联组件选择数据时&#xff0c;可以通过快速筛选功能&#xff0…