Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 1575|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-15 14:42:33 | 显示全部楼层 |阅读模式

      一、前言

      关于本文中用到的这种图着色解决方法,不知道有没前人提出过。如果说没人提出过,那么就算是一个新的解决方法吧,具体性能对比没深入研究,但是求出的解基本是和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:\timFilm\test.txt')
    18     print('')
    19     for i in edge:
    20         print('    ', end='')
    21         for j in i:
    22             print(j, end='\t\t')
    23         print('\n')
    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 == max(edgeNum) and edgeNum != 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 == 0:
    47                             # 为不冲突的顶点着色
    48                             color = colorNum + 1
    49                             disabled.append(i)
    50                             edgeNum = 0
    51                             # 增加当前颜色的禁忌点
    52                             temp = [x + y for (x, y) in zip(edge, 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()

     

     

       

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-21 18:50 , Processed in 0.069525 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表