This source file includes following definitions.
- kPartitioning
- memory_allocation
- initialization
- algo
- nextGain
- balancing
- destruction
- kpartition_greedy2
- allocate_vertex2
- eval_cost2
- build_p_vector
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "k-partitioning.h"
4 #include "tm_mt.h"
5 #include "tm_verbose.h"
6
7 void memory_allocation(PriorityQueue ** Q, PriorityQueue ** Qinst, double *** D, int n, int k);
8 void initialization(int * const part, double ** const matrice, PriorityQueue * const Qpart, PriorityQueue * const Q, PriorityQueue * const Qinst, double ** const D, int n, int k, int * const deficit, int * const surplus);
9 void algo(int * const part, double ** const matrice, PriorityQueue * const Qpart, PriorityQueue * const Q, PriorityQueue * const Qinst, double ** const D, int n, int * const deficit, int * const surplus);
10 double nextGain(PriorityQueue * const Qpart, PriorityQueue * const Q, int * const deficit, int * const surplus);
11 void balancing(int n, int deficit, int surplus, double ** const D, int * const part);
12 void destruction(PriorityQueue * Qpart, PriorityQueue * Q, PriorityQueue * Qinst, double ** D, int n, int k);
13
14 void allocate_vertex2(int u, int *res, double **comm, int n, int *size, int max_size);
15 double eval_cost2(int *,int,double **);
16 int *kpartition_greedy2(int k, double **comm, int n, int nb_try_max, int *constraints, int nb_constraints);
17 int* build_p_vector(double **comm, int n, int k, int greedy_trials, int * constraints, int nb_constraints);
18
19 int* kPartitioning(double ** comm, int n, int k, int * constraints, int nb_constraints, int greedy_trials)
20 {
21
22
23 PriorityQueue Qpart, *Q = NULL, *Qinst = NULL;
24 double **D = NULL;
25 int deficit, surplus, *part = NULL;
26 int real_n = n-nb_constraints;
27
28 part = build_p_vector(comm, n, k, greedy_trials, constraints, nb_constraints);
29
30 memory_allocation(&Q, &Qinst, &D, real_n, k);
31
32
33
34 initialization(part, comm, &Qpart, Q, Qinst, D, real_n, k, &deficit, &surplus);
35
36
37 while((nextGain(&Qpart, Q, &deficit, &surplus))>0)
38 {
39 algo(part, comm, &Qpart, Q, Qinst, D, real_n, &deficit, &surplus);
40 }
41
42
43 balancing(real_n, deficit, surplus, D, part);
44
45
46 destruction(&Qpart, Q, Qinst, D, real_n, k);
47
48 return part;
49 }
50
51 void memory_allocation(PriorityQueue ** Q, PriorityQueue ** Qinst, double *** D, int n, int k)
52 {
53 int i;
54 *Q = calloc(k, sizeof(PriorityQueue));
55 *Qinst = calloc(n, sizeof(PriorityQueue));
56 *D = malloc(sizeof(double *) * n);
57 for(i=0; i < n; ++i)
58 (*D)[i] = calloc(k, sizeof(double));
59 }
60
61 void initialization(int * const part, double ** const matrice, PriorityQueue * const Qpart, PriorityQueue * const Q, PriorityQueue * const Qinst, double ** const D, int n, int k, int * const deficit, int * const surplus)
62 {
63 int i,j;
64
65
66
67 PQ_init(Qpart, k);
68
69
70
71 for(i=0; i<k; ++i)
72 PQ_init(&Q[i], n);
73
74
75 for(i=0; i<n; ++i)
76 PQ_init(&Qinst[i], k);
77
78
79 for(i=0; i < n; ++i)
80 {
81 for(j=0; j < n; ++j)
82 {
83 D[i][part[j]] += matrice[i][j];
84 }
85 }
86
87
88
89 for(i=0; i < n; ++i)
90 for(j=0; j < k; ++j)
91 PQ_insert(&Qinst[i], j, D[i][j]);
92
93
94 for(i=0; i<n; ++i)
95 PQ_insert(&Q[part[i]], i, PQ_findMaxKey(&Qinst[i])-D[i][part[i]]);
96
97
98 for(i=0; i < k; ++i)
99 PQ_insert(Qpart, i, PQ_findMaxKey(&Q[i]));
100
101
102
103 *surplus = *deficit = 0;
104 }
105
106 void algo(int * const part, double ** const matrice, PriorityQueue * const Qpart, PriorityQueue * const Q, PriorityQueue * const Qinst, double ** const D, int n, int * const deficit, int * const surplus)
107 {
108 int p,u,v,j;
109 double d;
110 if(*deficit == *surplus)
111 {
112 p = PQ_deleteMax(Qpart);
113 u = PQ_deleteMax(&Q[p]);
114 *deficit = part[u];
115 }
116 else
117 {
118 u = PQ_deleteMax(&Q[*surplus]);
119 PQ_delete(Qpart, part[u]);
120 }
121 d = PQ_findMaxKey(&Q[part[u]]);
122 PQ_insert(Qpart, part[u], d);
123 j = PQ_deleteMax(&Qinst[u]);
124 if ( j < 0){
125 if(tm_get_verbose_level() >= CRITICAL)
126 fprintf(stderr,"Error Max element in priority queue negative!\n");
127 exit(-1);
128 }
129 *surplus = j;
130
131 for(v=0; v < n; ++v)
132 {
133 j = part[u];
134 D[v][j]= D[v][j] - matrice[u][v];
135 PQ_adjustKey(&Qinst[v], j, D[v][j]);
136 j = *surplus;
137 D[v][j] = D[v][j] + matrice[u][v];
138 PQ_adjustKey(&Qinst[v], j, D[v][j]);
139 d = PQ_findMaxKey(&Qinst[v]) - D[v][part[v]];
140 PQ_adjustKey(&Q[part[v]], v, d);
141 d = PQ_findMaxKey(&Q[part[v]]);
142 PQ_adjustKey(Qpart, part[v], d);
143 }
144 part[u] = *surplus;
145
146 d = PQ_findMaxKey(&Qinst[u]) - D[u][part[u]];
147 if(!PQ_isEmpty(&Qinst[u]))
148 PQ_insert(&Q[part[u]], u, d);
149 PQ_adjustKey(Qpart, part[u], d);
150 }
151
152 double nextGain(PriorityQueue * const Qpart, PriorityQueue * const Q, int * const deficit, int * const surplus)
153 {
154 double res;
155 if(*deficit == *surplus)
156 res = PQ_findMaxKey(Qpart);
157 else
158 res = PQ_findMaxKey(&Q[*surplus]);
159 return res;
160 }
161
162 void balancing(int n, int deficit, int surplus, double ** const D, int * const part)
163 {
164 if(surplus != deficit)
165 {
166 int i;
167 PriorityQueue moves;
168 PQ_init(&moves, n);
169 for(i=0; i<n; ++i)
170 {
171 if(part[i] == surplus)
172 PQ_insert(&moves, i, D[i][deficit]-D[i][surplus]);
173 }
174 part[PQ_deleteMax(&moves)] = deficit;
175 PQ_exit(&moves);
176 }
177 }
178
179 void destruction(PriorityQueue * Qpart, PriorityQueue * Q, PriorityQueue * Qinst, double ** D, int n, int k)
180 {
181 int i;
182 PQ_exit(Qpart);
183 for(i=0; i<k; ++i)
184 PQ_exit(&Q[i]);
185 free(Q);
186 for(i=0; i<n; ++i)
187 {
188 PQ_exit(&Qinst[i]);
189 }
190 free(Qinst);
191
192 for(i=0; i<n; ++i)
193 free(D[i]);
194 free(D);
195 }
196
197
198 int *kpartition_greedy2(int k, double **comm, int n, int nb_try_max, int *constraints, int nb_constraints)
199 {
200 int *res = NULL, *best_res=NULL, *size = NULL;
201 int i,j,nb_trials;
202 int max_size;
203 double cost, best_cost = -1;
204
205 for( nb_trials = 0 ; nb_trials < nb_try_max ; nb_trials++ ){
206 res = (int *)malloc(sizeof(int)*n);
207 for ( i = 0 ; i < n ; ++i )
208 res[i] = -1;
209
210 size = (int *)calloc(k,sizeof(int));
211 max_size = n/k;
212
213
214 if (nb_constraints){
215 int nb_real_nodes = n-nb_constraints;
216 for(i=0; i<nb_constraints; ++i)
217 {
218 int i_part = constraints[i]/max_size;
219 res[nb_real_nodes+i] = i_part;
220 size[i_part]++;
221 }
222 }
223
224
225 for ( i = 0 ; i < k ; ++i ){
226
227 if(size[i] >= max_size)
228 continue;
229
230 do{
231
232 j = genrand_int32() % n;
233 } while ( res[j] != -1 );
234
235 res[j] = i;
236
237 size[i]++;
238 }
239
240
241 for( i = 0 ; i < n ; ++i )
242 if( res[i] == -1)
243 allocate_vertex2(i, res, comm, n-nb_constraints, size, max_size);
244
245 cost = eval_cost2(res,n-nb_constraints,comm);
246
247
248 if((cost<best_cost) || (best_cost == -1)){
249 best_cost=cost;
250 free(best_res);
251 best_res=res;
252 }else
253 free(res);
254
255 free(size);
256 }
257
258
259
260
261 return best_res;
262 }
263
264 void allocate_vertex2(int u, int *res, double **comm, int n, int *size, int max_size)
265 {
266 int i,best_part = -1;
267 double cost, best_cost = -1;
268
269
270
271 for( i = 0 ; i < n ; ++i){
272 if (( res[i] != -1 ) && ( size[res[i]] < max_size )){
273 cost = comm[u][i];
274 if (( cost > best_cost)){
275 best_cost = cost;
276 best_part = res[i];
277 }
278 }
279 }
280
281
282
283
284 res[u] = best_part;
285 size[best_part]++;
286 }
287
288 double eval_cost2(int *partition, int n, double **comm)
289 {
290 double cost = 0;
291 int i,j;
292
293 for( i = 0 ; i < n ; ++i )
294 for( j = i+1 ; j < n ; ++j )
295 if(partition[i] != partition[j])
296 cost += comm[i][j];
297
298 return cost;
299 }
300
301 int* build_p_vector(double **comm, int n, int k, int greedy_trials, int * constraints, int nb_constraints)
302 {
303 int * part = NULL;
304 if(greedy_trials>0)
305 {
306 part = kpartition_greedy2(k, comm, n, greedy_trials, constraints, nb_constraints);
307 }
308 else
309 {
310 int * size = calloc(k, sizeof(int));
311 int i,j;
312 int nodes_per_part = n/k;
313 int nb_real_nodes = n-nb_constraints;
314 part = malloc(sizeof(int) * n);
315 for(i=0; i<nb_constraints; i++)
316 {
317 int i_part = constraints[i]/nodes_per_part;
318 part[nb_real_nodes+i] = i_part;
319 size[i_part]++;
320 }
321 j=0;
322
323 for(i=0; i<nb_real_nodes; i++)
324 {
325 if(size[j] < nodes_per_part)
326 {
327 size[j]++;
328 part[i] = j;
329 }
330 else
331 {
332 i--;
333 }
334 j = (j+1)%k;
335 }
336 free(size);
337 }
338 return part;
339 }