遗传算法求解旅行商问题分析

news2025/5/16 16:59:53

目录

一、问题分析

二、实现步骤

1)初始化种群

2)计算适应度

 3)选择操作

4)交叉操作

5)变异操作

三、求解结果

四、总结 


本文通过一个经典的旅行商问题,详细阐述在实际问题中如何运用遗传算法来进行分析求解。

一、问题分析

       旅行商问题抽象为数学描述为,在平面内有有限个点,寻找一条路径穿过所有点,使路径长度最短。这个问题描述很简单,其实想要求解也很简单,因为途径所有点的路径数量是有限的,我们可以采用穷举法计算每一条路径的距离值,然后得到最短路径。但是采用穷举法的可行性不高,当我们要途径几十个点时,所有路径的总数是n!,这是一个非常庞大的数字,穷举已经不现实。因此我们选择采用其他智能优化算法来求解该问题。

       那么应该如何选择计算方法呢?从上面的分析中我们已经知道,这是一个求解最优解问题,我们还知道这个问题的解是有限范围的,因此我们可以选择遗传算法来求解。下面我们将沿着遗传算法经典步骤,逐步详细说明如何用遗传算法来求解旅行商问题。

二、实现步骤

1)初始化种群

       在初始化种群前,我们首先应考虑如何根据实际问题来设计个体和种群。在旅行商问题中,个体也就是解表征的是一组城市的排列结果,这个解不是单个的数值,而是一个组合。如果我们将每个城市依次编号,那么这个解就是一个N维的向量,向量元素为1到N之间的整数,其中N为城市总数。这个向量非常类似于一个群体中的个体,它已经由基因(城市编号)组成。因此我们可以直接使用这个向量作为群体的个体。初始化群体的代码如下。

       我们定义种群个体数量为100,最大迭代代数为1000,初始种群的大小就是一个100×31(n_cities)的矩阵,n_cities表示个体的基因数,也是城市数量。第一个for循环完成了初始种群的赋值。

    % 遗传算法参数
    population_size = 100;    % 种群大小
    max_generations = 1000;    % 最大迭代次数
    crossover_rate = 0.8;      % 交叉概率
    mutation_rate = 0.1;       % 变异概率
    tournament_size = 5;       % 锦标赛选择大小
    elite_num = 2;             % 精英保留数目
    
    % 初始化种群
    population = zeros(population_size, n_cities);
    for i = 1:population_size
        population(i,:) = randperm(n_cities);
    end

2)计算适应度

       在旅行商问题中,我们的目标值只有一个,就是路径的距离最短。在得到一个种群之后,我们可以直接计算出种群中每个个体,即每种路径的距离值。显然,距离值越小,适应度越大。因此,可以使用距离的导数来表征个体适应度的大小。具体实现代码如下。distances为已经计算好的两两城市之间的距离,此处直接提出相加即可。

        % 计算适应度
        fitness = zeros(population_size, 1);
        for i = 1:population_size
            fitness(i) = 1 / calculate_total_distance(population(i,:), distances);
        end
% 计算路径总长度
function total_dist = calculate_total_distance(path, distances)
    n = length(path);
    total_dist = 0;
    for i = 1:n-1
        total_dist = total_dist + distances(path(i), path(i+1));
    end
    total_dist = total_dist + distances(path(end), path(1));
end

 3)选择操作

       此处采用锦标赛法选择需要继承的父代。该方法的思想是随机从种群中抽取部分个体,然后将这部分个体中适应度最高的个体传递给下一代。此处直接选择两个父代的个体,以便直接进行后续的交叉和变异操作。

% 锦标赛选择父代
parent1 = tournament_selection(population, fitness, tournament_size);
parent2 = tournament_selection(population, fitness, tournament_size);
% 锦标赛选择
function selected = tournament_selection(population, fitness, tournament_size)
    candidates = randperm(size(population,1), tournament_size);
    [~, idx] = max(fitness(candidates));
    selected = population(candidates(idx), :);
