Dip  0.92.4
MAD_CliquerI.h
Go to the documentation of this file.
1 //===========================================================================//
2 // This file is part of the Decomp Solver Framework. //
3 // //
4 // Decomp is distributed under the Common Public License as part of the //
5 // COIN-OR repository (http://www.coin-or.org). //
6 // //
7 // Authors: Matthew Galati, SAS Institute Inc. (matthew.galati@sas.com) //
8 // Ted Ralphs, Lehigh University (ted@lehigh.edu) //
9 // Jiadong Wang, Lehigh University (jiw408@lehigh.edu) //
10 // //
11 // Copyright (C) 2002-2019, Lehigh University, Matthew Galati, and Ted Ralphs//
12 // All Rights Reserved. //
13 //===========================================================================//
14 
15 #ifndef MAD_CLIQUERI_INCLUDED
16 #define MAD_CLIQUERI_INCLUDED
17 
18 // --------------------------------------------------------------------- //
19 #ifndef ELEMENTSIZE
20 typedef unsigned long int setelement;
21 # if (ULONG_MAX == 65535)
22 # define ELEMENTSIZE 16
23 # elif (ULONG_MAX == 4294967295)
24 # define ELEMENTSIZE 32
25 # else
26 # define ELEMENTSIZE 64
27 # endif
28 #endif /* !ELEMENTSIZE */
29 typedef setelement * set_t;
30 
31 // --------------------------------------------------------------------- //
32 /*** Counting amount of 1 bits in a setelement ***/
33 
34 /* Array for amount of 1 bits in a byte. */
35 static int set_bit_count[256] = {
36  0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
37  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
38  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
39  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
40  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
41  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
42  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
43  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
44  1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
45  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
46  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
47  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
48  2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
49  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
50  3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
51  4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 };
52 
53 /* The following macros assume that all higher bits are 0.
54  * They may in some cases be useful also on with other ELEMENTSIZE's,
55  * so we define them all. */
56 #define SET_ELEMENT_BIT_COUNT_8(a) (set_bit_count[(a)])
57 #define SET_ELEMENT_BIT_COUNT_16(a) (set_bit_count[(a)>>8] + \
58  set_bit_count[(a)&0xFF])
59 #define SET_ELEMENT_BIT_COUNT_32(a) (set_bit_count[(a)>>24] + \
60  set_bit_count[((a)>>16)&0xFF] + \
61  set_bit_count[((a)>>8)&0xFF] + \
62  set_bit_count[(a)&0xFF])
63 #define SET_ELEMENT_BIT_COUNT_64(a) (set_bit_count[(a)>>56] + \
64  set_bit_count[((a)>>48)&0xFF] + \
65  set_bit_count[((a)>>40)&0xFF] + \
66  set_bit_count[((a)>>32)&0xFF] + \
67  set_bit_count[((a)>>24)&0xFF] + \
68  set_bit_count[((a)>>16)&0xFF] + \
69  set_bit_count[((a)>>8)&0xFF] + \
70  set_bit_count[(a)&0xFF])
71 #if (ELEMENTSIZE==64)
72 # define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_64(a)
73 # define FULL_ELEMENT ((setelement)0xFFFFFFFFFFFFFFFF)
74 #elif (ELEMENTSIZE==32)
75 # define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_32(a)
76 # define FULL_ELEMENT ((setelement)0xFFFFFFFF)
77 #elif (ELEMENTSIZE==16)
78 # define SET_ELEMENT_BIT_COUNT(a) SET_ELEMENT_BIT_COUNT_16(a)
79 # define FULL_ELEMENT ((setelement)0xFFFF)
80 #else
81 # error "SET_ELEMENT_BIT_COUNT(a) not defined for current ELEMENTSIZE"
82 #endif
83 
84 // --------------------------------------------------------------------- //
85 /*
86  * Gives a value with bit x (counting from lsb up) set.
87  *
88  * Making this as a table might speed up things on some machines
89  * (though on most modern machines it's faster to shift instead of
90  * using memory). Making it a macro makes it easy to change.
91  */
92 #define SET_BIT_MASK(x) ((setelement)1<<(x))
93 
94 /* Set handling macros */
95 #define SET_ELEMENT_CONTAINS(e,v) ((e)&SET_BIT_MASK(v))
96 #define SET_ADD_ELEMENT(s,a) \
97  ((s)[(a)/ELEMENTSIZE] |= SET_BIT_MASK((a)%ELEMENTSIZE))
98 #define SET_DEL_ELEMENT(s,a) \
99  ((s)[(a)/ELEMENTSIZE] &= ~SET_BIT_MASK((a)%ELEMENTSIZE))
100 #define SET_CONTAINS_FAST(s,a) (SET_ELEMENT_CONTAINS((s)[(a)/ELEMENTSIZE], \
101  (a)%ELEMENTSIZE))
102 #define SET_CONTAINS(s,a) (((a)<SET_MAX_SIZE(s))?SET_CONTAINS_FAST(s,a):0)
103 
104 /* Sets can hold values between 0,...,SET_MAX_SIZE(s)-1 */
105 #define SET_MAX_SIZE(s) ((s)[-1])
106 
107 /* Sets consist of an array of SET_ARRAY_LENGTH(s) setelements */
108 #define SET_ARRAY_LENGTH(s) (((s)[-1]+ELEMENTSIZE-1)/ELEMENTSIZE)
109 
110 /*
111  * set_size()
112  *
113  * Returns the number of elements in set s.
114  */
115 static inline int set_size(set_t s) {
116  int count=0;
117  setelement * c;
118  for (c=s; c < s+SET_ARRAY_LENGTH(s); c++)
119  count+=SET_ELEMENT_BIT_COUNT(*c);
120  return count;
121 }
122 
123 
124 /*
125  * set_new()
126  *
127  * Create a new set that can hold values in the range 0,...,size-1.
128  */
129 static inline set_t set_new(int size) {
130  int n;
131  set_t s;
132  n=(size/ELEMENTSIZE+1)+1;
133  s=(setelement*)calloc(n,sizeof(setelement));
134  s[0]=size;
135  return &(s[1]);
136 }
137 
138 /*
139  * set_free()
140  *
141  * Free the memory associated with set s.
142  */
143 static inline void set_free(set_t s) {
144  free(&(s[-1]));
145 }
146 
147 /*
148  * set_duplicate()
149  *
150  * Returns a newly allocated duplicate of set s.
151  */
152 static inline set_t set_duplicate(set_t s) {
153  set_t newT;
154 
155  newT=set_new(SET_MAX_SIZE(s));
156  memcpy(newT,s,SET_ARRAY_LENGTH(s)*sizeof(setelement));
157  return newT;
158 }
159 
160 // --------------------------------------------------------------------- //
161 typedef struct _graph_t graph_t;
162 struct _graph_t {
163  int n; /* Vertices numbered 0...n-1 */
164  set_t * edges; /* A list of n sets (the edges). */
165  int * weights; /* A list of n vertex weights. */
166 };
167 
168 // --------------------------------------------------------------------- //
169 #define GRAPH_ADD_EDGE(g,i,j) do { \
170  SET_ADD_ELEMENT((g)->edges[(i)],(j)); \
171  SET_ADD_ELEMENT((g)->edges[(j)],(i)); \
172 } while (0)
173 #define GRAPH_DEL_EDGE(g,i,j) do { \
174  SET_DEL_ELEMENT((g)->edges[(i)],(j)); \
175  SET_DEL_ELEMENT((g)->edges[(j)],(i)); \
176 } while (0)
177 
178 #define GRAPH_IS_EDGE_FAST(g,i,j) (SET_CONTAINS_FAST((g)->edges[(i)],(j)))
179 
180 // --------------------------------------------------------------------- //
181 extern graph_t * graph_new (int n);
182 extern void graph_free (graph_t * g);
183 extern void graph_print(graph_t * g);
184 extern int graph_edge_count(graph_t *g);
185 
186 static inline int graph_subgraph_weight(graph_t * g, set_t s) {
187  unsigned int i,j;
188  int count=0;
189  setelement e;
190  for (i=0; i<SET_ARRAY_LENGTH(s); i++) {
191  if (s[i]) {
192  e=s[i];
193  for (j=0; j<ELEMENTSIZE; j++) {
194  if (e&1)
195  count+=g->weights[i*ELEMENTSIZE+j];
196  e = e>>1;
197  }
198  }
199  }
200  return count;
201 }
202 
203 // --------------------------------------------------------------------- //
206  int * (*reorder_function)(graph_t *, int);
207  int * reorder_map;
208 
209  /* arguments: level, n, max, user_time, system_time, opts */
210  int (*time_function)(int, int, int, int, double, double, clique_options *);
211  FILE * output;
212 
214  void * user_data;
217 };
219 
220 // --------------------------------------------------------------------- //
221 /*
222  * clique_find_all()
223  *
224  * Find all cliques with weight at least min_weight and at most max_weight.
225  *
226  * g - the graph
227  * min_weight - minimum weight of cliques to search for. If min_weight==0,
228  * searches for maximum weight cliques.
229  * max_weight - maximum weight of cliques to search for. If max_weight==0,
230  * no upper limit is used. If min_weight==0, max_weight must
231  * also be 0.
232  * maximal - require cliques to be maximal cliques
233  * opts - time printing and clique storage options
234  *
235  * Returns the number of cliques found. This can be less than the number
236  * of cliques in the graph iff opts->time_function() or opts->user_function()
237  * returns FALSE (request abort).
238  *
239  * The cliques found are stored in opts->clique_list[] and
240  * opts->user_function() is called with them (if non-NULL). The cliques
241  * stored in opts->clique_list[] are newly allocated, and can be freed
242  * by set_free().
243  *
244  * Note: Automatically uses clique_unweighted_find_all if all vertex
245  * weights are the same.
246  */
247 int clique_find_all(graph_t * g,
248  int min_weight,
249  int max_weight,
250  int maximal,
251  clique_options * opts);
252 
253 
254 /*
255  * clique_find_single()
256  *
257  * Returns a clique with weight at least min_weight and at most max_weight.
258  *
259  * g - the graph
260  * min_weight - minimum weight of clique to search for. If min_weight==0,
261  * searches for a maximum weight clique.
262  * max_weight - maximum weight of clique to search for. If max_weight==0,
263  * no upper limit is used. If min_weight==0, max_weight must
264  * also be 0.
265  * maximal - require returned clique to be maximal
266  * opts - time printing options
267  *
268  * Returns the set of vertices forming the clique, or NULL if a clique
269  * of requested weight/maximality does not exist in the graph (or if
270  * opts->time_function() requests abort).
271  *
272  * The returned clique is newly allocated and can be freed by set_free().
273  *
274  * Note: Does NOT use opts->user_function() or opts->clique_list[].
275  * Note: Automatically uses clique_unweighted_find_single if all vertex
276  * weights are the same.
277  */
279  int min_weight,
280  int max_weight,
281  int maximal,
282  clique_options * opts);
283 
284 /*
285  * clique_unweighted_find_all()
286  *
287  * Find all cliques with size at least min_size and at most max_size.
288  *
289  * g - the graph
290  * min_size - minimum size of cliques to search for. If min_size==0,
291  * searches for maximum cliques.
292  * max_size - maximum size of cliques to search for. If max_size==0, no
293  * upper limit is used. If min_size==0, this must also be 0.
294  * maximal - require cliques to be maximal cliques
295  * opts - time printing and clique storage options
296  *
297  * Returns the number of cliques found. This can be less than the number
298  * of cliques in the graph iff opts->time_function() or opts->user_function()
299  * returns FALSE (request abort).
300  *
301  * The cliques found are stored in opts->clique_list[] and
302  * opts->user_function() is called with them (if non-NULL). The cliques
303  * stored in opts->clique_list[] are newly allocated, and can be freed
304  * by set_free().
305  */
307  int min_size,
308  int max_size,
309  int maximal,
310  clique_options * opts);
311 
312 #endif
int(* time_function)(int, int, int, int, double, double, clique_options *)
Definition: MAD_CliquerI.h:210
int * weights
Definition: MAD_CliquerI.h:165
int clique_find_all(graph_t *g, int min_weight, int max_weight, int maximal, clique_options *opts)
int graph_edge_count(graph_t *g)
int clique_unweighted_find_all(graph_t *g, int min_size, int max_size, int maximal, clique_options *opts)
static int set_bit_count[256]
Definition: MAD_CliquerI.h:35
static void set_free(set_t s)
Definition: MAD_CliquerI.h:143
void graph_print(graph_t *g)
#define ELEMENTSIZE
Definition: MAD_CliquerI.h:26
#define SET_MAX_SIZE(s)
Definition: MAD_CliquerI.h:105
graph_t * graph_new(int n)
int(* user_function)(set_t, graph_t *, clique_options *)
Definition: MAD_CliquerI.h:213
set_t clique_find_single(graph_t *g, int min_weight, int max_weight, int maximal, clique_options *opts)
set_t * clique_list
Definition: MAD_CliquerI.h:215
setelement * set_t
Definition: MAD_CliquerI.h:29
unsigned long int setelement
Definition: MAD_CliquerI.h:20
static int set_size(set_t s)
Definition: MAD_CliquerI.h:115
static int graph_subgraph_weight(graph_t *g, set_t s)
Definition: MAD_CliquerI.h:186
#define SET_ARRAY_LENGTH(s)
Definition: MAD_CliquerI.h:108
#define SET_ELEMENT_BIT_COUNT(a)
Definition: MAD_CliquerI.h:72
set_t * edges
Definition: MAD_CliquerI.h:164
static set_t set_duplicate(set_t s)
Definition: MAD_CliquerI.h:152
clique_options * clique_default_options
static set_t set_new(int size)
Definition: MAD_CliquerI.h:129
void graph_free(graph_t *g)