Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
			
		}
	}	
}
Ejemplo n.º 3
0
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;
}