From e9879a2cb18f69db3cefb300137167b3c20dbdcb Mon Sep 17 00:00:00 2001 From: pigne <yoann.pigne@gmail.com> Date: Sun, 15 May 2011 15:15:36 +0200 Subject: [PATCH] Updated Welsh-Powell from outdated API (assuming color attributes can change the display). Added documentation --- .../algorithm/coloring/WelshPowell.java | 197 ++++++++++++------ 1 file changed, 132 insertions(+), 65 deletions(-) diff --git a/src/org/graphstream/algorithm/coloring/WelshPowell.java b/src/org/graphstream/algorithm/coloring/WelshPowell.java index 823971a..2ed1f5b 100644 --- a/src/org/graphstream/algorithm/coloring/WelshPowell.java +++ b/src/org/graphstream/algorithm/coloring/WelshPowell.java @@ -37,12 +37,12 @@ import org.graphstream.algorithm.*; import org.graphstream.graph.*; /** - * Welsh Powell static colorating algorithm. + * Welsh Powell static graph coloring algorithm. * * <p> - * This class is intended to give some algorithm for computing the well-known - * coloring problem. It provides the Welsh and Powell greedy algorithm that may - * used as a static method. + * This class is intended to implement the Welsh-Powell algorithm for the + * problem of graph coloring. It provides a greedy algorithm that runs on a + * static graph. * </p> * * <p> @@ -63,39 +63,134 @@ import org.graphstream.graph.*; * <p> * * <p> - * This algorithm is known to use at most d(G)+1 colors where d(G) represents - * the largest value of the degree in the graph G. + * Note that the given colors are not real colors. Instead they are positive + * integers starting 0. So, for instance, if a colored graph's chromatic number + * is 3, then nodes will be "colored" with one of 0, 1 or 2. * </p> * + * * <p> - * After computation (using {@link #compute()}, the algorithm returns its result - * using the {@link #getLastComputedResult()} method. If you passed "true" to - * the <tt>modify</tt> parameter, the colors are stored in the graph as - * attributes. By default the attribute name is "color", so that the viewer - * displays them accordingly, but you can optionnaly choose the attribute name. + * After computation (using {@link #compute()}, the algorithm result for the + * computation, the chromatic number, is accessible with the + * {@link #getLastComputedResult()} method. Colors (of "Integer" type) are stored in the graph as attributes (one for each node). + * By default the attribute name is "WelshPowell.color", but you can optional choose the + * attribute name. * </p> * + * + * + * <h2>Example</h2> + * import java.io.IOException; + * import java.io.StringReader; + * + * import org.graphstream.algorithm.coloring.WelshPowell; + * import org.graphstream.graph.ElementNotFoundException; + * import org.graphstream.graph.Graph; + * import org.graphstream.graph.Node; + * import org.graphstream.graph.implementations.DefaultGraph; + * import org.graphstream.stream.GraphParseException; + * import org.graphstream.stream.file.FileSourceDGS; + * + * public class WelshPowellTest { + * // B-(1)-C + * // / \ + * // (1) (10) + * // / \ + * // A F + * // \ / + * // (1) (1) + * // \ / + * // D-(1)-E + * static String my_graph = + * "DGS004\n" + * + "my 0 0\n" + * + "an A \n" + * + "an B \n" + * + "an C \n" + * + "an D \n" + * + "an E \n" + * + "an F \n" + * + "ae AB A B weight:1 \n" + * + "ae AD A D weight:1 \n" + * + "ae BC B C weight:1 \n" + * + "ae CF C F weight:10 \n" + * + "ae DE D E weight:1 \n" + * + "ae EF E F weight:1 \n" + * ; + * public static void main(String[] args) throws IOException, ElementNotFoundException, GraphParseException { + * Graph graph = new DefaultGraph("Welsh Powell Test"); + * StringReader reader = new StringReader(my_graph); + * + * FileSourceDGS source = new FileSourceDGS(); + * source.addSink(graph); + * source.readAll(reader); + * + * WelshPowell wp = new WelshPowell("color"); + * wp.init(graph); + * wp.compute(); + * + * System.out.println("The chromatic number of this graph is : "+wp.getChromaticNumber()); + * for(Node n : graph){ + * System.out.println("Node "+n.getId()+ " : color " +n.getAttribute("color")); + * } + * } + * } + * </pre> + * + * This shall return: + * <pre> + * The chromatic number of this graph is : 3 + * Node D : color 0 + * Node E : color 2 + * Node F : color 1 + * Node A : color 2 + * Node B : color 1 + * Node C : color 0 + * </pre> + * + * + * <h2>Extra Feature</h2> + * * <p> - * This algorithm uses the <i>std-algo-1.0</i> algorithm's standard. + * Consider you what to display the result of they coloring algorithm on a displayed graph, + * then adding the following code to the previous example may help you: * </p> * + * <pre> + * Color[] cols = new Color[wp.getChromaticNumber()]; + * for(int i=0;i< wp.getChromaticNumber();i++){ + * cols[i]=Color.getHSBColor((float) (Math.random()), 0.8f, 0.9f); + * } + * for(Node n : graph){ + * int col = (int) n.getNumber("color"); + * n.addAttribute("ui.style", "fill-color:rgba("+cols[col].getRed()+","+cols[col].getGreen()+","+cols[col].getBlue()+",200);" ); + * } + * + * graph.display(); + * </pre> + + * + * + * @complexity + * This algorithm is known to use at most d(G)+1 colors where d(G) represents + * the largest value of the degree in the graph G. + * + * @reference + * Welsh, D. J. A.; Powell, M. B. (1967), + * "An upper bound for the chromatic number of a graph and its application to timetabling problems", + * The Computer Journal 10 (1): 85–86, doi:10.1093/comjnl/10.1.85 + * * @version 0.1 30/08/2007 * @author Frédéric Guinand * @author Antoine Dutot * @author Yoann Pigné */ public class WelshPowell implements Algorithm { - // Attributes - - /** - * Modify the graph ?. - */ - protected boolean modify = false; /** * Name of the attributes added to the graph. */ - protected String attrName = "color"; + protected String attrName = "WelshPowell.color"; /** * The graph. @@ -103,40 +198,29 @@ public class WelshPowell implements Algorithm { protected Graph g; /** - * The algorithm result (number of colors). + * The algorithm's result : the chromatic number. */ - protected int result; + protected int chromaticNumber; // Constructors /** * New Welsh and Powell coloring algorithm. * - * @param modify - * A boolean equals to true if the graph has to be modified, - * false otherwise * @param attrName - * If modify is true, then attrName may be indicated as the name - * of the attribute corresponding to the color allocated by this - * algorithm. Note that if attrName is "color", then the color of - * the nodes will be modified accordingly. + * name of the attribute corresponding to the color allocated by + * this algorithm. */ - public WelshPowell(boolean modify, String attrName) { - this.modify = modify; + public WelshPowell(String attrName) { this.attrName = attrName; } /** - * New Welsh and Powell coloring algorithm, using "color" as the attribute - * name. If the graph is to be modified, the modification will store colors - * in it and the viewer should display them accordingly. + * New Welsh and Powell coloring algorithm, using "WelshPowell.color" as the attribute + * name. * - * @param modify - * A boolean equals to true if the graph has to be modified, - * false otherwise */ - public WelshPowell(boolean modify) { - this.modify = modify; + public WelshPowell() { } // Accessors @@ -147,8 +231,8 @@ public class WelshPowell implements Algorithm { * @return The number of colors. * @see #compute() */ - public int getLastComputedResult() { - return result; + public int getChromaticNumber() { + return chromaticNumber; } // Commands @@ -163,15 +247,6 @@ public class WelshPowell implements Algorithm { this.attrName = attrName; } - /** - * Modify the graph when computing the algorithm?. - * - * @param modify - * If true, attributes are stored in the graph. - */ - public void setModify(boolean modify) { - this.modify = modify; - } /* * (non-Javadoc) @@ -189,9 +264,9 @@ public class WelshPowell implements Algorithm { * @see org.graphstream.algorithm.Algorithm#compute() */ public void compute() { - String attributeName = "welshpowell"; + String attributeName = "WelshPowell.color"; - if (modify && (attrName != null)) + if (attrName != null) attributeName = attrName; // ------- STEP 1 ----------- @@ -230,18 +305,18 @@ public class WelshPowell implements Algorithm { // ------ STEP 2 -------- // color initialization - ArrayList<Color> allColors = new ArrayList<Color>(); - Color col; + ArrayList<Integer> allColors = new ArrayList<Integer>(); + Integer col; int nbColors = 0; for (int i = 0; i < g.getNodeCount(); i++) { - col = Color.getHSBColor((float) (Math.random()), 0.8f, 0.9f); + col = i; allColors.add(col); } // ------- STEP 3 -------- - Color currentColor = allColors.remove(0); + Integer currentColor = allColors.remove(0); nbColors++; while (!sortedNodes.isEmpty()) { @@ -257,7 +332,7 @@ public class WelshPowell implements Algorithm { Node neighb = neighbors.next(); if (neighb.hasAttribute(attributeName)) { - if (((Color) (neighb.getAttribute(attributeName))) + if (((neighb.getAttribute(attributeName))) .equals(currentColor)) { conflict = true; } @@ -276,14 +351,6 @@ public class WelshPowell implements Algorithm { nbColors++; } - if (!modify) { - nodes = g.getNodeIterator(); - - while (nodes.hasNext()) { - nodes.next().removeAttribute(attributeName); - } - } - - result = nbColors; + chromaticNumber = nbColors-1; } } \ No newline at end of file -- GitLab