void KCenterClustering::ClusterIncrement( int * nClusters, double * maxRadius ) { if( numClusters == 0 ) { // randomly pick one node as the first center. srand( (unsigned)time( NULL ) ); int nc = rand() % N; // new center // add the ind-th node to the first center. pCenters[0] = nc; // compute the distances from each node to the first center. // initialize the circular linked list, the center is the // sentinel node. const double *x_nc, *x_j; x_nc = px + nc*d; x_j = px; for (int j = 0; j < N; x_j += d, j++) { dist_C[j] = (j==nc)? 0.0:ddist(d, x_j, x_nc); cnext[j] = j+1; cprev[j] = j-1; } cnext[N-1] = 0; // link the tail to the head. cprev[0] = N-1; // link the head to the tail. // compute the radius of the first cluster and the farthest // node to the center. nc = idmax(N,dist_C); far2c[0] = nc; r[0] = dist_C[nc]; MaxClusterRadius=sqrt(r[0]); numClusters++; } else { if( numClusters < K && MaxClusterRadius > 0 ) { int i = numClusters; int nc; const double *x_nc, *x_j; //find the maximum of vector dist_C, i.e., find the node //that is farthest away from C. It is a new center. nc = idmax(i,r); nc = far2c[nc]; pCenters[i] = nc; //add the ind-th node to the current center. r[i] = dist_C[nc] = 0.0;pci[nc]=i; far2c[i] = nc; cnext[cprev[nc]] = cnext[nc]; // delete nc cprev[cnext[nc]] = cprev[nc]; cnext[nc] = cprev[nc] = nc; //self-loop //update the distances from each point to the current center. x_nc = px + nc*d; for (int j = 0; j < i; j++) { int ct_j = pCenters[j]; x_j = px + ct_j*d; double dc2cq = ddist(d, x_j, x_nc) / 4; if (dc2cq < r[j]) // neighbor cluster { r[j] = 0.0; far2c[j] = ct_j; int k = cnext[ct_j]; while (k != ct_j) // visit the circular linked list { int nextk = cnext[k]; //compare the distances from new center //and from current center. double dist2c_k = dist_C[k]; if ( dc2cq < dist2c_k ) { x_j = px + k*d; double dd = ddist(d, x_j, x_nc); if ( dd < dist2c_k ) { dist_C[k] = dd; // update distances to center pci[k]=i; if (r[i] < dd) // find max r { r[i] = dd; far2c[i] = k; } cnext[cprev[k]] = nextk; // delete nextk from ct_j cprev[nextk] = cprev[k]; cnext[k] = cnext[nc]; // insert nextk to nc cprev[cnext[nc]] = k; cnext[nc] = k; cprev[k] = nc; } else if ( r[j] < dist2c_k ) { r[j] = dist2c_k; far2c[j] = k; } } else if ( r[j] < dist2c_k ) { r[j] = dist2c_k; far2c[j] = k; } // if d < 2 r_k k = nextk; } // while k } // if d < 2 r } // for j numClusters++; nc = idmax(numClusters,r); MaxClusterRadius=sqrt(r[nc]); } // if( numClusters < K && MaxClusterRadius > 0 ) } // else ( numClusters > 0 ) if( nClusters != NULL ) *nClusters = numClusters; if( maxRadius != NULL ) *maxRadius = MaxClusterRadius; }
void Kcenter(double *x , int d , int Nx , int K , double *xc , int *indxc , int *indx , int *xboxsz , double *dist_C) { double *x_ind , *x_j; register double temp ; int i , j , ind , nd , ibase; /* randomly pick one node as the first center. */ /* srand( (unsigned)time( NULL ) ); */ /* ind = rand() % Nx; */ ind = 1; *indxc++ = ind; x_j = x; x_ind = x + ind*d; for (j = 0 ; j < Nx ; x_j += d , j++) { dist_C[j] = (j==ind) ? 0.0 : ddist(x_j , x_ind , d); indx[j] = 0; } for(i = 1 ; i < K ; i++) { ind = idmax(dist_C , Nx); *indxc++ = ind; x_j = x; x_ind = x + ind*d; for (j = 0 ; j < Nx ; x_j += d, j++) { temp = (j==ind) ? 0.0 : ddist(x_j , x_ind , d); if (temp < dist_C[j]) { dist_C[j] = temp; indx[j] = i; } } } for (i = 0 ; i < K ; i++) { xboxsz[i] = 0; } for (i = 0; i < d*K; i++) { xc[i] = 0.0; } for (i = 0 , nd = 0 ; i < Nx ; i++ , nd += d) { xboxsz[indx[i]]++; ibase = indx[i]*d; for (j = 0 ; j < d; j++) { xc[j + ibase ] += x[j + nd]; } } for (i = 0 , ibase = 0 ; i < K ; i++ , ibase += d) { temp = 1.0/xboxsz[i]; for (j = 0; j < d; j++) { xc[j + ibase] *= temp; } } }
int KCenterClustering::Cluster() { // randomly pick one node as the first center. srand( (unsigned)time( NULL ) ); int nc = rand() % N; // new center // add the ind-th node to the first center. pCenters[0] = nc; // compute the distances from each node to the first center. // initialize the circular linked list, the center is the // sentinel node. const double *x_nc, *x_j; x_nc = px + nc*d; x_j = px; for (int j = 0; j < N; x_j += d, j++) { dist_C[j] = (j==nc)? 0.0:ddist(d, x_j, x_nc); cnext[j] = j+1; cprev[j] = j-1; } cnext[N-1] = 0; // link the tail to the head. cprev[0] = N-1; // link the head to the tail. // compute the radius of the first cluster and the farthest // node to the center. nc = idmax(N,dist_C); far2c[0] = nc; r[0] = dist_C[nc]; MaxClusterRadius=sqrt(r[0]); numClusters = 1; for(int i = 1; i < K && MaxClusterRadius > 0; i++) { //find the maximum of vector dist_C, i.e., find the node //that is farthest away from C. It is a new center. nc = idmax(i,r); nc = far2c[nc]; pCenters[i] = nc; //add the ind-th node to the current center. r[i] = dist_C[nc] = 0.0;pci[nc]=i; far2c[i] = nc; cnext[cprev[nc]] = cnext[nc]; // delete nc cprev[cnext[nc]] = cprev[nc]; cnext[nc] = cprev[nc] = nc; //self-loop //update the distances from each point to the current center. x_nc = px + nc*d; for (int j = 0; j < i; j++) { int ct_j = pCenters[j]; x_j = px + ct_j*d; double dc2cq = ddist(d, x_j, x_nc) / 4; if (dc2cq < r[j]) // neighbor cluster { r[j] = 0.0; far2c[j] = ct_j; int k = cnext[ct_j]; while (k != ct_j) // visit the circular linked list { int nextk = cnext[k]; //compare the distances from new center //and from current center. double dist2c_k = dist_C[k]; if ( dc2cq < dist2c_k ) { x_j = px + k*d; double dd = ddist(d, x_j, x_nc); if ( dd < dist2c_k ) { dist_C[k] = dd; // update distances to center pci[k]=i; if (r[i] < dd) // find max r { r[i] = dd; far2c[i] = k; } cnext[cprev[k]] = nextk; // delete nextk from ct_j cprev[nextk] = cprev[k]; cnext[k] = cnext[nc]; // insert nextk to nc cprev[cnext[nc]] = k; cnext[nc] = k; cprev[k] = nc; } else if ( r[j] < dist2c_k ) { r[j] = dist2c_k; far2c[j] = k; } } else if ( r[j] < dist2c_k ) { r[j] = dist2c_k; far2c[j] = k; } // if d < 2 r_k k = nextk; } // while k } // if d < 2 r } // for j // added by vlad 2/6/07 to make sure that we don't keep clustering once each cluster has radius 0 // otherwise some clusters will have no pts assigned to them nc = idmax(i+1,r); MaxClusterRadius=sqrt(r[nc]); numClusters = i+1; } // for i // commented by vlad 2/6/07 to move it above inside of the loop //nc = idmax(K,r); //MaxClusterRadius=sqrt(r[nc]); //numClusters = K; // added by Vlad 1/24/07 return numClusters; }