图着色算法详解

图着色算法详解


图着色算法简介

        图的 m- 着色判定问题 —— 给定无向连通图 G m 种不同的颜色。用这些颜色为图 G 的各顶点着色,每个顶点着一种颜色,是否有一种着色法使 G 中任意相邻的 2 个顶点着不同颜色 ?

       图的m-着色优化问题——若一个图最少需要m种颜色才能使图中任意相邻的2个顶点着不同颜色,则称这个数m为该图的色数。求一个图的最小色数m的问题称为m-着色优化问题。


 

算法实现

算法描述:color[n]存储n个顶点的着色方案,可以选择的颜色为1到m。
当t=1时,对当前第t个顶点开始着色:若t>n,则已求得一个解,输出着色方案即可。否则,依次对顶点t着色1-m, 若t与所有其它相邻顶点无颜色冲突,则继续为下一顶点着色;否则,回溯,测试下一颜色。

代码如下:

#include<stdio.h>

int color[100];
bool ok(int k,int c[][100]) //判断顶点k的着色是否发生冲突
{
  int i,j;
  for(i=1;i<k;i++)
  {
    if(c[k][i]==1&&color[i]==color[k]) //同时满足边的关联关系和颜色冲突
		return false;
  }
  return true;
}

void graphcolor(int n,int m,int c[][100])
{
  int i,k;
  for(i=1;i<=n;i++)
	  color[i]=0;
  k=1;
  while(k>=1) //最后回溯的结果k=0,即已经输出了所有可能的配色方案
  {
   color[k]=color[k]+1;
   while(color[k]<=m)
	   if(ok(k,c)) break;
	   else color[k]=color[k]+1; //搜索下一个颜色
   if(color[k]<=m&&k==n)
   {
     for(i=1;i<=n;i++)
		 printf("%d ",color[i]);
	 printf("\n");
   }
   else if(color[k]<=m&&k<n)
	   k=k+1; //处理下一个顶点
   else
   {        //else是在上面k==n条件执行之后运行的,即已经输出了一种配色方案的情况下
     color[k]=0;
	 k=k-1;//回溯
   }
  }
}
void main()
{
  int i,j,n,m;
  int c[100][100];//存储n个顶点的无向图的数组
  printf("输入顶点数n和着色数m:\n");
  scanf("%d %d",&n,&m);
  printf("输入无向图的邻接矩阵: \n");
  for(i=1;i<=n;i++)
	  for(j=1;j<=n;j++)
		  scanf("%d",&c[i][j]);
  printf("着色所有可能的解:\n");
  graphcolor(n,m,c);
}

图着色算法的寄存器分配技术

    利用相交图(interference graph)来表示程序变量的生命期是否相交,将寄存器分配给变量的问题,可以近似地看成是给相交图着色:相交图中,相交的节点不能着同一颜色;每一种颜色对应一个寄存器。Chaitin等人最早提出了基于图着色的寄存器分配方法其着色思路采用了Kempe的着色方法,即,任意一个邻居节点数目少于k的节点,都能够被k着色。判断一个图是否能够被k(k>=3)种颜色着色,即k着色问题,被Karp证明是一个NP-complete问题。
 
    但是,寄存器分配不仅仅是图着色的问题。当寄存器数目不足以分配某些变量时,就必须将这些变量溢出到内存中,该过程成为spill。最小化溢出代价的问题,也是一个NP-complete问题。如果简化该问题——假设所有溢出代价相等,那么最小化溢出代价的问题,等价于k着色问题,仍然是NP-complete问题。
    此外,如果两个变量的生命期仅仅因为出现在同一个拷贝指令中而相邻,那么,通过将这两个变量分配到同一个寄存器,就可以消除该拷贝指令,成为coalescing。这个方向的努力在Chaitin的文章以后的1/4个世纪,成为推动寄存器分配的主要动力之一,涌现出了包括aggressive coalescing,conservative coalescing和optimistic coalescing。但是,将两个变量分配到同一个寄存器,等价于将这两个变量合并成同一个变量,生命期合并,因而会加剧相交图的聚簇现象,降低相交图的可着色性。Bouchez等人证明了目前的coalescing问题都是NP-complete的。
    为了降低相交图的聚簇现象,提高相交图的可着色性,可以通过将变量拷贝给一个临时变量,并将以后对该变量的使用替换成对该临时变量的使用,从而将一个变量的生命期分解成两个变量的生命期,称为live range splitting。显然,这是一个与coalescing的作用相反的过程。Bouchez等人考虑了该方法的复杂度。
    此外,寄存器分配还需要考虑寄存器别名(aliasing)和预着色(pre-coloring)的问题。寄存器别名是指,在某些体系结构中,一个寄存器的赋值可能会影响到另外一个寄存器。比如,在x86中,对AX寄存器的赋值,会影响AL和AH寄存器。预着色是指,某些变量必须被分配到特定的寄存器。比如,许多体系结构会采用特定寄存器来传递函数参数。
    George和Appel发展了Chaitin的算法,更好地考虑了coalescing过程和赋值过程,以及各过程之间的迭代,在基于图着色的寄存器分配方法中具有广泛的影响。
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页