遗传算法解决TSP问题(C++)

这篇博客介绍了如何使用遗传算法解决旅行商问题(TSP)。遗传算法因其全局搜索和不受问题参数限制的优势被选中。文章详细阐述了遗传算法的概念、基本操作,包括选择、交叉和变异,并具体解释了在TSP问题中的应用。作者提供了C++源代码,展示了求解38个城市TSP问题的近似解,并讨论了如何优化算法以提高效率。
摘要由CSDN通过智能技术生成

很早做了综合实训,题目是用 遗传算法解决TSP问题。
今天写篇博客,一方面作为分享,另一方面作为知识回顾~

为什么采用遗传算法解决问题呢?因为相比于其他普通算法,遗传算法有很大的优势,它摆脱了传统算法对问题参数的依赖,如连续、可导、可微等限制,只需对参数的编码进行操作,减少了求解问题的复杂性,同时它是一种全局搜索算法避免了陷入局部最优解。
本文章程序中,是求其TSP(38个城市)的近似解;去掉主函数的注释代码,便可以在data.txt文件里读取数据,并在Linux环境下用GNUplot绘制图像。

阅读前先说下本篇文章的思路:首先我们介绍下何为遗传算法及相关概念,之后在粗谈什么是TSP问题,最后在讲解源代码,及程序运行流程和采用的各种策略。

一、基因遗传算法

1.1基因算法简介
遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。遗传算法是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成。每个个体实际上是染色体(chromosome)带有特征的实体。染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。因此,在一开始需要实现从表现型到基因型的映射即编码工作。由于仿照基因编码的工作很复杂,我们往往进行简化,如二进制编码,初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代(generation)演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度(fitness)大小选择(selection)个体,并借助于自然遗传学的遗传算子(genetic operators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似最优解。
1.2基本概念
由于遗传算法是由进化论和遗传学机理而产生的搜索算法,所以在这个算法中会用到很多生物遗传学知识,下面是我们将会用来的一些术语说明:

染色体:
染色体又可以叫做基因型个体(individuals),一定数量的个体组成了群体(population),群体中个体的数量叫做群体大小。
基因:
基因是串中的元素,基因用于表示个体的特征。例如有一个串S=1011,则其中的1,0,1,1这4个元素分别称为基因。它们的值称为等位基因(Alleles)。
基因位点:
基因位点在算法中表示一个基因在串中的位置称为基因位置(Gene Position),有时也简称基因位。基因位置由串的左向右计算,例如在串 S=1101 中,0的基因位置是3。
特征值:
在用串表示整数时,基因的特征值与二进制数的权一致;例如在串 S=1011 中,基因位置3中的1,它的基因特征值为2;基因位置1中的1,它的基因特征值为8。
适应度:
各个个体对环境的适应程度叫做适应度(fitness)。为了体现染色体的适应能力,引入了对问题中的每一个染色体都能进行度量的函数,叫适应度函数。 这个函数是计算个体在群体中被使用的概率。

1.3遗传算法结构
遗传操作是模拟生物基因遗传的做法。在遗传算法中,通过编码组成初始群体后,遗传操作的任务就是对群体的个体按照它们对环境适应度(适应度评估)施加一定的操作,从而实现优胜劣汰的进化过程。从优化搜索的角度而言,遗传操作可使问题的解,一代又一代地优化,并逼近最优解。
遗传操作包括以下三个基本遗传算子(genetic operator):选择(selection);交叉(crossover);变异(mutation)
这三个遗传算子有如下特点:
个体遗传算子的操作都是在随机扰动情况下进行的。因此,群体中个体向最优解迁移的规则是随机的。需要强调的是,这种随机化操作和传统的随机搜索方法是有区别的。遗传操作进行的高效有向的搜索而不是如一般随机搜索方法所进行的无向搜索。
遗传操作的效果和上述三个遗传算子所取的操作概率,编码方法,群体大小,初始群体以及适应度函数的设定密切相关。

遗传算法的基本运算过程如下:
a)初始化:设置进化代数计数器t=0,设置最大进化代数T,随机生成M个个体作为初始群体P(0)。
b)个体评价:计算群体P(t)中各个个体的适应度。
遗传算法
c)选择运算:将选择算子作用于群体。选择的目的是把优化的个体直接遗传到下一代或通过配对交叉产生新的个体再遗传到下一代。选择操作是建立在群体中个体的适应度评估基础上的。
d)交叉运算:将交叉算子作用于群体。遗传算法中起核心作用的就是交叉算子。
e)变异运算:将变异算子作用于群体。即是对群体中的个体串的某些基因座上的基因值作变动。
群体P(t)经过选择、交叉、变异运算之后得到下一代群体P(t+1)。
f)终止条件判断:若t=T,则以进化过程中所得到的具有最大适应度个体作为最优解输出,终止计算。
这里写图片描述

二、TSP问题

旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。
旅行商问题是一个典型的组合优化问题,并且是一个np难问题,其可能的路径数目与城市数目n是成指数型增长的,所以一般很难精确地求出其最优解,本文采用遗传算法求其TSP(38个城市)的近似解。

三、现在进入正题

1、源代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "math.h"
#include "time.h"
#include <unistd.h>
#include <bits/stdc++.h>
#define CITY_NUM 38     //城市数,城市编号是0~CITY_NUM-1
#define POPSIZE 300        //种群个体数
#define MAXVALUE 10000000   //路径最大值上限
#define N 100000//需要根据实际求得的路径值修正
unsigned seed=(unsigned)time(0);
double Hash[CITY_NUM+1];
typedef struct CityPosition
{
    double x;
    double y;
}CityPosition;

CityPosition CityPos[38]={
    {
  11003.611100,42102.500000},{
  11108.611100,42373.888900},{
  11133.333300,42885.833300},{
  11155.833300,42712.500000},{
  11183.333300,42933.333300},{
  11297.500000,42853.333300},{
  11310.277800,42929.444400},{
  11416.666700,42983.333300},{
  11423.888900,43000.277800},{
  11438.333300,42057.222200},{
  11461.111100,43252.777800},{
  11485.555600,43187.222200},{
  11503.055600,42855.277800},{
  11511.388900,
  • 33
    点赞
  • 296
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值