end

4)交叉操作

        直接对选出的两个父代个体执行交叉操作。此处采用的交叉方法为顺序交叉法,其算法思想如下图所示。首先随机得到一个交叉区域,将个体P1中该区域的元素赋给新个体child1的对应区域位置,然后将P2以交叉区域后边界分为前后两段,并将前后两段互换位置得到一个新的片段,当然这个片段中删除了交叉区域中已经存在的元素,然后再将这个片段分别赋给child1的两端,不要覆盖交叉区域。这样就得到了交叉后的第一个新个体,然后交换P1和P2角色,执行上述操作,得到child2第二个个体,这样交叉操作就完成了。

% 交叉
if rand < crossover_rate
    [child1, child2] = ox_crossover(parent1, parent2);
else
    child1 = parent1;
    child2 = parent2;
end
% 顺序交叉 (OX)
function [child1, child2] = ox_crossover(parent1, parent2)
    n = length(parent1);
    points = sort(randperm(n, 2));
    start = points(1);
    end_ = points(2);
    % 子代1
    segment1 = parent1(start:end_);
    remaining = [];
    for i = [end_+1:n, 1:end_]
        city = parent2(i);
        if ~ismember(city, segment1)
            remaining = [remaining, city];
        end
    end
    child1 = zeros(1, n);
    child1(start:end_) = segment1;
    child1([1:start-1, end_+1:n]) = remaining(1:n - (end_ - start + 1));  
    % 子代2
    segment2 = parent2(start:end_);
    remaining = [];
    for i = [end_+1:n, 1:end_]
        city = parent1(i);
        if ~ismember(city, segment2)
            remaining = [remaining, city];
        end
    end
    child2 = zeros(1, n);
    child2(start:end_) = segment2;
    child2([1:start-1, end_+1:n]) = remaining(1:n - (end_ - start + 1));
end

5)变异操作

       此处变异使用简单的交换操作,即交换个体中任意两个位置的元素。具体实现代码如下,首先随机产生一个随机数,判断是否满足可变异概率,然后在随机生成两个位置,将这两个位置的元素进行交换即可。

% 变异
child1 = mutate(child1, mutation_rate);
child2 = mutate(child2, mutation_rate);
% 变异(交换)
function mutated = mutate(individual, mutation_rate)
    mutated = individual;
    if rand < mutation_rate
        n = length(individual);
        pos = randperm(n, 2);
        mutated(pos(1)) = individual(pos(2));
        mutated(pos(2)) = individual(pos(1));
    end
end

三、求解结果

程序完整实现代码在这里。最终求解结果如下图所示,得到的最优距离为15598。

四、总结 

       通过遗传算法求解旅行商问题流程可知,遗传算法的各项具体操作实现方法不是固定不变的,需要根据实际问题分析处理。即使使用本文提供的实际程序计算,每次迭代计算得到的结果也是不一样的。旅行商问题本质上是一个排列问题,且越接近最优解时,解相邻元素的排列顺序越接近。根据这一特性,我们在进行交叉、变异产生新个体时就需要设计合适的算法实现,减小对排列顺序大幅度调整的概率。因此,我们以非常小的概率控制变异发生,在交叉过程中使用分段交叉,尽量保持相邻元素的排列顺序。总之,在遗传算法产生新的子代群体过程中,我们应尽量避免产生大量与上一代差异较大的个体,当然也尽可能保留少量差异大的个体,使种群始终向最优解方向缓慢进化,避免算法不收敛或陷入局部最优解中。

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

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

相关文章

打造网络安全堡垒,企业如何应对DDoS、CC、XSS和ARP攻击

网站已经成为企业展示形象、开展业务和实现线上营销的重要平台。然而&#xff0c;随着网络攻击手段的不断升级&#xff0c;DDoS、CC、XSS、ARP等攻击频频出现&#xff0c;严重威胁到企业的信息安全和业务稳定。本文将详细阐述网站被攻击后应采取的应急措施及预防策略&#xff0…

