运筹系列67:大规模TSP问题的EAX遗传算法

news/2024/10/31 3:19:51/

1. 算法介绍

EAX是edge assembly crossover 算子的缩写。本算法有Y nagata教授公布,目前在VLSI最大的几个案例上获得了best的成绩。另外目前MonoLisa 100K问题的最优解也是由其公布,若能得到更优解,可以获得1000美元奖励。
算法步骤如下:

  1. 获得一系列初始解,选取两条路径A和B进行重叠
  2. 拆解重叠后的路径形成一系列子路径,每一条子路径都是偶数条边,其中A和B交叉,称为AB-cycle
  3. 按照一定的规则(随机或者启发式)选取边,称为E-set
  4. 使用A和E-set中的边进行反向增删,得到一系列Intemidiate结果
  5. 使用启发式算法将Intemidiate结果构建成soild结果。
    在这里插入图片描述

2. 代码分析

参考代码https://github.com/nagata-yuichi/GA-EAX(原版)
以及https://github.com/wlsgusjjn/EAX-TSP.git (简化版)

2.1 概述

原版文件清单如下:

main.cpp- The main functionenv.cpp, env.h- Main procedure of the GAkopt.cpp kopt.h- Local search with the 2-opt neighborhoodcross.cpp cross.h- Edge assembly crossover,核心程序evaluator.cpp evaluator.h- Pre-processing procedures to the TSP instanceindi.cpp, indi.h - An individual (tour)rand.cpp, rand.h- Procedures for generating a random number and permutation etc sort.cpp, sort.h- Procedures for sorting***.tsp- Several TSP instances (TSPLIB format)

2.2 使用方法

编译:g++ -o jikken -O3 main.cpp env.cpp cross.cpp evaluator.cpp indi.cpp rand.cpp kopt.cpp sort.cpp -lm

运行:./jikken <integer1> <string1> <integer2> <integer3> <string2>
比如:./jikken 10 DATA 100 30 rat575.tsp
参数说明:

  • = number of trials
  • = filename to which results are written
  • = number of population (300 is recommended if N > 10,000)
  • = number of offspring solutions (30 is recommended)
  • = instance filename (the instance must conform with TSPLIB format)

如果string1位DATA,则会生成两个结果文件:
DATA_Result和DATA_BestSol

  • DATA_Result:存储迭代信息,格式如下:
    0 6773 173 0 3
    1 6773 174 0 3
    2 6773 166 0 3
    3 6773 173 0 3
    4 6773 173 0 3
    5 6773 171 0 3
    6 6773 182 0 3
    7 6773 168 0 3
    8 6773 173 0 3
    9 6773 173 0 3

    • 1st column: trial number
    • 2nd column: best tour length obtained in each run
    • 3rd column: the number of generations in each run
    • 4th column: the execution time (sec) for generating the initial population
    • 5th column: the execution time (sec) for each run of the GA

*DATA_BestSol:存储每一轮的最优结果

575 6773
1 24 25 26 27 28 29 52 50 51 74 73 72 49 48 47 70 71 93 94 116 …

  • 1st line: number of cities, tour length
  • 2nd line: a solution representing a sequence of the cities

如果想记录每一轮的所有路径,将main.cpp中的gEnv->WritePop()开启,结果会写入DATA_POP_*
随后可以将这个文件作为初始路径传给程序继续执行优化:./jikken 10 DATA2 100 30 rat575.tsp DATA_POP_0

2.3 自定义修改

还可以做一些自定义算法配置,主要在env。cpp里面的TEnvironment::Init() 可以修改搜索参数:

  Example1: Default settingfStage = 1;       /* Stage I */fFlagC[ 0 ] = 4;  /* Diversity preservation: 1:Greedy, 3:Distance, 4:Entropy */fFlagC[ 1 ] = 1;  /* Eset Type: 1:Single-AB, 2:Block2 */ Example2: Only Stage II is performed using EAX with the Block2 strategyfStage = 2;       /* Stage I */fFlagC[ 0 ] = 4;  /* Diversity preservation: 1:Greedy, 3:Distance, 4:Entropy */fFlagC[ 1 ] = 2;  /* Eset Type: 1:Single-AB, 2:Block2 */ Example3: The greedy selection is used instead of the entropy-preserving selection.fStage = 1;       /* Stage I */fFlagC[ 0 ] = 1;  /* Diversity preservation: 1:Greedy, 3:Distance, 4:Entropy */fFlagC[ 1 ] = 1;  /* Eset Type: 1:Single-AB, 2:Block2 */ 

TerminationCondition() 里可以修改停止条件

3. 2013年新版本的改进

参考文章:https://sci-hub.se/10.1287/ijoc.1120.0506,主要想法就是第一步将EAX的操作局部化,随后再执行正常的EAX算子。

3.1 GA整体流程

每一阶段的GA算法架构如下,其中Npop个初始解使用的是greedy local search +2-opt neighborhood。注意下面有两个参数Npop和Nch。
在这里插入图片描述
每个阶段的终止条件:如果最近的1500/Nch次迭代都没有改进,则令G=当前迭代总次数。继续迭代,直至连续G/10次迭代都没有改进

