Graph Coloring
Graph Coloring
Graph Coloring
Graph Coloring refers to the problem of coloring vertices of a graph in such a way that no two adjacent
vertices have the same color. This is also called the vertex coloring problem. If coloring is done using
at most m colors, it is called m-coloring.
Chromatic Number: The chromatic number of G, is the minimal number of colours necessary for
vertex coloring of graph and is denoted by X(G).
For example, the following can be colored a minimum of 2 colors and 3 colors.
We’re given a graph G consisting of V vertices and E edges connecting them. We’re asked to assign a
colour to each vertex of the graph such that the following conditions are fulfilled:
1. No two adjacent vertices have the same colour. Remember that two vertices are considered
adjacent if an edge connects them.
Since the problem is considered NP-Complete, no efficient algorithm can solve all types of graphs.
However, we’ll present following Greedy Approache that can give close to optimal solutions. However,
other approaches are also available. For example DSatur Approach (out of syllabus), Backtracking.
Greedy Approach
Let’s discuss the theoretical idea over an example and then jump into the implementation.
Theoretical Idea
In the greedy approach, we find a random ordering for the graph vertices. In addition, we number the
colours starting from 1. Then, we iterate over the vertices individually and assign the feasible colour
with the lowest number to each.
Let’s consider the same graph that we presented before. Assume we use the following vertex ordering:
{1, 2, 3, 4, 5, 6, 7}
We define a function that takes graph G and the array of vertices V in the order in which to apply the
colouring. We start by defining an array called color filled with zeros, indicating that we initially don’t
have any colour assigned for the vertices.
Then, we iterate over all vertices. For each vertex, we iterate over all its edges and add the child’s
colour to the usedColors set. After that, we move to find the correct colour to assign for the current
vertex.
We start the currentColor with zero and perform multiple iterations to do that. In each iteration, we
increase the currentColor by one and check if it’s not part of the userColors. If so, we assign it to the
current vertex.
Finally, we return the color array containing the solution to our problem.
Time Complexity
Throughout the algorithm, we iterate over each node exactly once. We iterate over all its edges for each
vertex and add the colours to a set. Thus, each edge is checked twice; once from each vertex, it
connects. After that, we iterate over the colours to find the accepted one with the lowest number. Since
each edge can make at most one colour invalid, we’ll perform E steps before finding a valid solution
for the vertex.
Therefore, assuming we use a HashSet with a constant complexity for adding elements, the overall time
complexity will be O(V + E).
M-Coloring Problem
Given an undirected graph and a number m, the task is to color the given graph with at most m colors
such that no two adjacent vertices of the graph are colored with the same color
Note: Here coloring of a graph means the assignment of colors to all vertices
• As shown in the above diagram, all the solutions are shown by coloring the first node in Red.
• Let’s choose Green color for the first node and explore the options for the remaining nodes.
• As shown in the above diagram, all the solutions are shown by coloring the first node in Green.
• Let’s choose Blue color for the first node and explore the options for the remaining nodes.
Below is the implementation of the above approach:
#include <stdbool.h>
#include <stdio.h>
#define V 4
/*
A utility function to check if the current color assignment is safe for vertex v i.e. checks whether the edge exists or not (i.e,
graph[v][i]==1). If exist then checks whether the color to be filled in the new vertex(c is sent in the parameter) is already
used by its adjacent vertices(i-->adj vertices) or not (i.e, color[i]==c)
*/
bool isSafe(int v, bool graph[V][V], int color[], int c)
{
for (int i = 0; i < V; i++)
if (graph[v][i] && c == color[i])
return false;
return true;
}
/*
This function solves the m Coloring problem using Backtracking. It mainly uses graphColoringUtil() to solve the problem.
It returns false if the m colors cannot be assigned, otherwise return true and prints assignments of colors to all vertices.
Please note that there may be more than one solutions, this function prints one of the feasible solutions.
*/
bool graphColoring(bool graph[V][V], int m)
{
// Initialize all color values as 0.
// This initialization is needed.
// correct functioning of isSafe().
int color[V];
for (int i = 0; i < V; i++)
color[i] = 0;
// Driver code
int main()
{
/*
Create following graph and test whether it is 3 colorable
(3)-------(2)
| / |
| / |
| / |
(0)-------(1)
*/
bool graph[V][V] = {
{ 0, 1, 1, 1 },
{ 1, 0, 1, 0 },
{ 1, 1, 0, 1 },
{ 1, 0, 1, 0 },
};
int m = 3; // Number of colors
// Function call
graphColoring(graph, m);
return 0;
}
Greedy-Coloring
C programming language implementation of Greedy Coloring, a graph theory algorithm.
In the study of graph coloring problems in mathematics and computer science, a greedy coloring is a
coloring of the vertices of a graph formed by a greedy algorithm that considers the vertices of the graph
in sequence and assigns each vertex its first available color. Greedy colorings can be found in linear
time, but they do not in general use the minimum number of colors possible.
#include<stdio.h>
typedef struct interval
{
int num,start,end,degree,color;
int* Edges;
}Interval;
void GreedyColoring();
void addEdge(Interval, Interval);
int partition(Interval *, int, int);
void quick_sort(Interval *, int, int);
void swap(Interval*, Interval*);
void main()
{
GreedyColoring();
}
void GreedyColoring()
{
int i,j, amount,last=1, MaxDegree=0, MinDegree = 0,Edges=0, Chrom=1;
printf("Please input amount:\n");
scanf_s("%d", &amount);
Interval* list = (Interval*)malloc(amount * sizeof(Interval));
printf("Please enter %d intervals (start - end)\n", amount);
for (i = 0; i < amount; i++)//Fill the list
{
list[i].num = i;
scanf_s("%d", &((list + i)->start));
scanf_s("%d", &((list + i)->end));
list[i].degree = 0;
list[i].Edges = (int*)calloc(amount, sizeof(int));
list[i].color = 1;
}
printf("The intervals family is:\n");
for (i = 0; i < amount; i++)//Prints the intervals family
{
printf("[%d , %d]", (list + i)->start, (list + i)->end);
if (i != amount - 1)
printf(" , ");
}
quick_sort(list, 0, amount-1);//Order list by start time (ascending)
printf("\nOrdered by start list:\n");
for (i = 0; i < amount; i++)//Prints the intervals family
{
printf("[%d , %d]", (list + i)->start, (list + i)->end);
if (i != amount - 1)
printf(" , ");
}
//----------------------------------------------------------
for (i = 0; i < amount; i++)//coloring loop
{
last = 1;
for (j = 0; j < i; j++)
{
if (((list[i].end) < (list[j].start)) || (list[j].end < list[i].start))
{
continue;
}
else
{
addEdge(list[i], list[j]);
Edges++;
list[i].degree++;
list[j].degree++;
last++;
if (list[i].color == list[j].color)
list[i].color = last;
}
}
}
for (i = 0; i < amount; i++)
{
if (list[i].degree <= MinDegree)
MinDegree = list[i].degree;
if (list[i].degree >= MaxDegree)
MaxDegree = list[i].degree;
if (list[i].color >= Chrom)
Chrom = list[i].color;
}
//----------------------------------------------------
printf("\nG Edges: %d\nChromatic Number Of G:%d\nMax Degree: %d\nMin Degree: %d\nG
Complement Edges: %d\nMax Degree Of G Complement: %d\nMin Degree Of G Complement: %d\
n",Edges,Chrom,MaxDegree,MinDegree,(amount*(amount-1)/2)-Edges,amount-1-MinDegree,amount-
1-MaxDegree);
for (i = 0; i < amount; i++)
{
printf("\n [%d,%d]:", list[i].start,list[i].end);
printf(" degree :%d", list[i].degree);
printf(" color :'%d'", list[i].color);
printf("\n[");
for (j = 0; j < amount; j++)
{
printf("%d ", list[i].Edges[j]);
}
printf("]\n");
free(list[i].Edges);
}
printf("Optional coloring:\n");
for (j = 1; j <= Chrom; j++)
{
printf("Color '%d' : ", j);
printf("{");
for (i = 0; i < amount; i++)
{
if (list[i].color == j)
printf("[%d , %d]", (list + i)->start, (list + i)->end);
}
printf("}");
printf("\n");
}
free(list);
}