65.9K
CodeProject is changing. Read more.
Home

Graph coloring using Recursive-Large-First (RLF) algorithm

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.20/5 (5 votes)

Jun 26, 2010

CPOL

1 min read

viewsIcon

83975

downloadIcon

2496

An implement of the Recursive-Large_First graph coloring in C/C++ language.

What is graph coloring

A coloring of a simple graph is the assignment of a color to each vertex of the graph so that no two adjacent vertices are assigned the same color. The chromatic number of a graph is the least number of colors needed for coloring of the graph. The problem here is to color a graph with its chromatic number.

Suppose that we are coloring a simple undirected graph.

Given a graph with n vertices. This algorithm will color each vertex with a number. F(x) is the color of vertex x.

In this article, I am using the Recursive-Largest-First algorithm by F. T. Leighton. Here is the pseudo code:

colornumber = 0; //number of used colors
    while (number_of_uncolored_vertex > 0){
        determine a vertex x of maximal degree in G;
        colornumber = colornumber + 1;
        F(x) = colornumber;
        NN = set of non-neighbors of x;
        while (cardinality_of_NN > 0){ //Find y in NN to be contracted into x
        maxcn =  1; //becomes the maximal number of common neighbors
        ydegree =  1; //becomes degree(y)
        for every vertex z in NN{
        cn=number of common neighbors of z and x;
        if (cn > maxcn or (cn == maxcn and degree(z) < ydegree)){
            y = z;
            ydegree = degree(y);
            maxcn = cn;
            }
        }
        if (maxcn == 0){ //in this case G is unconnected
            y=vertex of maximal degree in NN;
        }
        F(y) = colornumber;
        contract y into x;
        update the set NN of non-neighbors of x;
    }
    G = G   x; //remove x from G
}

Data structure

We can use an adjacency matrix to store the adjacent status of the vertices. If the graph has n vertices, there will be an n-degree square adjacency matrix.

a[i][j] will be 1 if the ith and jth vertices are adjacent, and 0 otherwise. For example:

gca_1.png

// below is the adjacency matrix
7 // number of vertices
0 1 1 0 1 1 0
1 0 0 1 0 1 1
1 0 0 1 1 1 0
0 1 1 0 0 1 1
1 0 1 0 0 0 1
1 1 1 1 0 0 0
0 1 0 1 1 0 0

We will color the vertices with numbers instead of color, uUsing an array color[n] to store the numbers. For example: color[0] stores the color number of the first vertex, so color[0] = 3 means we colored vertex 1 with color 3.

C/C++ code

Here is the ariables declaration:

// this program will work with graphs
// of which number of vertices is smaller or equal to 100
const int MAX = 100;
// necessary variables
// n is the number of vertices of the graph
int n;
// a[n][n] is the adjacency matrix of the graph
// a[i][j] = 1 if i-th and j-th vertices are adjacent
int a[MAX][MAX];
// array color[n] stores the colors of the vertices
// color[i] = 0 if we 've not colored it yet
int color[MAX];
// array degree[n] stores the degrees of the vertices
int degree[MAX];
// array NN[] stores all the vertices that is not adjacent to current vertex
int NN[MAX];
// NNCount is the number of that set
int NNCount;
// unprocessed is the number of vertices with which we 've not worked
int unprocessed;

Here is the coloring function:

// processing function
void Coloring()
{
    int x,y;
    int ColorNumber = 0;
    int VerticesInCommon = 0;
    while (unprocessed>0) // while there is an uncolored vertex
    {
        x = MaxDegreeVertex(); // find the one with maximum degree
        ColorNumber ++;
        color[x] = ColorNumber; // give it a new color        
        unprocessed --;
        UpdateNN(ColorNumber); // find the set of non-neighbors of x
        while (NNCount>0)
        {
        // find y, the vertex has the maximum neighbors in common with x
        // VerticesInCommon is this maximum number
            y = FindSuitableY(ColorNumber, VerticesInCommon);
        // in case VerticesInCommon = 0
        // y is determined that the vertex with max degree in NN
            if (VerticesInCommon == 0)
                y = MaxDegreeInNN();
        // color y the same to x
            color[y] = ColorNumber;
            unprocessed --;
            UpdateNN(ColorNumber);
        // find the new set of non-neighbors of x
        }
    }
}

Other necessary functions:

// function that reads input from file named "input.txt" in the same folder
void GetInput()
{
    ifstream in("input.txt");
    in >> n; // read the number of vertices first
    for (int i=0; i < n; i++) // then read the adjacency matrix        
        for (int j=0; j < n; j++)
            in >> a[i][j]; // read the element one by one
    in.close();
}