3.2 边交换算法

  1. 首先是筛选AB-cycle:在$G_{AB} 上随机游走,直至所有路径都已游走完毕。过程中一旦发现AB−cycle,立即保存并从上随机游走,直至所有路径都已游走完毕。过程中一旦发现AB-cycle,立即保存并从上随机游走,直至所有路径都已游走完毕。过程中一旦发现ABcycle,立即保存并从G_{AB} $中删除。
  2. AB-cycle筛选出一部分的集合叫做E-set。
  3. 使用A和E-set给出一个新的路径(可能有subtour),然后按照一定的规则消除subtour,生成新的路径
  4. 将新路径放入offspring集合中,直至没有新的offspring生成。

3.3 构筑E-set规则

3.2节中构造E-set时,局部EXA规则目前有两种:
1.随机策略:每个AB-cycles有0.5的概率选上
2.单个策略:随机在剩余的AB-cycles中选一个
subtour消除规则为:
1.每次都从最小的subtour开始,遍历所有待删除的边e
2.另一条待删除的边,需满足其中至少有一个点在e的最近10个点中

全局EXA规则有三种
1.K-multiple策略:随机选取K个AB-cycles,代码中K=5
2.block策略:主要思想是选取位置相近的AB-cycles
3.block2策略:首先定义A-vertex为连接A中两条边的点;B-vertex为连接B中两条边的点;C-vertex为连接A和B中各一条边的点,如下图。其中a和b的差别在于,b中对c-vertex做了精简。
在这里插入图片描述
在intermediate solution中,A-blocks和B-blocks被c-vertex隔开,且c-vertex的数量肯定是偶数。c-vertex的计算比subtour的计算要快。使用tabu-search选取E-set,规则为:

  1. 初始化Tabu[i] = 0
  2. 选一个较大的AB-cycle作为center AB-cycle然后从剩下的里面随机选取AB-cycle,每一个至少和AB-cycle都有一个接触点
  3. 在每次迭代过程中,当前E-set都会转移到临近的tabu解以外的c-vertex最小的subtour中,直至LS个阶段没有改进(这里令其为20)。
    在这里插入图片描述

4. 一些对比结果

如下,其中B-err是best solution error,如果是=的话,后面括号中表示获得最优值的次数。A-err是average,W-error则是worst。
在这里插入图片描述


http://www.ppmy.cn/news/32510.html

相关文章

第十四届蓝桥杯三月真题刷题训练——第 13 天

目录 第 1 题&#xff1a;特殊日期 问题描述 答案提交 运行限制 代码&#xff1a; 思路&#xff1a; 第 2 题&#xff1a;重合次数 问题描述 答案提交 运行限制 代码&#xff1a; 第 3 题&#xff1a;左移右移 问题描述 输入格式 输出格式 样例输入 样例输出…

四、HikariCP 源码分析之初始化分析一

HikariDataSource 的初始化 HikariDataSource是 HikariCP 开放给用户使用连接池的主要操作类。所以,我们创建一个 HikariCP 的连接池,其实就是构造一个HikariDataSource。 两个构造函数 它有两个构造函数:

HTTP 3.0来了,UDP取代TCP成为基础协议,TCP究竟输在哪里?

TCP 是 Internet 上使用和部署最广泛的协议之一&#xff0c;多年来一直被视为网络基石&#xff0c;随着HTTP/3正式被标准化&#xff0c;QUIC协议成功“上位”&#xff0c;UDP“取代”TCP成为基础协议&#xff0c;TCP究竟“输”在哪里&#xff1f; HTTP/3 采用了谷歌多年探索的基…

GPT-4,终于来了!

就在昨天凌晨&#xff0c;OpenAI发布了多模态预训练大模型GPT-4。 这不昨天一觉醒来&#xff0c;GPT-4都快刷屏了&#xff0c;不管是在朋友圈还是网络上都看到了很多信息和文章。 GPT是Generative Pre-trained Transformer的缩写&#xff0c;也即生成型预训练变换模型的意思。…

【华为OD机试真题 JAVA】GPU算力问题

标题:GPU算力问题 | 时间限制:1秒 | 内存限制:262144K | 语言限制:不限 为了充分发挥Gpu算力, 需要尽可能多的将任务交给GPU执行, 现在有一个任务数组, 数组元素表示在这1s内新增的任务个数, 且每秒都有新增任务, 假设GPU最多一次执行n个任务, 一次执行…

蓝桥杯第五天刷题

第一题&#xff1a;数的分解题目描述本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。把 2019 分解成 3 个各不相同的正整数之和&#xff0c;并且要求每个正整数都不包含数字 2和 4&#xff0c;一共有多少种不同的分解方法&…

Servlet的生命周期和使用

Servlet 课程目标 servlet的生命周期(掌握) servletConfig对象使用(了解) servletContext对象的使用&#xff08;掌握&#xff09; 一.原理 二.Servlet的生命周期 构造 servlet&#xff0c;然后使用 init 方法将其初始化。 第一次发送请求的时候。 执行一次(servlet可以看做…

【Linux】进程优先级前后台理解

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习&#xff08;Ⅰ&#xff09;浅谈Linux下的shell--BASH【Linux…