30 for (i=0; i<nvtxs; i++)
34 for (i=0; i<nvtxs; i++)
35 for (j=xadj[i]; j<xadj[i+1]; j++)
38 for (i=0; i<nvtxs; i++)
39 for (j=xadj[i]; j<xadj[i+1]; j++)
47 idxtype *xadj, *adjncy, *adjwgt, *where;
56 for (i=0; i<nvtxs; i++)
57 for (j=xadj[i]; j<xadj[i+1]; j++)
60 for (i=0; i<nvtxs; i++)
61 for (j=xadj[i]; j<xadj[i+1]; j++)
62 m_adjwgt[j] = adjwgt[j];
66 for (i=0; i<nvtxs; i++)
67 for (j=xadj[i]; j<xadj[i+1]; j++)
69 m_adjwgt[j] = 1.0/w[i];
70 for (i=0; i<nvtxs; i++)
71 for (j=xadj[i]; j<xadj[i+1]; j++)
73 m_adjwgt[j] /= w[adjncy[j]];
76 for (i=0; i<nvtxs; i++)
77 for (j=xadj[i]; j<xadj[i+1]; j++)
79 m_adjwgt[j] = adjwgt[j] *1.0/w[i];
82 for (i=0; i<nvtxs; i++)
83 for (j=xadj[i]; j<xadj[i+1]; j++)
85 m_adjwgt[j] /= w[adjncy[j]];
94 idxtype *xadj, *adjncy, *adjwgt, *where;
103 for (i=0; i<nvtxs; i++)
104 for (j=xadj[i]; j<xadj[i+1]; j++)
107 for (i=0; i<nvtxs; i++)
108 for (j=xadj[i]; j<xadj[i+1]; j++)
109 m_adjwgt[j] = adjwgt[j];
113 for (i=0; i<nvtxs; i++)
114 for (j=xadj[i]; j<xadj[i+1]; j++)
116 m_adjwgt[j] = 1.0/sqrt(w[i]);
117 for (i=0; i<nvtxs; i++)
118 for (j=xadj[i]; j<xadj[i+1]; j++)
120 m_adjwgt[j] /= sqrt(w[adjncy[j]]);
123 for (i=0; i<nvtxs; i++)
124 for (j=xadj[i]; j<xadj[i+1]; j++)
126 m_adjwgt[j] = adjwgt[j] *1.0/sqrt(w[i]);
129 for (i=0; i<nvtxs; i++)
130 for (j=xadj[i]; j<xadj[i+1]; j++)
132 m_adjwgt[j] /= sqrt(w[adjncy[j]]);
142 int nvtxs, nedges, moves, iter;
147 nvtxs = graph->
nvtxs;
166 moves =
local_search(ctrl, graph, nparts, chain_length, w, tpwgts, ubfactor);
187 int nvtxs, nbnd, nedges, me, i, j;
188 idxtype *squared_sum, *sum, *xadj, *adjncy, *adjwgt, *where, *new_where, *bndptr, *bndind;
189 float obj, old_obj, epsilon, *inv_sum, *squared_inv_sum;
192 int loopend, currit=0;
195 nvtxs = graph->
nvtxs;
200 where = graph->
where;
206 new_where =
idxmalloc(nvtxs,
"Weighted_kernel_k_means: new_where");
207 for (i=0; i<nvtxs; i++)
208 new_where[i] = where[i];
210 sum =
idxsmalloc(nparts,0,
"Weighted_kernel_k_means: weight sum");
211 inv_sum =
fmalloc(nparts,
"Weighted_kernel_k_means: sum inverse");
212 squared_inv_sum =
fmalloc(nparts,
"Weighted_kernel_k_means: squared sum inverse");
213 squared_sum =
idxsmalloc(nparts,0,
"Weighted_kernel_k_means: weight squared sum");
218 for (i=0; i<nvtxs; i++)
219 sum[where[i]] += w[i];
220 for (i=0; i<nparts; i++)
222 inv_sum[i] = 1.0/sum[i];
223 squared_inv_sum[i] = inv_sum[i]*inv_sum[i];
226 inv_sum[i] = squared_inv_sum[i] = 0;
237 for (i=0; i<nvtxs; i++){
239 for (j=xadj[i]; j<xadj[i+1]; j++)
240 if (where[adjncy[j]] == me)
241 squared_sum[me] += adjwgt[j];
245 for (i=0; i<nparts; i++)
247 obj += squared_sum[i]*1.0/sum[i];
250 linearTerm =
idxmalloc(nparts,
"Weighted_kernel_k_means: new_where");
253 float min_dist,
dist;
300 for (ii=0; ii<loopend; ii++){
306 float inv_wi=1.0/w[i];
307 for (k=0; k<nparts; k++)
309 for (j=xadj[i]; j<xadj[i+1]; j++)
310 linearTerm[where[adjncy[j]]] += adjwgt[j];
312 min_ind = me = where[i];
313 min_dist = squared_sum[me]*squared_inv_sum[me] - 2*inv_wi*linearTerm[me]*inv_sum[me];
317 for (k=0; k<me; k++){
318 dist = squared_sum[k]*squared_inv_sum[k] -2*inv_wi*linearTerm[k]*inv_sum[k];
330 for (k=me+1; k<nparts; k++){
331 dist = squared_sum[k]*squared_inv_sum[k] -2*inv_wi*linearTerm[k]*inv_sum[k];
345 new_where[i] = min_ind;
354 for (i=0; i<nparts; i++)
355 sum[i] = squared_sum[i] = 0;
356 for (i=0; i<nvtxs; i++)
357 sum[new_where[i]] += w[i];
358 for (i=0; i<nparts; i++)
360 inv_sum[i] = 1.0/sum[i];
361 squared_inv_sum[i] = inv_sum[i]*inv_sum[i];
364 inv_sum[i] = squared_inv_sum[i] = 0;
375 for (i=0; i<nvtxs; i++){
377 for (j=xadj[i]; j<xadj[i+1]; j++)
378 if (new_where[adjncy[j]] == me)
379 squared_sum[me] += adjwgt[j];
384 for (i=0; i<nparts; i++)
386 obj += squared_sum[i]*1.0/sum[i];
395 for (ii=0; ii<loopend; ii++){
400 where[i] = new_where[i];
404 }
while((obj - old_obj) > epsilon*obj && currit <
MAXITERATIONS);
405 free(sum); free(squared_sum); free(new_where); free(linearTerm); free(inv_sum); free(squared_inv_sum);
412 int nvtxs, nedges, nbnd, me, i, j, k, s, ii;
413 idxtype *sum, *squared_sum, *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind;
414 float change, obj, epsilon, **kDist, *accum_change;
415 int moves, actual_length, *mark, fidx, loopend;
419 nvtxs = graph->
nvtxs;
423 where = graph->
where;
433 chain =
chainmalloc(chain_length,
"Local_search: local search chain");
434 mark =
ismalloc(loopend, 0 ,
"Local_search: mark");
435 sum =
idxsmalloc(nparts,0,
"Local_search: weight sum");
436 squared_sum =
idxsmalloc(nparts,0,
"Local_search: weight squared sum");
437 kDist =
f2malloc(loopend, nparts,
"Local_search: distance matrix");
438 accum_change =
fmalloc(chain_length+1,
"Local_search: accumulated change");
441 for (i = 0; i<nparts; i++)
442 sum[i] = squared_sum[i] = 0;
443 for (i = 0; i<loopend; i++)
444 for (j = 0; j<nparts; j++)
446 for (i = 0; i<chain_length+1; i++)
451 actual_length = chain_length;
453 for (i=0; i<nvtxs; i++)
454 sum[where[i]] += w[i];
455 for (i=0; i<nvtxs; i++){
457 for (j=xadj[i]; j<xadj[i+1]; j++)
458 if (where[adjncy[j]] == me)
459 squared_sum[me] += adjwgt[j];
464 for (ii=0; ii<loopend; ii++){
469 for (j=xadj[i]; j<xadj[i+1]; j++)
471 kDist[ii][where[adjncy[j]]] += 1.0*adjwgt[j]/w[i];
473 for (k=0; k<nparts; k++)
476 for (ii=0; ii<loopend; ii++)
478 kDist[ii][k] = squared_sum[k]/(1.0*sum[k]*sum[k]) - 2*kDist[ii][k]/sum[k];
480 for (i=0; i<nparts; i++)
482 obj += squared_sum[i]*1.0/sum[i];
483 for (i=0; i<chain_length; i++)
485 float tempMinChange, tempchange, temp_q;
486 int tempid, tempMoveTo, from, to, tempbndind;
491 tempMoveTo = where[tempid];
495 for (ii=0; ii<loopend; ii++){
503 for (k=0; k<nparts; k++)
506 tempchange = -kDist[ii][me]*sum[me]*w[j]/(sum[me]-w[j]) + kDist[ii][k]*sum[k]*w[j]/(sum[k]+w[j]);
507 if (tempchange < tempMinChange){
508 tempMinChange = tempchange;
516 if ((tempMoveTo == where[tempid]) || (mark[tempbndind] >0)){
522 chain[i].
point = tempid;
523 chain[i].
from = where[tempid];
524 chain[i].
to = tempMoveTo;
525 chain[i].
change = tempMinChange;
527 mark[tempbndind] = 1;
529 accum_change[i+1] = accum_change[i] + tempMinChange;
530 from = chain[i].
from;
533 sum[from] -= w[tempid];
534 sum[to] += w[tempid];
536 for (j=xadj[tempid]; j<xadj[tempid+1]; j++)
537 if (where[adjncy[j]] == from)
538 squared_sum[from] -= 2*adjwgt[j];
540 for (ii=0; ii<loopend; ii++){
547 for (j=xadj[s]; j<xadj[s+1]; j++)
548 if (where[adjncy[j]] == from)
550 kDist[ii][from] += adjwgt[j]*1.0/w[s];
552 temp_q = squared_sum[from]/(1.0*sum[from]*sum[from]);
555 for (ii=0; ii<loopend; ii++)
556 kDist[ii][from] = temp_q - 2*kDist[ii][from]/sum[from];
558 for (j=xadj[tempid]; j<xadj[tempid+1]; j++)
559 if (where[adjncy[j]] == to)
560 squared_sum[to] += 2*adjwgt[j];
563 for (ii=0; ii<loopend; ii++){
570 for (j=xadj[s]; j<xadj[s+1]; j++)
571 if (where[adjncy[j]] == to)
573 kDist[ii][to] += adjwgt[j]*1.0/w[s];
575 temp_q = squared_sum[to]/(1.0*sum[to]*sum[to]);
578 for (ii=0; ii<loopend; ii++)
580 kDist[ii][to] = temp_q - 2*kDist[ii][to]/sum[to];
583 fidx =
samin(actual_length, accum_change);
584 if (accum_change[fidx] < -epsilon * obj){
585 for (i= fidx+1; i<=actual_length; i++)
586 where[chain[i-1].
point] = chain[i-1].from;
588 change = accum_change[fidx];
591 for (i= 0; i<actual_length; i++)
592 where[chain[i].
point] = chain[i].from;
597 free(sum); free(squared_sum);free(accum_change); free(chain); free(mark);
600 for (i= 0; i<loopend; i++)
610 int k, j, s, i, nbnd, temp, q1, q2, minchange_id, new_squared_sum1, new_squared_sum2, me, nedges, nvtxs, loopend;
611 float tempchange, minchange, obj, cut;
612 idxtype *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind;
615 nvtxs = graph->
nvtxs;
619 where = graph->
where;
637 new_squared_sum1= new_squared_sum2= squared_sum[me];
640 float inv_sum1 = 1.0/sum[me], inv_sum2 = 1.0/(sum[me]-w[s]);
642 for(k= 0; k<me; k++){
643 q1 = squared_sum[me] - linearTerm[ii][me]*2 + self_sim[ii];
644 q2 = squared_sum[k] + linearTerm[ii][k] *2 - self_sim[ii];
646 tempchange = squared_sum[me]*inv_sum1 + squared_sum[k]*1.0/sum[k] - q1*inv_sum2- q2*1.0/(sum[k]+w[s]);
648 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2 - q2*1.0/(sum[k]+w[s]);
650 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2;
652 if(tempchange < minchange){
653 minchange = tempchange;
655 new_squared_sum1 = q1;
656 new_squared_sum2 = q2;
659 for(k= me+1; k<nparts; k++){
660 q1 = squared_sum[me] - linearTerm[ii][me]*2 +self_sim[ii];
661 q2 = squared_sum[k] + linearTerm[ii][k]*2 - self_sim[ii];
663 tempchange = squared_sum[me]*inv_sum1 + squared_sum[k]*1.0/sum[k] - q1*inv_sum2- q2*1.0/(sum[k]+w[s]);
665 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2 - q2*1.0/(sum[k]+w[s]);
667 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2;
669 if(tempchange < minchange){
670 minchange = tempchange;
672 new_squared_sum1 = q1;
673 new_squared_sum2 = q2;
677 where[s] = minchange_id;
679 sum[minchange_id] += w[s];
704 for (ii = 0; ii<loopend; ii++)
705 for (j = 0; j<nparts; j++)
706 linearTerm[ii][j] = 0;
707 for (ii =0; ii<loopend; ii++){
712 for (j=xadj[s]; j<xadj[s+1]; j++){
714 linearTerm[ii][where[adjncy[j]]] += adjwgt[j];
716 self_sim[ii] = adjwgt[j];
729 squared_sum[me] = new_squared_sum1;
730 squared_sum[minchange_id] = new_squared_sum2;
737 int j, s, ii, nbnd, q1, q2, minchange_id, new_squared_sum1, new_squared_sum2, me, nvtxs, loopend;
738 float tempchange, minchange;
739 idxtype *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind;
741 nvtxs = graph->
nvtxs;
745 where = graph->
where;
749 minchange_id = bndind[0];
757 for(ii=0; ii<loopend; ii++){
763 new_squared_sum1= new_squared_sum2= squared_sum[me];
766 float inv_sum1 = 1.0/sum[me], inv_sum2 = 1.0/(sum[me]-w[s]);
768 q1 = squared_sum[me] - linearTerm[ii][me]*2 + self_sim[ii];
769 q2 = squared_sum[k] + linearTerm[ii][k] *2 + self_sim[ii];
771 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2 - q2*1.0/(sum[k]+w[s]);
773 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2;
775 if(tempchange < minchange){
776 minchange = tempchange;
778 new_squared_sum1 = q1;
779 new_squared_sum2 = q2;
784 where[minchange_id] = k;
785 sum[me] -= w[minchange_id];
786 sum[k] += w[minchange_id];
802 for (ii = 0; ii<loopend; ii++)
803 for (j = 0; j<nparts; j++)
804 linearTerm[ii][j] = 0;
805 for (ii =0; ii<loopend; ii++){
810 for (j=xadj[s]; j<xadj[s+1]; j++){
812 linearTerm[ii][where[adjncy[j]]] += adjwgt[j];
814 self_sim[ii] = adjwgt[j];
913 int *clustersize=
imalloc(nparts,
"remove_empty_clusters: clusterSize");
914 int number_of_empty_cluster=0, i, s;
916 for(i=0; i<nparts; i++)
919 for(i=0; i<nparts; i++)
920 if(clustersize[i] ==0)
921 number_of_empty_cluster ++;
923 if(number_of_empty_cluster>0)
924 local_search(ctrl, graph, nparts, 1, w, tpwgts, ubfactor);
930 int *clustersize=
imalloc(nparts,
"remove_empty_clusters: clusterSize");
931 int number_of_empty_cluster=0, i, s, loopend;
933 for(i=0; i<nparts; i++)
936 for(i=0; i<nparts; i++)
937 if(clustersize[i] ==0)
938 number_of_empty_cluster ++;
941 if(number_of_empty_cluster>0){
942 int nvtxs, me, j, k, ii;
943 idxtype *sum, *squared_sum, *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind, *self_sim, nbnd;
946 nvtxs = graph->
nvtxs;
950 where = graph->
where;
960 sum =
idxsmalloc(nparts,0,
"Local_search: weight sum");
961 squared_sum =
idxsmalloc(nparts,0,
"Local_search: weight squared sum");
962 self_sim =
idxsmalloc(loopend, 0,
"Local_search: self similarity");
963 linearTerm =
i2malloc(loopend, nparts,
"Local_search: linear term");
965 for (i=0; i<nvtxs; i++)
966 sum[where[i]] += w[i];
967 for (i=0; i<nvtxs; i++){
969 for (j=xadj[i]; j<xadj[i+1]; j++)
970 if (where[adjncy[j]] == me)
971 squared_sum[me] += adjwgt[j];
974 for (ii = 0; ii<loopend; ii++)
975 for (j = 0; j<nparts; j++)
976 linearTerm[ii][j] = 0;
977 for (ii =0; ii<loopend; ii++){
982 for (j=xadj[s]; j<xadj[s+1]; j++){
983 linearTerm[ii][where[adjncy[j]]] += adjwgt[j];
985 self_sim[ii] = adjwgt[j];
988 for(k=0; k<nparts; k++)
989 if(clustersize[k] ==0){
992 free(sum); free(squared_sum); free(self_sim);
995 for (i= 0; i<loopend; i++)
1014 int i, nlevels, mustfree=0, temp_cl;
1021 temp_cl = chain_length;
1024 for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->
finer, nlevels++);
1038 if (graph == orggraph){
1040 pingpong(ctrl, graph, nparts, chain_length, tpwgts, ubfactor, 1);
1045 pingpong(ctrl, graph, nparts, chain_length, tpwgts, ubfactor, 0);
1067 if (graph == orggraph)
1075 graph = graph->
finer;
float ComputeRAsso(GraphType *graph, idxtype *where, int npart)
float ComputeNCut(GraphType *graph, idxtype *where, int npart)
static double dist(double x1, double y1, double x2, double y2)
#define IFSET(a, flag, cmd)
Chains * chainmalloc(int n, char *msg)
int ** i2malloc(int, int, char *)
void clusterSize(GraphType *graph, int *clustersize)
float ** f2malloc(int n, int m, char *msg)
#define ComputeKWayPartitionParams
#define ProjectKWayPartition
int local_search(CtrlType *ctrl, GraphType *graph, int nparts, int chain_length, idxtype *w, float *tpwgts, float ubfactor)
void move1Point2EmptyCluster(GraphType *graph, int nparts, idxtype *sum, idxtype *squared_sum, idxtype *w, idxtype *self_sim, int **linearTerm, int k)
void Weighted_kernel_k_means(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *w, float *tpwgts, float ubfactor)
void Compute_Weights(CtrlType *ctrl, GraphType *graph, idxtype *w)
void remove_empty_clusters_l2(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *w, float *tpwgts, float ubfactor)
float onePoint_move(GraphType *graph, int nparts, idxtype *sum, idxtype *squared_sum, idxtype *w, idxtype *self_sim, int **linearTerm, int ii)
void remove_empty_clusters_l1(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *w, float *tpwgts, float ubfactor)
void transform_matrix(CtrlType *ctrl, GraphType *graph, idxtype *w, float *m_adjwgt)
void pingpong(CtrlType *ctrl, GraphType *graph, int nparts, int chain_length, float *tpwgts, float ubfactor, int toplevel)
void MLKKMRefine(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, int chain_length, float *tpwgts, float ubfactor)
void transform_matrix_half(CtrlType *ctrl, GraphType *graph, idxtype *w, float *m_adjwgt)