Open In App

Edge Coloring of a Graph

In graph theory, edge coloring of a graph is an assignment of “colors” to the edges of the graph so that no two adjacent edges have the same color with an optimal number of colors. Two edges are said to be adjacent if they are connected to the same vertex. There is no known polynomial time algorithm for edge-coloring every graph with an optimal number of colors. 

Nevertheless, a number of algorithms have been developed that relax one or more of these criteria, they only work on a subset of graphs, or they do not always use an optimal number of colors, or they do not always run in polynomial time.

Examples

Input : u1 = 1, v1 = 4 
        u2 = 1, v2 = 2
        u3 = 2, v3 = 3
        u4 = 3, v4 = 4
Output : Edge 1 is of color 1
         Edge 2 is of color 2
         Edge 3 is of color 1
         Edge 4 is of color 2

The above input shows the pair of vertices(ui, vi)
who have an edge between them. The output shows the color 
assigned to the respective edges.

Edge colorings are one of several different types of graph coloring problems. The above figure of a Graph shows an edge coloring of a graph by the colors green and black, in which no adjacent edge have the same color.

Below is an algorithm to solve the edge coloring problem which may not use an optimal number of colors: 

Algorithm: 

  1. Use BFS traversal to start traversing the graph.
  2. Pick any vertex and give different colors to all of the edges connected to it, and mark those edges as colored.
  3. Traverse one of it’s edges.
  4. Repeat step to with a new vertex until all edges are colored.

Below is the implementation of above approach: 




// C++ program to illustrate Edge Coloring
#include <bits/stdc++.h>
using namespace std;
 
// function to determine the edge colors
void colorEdges(int ptr, vector<vector<pair<int, int> > >& gra,
                vector<int>& edgeColors, bool isVisited[])
{
    queue<int> q;
    int c = 0;
 
    unordered_set<int> colored;
 
    // return if isVisited[ptr] is true
    if (isVisited[ptr])
        return;
 
    // Mark the current node visited
    isVisited[ptr] = 1;
 
    // Traverse all edges of current vertex
    for (int i = 0; i < gra[ptr].size(); i++) {
        // if already colored, insert it into the set
        if (edgeColors[gra[ptr][i].second] != -1)
            colored.insert(edgeColors[gra[ptr][i].second]);
    }
 
    for (int i = 0; i < gra[ptr].size(); i++) {
        // if not visited, inset into the queue
        if (!isVisited[gra[ptr][i].first])
            q.push(gra[ptr][i].first);
 
        if (edgeColors[gra[ptr][i].second] == -1) {
            // if col vector -> negative
            while (colored.find(c) != colored.end())
 
                // increment the color
                c++;
 
            // copy it in the vector
            edgeColors[gra[ptr][i].second] = c;
 
            // then add it to the set
            colored.insert(c);
            c++;
        }
    }
 
    // while queue's not empty
    while (!q.empty()) {
        int temp = q.front();
        q.pop();
 
        colorEdges(temp, gra, edgeColors, isVisited);
    }
 
    return;
}
 
// Driver Function
int main()
{
    set<int> empty;
 
    // declaring vector of vector of pairs, to define Graph
    vector<vector<pair<int, int> > > gra;
 
    vector<int> edgeColors;
 
    bool isVisited[100000] = { 0 };
 
    // Enter the Number of Vertices
    // and the number of edges
    int ver = 4;
    int edge = 4;
 
    gra.resize(ver);
    edgeColors.resize(edge, -1);
 
    // Enter edge & vertices of edge
    // x--; y--;
    // Since graph is undirected, push both pairs
    // (x, y) and (y, x)
    // graph[x].push_back(make_pair(y, i));
    // graph[y].push_back(make_pair(x, i));
    gra[0].push_back(make_pair(1, 0));
    gra[1].push_back(make_pair(0, 0));
 
    gra[1].push_back(make_pair(2, 1));
    gra[2].push_back(make_pair(1, 1));
 
    gra[2].push_back(make_pair(3, 2));
    gra[3].push_back(make_pair(2, 2));
 
    gra[0].push_back(make_pair(3, 3));
    gra[3].push_back(make_pair(0, 3));
 
    colorEdges(0, gra, edgeColors, isVisited);
 
    // printing all the edge colors
    for (int i = 0; i < edge; i++)
        cout << "Edge " << i + 1 << " is of color "
             << edgeColors[i] + 1 << "\n";
 
    return 0;
}




import java.util.*;
 
