美文网首页
禁忌算法、遗传算法,HEAD算法求解图染色问题(K-Colori

禁忌算法、遗传算法,HEAD算法求解图染色问题(K-Colori

作者: 缱绻顾 | 来源:发表于2018-04-25 17:21 被阅读0次

具体可参考本人博客GitHub
HEAD算法论文中得到了K=47的结果,但是运算量太大,本人并没有得到。
算法主要参考了 hujinglovekmg《禁忌搜索算法解决图着色问题》和华科吕志鹏老师的教学ppt《Chapter 4 Hybrid Evolutionary Algorithm: A Case Study on Graph Coloring》

核心代码部分

01 判断条件优化

在ppt中,关于禁忌算法的描述如下图:


禁忌搜索算法

步骤3.3,会计算出delt相同的moves,而相同的moves中,tabu & non-tabu moves可能同时存在。而在步骤3.4中,在上述情况存在时,若满足aspiration,则会优先选择tabu moves。而我们希望的,应该是在此种情况时,tabu & non-tabu moves一起随机选择。因此,可以把判断条件写为

if (tmp_delt <= delt && ( iter> h_tabu[j]|| (tmp_delt + f)<best_f)) { // 1&&(2||3)
    if (tmp_delt < delt) {//当前解小于本次迭代最优解,则重新开始保存解
    equ_count = 0;
    delt = tmp_delt;
    }
    equ_delt[equ_count][0] = i;
    equ_delt[equ_count][1] = j;
    equ_count++;
}

在计算完所有的critical one-moves后,再从equ_delt保存的moves中,随机选一个。

    int tmp = rand() % equ_count;//有多个解时,随机选择
    sel_vertex = equ_delt[tmp][0];
    sel_color = equ_delt[tmp][1];

其中,变量delt表示本次迭代的最好解,变量tmp_delt表示当次计算出的delt,变量best_f表示历史最好解。i和 j 分别表示顶点和颜色。
若满足条件(1&&2),则是non-tabu move;若满足条件(1&&3),则是tabu move。

02 随机选解的另一种方法

另有一种并不需要每次都保存下相同delt的move的方法。

if (tmp_delt <= delt && ( iter> h_tabu[j]|| (tmp_delt + f)<best_f)) { // 1&&(2||3){
    if (tmp_delt < delt) {
    equ_count = 1;
    delt = tmp_delt;
    sel_vertex = i;
    sel_color = j;
    }
    if (rand() % equ_count == 0) {
    sel_vertex = i;
    sel_color = j;
  }
  equ_count++;
}                           
  • equ_count==1时,第一个move有1/1的概率取得(此时(rand() % equ_count == 0)的概率为1);
  • equ_count==2时,第一个相等的move有1/1*(1-1/2)=1/2的概率取得,第二个相等的move有1/2的概率取得;
  • equ_count==3时,第一个相等move有1/1*1/2*(1-1/3)=1/3的概率取得,第二个相等的move有1/2*(1-1/3)=1/3的概率取得,第三个相等的move有1/3的概率取得;
    ……
    依次类推.
    但是rand()函数和取余的运算,耗时较大。
if (rand() % equ_count == 0) {
    sel_vertex = i;
    sel_color = j;
}// 耗时约为3/10000毫秒
equ_delt[equ_count][0] = i;
equ_delt[equ_count][1] = j;
//耗时约为7/10000000毫秒

所以在equ_count已知范围,并且范围不大(避免数组出现问题)的情况下,用前节的方法会更好。
在本例中,equ_count的最大值为N*(K-1),N为总顶点数,K为总颜色数。即在一次迭代中,可以得到相同delt的moves,最多有N*(K-1)个。

运行结果

  • i5-7400 CPU,8.00GB
  • vs 2017
  • 采用O2(代码速度)最快编译。vs->属性->c/c++->优化->O2
  • release版本
  • 算例为DSJC500.5.col,颜色数为49
迭代次数 时间(ms) 迭代频率(次/s)
1 6637998 20931 317137
2 23955577 75391 317751
3 38922336 123361 315516
4 96602832 302124 319746
5 12942501 40556 319127
6 2570572 8239 312000
7 139941246 439614 318328
8 218616457 690711 316509
9 52939800 168495 314192
10 7037286 21899 321352
11 9168899 28408 322758
12 13672252 41232 331593
平均值 51917313 163413.4 318834

非核心部分

01 初始化读取文件

算例DSJC500.5.col的格式为

DSJC500.5.col的部分截图
  • “edge”后的数字分别代表顶点总数和边的总数;
  • “e”后为两相邻顶点,其中,第一个数字都是大于第二个数字的,不会有重复。
    因此,需要以空格和换行符为界,把每个词分开。
    代码如下:
#include<string>
#include<fstream>
using namespace std;
void readData(string fileName)
{
    ifstream ifs;
    ifs.open(fileName);
    string str;
    ifs>>str;
    while(!ifs.eof())
    {
        if(str=="edge")
        {
            ifs>>N; //int N,顶点数目
            //其他代码
        }
        if(str=="e")
        {
            int m,n;
            ifs>>m>>n;
            //其他代码
        }
        ifs>>str;
    }
    ifs.close();
}

ifstream ifs;即可实现把文件内容读入不同类型的变量。

02 随机生成初始解

#include<stdlib.h>
    sol = new int[N];//每个顶点的颜色
    srand(time(NULL));
    for (int i = 0; i < N; i++)
    {   
        sol[i] = rand() % K;  //给每个点随机着色    
    }

注意,rand()生成的随机数,实际上是伪随机数,srand()则决定了选择的随机数序列是哪一个。srand(time(NULL))则是按照系统实际,选择随机数序列,若不加上这一句,则每次都会得到相同的初始解。

小结

本文中的禁忌搜索算法的迭代次数与初始解的关系很大,怎样才能迅速收敛到最优解,还需思考。
算例DSJC500.5.col的历史最优解为48,用纯禁忌算法已经很难算出来。
越简单的数据类型,效率越高。最开始我用了vector,后来用了链表,再后来全改成了数组,速度有了很大的提升。

相关文章

  • 禁忌算法、遗传算法,HEAD算法求解图染色问题(K-Colori

    具体可参考本人博客GitHubHEAD算法论文中得到了K=47的结果,但是运算量太大,本人并没有得到。算法主要参考...

  • awesome 禁忌搜索

    禁忌搜索(Tabu Search)算法及python实现 实验10 禁忌搜索算法求解tsp问题

  • 2019-01-28

    Local Search 常用的local search 算法有 爬山算法, 模拟退火算法, 遗传算法和禁忌查找等...

  • 遗传算法

    参考文献:知乎遗传算法 编码解码知识 实现遗传算法的第一步就是明确对求解问题的编码和解码方式。对于函数优化问题,一...

  • 2019-04-16派森学习第148天

    遗传算法中的crossover和VRP问题中的2-Opt算法。 交叉(crossover) 两个染色体的某一相同位...

  • 数学建模

    1.启发式算法 它主要包括禁忌搜索,模拟退火,遗传算法,神经网络,蚁群算法 模拟退火算法 Metropolis准则...

  • 遗传算法(Genetic Algorithm ,GA)学习笔记

    1 遗传算法的概念 1.1 遗传算法的科学定义   遗传算法(Genetic Algorithm, GA) 是模拟...

  • 遗传算法综述

    作者:刘衍 【嵌牛导读】:遗传算法简介与其应用 【嵌牛鼻子】:遗传算法 优化算法 java 【嵌牛提问】:遗传算法...

  • TSP问题—启发式遗传算法

    本章涉及知识点1、达尔文进化论2、遗传算法的思想3、遗传算法下的TSP模型4、染色体的编码5、种群的初始化6、适应...

  • 遗传算法helloworld级别的python实现(结果可视化)

    问题描述: 用遗传算法求使得F(X)最大的X,问题来源:莫烦的python教程之遗传算法 最终效果:

网友评论

      本文标题:禁忌算法、遗传算法,HEAD算法求解图染色问题(K-Colori

      本文链接:https://www.haomeiwen.com/subject/fiselftx.html