/* ==========================================
* JGraphT : a free Java graph-theory library
* ==========================================
*
* Project Info: http://jgrapht.sourceforge.net/
* Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
*
* (C) Copyright 2003-2008, by Barak Naveh and Contributors.
*
* This program and the accompanying materials are dual-licensed under
* either
*
* (a) the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation, or (at your option) any
* later version.
*
* or (per the licensee's choosing)
*
* (b) the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation.
*/
/* -------------------
* ChromaticNumber.java
* -------------------
* (C) Copyright 2008-2008, by Andrew Newell and Contributors.
*
* Original Author: Andrew Newell
* Contributor(s): gpaschos@netscape.net, harshalv@telenav.com
*
* $Id$
*
* Changes
* -------
* 24-Dec-2008 : Initial revision (AN);
*
*/
package org.jgrapht.alg;
import java.util.*;
import org.jgrapht.*;
import org.jgrapht.alg.util.*;
import org.jgrapht.graph.*;
/**
* Allows the <a href="http://mathworld.wolfram.com/ChromaticNumber.html">
* chromatic number</a> of a graph to be calculated. This is the minimal number
* of colors needed to color each vertex such that no two adjacent vertices
* share the same color. This algorithm will not find the true chromatic number,
* since this is an NP-complete problem. So, a greedy algorithm will find an
* approximate chromatic number.
*
* @author Andrew Newell
* @since Dec 21, 2008
*/
public abstract class ChromaticNumber
{
/**
* Finds the number of colors required for a greedy coloring of the graph.
*
* @param g an undirected graph to find the chromatic number of
*
* @return integer the approximate chromatic number from the greedy
* algorithm
*/
public static <V, E> int findGreedyChromaticNumber(UndirectedGraph<V, E> g)
{
Map<Integer, Set<V>> coloredGroups = findGreedyColoredGroups(g);
return coloredGroups.keySet().size();
}
/**
* Finds a greedy coloring of the graph.
*
* @param g an undirected graph for which to find the coloring
*/
public static <V, E> Map<Integer, Set<V>> findGreedyColoredGroups(
UndirectedGraph<V, E> g)
{
// A copy of the graph is made, so that elements of the graph may be
// removed to carry out the algorithm
UndirectedGraph<V, E> sg = new UndirectedSubgraph<V, E>(g, null, null);
// The Vertices will be sorted in decreasing order by degree, so that
// higher degree vertices have priority to be colored first
VertexDegreeComparator<V, E> comp =
new VertexDegreeComparator<V, E>(sg);
List<V> sortedVertices = new LinkedList<V>(sg.vertexSet());
Collections.sort(sortedVertices, comp);
Collections.reverse(sortedVertices);
int color;
// create a map which will hold color as key and Set<V> as value
Map<Integer, Set<V>> coloredGroups = new HashMap<Integer, Set<V>>();
// We'll attempt to color each vertex with a single color each
// iteration, and these vertices will be removed from the graph at the
// end of each iteration
for (color = 0; sg.vertexSet().size() > 0; color++) {
// This set will contain vertices that are colored with the
// current color of this iteration
Set<V> currentColor = new HashSet<V>();
for (
Iterator<V> iter = sortedVertices.iterator();
iter.hasNext();)
{
V v = iter.next();
// Add new vertices to be colored as long as they are not
// adjacent with any other vertex that has already been colored
// with the current color
boolean flag = true;
for (
Iterator<V> innerIter = currentColor.iterator();
innerIter.hasNext();)
{
V temp = innerIter.next();
if (sg.containsEdge(temp, v)) {
flag = false;
break;
}
}
if (flag) {
currentColor.add(v);
iter.remove();
}
}
// Add all these vertices as a group for this color
coloredGroups.put(color, currentColor);
// Remove vertices from the graph and then repeat the process for
// the next iteration
sg.removeAllVertices(currentColor);
}
return coloredGroups;
}
}
// End ChromaticNumber.java