深度解析物理机服务器故障修复时间:影响因素与优化策略

一、物理机故障修复的核心影响因素 物理机作为企业 IT 基础设施的核心载体&#xff0c;其故障修复效率直接关系到业务连续性。故障修复时间&#xff08;MTTR&#xff09;受多重因素交叉影响&#xff1a; 1. 故障类型的复杂性 硬件级故障&#xff1a; 简单故障&#xff1a;内存…

印度全印度游戏联合会(AIGF)介绍与用途

本文为印度AIGF的介绍科普文&#xff0c;自去年开始&#xff0c;印度Rummy类游戏申请印度支付都需要拥有AIGF的会员及产品证书。 如需要rummy可以通过AIGF审核的源。码&#xff0c;或咨询AIGF的相关内容&#xff0c;可以联。系老妙。 全印度游戏联合会&#xff08;All India G…

可视化数据图表怎么做?如何实现三维数据可视化?

目录 一、三维数据可视化的要点 1. 明确数据可视化的目标 2. 筛选与整理数据 3. 选择合适的图表类型 4. 运用专业工具制作 5. 优化图表的展示效果 二、数据可视化图表怎么做&#xff1f; 1. 理解三维数据的特性 2. 数据处理与三维建模 3. 设置光照与材质效果 4. 添加…

视频分辨率增强与自动补帧

一、视频分辨率增强 1.传统分辨率增强方法 传统的视频分辨率增强方法主要基于插值技术。这些方法通过对低分辨率视频帧中已知像素点的分布规律和相邻像素之间的相关性进行分析&#xff0c;在两者之间插入新的像素点以达到增加视频分辨率的目的。例如&#xff0c;最近邻插值算…

【SPIN】用Promela验证顺序程序:从断言到SPIN实战(SPIN学习系列--2)

你写了一段自认为“天衣无缝”的程序&#xff0c;但如何确保它真的没有bug&#xff1f;靠手动测试&#xff1f;可能漏掉边界情况&#xff1b;靠直觉&#xff1f;更不靠谱&#xff01;这时候&#xff0c;Promela SPIN组合就像程序的“显微镜”——用形式化验证技术&#xff0c;…

降本增效双突破:Profinet转Modbus TCP助力包布机产能与稳定性双提升

在现代工业自动化领域&#xff0c;ModbusTCP和Profinet是两种常见的通讯协议。它们在数据传输、设备控制等方面有着重要作用。然而&#xff0c;由于这两种协议的工作原理和应用环境存在差异&#xff0c;直接互联往往会出现兼容性问题。此时&#xff0c;就需要一种能够实现Profi…

JESD204 ip核使用与例程分析(一)

JESD204 ip核使用与例程分析(一) JESD204理解JESD204 与JESD204 PHY成对使用原因JESD204B IP核JESD204B IP核特点JESD204B IP核配置第一页第二页第三页第四页JESD204 PHY IP核配置第一页第二页JESD204理解 JESD204B是一种针对ADC、DAC设计的传输接口协议。此协议包含四层, …

Kubernetes控制平面组件:Kubelet详解(一):API接口层介绍

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

牛客网NC22015:最大值和最小值

牛客网NC22015&#xff1a;最大值和最小值 题目描述 题目要求 输入&#xff1a;一行&#xff0c;包含三个整数 a, b, c &#xff08;1≤a,b,c≤1000000&#xff09; 输出&#xff1a;两行&#xff0c;第一行输出最大数&#xff0c;第二行输出最小数。 样例输入&#xff1a; …

浪潮云边协同:赋能云计算变革的强力引擎

