001 /** 002 * 003 */ 004 package edu.wwu.tobikley.acgc.algorithms; 005 006 import java.math.BigInteger; 007 008 import edu.uci.ics.jung.graph.Graph; 009 import edu.uci.ics.jung.graph.Vertex; 010 import edu.wwu.tobikley.acgc.graphcoloring.ColoredGraph; 011 import edu.wwu.tobikley.acgc.mc.JerrumChain; 012 import edu.wwu.tobikley.acgc.mc.HomogeneousMarkovChain; 013 014 /** 015 * Implements the fully polynomial randomized approximation scheme, specified 016 * by Marc Jerrum, as a <code>CountingAlgorithm</code>. 017 * To determine an approximation for number of proper q-Colorings a Markov Chain 018 * is run to randomly generate proper q-Colorings from a equidistribution. 019 * The Markov Chain is characterized by the following transition mechanism: 020 * 021 * <ol> 022 * <li>Pick a vertex v from V uniformly at random. 023 * <li>Pick a color c from C uniformly at random. 024 * <li>Recolor vertex v with color c, if the resulting q-Coloring is proper. 025 * If it is not, undo the recoloring. 026 * </ol> 027 * 028 * For further information, refer to 029 * 030 * <ul> 031 * <li> Häggström, O.: Finite Markov Chains and Algorithmic Applications, 032 * Cambridge u. a.: Cambridge Univ. Press 2002, pp. 45-75. 033 * <li> Jerrum, M.: A Very Simple Algorithm for Estimating the Number 034 * of k-Colorings of a Low-Degree Graph. 035 * In: Random Structures and Algorithms, 7 (1995) 2, pp. 157–165. 036 * </ul> 037 * 038 * @version 1.0 039 * @author Tobias Kley 040 */ 041 public class JerrumCountingAlgorithm extends ApproximateCountingAlgorithm { 042 043 protected String progressTextSubgraph = null; 044 /** 045 * 046 */ 047 public JerrumCountingAlgorithm(Graph g, int numberOfColors, double epsilon) { 048 super(g, numberOfColors, epsilon); 049 N = (int)Math.ceil((q * k * Math.log(4.0 * k * l / epsilon)) / (q - 2.0 * Delta)); 050 t = (int)Math.ceil(37.0 * l / (epsilon * epsilon)); 051 T = 1; 052 initializeInitialState(); 053 } 054 055 /** 056 * 057 */ 058 public JerrumCountingAlgorithm(Graph g, int numberOfColors, double epsilon, double alpha) { 059 super(g, numberOfColors, epsilon); 060 N = (int)Math.ceil((q * k * Math.log(4.0 * k * l / epsilon)) / (q - 2.0 * Delta)); 061 t = (int)Math.ceil(37.0 * l / (epsilon * epsilon)); 062 T = (int)Math.ceil(-1*Math.log(alpha))*12+1; 063 initializeInitialState(); 064 } 065 066 /** 067 * 068 */ 069 public JerrumCountingAlgorithm(Graph g, int numberOfColors, double epsilon, int T) { 070 super(g, numberOfColors, epsilon); 071 N = (int)Math.ceil((q * k * Math.log(4.0 * k * l / epsilon)) / (q - 2.0 * Delta)); 072 t = (int)Math.ceil(37.0 * l / (epsilon * epsilon)); 073 this.T = T; 074 initializeInitialState(); 075 } 076 077 protected BigInteger algorithmIteration() { 078 returnVal = BigInteger.valueOf(numberOfColors); 079 returnVal = returnVal.pow((int)k); 080 081 for (int i = 1; i <= l; i++) { 082 graphWorkingCopy.removeEdge(graphWorkingCopy.getEdge(i)); 083 int properColorings = 0; 084 for (int j = 1; j <= t; j++) { 085 graphWorkingCopy.setVertexColoring(initialState); 086 HomogeneousMarkovChain gd = new JerrumChain(mt, graphWorkingCopy, numberOfColors); 087 ColoredGraph sample = (ColoredGraph)gd.next(N); 088 int c1 = sample.getColor((Vertex)sample.getEdge(i).getEndpoints().getFirst()); 089 int c2 = sample.getColor((Vertex)sample.getEdge(i).getEndpoints().getSecond()); 090 if (c1 != c2) { 091 properColorings++; 092 } 093 double p = (iterationAlgorithm * l * t + (i-1)*t + (j-1))/(t*T*l); 094 setProgress((int)(100*p)); 095 setProgressText("Calculating "+(int)(iterationAlgorithm+1)+". of "+T+" iteration(s) / "+ (int)i + ". of "+(int)l+" subgraph(s)"+" ("+100*(j-1)/t+"%)."); 096 } 097 returnVal = returnVal.multiply(new BigInteger(String.valueOf(properColorings))); 098 } 099 returnVal = returnVal.divide(new BigInteger(String.valueOf(t)).pow((int)l)); 100 return returnVal; 101 } 102 103 /** 104 * @param progress the progress to set 105 */ 106 private synchronized void setProgress(int progress) { 107 this.progress = progress; 108 } 109 110 /** 111 * @param progressText the progressText to set 112 */ 113 private synchronized void setProgressText(String progressText) { 114 this.progressText = progressText; 115 } 116 117 }