public class Main {
    public static void colorEdges(int ptr, ArrayList<ArrayList<Pair<Integer, Integer>>> gra, ArrayList<Integer> edgeColors, boolean[] isVisited) {
        Queue<Integer> q = new LinkedList<>();
        int c = 0;
        Set<Integer> colored = new HashSet<>();
 
        if (isVisited[ptr]) {
            return;
        }
 
        isVisited[ptr] = true;
 
        for (int i = 0; i < gra.get(ptr).size(); i++) {
            if (edgeColors.get(gra.get(ptr).get(i).getValue()) != -1) {
                colored.add(edgeColors.get(gra.get(ptr).get(i).getValue()));
            }
        }
 
        for (int i = 0; i < gra.get(ptr).size(); i++) {
            if (!isVisited[gra.get(ptr).get(i).getKey()]) {
                q.add(gra.get(ptr).get(i).getKey());
            }
 
            if (edgeColors.get(gra.get(ptr).get(i).getValue()) == -1) {
                while (colored.contains(c)) {
                    c++;
                }
 
                edgeColors.set(gra.get(ptr).get(i).getValue(), c);
                colored.add(c);
                c++;
            }
        }
 
        while (!q.isEmpty()) {
            int temp = q.poll();
            colorEdges(temp, gra, edgeColors, isVisited);
        }
 
        return;
    }
 
    public static void main(String[] args) {
        // Enter the Number of Vertices and the number of edges
        int ver = 4;
        int edge = 4;
 
        ArrayList<ArrayList<Pair<Integer, Integer>>> gra = new ArrayList<>(ver);
        for (int i = 0; i < ver; i++) {
            gra.add(new ArrayList<>());
        }
 
        ArrayList<Integer> edgeColors = new ArrayList<>(Collections.nCopies(edge, -1));
        boolean[] isVisited = new boolean[100000];
 
        gra.get(0).add(new Pair<>(1, 0));
        gra.get(1).add(new Pair<>(0, 0));
 
        gra.get(1).add(new Pair<>(2, 1));
        gra.get(2).add(new Pair<>(1, 1));
 
        gra.get(2).add(new Pair<>(3, 2));
        gra.get(3).add(new Pair<>(2, 2));
 
        gra.get(0).add(new Pair<>(3, 3));
        gra.get(3).add(new Pair<>(0, 3));
 
        colorEdges(0, gra, edgeColors, isVisited);
 
        // printing all the edge colors
        for (int i = 0; i < edge; i++) {
            System.out.println("Edge " + (i + 1) + " is of color " + (edgeColors.get(i) + 1));
        }
    }
}
 
class Pair<K, V> {
    public final K key;
    public final V value;
 
    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }
 
    public K getKey() {
        return key;
    }
 
    public V getValue() {
        return value;
    }
}




# Python3 program to illustrate Edge Coloring
 
from queue import Queue
# function to determine the edge colors
def colorEdges(ptr, gra, edgeColors, isVisited):
    q=Queue()
    c = 0
 
    colored=set()
 
    # return if isVisited[ptr] is true
    if (isVisited[ptr]):
        return
 
    # Mark the current node visited
    isVisited[ptr] = True
 
    # Traverse all edges of current vertex
    for i in range(len(gra[ptr])) :
        # if already colored, insert it into the set
        if (edgeColors[gra[ptr][i][1]] != -1):
            colored.add(edgeColors[gra[ptr][i][1]])
     
 
    for i in range(len(gra[ptr])) :
        # if not visited, inset into the queue
        if not isVisited[gra[ptr][i][0]]:
            q.put(gra[ptr][i][0])
 
        if (edgeColors[gra[ptr][i][1]] == -1) :
            # if col vector -> negative
            while c in colored:
 
                # increment the color
                c+=1
 
            # copy it in the vector
            edgeColors[gra[ptr][i][1]] = c
 
            # then add it to the set
            colored.add(c)
            c+=1
         
     
 
    # while queue's not empty
    while not q.empty() :
        temp = q.get()
 
        colorEdges(temp, gra, edgeColors, isVisited)
     
 
    return
 
 
# Driver Function
if __name__=='__main__':
    empty=set()
 
    # declaring vector of vector of pairs, to define Graph
    gra=[]
 
    edgeColors=[]
 
    isVisited=[False]*100000
 
    # Enter the Number of Vertices
    # and the number of edges
    ver = 4
    edge = 4
 
    gra=[[] for _ in range(ver)]
    edgeColors=[-1]*edge
 
    # Enter edge & vertices of edge
    # x-- y--
    # Since graph is undirected, push both pairs
    # (x, y) and (y, x)
    # graph[x].append((y, i))
    # graph[y].append((x, i))
    gra[0].append((1, 0))
    gra[1].append((0, 0))
 
    gra[1].append((2, 1))
    gra[2].append((1, 1))
 
    gra[2].append((3, 2))
    gra[3].append((2, 2))
 
    gra[0].append((3, 3))
    gra[3].append((0, 3))
 
    colorEdges(0, gra, edgeColors, isVisited)
 
    # printing all the edge colors
    for i in range(edge):
        print("Edge {} is of color {}".format(i + 1,edgeColors[i] + 1))




using System;
using System.Collections.Generic;
 
