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 int nvtxs, nedges, moves, iter;
106 printf(
"Chain length is %d.\n", chain_length);
118 moves =
local_search(ctrl, graph, nparts, chain_length, w, tpwgts, ubfactor);
119 printf(
"Number of local search moves is %d\n", moves);
120 printf(
"Number of boundary points is %d\n", graph->
nbnd);
139 int nvtxs, nbnd, nedges, me, i, j;
140 idxtype *squared_sum, *sum, *xadj, *adjncy, *adjwgt, *where, *new_where, *bndptr, *bndind;
141 float obj, old_obj, epsilon, *inv_sum, *squared_inv_sum;
147 nvtxs = graph->
nvtxs;
152 where = graph->
where;
158 new_where =
imalloc(nvtxs,
"Weighted_kernel_k_means: new_where");
159 for (i=0; i<nvtxs; i++)
160 new_where[i] = where[i];
162 sum =
idxsmalloc(nparts,0,
"Weighted_kernel_k_means: weight sum");
163 inv_sum =
fmalloc(nparts,
"Weighted_kernel_k_means: sum inverse");
164 squared_inv_sum =
fmalloc(nparts,
"Weighted_kernel_k_means: squared sum inverse");
165 squared_sum =
idxsmalloc(nparts,0,
"Weighted_kernel_k_means: weight squared sum");
170 for (i=0; i<nvtxs; i++)
171 sum[where[i]] += w[i];
172 for (i=0; i<nparts; i++)
174 inv_sum[i] = 1.0/sum[i];
175 squared_inv_sum[i] = inv_sum[i]*inv_sum[i];
178 inv_sum[i] = squared_inv_sum[i] = 0;
189 for (i=0; i<nvtxs; i++){
191 for (j=xadj[i]; j<xadj[i+1]; j++)
192 if (where[adjncy[j]] == me)
193 squared_sum[me] += adjwgt[j];
197 for (i=0; i<nparts; i++)
199 obj += squared_sum[i]*1.0/sum[i];
202 linearTerm =
imalloc(nparts,
"Weighted_kernel_k_means: new_where");
205 float min_dist,
dist;
251 for (ii=0; ii<loopend; ii++){
257 float inv_wi=1.0/w[i];
258 for (k=0; k<nparts; k++)
260 for (j=xadj[i]; j<xadj[i+1]; j++)
261 linearTerm[where[adjncy[j]]] += adjwgt[j];
263 min_ind = me = where[i];
264 min_dist = squared_sum[me]*squared_inv_sum[me] - 2*inv_wi*linearTerm[me]*inv_sum[me];
268 for (k=0; k<me; k++){
269 dist = squared_sum[k]*squared_inv_sum[k] -2*inv_wi*linearTerm[k]*inv_sum[k];
281 for (k=me+1; k<nparts; k++){
282 dist = squared_sum[k]*squared_inv_sum[k] -2*inv_wi*linearTerm[k]*inv_sum[k];
296 new_where[i] = min_ind;
305 for (i=0; i<nparts; i++)
306 sum[i] = squared_sum[i] = 0;
307 for (i=0; i<nvtxs; i++)
308 sum[new_where[i]] += w[i];
309 for (i=0; i<nparts; i++)
311 inv_sum[i] = 1.0/sum[i];
312 squared_inv_sum[i] = inv_sum[i]*inv_sum[i];
315 inv_sum[i] = squared_inv_sum[i] = 0;
326 for (i=0; i<nvtxs; i++){
328 for (j=xadj[i]; j<xadj[i+1]; j++)
329 if (new_where[adjncy[j]] == me)
330 squared_sum[me] += adjwgt[j];
335 for (i=0; i<nparts; i++)
337 obj += squared_sum[i]*1.0/sum[i];
346 for (ii=0; ii<loopend; ii++){
351 where[i] = new_where[i];
355 }
while((obj - old_obj)> epsilon*obj);
356 free(sum); free(squared_sum); free(new_where); free(linearTerm); free(inv_sum); free(squared_inv_sum);
545 int k, j, s, i, nbnd, temp, q1, q2, minchange_id, new_squared_sum1, new_squared_sum2, me, nedges, nvtxs;
546 float tempchange, minchange, obj, cut;
547 idxtype *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind;
550 nvtxs = graph->
nvtxs;
554 where = graph->
where;
563 new_squared_sum1= new_squared_sum2= squared_sum[me];
566 float inv_sum1 = 1.0/sum[me], inv_sum2 = 1.0/(sum[me]-w[s]);
568 for(k= 0; k<me; k++){
569 q1 = squared_sum[me] - linearTerm[ii][me]*2 + self_sim[ii];
570 q2 = squared_sum[k] + linearTerm[ii][k] *2 + self_sim[ii];
572 tempchange = squared_sum[me]*inv_sum1 + squared_sum[k]*1.0/sum[k] - q1*inv_sum2- q2*1.0/(sum[k]+w[s]);
574 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2 - q2*1.0/(sum[k]+w[s]);
576 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2;
578 if(tempchange < minchange){
579 minchange = tempchange;
581 new_squared_sum1 = q1;
582 new_squared_sum2 = q2;
585 for(k= me+1; k<nparts; k++){
586 q1 = squared_sum[me] - linearTerm[ii][me]*2 +self_sim[ii];
587 q2 = squared_sum[k] + linearTerm[ii][k]*2 + self_sim[ii];
589 tempchange = squared_sum[me]*inv_sum1 + squared_sum[k]*1.0/sum[k] - q1*inv_sum2- q2*1.0/(sum[k]+w[s]);
591 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2 - q2*1.0/(sum[k]+w[s]);
593 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2;
595 if(tempchange < minchange){
596 minchange = tempchange;
598 new_squared_sum1 = q1;
599 new_squared_sum2 = q2;
603 where[s] = minchange_id;
605 sum[minchange_id] += w[s];
611 for (j=xadj[s]; j<xadj[s+1]; j++){
612 int boundary, adj_temp;
613 adj_temp = adjncy[j];
614 boundary = bndptr[adj_temp];
618 linearTerm[boundary][me] -= adjwgt[j];
622 linearTerm[boundary][minchange_id] += adjwgt[j];
635 squared_sum[me] = new_squared_sum1;
636 squared_sum[minchange_id] = new_squared_sum2;
643 int j, s, ii, nbnd, q1, q2, minchange_id, new_squared_sum1, new_squared_sum2, me, nvtxs;
644 float tempchange, minchange;
645 idxtype *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind;
647 nvtxs = graph->
nvtxs;
651 where = graph->
where;
655 minchange_id = bndind[0];
658 for(ii=0; ii<nbnd; ii++){
661 new_squared_sum1= new_squared_sum2= squared_sum[me];
664 float inv_sum1 = 1.0/sum[me], inv_sum2 = 1.0/(sum[me]-w[s]);
666 q1 = squared_sum[me] - linearTerm[ii][me]*2 + self_sim[ii];
667 q2 = squared_sum[k] + linearTerm[ii][k] *2 + self_sim[ii];
669 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2 - q2*1.0/(sum[k]+w[s]);
671 tempchange = squared_sum[me]*inv_sum1 - q1*inv_sum2;
673 if(tempchange < minchange){
674 minchange = tempchange;
676 new_squared_sum1 = q1;
677 new_squared_sum2 = q2;
682 where[minchange_id] = k;
683 sum[me] -= w[minchange_id];
684 sum[k] += w[minchange_id];
686 for (j=xadj[minchange_id]; j<xadj[minchange_id+1]; j++){
687 int boundary, adj_temp;
688 adj_temp = adjncy[j];
689 boundary = bndptr[adj_temp];
691 linearTerm[boundary][me] -= adjwgt[j];
692 linearTerm[boundary][k] += adjwgt[j];
694 squared_sum[me] = new_squared_sum1;
695 squared_sum[k] = new_squared_sum2;
702 int nvtxs, nedges, nbnd, me, i, j, k, s, ii;
703 idxtype *sum, *squared_sum, *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind, *self_sim;
704 float change, obj, epsilon, accum_change, minchange;
705 int moves, loopTimes, **linearTerm;
708 nvtxs = graph->
nvtxs;
712 where = graph->
where;
717 sum =
idxsmalloc(nparts,0,
"Local_search: weight sum");
718 squared_sum =
idxsmalloc(nparts,0,
"Local_search: weight squared sum");
719 self_sim =
idxsmalloc(nbnd, 0,
"Local_search: self similarity");
720 linearTerm =
i2malloc(nbnd, nparts,
"Local_search: linear term");
726 for (i=0; i<nvtxs; i++)
727 sum[where[i]] += w[i];
728 for (i=0; i<nvtxs; i++){
730 for (j=xadj[i]; j<xadj[i+1]; j++)
731 if (where[adjncy[j]] == me)
732 squared_sum[me] += adjwgt[j];
735 for (ii = 0; ii<nbnd; ii++)
736 for (j = 0; j<nparts; j++)
737 linearTerm[ii][j] = 0;
738 for (ii =0; ii<nbnd; ii++){
740 for (j=xadj[s]; j<xadj[s+1]; j++){
742 linearTerm[ii][where[adjncy[j]]] += adjwgt[j];
744 self_sim[ii] = adjwgt[j];
750 for (i=0; i<nparts; i++)
752 obj += squared_sum[i]*1.0/sum[i];
758 while (loopTimes < chain_length){
761 for (ii=0; ii<nbnd; ii++){
762 minchange =
onePoint_move(graph, nparts, sum, squared_sum, w, self_sim, linearTerm, ii);
763 accum_change += minchange;
766 if (accum_change > -epsilon * obj){
773 free(sum); free(squared_sum); free(self_sim);
776 for (i= 0; i<nbnd; i++)
786 int *clustersize=
imalloc(nparts,
"remove_empty_clusters: clusterSize");
787 int number_of_empty_cluster=0, i, s;
789 for(i=0; i<nparts; i++)
792 for(i=0; i<nparts; i++)
793 if(clustersize[i] ==0)
794 number_of_empty_cluster ++;
796 if(number_of_empty_cluster>0)
797 local_search(ctrl, graph, nparts, 1, w, tpwgts, ubfactor);
803 int *clustersize=
imalloc(nparts,
"remove_empty_clusters: clusterSize");
804 int number_of_empty_cluster=0, i, s;
806 for(i=0; i<nparts; i++)
809 for(i=0; i<nparts; i++)
810 if(clustersize[i] ==0)
811 number_of_empty_cluster ++;
814 if(number_of_empty_cluster>0){
815 int nvtxs, me, j, k, ii;
816 idxtype *sum, *squared_sum, *xadj, *adjncy, *adjwgt, *where, *bndptr, *bndind, *self_sim, nbnd;
819 nvtxs = graph->
nvtxs;
823 where = graph->
where;
828 sum =
idxsmalloc(nparts,0,
"Local_search: weight sum");
829 squared_sum =
idxsmalloc(nparts,0,
"Local_search: weight squared sum");
830 self_sim =
idxsmalloc(nbnd, 0,
"Local_search: self similarity");
831 linearTerm =
i2malloc(nbnd, nparts,
"Local_search: linear term");
833 for (i=0; i<nvtxs; i++)
834 sum[where[i]] += w[i];
835 for (i=0; i<nvtxs; i++){
837 for (j=xadj[i]; j<xadj[i+1]; j++)
838 if (where[adjncy[j]] == me)
839 squared_sum[me] += adjwgt[j];
842 for (ii = 0; ii<nbnd; ii++)
843 for (j = 0; j<nparts; j++)
844 linearTerm[ii][j] = 0;
845 for (ii =0; ii<nbnd; ii++){
847 for (j=xadj[s]; j<xadj[s+1]; j++){
848 linearTerm[ii][where[adjncy[j]]] += adjwgt[j];
850 self_sim[ii] = adjwgt[j];
853 for(k=0; k<nparts; k++)
854 if(clustersize[k] ==0){
857 free(sum); free(squared_sum); free(self_sim);
860 for (i= 0; i<nbnd; i++)
879 int i, nlevels, mustfree=0, temp_cl;
886 temp_cl = chain_length;
889 for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->
finer, nlevels++);
903 if (graph == orggraph){
905 pingpong(ctrl, graph, nparts, chain_length, tpwgts, ubfactor, 1);
910 pingpong(ctrl, graph, nparts, chain_length, tpwgts, ubfactor, 0);
932 if (graph == orggraph)
940 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)
int ** i2malloc(int, int, char *)
void clusterSize(GraphType *graph, int *clustersize)
#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)