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.JerrumHeatBathChain; 012 import edu.wwu.tobikley.acgc.mc.HomogeneousMarkovChain; 013 014 /** 015 * Implements a variant of the fully polynomial randomized approximation scheme, specified 016 * by Marc Jerrum, as a <code>CountingAlgorithm</code>. 017 * To determine an approximation for the 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 the set of all colors that will reveil 024 * a proper q-Coloring if vertex v is colored with color c, 025 * uniformly at random. 026 * <li>Recolor vertex v with color c. 027 * </ol> 028 * 029 * For further information, refer to 030 * 031 * <ul> 032 * <li> Dyer, M.; Greenhill, C.: A More Rapidly Mixing Markov Chain 033 * for Graph Colorings. In: Random Structures and Algorithms, 034 * 13 (1998) 3-4, pp. 285–317. 035 * <li> Jerrum, M.: A Very Simple Algorithm for Estimating the Number 036 * of k-Colorings of a Low-Degree Graph. 037 * In: Random Structures and Algorithms, 7 (1995) 2, pp. 157–165. 038 * </ul> 039 * 040 * @version 1.0 041 * @author Tobias Kley 042 */ 043 public class JerrumHeatBathCountingAlgorithm extends ApproximateCountingAlgorithm { 044 045 protected String progressTextSubgraph = null; 046 /** 047 * 048 */ 049 public JerrumHeatBathCountingAlgorithm(Graph g, int numberOfColors, double epsilon) { 050 super(g, numberOfColors, epsilon); 051 if (q > 2.0 * Delta) { 052 N = (int)Math.ceil(((q - Delta) * k * Math.log(4.0 * k * l / epsilon)) / (q - 2.0 * Delta)); 053 } else { 054 N = (int)Math.ceil(6.0 * Delta * Math.pow(k,3) * Math.log(4.0 * l / epsilon)); 055 } 056 t = (int)Math.ceil(37.0 * l / (epsilon * epsilon)); 057 T = 1; 058 initializeInitialState(); 059 } 060 061 /** 062 * 063 */ 064 public JerrumHeatBathCountingAlgorithm(Graph g, int numberOfColors, double epsilon, double alpha) { 065 super(g, numberOfColors, epsilon); 066 if (q > 2.0 * Delta) { 067 N = (int)Math.ceil(((q - Delta) * k * Math.log(4.0 * k * l / epsilon)) / (q - 2.0 * Delta)); 068 } else { 069 N = (int)Math.ceil(6.0 * Delta * Math.pow(k,3) * Math.log(4.0 * l / epsilon)); 070 } 071 t = (int)Math.ceil(37.0 * l / (epsilon * epsilon)); 072 T = (int)Math.ceil(-1*Math.log(alpha))*12+1; 073 initializeInitialState(); 074 } 075 076 /** 077 * 078 */ 079 public JerrumHeatBathCountingAlgorithm(Graph g, int numberOfColors, double epsilon, int T) { 080 super(g, numberOfColors, epsilon); 081 if (q > 2.0 * Delta) { 082 N = (int)Math.ceil(((q - Delta) * k * Math.log(4.0 * k * l / epsilon)) / (q - 2.0 * Delta)); 083 } else { 084 N = (int)Math.ceil(6.0 * Delta * Math.pow(k,3) * Math.log(4.0 * l / epsilon)); 085 } 086 t = (int)Math.ceil(37.0 * l / (epsilon * epsilon)); 087 this.T = T; 088 initializeInitialState(); 089 } 090 091 protected BigInteger algorithmIteration() { 092 returnVal = BigInteger.valueOf(numberOfColors); 093 returnVal = returnVal.pow((int)k); 094 095 for (int i = 1; i <= l; i++) { 096 graphWorkingCopy.removeEdge(graphWorkingCopy.getEdge(i)); 097 int properColorings = 0; 098 for (int j = 1; j <= t; j++) { 099 graphWorkingCopy.setVertexColoring(initialState); 100 HomogeneousMarkovChain gd = new JerrumHeatBathChain(mt, graphWorkingCopy, numberOfColors); 101 ColoredGraph sample = (ColoredGraph)gd.next(N); 102 int c1 = sample.getColor((Vertex)sample.getEdge(i).getEndpoints().getFirst()); 103 int c2 = sample.getColor((Vertex)sample.getEdge(i).getEndpoints().getSecond()); 104 if (c1 != c2) { 105 properColorings++; 106 } 107 double p = (iterationAlgorithm * l * t + (i-1)*t + (j-1))/(t*T*l); 108 setProgress((int)(100*p)); 109 setProgressText("Calculating "+(int)(iterationAlgorithm+1)+". of "+T+" iteration(s) / "+ (int)i + ". of "+(int)l+" subgraph(s)"+" ("+100*(j-1)/t+"%)."); 110 } 111 returnVal = returnVal.multiply(new BigInteger(String.valueOf(properColorings))); 112 } 113 returnVal = returnVal.divide(new BigInteger(String.valueOf(t)).pow((int)l)); 114 return returnVal; 115 } 116 117 /** 118 * @param progress the progress to set 119 */ 120 private synchronized void setProgress(int progress) { 121 this.progress = progress; 122 } 123 124 /** 125 * @param progressText the progressText to set 126 */ 127 private synchronized void setProgressText(String progressText) { 128 this.progressText = progressText; 129 } 130 131 }