class MainClass {
    public static void ColorEdges(int ptr, List<List<Tuple<int, int>>> gra, List<int> edgeColors, bool[] isVisited) {
        Queue<int> q = new Queue<int>();
        int c = 0;
        HashSet<int> colored = new HashSet<int>();
 
        if (isVisited[ptr]) {
            return;
        }
 
        isVisited[ptr] = true;
 
        for (int i = 0; i < gra[ptr].Count; i++) {
            if (edgeColors[gra[ptr][i].Item2] != -1) {
                colored.Add(edgeColors[gra[ptr][i].Item2]);
            }
        }
 
        for (int i = 0; i < gra[ptr].Count; i++) {
            if (!isVisited[gra[ptr][i].Item1]) {
                q.Enqueue(gra[ptr][i].Item1);
            }
 
            if (edgeColors[gra[ptr][i].Item2] == -1) {
                while (colored.Contains(c)) {
                    c++;
                }
 
                edgeColors[gra[ptr][i].Item2] = c;
                colored.Add(c);
                c++;
            }
        }
 
        while (q.Count != 0) {
            int temp = q.Dequeue();
            ColorEdges(temp, gra, edgeColors, isVisited);
        }
 
        return;
    }
 
    public static void Main() {
        // Enter the Number of Vertices and the number of edges
        int ver = 4;
        int edge = 4;
 
        List<List<Tuple<int, int>>> gra = new List<List<Tuple<int, int>>>(ver);
        for (int i = 0; i < ver; i++) {
            gra.Add(new List<Tuple<int, int>>());
        }
 
        List<int> edgeColors = new List<int>(new int[edge]);
        for (int i = 0; i < edgeColors.Count; i++) {
            edgeColors[i] = -1;
        }
         
        bool[] isVisited = new bool[100000];
 
        gra[0].Add(new Tuple<int, int>(1, 0));
        gra[1].Add(new Tuple<int, int>(0, 0));
 
        gra[1].Add(new Tuple<int, int>(2, 1));
        gra[2].Add(new Tuple<int, int>(1, 1));
 
        gra[2].Add(new Tuple<int, int>(3, 2));
        gra[3].Add(new Tuple<int, int>(2, 2));
 
        gra[0].Add(new Tuple<int, int>(3, 3));
        gra[3].Add(new Tuple<int, int>(0, 3));
 
        ColorEdges(0, gra, edgeColors, isVisited);
 
        // printing all the edge colors
        for (int i = 0; i < edge; i++) {
            Console.WriteLine("Edge " + (i + 1) + " is of color " + (edgeColors[i] + 1));
        }
    }
}




// JavaScript program to illustrate Edge Coloring
 
// function to determine the edge colors
function colorEdges(ptr, gra, edgeColors, isVisited) {
    let q = [];
    let c = 0;
    let colored = new Set();
    // return if isVisited[ptr] is true
    if (isVisited[ptr]) {
        return;
    }
 
    // Mark the current node visited
    isVisited[ptr] = true;
 
    // Traverse all edges of current vertex
    for (let i = 0; i < gra[ptr].length; i++) {
        // if already colored, insert it into the set
        if (edgeColors[gra[ptr][i][1]] != -1) {
            colored.add(edgeColors[gra[ptr][i][1]]);
        }
    }
 
    for (let i = 0; i < gra[ptr].length; i++) {
        // if not visited, inset into the queue
        if (!isVisited[gra[ptr][i][0]]) {
            q.push(gra[ptr][i][0]);
        }
 
        if (edgeColors[gra[ptr][i][1]] == -1) {
            // if col vector -> negative
            while (colored.has(c)) {
 
                // increment the color
                c++;
            }
 
            // copy it in the vector
            edgeColors[gra[ptr][i][1]] = c;
 
            // then add it to the set
            colored.add(c);
            c++;
        }
    }
 
    // while queue's not empty
    while (q.length > 0) {
        let temp = q.shift();
        colorEdges(temp, gra, edgeColors, isVisited);
    }
 
    return;
}
 
// Driver Function
function main() {
    let empty = new Set();
    // declaring vector of vector of pairs, to define Graph
    let gra = [];
 
    let edgeColors = [];
 
    let isVisited = new Array(100000).fill(false);
 
    // Enter the Number of Vertices
    // and the number of edges
    let ver = 4;
    let edge = 4;
 
    for (let i = 0; i < ver; i++) {
        gra.push([]);
    }
 
    edgeColors = new Array(edge).fill(-1);
 
    // Enter edge & vertices of edge
    // x-- y--
    // Since graph is undirected, push both pairs
    // (x, y) and (y, x)
    // graph[x].push([y, i])
    // graph[y].push([x, i])
    gra[0].push([1, 0]);
    gra[1].push([0, 0]);
 
    gra[1].push([2, 1]);
    gra[2].push([1, 1]);
 
    gra[2].push([3, 2]);
    gra[3].push([2, 2]);
 
    gra[0].push([3, 3]);
    gra[3].push([0, 3]);
 
    colorEdges(0, gra, edgeColors, isVisited);
 
    // printing all the edge colors
    for (let i = 0; i < edge; i++) {
        console.log("Edge " + (i + 1) + " is of color " + (edgeColors[i] + 1));
    }
}
 
// Calling the main function
main();
 
// contributed by adityasharmadev01

Output
Edge 1 is of color 1
Edge 2 is of color 2
Edge 3 is of color 1
Edge 4 is of color 2

Complexity Analysis:


Article Tags :