static void chooseRemaining ( Relation < ? extends NumberVector > relation , DBIDs ids , DistanceQuery < NumberVector > distQ , int k , List < NumberVector > means , WritableDoubleDataStore weights , double weightsum , Random random ) { while ( true ) { if ( weightsum > Double . MAX_VALUE ) { throw new IllegalStateException ( "Could not choose a reasonable mean - too many data points, too large distance sum?" ) ; } if ( weightsum < Double . MIN_NORMAL ) { LoggingUtil . warning ( "Could not choose a reasonable mean - to few data points?" ) ; } double r = random . nextDouble ( ) * weightsum ; while ( r <= 0 && weightsum > Double . MIN_NORMAL ) { r = random . nextDouble ( ) * weightsum ; // Try harder to not choose 0. } DBIDIter it = ids . iter ( ) ; while ( it . valid ( ) ) { if ( ( r -= weights . doubleValue ( it ) ) < 0 ) { break ; } it . advance ( ) ; } if ( ! it . valid ( ) ) { // Rare case, but happens due to floating math weightsum -= r ; // Decrease continue ; // Retry } // Add new mean: final NumberVector newmean = relation . get ( it ) ; means . add ( newmean ) ; if ( means . size ( ) >= k ) { break ; } // Update weights: weights . putDouble ( it , 0. ) ; weightsum = updateWeights ( weights , ids , newmean , distQ ) ; } }
Choose remaining means weighted by distance .