// initializing function
void Init()
{
    for (int i=0; i < n; i++)
    {
        color[i] = 0; // be sure that at first, no vertex is colored
        degree[i] = 0; // count the degree of each vertex
        for (int j = 0; j < n; j++)
            if (a[i][j] == 1) // if i-th vertex is adjacent to another
                degree[i] ++; // increase its degree by 1
    }
    NNCount = 0; // number of element in NN set
    unprocessed = n;
}

// this function finds the unprocessed vertex of which degree is maximum
int MaxDegreeVertex()
{
    int max = -1;
    int max_i;
    for (int i =0; i < n; i++)
        if (color[i] == 0)
            if (degree[i]>max)
            {
                max = degree[i];
                max_i = i;
            }
    return max_i;
}

// this function is for UpdateNN function
// it reset the value of scanned array
void scannedInit(int scanned[MAX])
{
    for (int i=0; i < n; i++)
        scanned[i] = 0;
}

// this function updates NN array
void UpdateNN(int ColorNumber)
{
    NNCount = 0;
    // firstly, add all the uncolored vertices into NN set
    for (int i=0; i < n; i++)
        if (color[i] == 0)
        {
            NN[NNCount] = i;
            NNCount ++; // when we add a vertex, increase the NNCount
        }
    // then, remove all the vertices in NN that
    // is adjacent to the vertices colored ColorNumber
    for (int i=0; i < n; i++)
        if (color[i] == ColorNumber) // find one vertex colored ColorNumber
            for (int j=0; j < NNCount; j++)
                while (a[i][NN[j]] == 1)
                // remove vertex that adjacent to the found vertex
                {
                    NN[j] = NN[NNCount - 1];
                    NNCount --; // decrease the NNCount
                }
}

// this function will find suitable y from NN
int FindSuitableY(int ColorNumber, int& VerticesInCommon)
{
    int temp,tmp_y,y;
    // array scanned stores uncolored vertices
    // except the vertex is being processing
    int scanned[MAX];
    VerticesInCommon = 0;
    for (int i=0; i < NNCount; i++) // check the i-th vertex in NN
    {
        // tmp_y is the vertex we are processing
        tmp_y = NN[i];
        // temp is the neighbors in common of tmp_y
        // and the vertices colored ColorNumber
        temp = 0;
        scannedInit(scanned);
        //reset scanned array in order to check all 
        //the vertices if they are adjacent to i-th vertex in NN
        for (int x=0; x < n; x++)
            if (color[x] == ColorNumber) // find one vertex colored ColorNumber
                for (int k=0; k < n; k++)
                    if (color[k] == 0 && scanned[k] == 0)
                        if (a[x][k] == 1 && a[tmp_y][k] == 1)
                        // if k is a neighbor in common of x and tmp_y
                        {
                            temp ++;
                            scanned[k] = 1; // k is scanned
                        }
        if (temp > VerticesInCommon)
        {
            VerticesInCommon = temp;
            y = tmp_y;
        }
    }
    return y;
}

// find the vertex in NN of which degree is maximum
int MaxDegreeInNN()
{
    int tmp_y; // the vertex has the current maximum degree
    int temp, max = 0;
    for (int i=0; i < NNCount; i++)
    {
        temp = 0;
        for (int j=0; j < n; j++)
            if (color[j] == 0 && a[NN[i]][j] == 1)
                temp ++;
        if (temp>max) // if the degree of vertex NN[i] is higher than tmp_y's one
        {
            max = temp; // assignment NN[i] to tmp_y
            tmp_y = NN[i];
        }
    }
    if (max == 0) // so all the vertices have degree 0
        return NN[0];
    else // exist a maximum, return it
        return tmp_y;
}

// print out the output
void PrintOutput()
{
    for (int i=0; i < n; i++)
    // element i-th of array color stores the color of (i+1)-th vertex
        cout << "Vertex " << i+1 
             << " is colored " << color[i] << endl;
}

// main function
void main()
{
    GetInput(); // read the input adjacency matrix from file
    Init(); // initialize the data : degree, color array ..
    Coloring(); // working function
    PrintOutput(); // print the result onto the console lines
    getch();
}

Result

This is the result for the above example:

gcq_3.png

gca_4.png

Reference

  • Graph coloring in Wiki
  • Leighton, F. T., A graph coloring algorithm for large scheduling problems, Journal of Research of the National Bureau of Standards 84 (1979).