在数字化浪潮以排山倒海之势席卷全球的当下&#xff0c;第五届数字中国建设峰会在福州盛大开幕。这场以“创新驱动新变革&#xff0c;数字引领新格局”为主题的行业盛会&#xff0c;宛如一座汇聚智慧与力量的灯塔&#xff0c;吸引了国内外众多行业精英齐聚一堂&#xff0c;共同…

【GESP】C++三级模拟题 luogu-B3848 [GESP样题 三级] 逛商场

GESP三级模拟样题&#xff0c;一维数组相关&#xff0c;难度★★✮☆☆。 题目题解详见&#xff1a;https://www.coderli.com/gesp-3-luogu-b3848/ 【GESP】C三级模拟题 luogu-B3848 [GESP样题 三级] 逛商场 | OneCoderGESP三级模拟样题&#xff0c;一维数组相关&#xff0c;…

腾讯怎样基于DeepSeek搭建企业应用?怎样私有化部署满血版DS?直播:腾讯云X DeepSeek!

2025新春&#xff0c;DeepSeek横空出世&#xff0c;震撼全球&#xff01; 通过算法优化&#xff0c;DeepSeek将训练与推理成本降低至国际同类模型的1/10&#xff0c;极大的降低了AI应用开发的门槛。 可以预见&#xff0c;2025年&#xff0c;是AI应用落地爆发之年&#xff01; ✔…

表记录的检索

1.select语句的语法格式 select 字段列表 from 表名 where 条件表达式 group by 分组字段 [having 条件表达式] order by 排序字段 [asc|desc];说明&#xff1a; from 子句用于指定检索的数据源 where子句用于指定记录的过滤条件 group by 子句用于对检索的数据进行分组 ha…

QT——概述

<1>, Qt概述 Qt 是⼀个 跨平台的 C 图形⽤⼾界⾯应⽤程序框架 Qt ⽀持多种开发⼯具&#xff0c;其中⽐较常⽤的开发⼯具有&#xff1a;Qt Creator、Visual Studio、Eclipse. 一&#xff0c;Qt Creator 集成开发环境&#xff08;IDE&#xff09; Qt Creator 是⼀个轻量…

DataHub:现代化元数据管理的核心平台与应用实践

一、DataHub平台概述 DataHub是由LinkedIn开源并持续维护的下一代元数据管理平台&#xff0c;它采用实时流式架构&#xff08;基于Kafka&#xff09;实现元数据的收集、处理和消费&#xff0c;为现代数据栈提供了端到端的元数据解决方案。作为数据治理的基础设施&#xff0c;D…

ubuntu服务器版启动卡在start job is running for wait for...to be Configured

目录 前言 一、原因分析 二、解决方法 总结 前言 当 Ubuntu 服务器启动时&#xff0c;系统会显示类似 “start job is running for wait for Network to be Configured” 或 “start job is running for wait for Plymouth Boot Screen Service” 等提示信息&#xff0c;并且…

QT6 源(101)阅读与注释 QPlainTextEdit,其继承于QAbstractScrollArea,属性学习与测试

&#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09;属性学习与测试 &#xff1a; &#xff08;4&#xff09; &#xff08;5&#xff09; 谢谢

Coze 实战教程 | 10 分钟打造你的AI 助手

> 文章中的 xxx 自行替换&#xff0c;文章被屏蔽了。 &#x1f4f1; 想让你的xxx具备 AI 对话能力&#xff1f;本篇将手把手教你&#xff0c;如何用 Coze 平台快速构建一个能与用户自然交流、自动回复提问的 xxx助手&#xff0c;零代码、超高效&#xff01; &#x1f4cc;…

牛客网 NC22167: 多组数据a+b

牛客网 NC22167: 多组数据ab 题目分析 这道题目来自牛客网&#xff08;题号&#xff1a;NC22167&#xff09;&#xff0c;要求我们计算两个整数a和b的和。乍看简单&#xff0c;但有以下特殊点需要注意&#xff1a; 输入包含多组测试数据每组输入两个整数当两个整数都为0时表示…