int main(int argc, char** argv) { printf("Start!\n"); int points[NUM_PTS][DIMENSIONS]; int i; int j; //int* dumm; for (i = 0; i < NUM_PTS; i++) { for (j = 0; j < DIMENSIONS; j++) { points[i][j] = i; //dumm = malloc(sizeof(int)); } } printf("Entering dbscan.\n"); DynamicArray* dummy; dummy = dbscan( points, NUM_PTS, 1, 1 ); printf("Leaving dbscan.\n"); printf("Num clusters: %d\n", (*dummy).num_elements); printf("Freeing the main list of points\n"); DynamicArray* all_points = dynamic_array_get_element( dummy, 0 ); DBScanPoint* pt; DynamicArray* arr; for ( i = 0; i < NUM_PTS; i++ ) { pt = dynamic_array_get_element( all_points, i ); arr = (*pt).points_in_threshold; free( (*arr)._elements ); free(arr); free(pt); } free( (*all_points)._elements ); free( all_points ); printf("Doing this shit.\n"); DynamicArray* inner_arr; for ( i = 1; i < (*dummy).num_elements; i++ ) { inner_arr = dynamic_array_get_element( dummy, i ); if (inner_arr == NULL) printf("GOD DAMNIT\n"); /* for (j = 0; j < (*inner_arr).num_elements; j++) { free( dynamic_array_get_element( inner_arr, j ) ); } */ free( (*inner_arr)._elements ); free( inner_arr ); } free( (*dummy)._elements ); free( dummy ); printf("Now im doing this shit\n"); //destroy_dynamic_array( dummy, LEAVE_ELEMENTS ); //destroy_n_nested_dynamic_array( dummy, 2, LEAVE_ELEMENTS ); printf("Done freeing shit.\n"); return 0; }
void DBSCAN::wfit( const DBSCAN::ClusterData& C, const DBSCAN::FeaturesWeights& W ) { prepare_labels( C.size1() ); const DBSCAN::DistanceMatrix D = calc_dist_matrix( C, W ); dbscan( D ); }
QVariantMap QgsDbscanClusteringAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) { std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); if ( !source ) throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) ); const std::size_t minSize = static_cast< std::size_t>( parameterAsInt( parameters, QStringLiteral( "MIN_SIZE" ), context ) ); const double eps = parameterAsDouble( parameters, QStringLiteral( "EPS" ), context ); const bool borderPointsAreNoise = parameterAsBoolean( parameters, QStringLiteral( "DBSCAN*" ), context ); QgsFields outputFields = source->fields(); const QString clusterFieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context ); QgsFields newFields; newFields.append( QgsField( clusterFieldName, QVariant::Int ) ); outputFields = QgsProcessingUtils::combineFields( outputFields, newFields ); QString dest; std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, outputFields, source->wkbType(), source->sourceCrs() ) ); if ( !sink ) throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) ); // build spatial index feedback->pushInfo( QObject::tr( "Building spatial index" ) ); QgsSpatialIndexKDBush index( *source, feedback ); if ( feedback->isCanceled() ) return QVariantMap(); // dbscan! feedback->pushInfo( QObject::tr( "Analysing clusters" ) ); std::unordered_map< QgsFeatureId, int> idToCluster; idToCluster.reserve( index.size() ); QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setNoAttributes() ); const long featureCount = source->featureCount(); int clusterCount = 0; dbscan( minSize, eps, borderPointsAreNoise, featureCount, features, index, idToCluster, clusterCount, feedback ); // write clusters const double writeStep = featureCount > 0 ? 10.0 / featureCount : 1; features = source->getFeatures(); int i = 0; QgsFeature feat; while ( features.nextFeature( feat ) ) { i++; if ( feedback->isCanceled() ) { break; } feedback->setProgress( 90 + i * writeStep ); QgsAttributes attr = feat.attributes(); auto cluster = idToCluster.find( feat.id() ); if ( cluster != idToCluster.end() ) { attr << cluster->second; } else { attr << QVariant(); } feat.setAttributes( attr ); sink->addFeature( feat, QgsFeatureSink::FastInsert ); } QVariantMap outputs; outputs.insert( QStringLiteral( "OUTPUT" ), dest ); outputs.insert( QStringLiteral( "NUM_CLUSTERS" ), clusterCount ); return outputs; }
void DBSCAN::fit_precomputed( const DBSCAN::DistanceMatrix& D ) { prepare_labels( D.size1() ); dbscan( D ); }
std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_numerical_result){ std::vector< std::pair<int,int> > result; m_cluster_vector.clear(); for(unsigned int ii = 0; ii < in_numerical_result.size(); ii++){ const OneObjectRow& oor = in_numerical_result.getRow(ii); //populate the list of valid items with LAB color mean, ID and the cluster state if ( oor.isValid() || (oor.getGUIValid() == 1) ){ m_cluster_vector.push_back(ClusterPoint( ii, 0, false, oor.getLABMean() )); } else { result.push_back( std::make_pair<int,int>( ii, 0 ) ); } } dbscan(); //Count how many cells per cluster, make the most populated cell group cluster 1 //To start, just make a vector of all cluster IDs std::vector<int> cluster_ids; for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ cluster_ids.push_back(it->getClusterID()); } //if we have clusters if (!cluster_ids.empty()){ DEV_INFOS("Re-ordering them to make cluster 1 most abudant"); int highest_cluster_number = *std::max_element(cluster_ids.begin(), cluster_ids.end()); //create a vector with the length equal to number of clusters, we will stick //the amount of each cluster we have in here //remember we start at cluster 0, we use pairs to preserve the index (original cluster num) DEV_INFOS("Make cluster counts vector with " << highest_cluster_number+1 << " elements"); std::vector<std::pair<int,int>> cluster_counts; for (int ii=0; ii<=highest_cluster_number; ii++){ cluster_counts.push_back(std::pair<int,int>(ii,0)); } //DEV_INFOS("Populate cluster vector"); //poulate the vector so it contains <clusterID, number_of_clusters> for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ cluster_counts[it->getClusterID()].second++; } //Force NA cluster to be sorted last. cluster_counts[0].second=0; //DEV_INFOS("Sorting Cluster Abundancies"); //sort by second pair element std::sort(cluster_counts.begin(),cluster_counts.end(), sort_by_second); for (auto it=cluster_counts.begin(); it != cluster_counts.end(); it++){ //DEV_INFOS("a: "<< it->first << " b: " <<it->second); } //make a map that gives map['oldID']=newID std::map<int,int> cluster_map; for (int ii=0; ii<=highest_cluster_number; ii++){ cluster_map.insert( std::pair<int,int>(cluster_counts[ii].first, ii+1)); //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<<ii); } //remember to reset cluster 0 to position 0, as this is NA, //Just above we added one to all the other cluster numbers //to leave room for this cluster_map[0]=0; DEV_INFOS("Preparing Results Vector"); //Populate based on the map //Don't forget cluster 0 = NA for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ result.push_back(std::pair<int,int>( it->getID(), cluster_map[it->getClusterID()] )); } } //We have no clusters, but we need to prepare the results vector anyway else { for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ result.push_back(std::make_pair<int,int>( it->getID(), it->getClusterID() )); } } return result; }