001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ 004 005 package graphlab.extensions.reports; 006 007 import graphlab.graph.graph.VertexModel; 008 import graphlab.library.BaseEdge; 009 import graphlab.library.BaseGraph; 010 import graphlab.library.BaseVertex; 011 012 import java.util.ArrayDeque; 013 import java.util.Iterator; 014 import java.util.LinkedList; 015 016 /** 017 * generates all partitionings of the given graph with t or less partitions 018 * which in each partition does not have any edges 019 * 020 * @author Azin Azadi 021 */ 022 public class Partitioner { 023 public BaseVertex[] vertices; 024 public int[][] edgeArray; 025 public int[] color; 026 private BaseGraph g; 027 028 029 public Partitioner(final BaseGraph g) { 030 this.g = g; 031 edgeArray = g.getEdgeArray(); 032 vertices = g.getVertexArray(); 033 } 034 035 public boolean findAllSubsets(SubSetListener listener) { 036 color = new int[vertices.length]; 037 038 ArrayDeque<BaseVertex> v = new ArrayDeque<BaseVertex>(); 039 for (BaseVertex _ : g.getVertexArray()) { 040 v.add(_); 041 } 042 043 return findAllSubsetsRecursively(1, listener, v, new ArrayDeque<BaseVertex>(), new ArrayDeque<BaseVertex>()); 044 } 045 046 public int findMaxIndSet(boolean putFirstVertexInSet) { 047 color = new int[vertices.length]; 048 049 v = new ArrayDeque<BaseVertex>(); 050 set = new boolean[g.getVerticesCount()]; 051 int i = 0; 052 for (BaseVertex _ : g.getVertexArray()) { 053 v.add(_); 054 set[i++] = false; 055 } 056 maxSet = Integer.MIN_VALUE; 057 058 // curRejectedFromSet = 0; 059 // minRejectedFromSet = Integer.MAX_VALUE; 060 061 curSet = 0; 062 int start = 0; 063 // putFirstVertexInSet = false; 064 if (putFirstVertexInSet) { 065 curSet = 1; 066 set[0] = true; 067 v.remove(vertices[0]); 068 for (int ii : edgeArray[0]) { 069 v.remove(vertices[ii]); 070 } 071 } 072 073 V = new VertexModel[v.size()]; 074 N = v.size(); 075 v.toArray(V); 076 077 ID = new int[vertices.length]; 078 for (i = 0; i < vertices.length; i++) { 079 ID[i] = vertices[i].getId(); 080 } 081 mark = new boolean[vertices.length]; 082 found = 0; 083 findMaxIndSetsRecursively(0); 084 System.out.println(found + " , iter:" + iter); 085 return maxSet; 086 } 087 088 boolean set[]; 089 boolean mark[]; 090 // boolean markbck[]; 091 092 VertexModel[] V; 093 int ID[]; 094 int N; 095 ArrayDeque<BaseVertex> v; 096 int maxSet = Integer.MIN_VALUE; 097 int curSet; 098 // int curRejectedFromSet; 099 // int minRejectedFromSet; 100 int found = 0; 101 int iter = 0; 102 103 int i; 104 105 private void findMaxIndSetsRecursively(int iv) { 106 while (iv < N && mark[iv]) { 107 iv++; 108 } 109 iter++; 110 if (curSet + (N - iv) < maxSet) { 111 return; 112 } 113 if (iv >= N) { 114 if (curSet > maxSet) { 115 maxSet = curSet; 116 found++; 117 System.out.println("A" + maxSet); 118 } 119 // } 120 return; 121 } 122 123 int vid = V[iv].getId(); 124 //set and backup marks 125 int[] nv = edgeArray[vid]; 126 int ss = nv.length; 127 128 boolean markbck[] = new boolean[ss]; 129 for (i = 0; i < ss; i++) { 130 markbck[i] = mark[nv[i]]; 131 mark[nv[i]] = true; 132 } 133 134 //put vid in set 135 int iiv = iv + 1; 136 while (iiv < N && mark[iiv]) { 137 iiv++; 138 } 139 140 set[vid] = true; 141 curSet++; 142 /*****************************/ 143 findMaxIndSetsRecursively(iiv); 144 /*****************************/ 145 curSet--; 146 set[vid] = false; 147 148 149 for (i = 0; i < ss; i++) { 150 mark[nv[i]] = markbck[i]; 151 } 152 //BackTrak on complement 153 iiv = iv + 1; 154 while (iiv < N && mark[iiv]) { 155 iiv++; 156 } 157 /*****************************/ 158 findMaxIndSetsRecursively(iiv); 159 /*****************************/ 160 } 161 162 163 public boolean findAllPartitionings(final int t, final ColoringListener listener) { 164 color = new int[vertices.length]; 165 166 ArrayDeque<BaseVertex> v = new ArrayDeque<BaseVertex>(); 167 for (BaseVertex _ : g.getVertexArray()) { 168 v.add(_); 169 } 170 if (findAllPartitioningsRecursively(t, new ColoringListener() { 171 public boolean coloringFound(final int t) { 172 if (checkColoring(g)) { 173 boolean b = listener.coloringFound(t); 174 return b; 175 } 176 return false; 177 } 178 }, v)) return true; 179 return false; 180 } 181 182 public boolean findAllPartitioningsRecursively(final int tt, final ColoringListener listener, final ArrayDeque<BaseVertex> v) { 183 if (tt == 0 || v.size() == 0) { 184 return listener.coloringFound(tt); 185 } 186 BaseVertex fv = v.removeFirst(); 187 color[fv.getId()] = tt; 188 189 //inkedList<BaseVertex> _v = new LinkedList<BaseVertex>(v); 190 ArrayDeque<BaseVertex> compl = new ArrayDeque<BaseVertex>(); 191 if (findAllSubsetsRecursively(tt, new SubSetListener() { 192 LinkedList<BaseVertex> vert = new LinkedList<BaseVertex>(); 193 194 public boolean subsetFound(final int t, ArrayDeque<BaseVertex> complement, ArrayDeque<BaseVertex> set) { 195 return findAllPartitioningsRecursively(tt - 1, listener, complement); 196 } 197 } 198 , v, new ArrayDeque<BaseVertex>(), compl)) return true; 199 color[fv.getId()] = 0; 200 v.addFirst(fv); 201 return false; 202 } 203 204 private boolean findAllSubsetsRecursively(final int t, SubSetListener listener, ArrayDeque<BaseVertex> v, ArrayDeque<BaseVertex> set, ArrayDeque<BaseVertex> complement) { 205 if (t == 0 || v.size() == 0) { 206 //all colorings of valid and checked before except the remaining vertices which all have color 0 207 for (BaseVertex _v : v) { 208 for (int i : edgeArray[_v.getId()]) 209 if (color[i] == 0) 210 return false; 211 } 212 //so it is a valid partitioning (coloring) 213 if (listener.subsetFound(t, complement, set)) return true; 214 return false; 215 } 216 BaseVertex _ = v.removeFirst(); 217 218 boolean canColoredT = true; 219 for (int i : edgeArray[_.getId()]) { 220 if (color[i] == t) { 221 canColoredT = false; 222 break; 223 } 224 } 225 if (canColoredT) { 226 color[_.getId()] = t; 227 set.add(_); 228 if (findAllSubsetsRecursively(t, listener, v, set, complement)) return true; 229 set.remove(_); 230 } 231 232 color[_.getId()] = 0; 233 complement.add(_); 234 if (findAllSubsetsRecursively(t, listener, v, set, complement)) return true; 235 complement.remove(_); 236 v.addFirst(_); 237 return false; 238 } 239 240 /** 241 * @param g 242 * @return true if the coloring of g is a valid vertex coloring 243 */ 244 public boolean checkColoring(BaseGraph g) { 245 Iterator<BaseEdge> ie = g.edgeIterator(); 246 while (ie.hasNext()) { 247 BaseEdge e = ie.next(); 248 if (color[e.source.getId()] == color[e.target.getId()]) { 249 return false; 250 } 251 } 252 return true; 253 } 254 255 }