• 解决图着色问题 python代码实现


      一、前言

      关于本文中用到的这种图着色解决方法,不知道有没前人提出过。如果说没人提出过,那么就算是一个新的解决方法吧,具体性能对比没深入研究,但是求出的解基本是和Graph Coloring Instances网站里面的最优解一样的。

      我们都知道,很多问题都可以转化成图着色问题来进行解决,所以本文的例子直接是无向图。

      二、解决思路  

      不太成熟的想法:

      要使得相邻点的颜色不同,着色方案有很多种,那么究竟哪种着色方案使用的颜色最少呢?

      首先最开始看到这个问题时,我最开始的思路是每次用尽量少的颜色给尽量多的点上色。

      

    ->->->->->

      以上是个简单的图,我选用的步骤为:

      1、找出度最大的顶点2、3、5(度均为4)。

      2、对2着色C1,然后遍历相邻点

      3、给1着色C2

      4、给3着色C2,和1冲突,着色C3

      5、给5着色C2,不冲突

      6、给4着色C2,与5冲突,着色C3

      7、给4着色C1,不冲突

      从一次性上完一种颜色入手:

      本来是想实现上一个想法的,但是在梳理的过程中,有一个新的想法,即是通过与以前运筹学课程上学过的方法结合,较为高效且高质量地解决问题。

      步骤如下:

      步骤一、给未上色点集中度最大的顶点上色Ci,生成可同色点集,为与该顶点不相邻且未上色的点的集合

      步骤二、遍历可同色点集,给点集中的点上色Ci,每上完一个点就生成一次可同色点集,为与上Ci点不相邻且未上色的点的集合,直到可同色点集为空

      步骤三、更新未上色点集,i=i+1,回到步骤一

      例:以下是myciel3.col数据的图,求最少能上几种颜色。

      

      邻接矩阵为

      

       每个顶点的度为4、4、4、4、4、3、3、3、3、3、5,度最大的顶点为第11个顶点。

      1、给V11上色C1,可同色集为{V1,V2,V3,V4,V5}

      2、给V1上色C1,可同色集为{V3,V5}

       3、给V3上色C1,可同色集为{}

      4、给V2上色C2,可同色集为{V4,V7,V9,V10}  

       5、给V4上色C2,可同色集为{V7,V9}

      6、给V7上色C2,可同色集为{V9}

      7、给V9上色C2,可同色集为{}

       8、给V5上色C3,可同色集为{V6,V8,V10}

      9、给V6上色C3,可同色集为{V10}

      10、给V10上色C3,可同色集为{}

      11、给V8上色C4,可同色集为{}

      上色后的图:

      

      颜色使用了4种,和已知最优解一样。

      三、python代码实现

      

     1 def getAdjMatrix(path):
     2     edge = []
     3     pointNum = 0
     4     with open(path, 'r') as fp:
     5         for line in fp.readlines():
     6             if line.startswith('p'):
     7                 pointNum = int(line.split()[2])
     8                 for i in range(pointNum):
     9                     edge.append([0 for i in range(pointNum)])
    10             if line.startswith('e') and pointNum > 0:
    11                 edge[int(line.split()[1]) - 1][int(line.split()[2]) - 1] = 1
    12                 edge[int(line.split()[2]) - 1][int(line.split()[1]) - 1] = 1
    13     return edge, pointNum
    14 
    15 
    16 def main():
    17     edge, pointNum = getAdjMatrix(r'F:	imFilm	est.txt')
    18     print('')
    19     for i in edge:
    20         print('    ', end='')
    21         for j in i:
    22             print(j, end='		')
    23         print('
    ')
    24     colorNum = 0
    25     disabled = []
    26 
    27     # 初始化color列表,用以记录每个顶点的着色情况
    28     color = []
    29     for i in range(pointNum):
    30         color.append(0)
    31     edgeNum = [sum(e) for e in edge]
    32     for k in range(pointNum):
    33         # 获取顶点最大度的索引值
    34         maxEdgePoint = [i for i in range(pointNum) if edgeNum[i] == max(edgeNum) and edgeNum[i] != 0]
    35         # 遍历最大度
    36         for p in maxEdgePoint:
    37             if p not in disabled:
    38                 # 选取还未着色且度最大的点p开始着色
    39                 color[p] = colorNum + 1
    40                 disabled.append(p)
    41                 edgeNum[p] = 0
    42                 # temp用于查找该颜色可用来着色的下一个顶点
    43                 temp = edge[p]
    44                 for i in range(pointNum):
    45                     if i not in disabled:
    46                         if temp[i] == 0:
    47                             # 为不冲突的顶点着色
    48                             color[i] = colorNum + 1
    49                             disabled.append(i)
    50                             edgeNum[i] = 0
    51                             # 增加当前颜色的禁忌点
    52                             temp = [x + y for (x, y) in zip(edge[i], temp)]
    53                 # 需要新颜色
    54                 colorNum = colorNum + 1
    55 
    56         # 每个顶点都已经着色
    57         if 0 not in color:
    58             break
    59     print(color)
    60     print(colorNum)
    61 
    62 
    63 main()

       

  • 相关阅读:
    Matplotlib学习
    Docker win10安装
    pandas读取文件报错
    python特殊函数__str__、__repr__和__len__
    tar命令总结
    lamp服务器站点目录被植入广告代码处理
    linux简单测试
    中国剩余定理
    牛客暑期第六场G /// 树形DP 最大流最小割定理
    逆元 组合A(n,m) C(n,m)递推 隔板法
  • 原文地址:https://www.cnblogs.com/zhuangzi101/p/10843610.html
Copyright © 2020-2023  润新知