Пример #1
0
    double64_t TestMerge(const CGraph* graph, const CommunityPartition* partition, const double64_t alfa, const CommunityInteraction& interaction) {
//        printf("Testing merge %d - %d\n", interaction.m_CommunityId1, interaction.m_CommunityId2);
//        PrintCommunity(partition, interaction.m_CommunityId1);
//        PrintCommunity(partition, interaction.m_CommunityId2);

        std::set<uint32_t> community;
        const uint32_t* nodes = &partition->m_Communities[partition->m_CommunityIndices[interaction.m_CommunityId1]+1];
        uint32_t size = partition->m_Communities[partition->m_CommunityIndices[interaction.m_CommunityId1]];
        double64_t before = 0.0;
        for( uint32_t i = 0; i < size; ++i ) {
            community.insert(nodes[i]);
            before += partition->m_NodeWCC[nodes[i]];
        }

        nodes = &partition->m_Communities[partition->m_CommunityIndices[interaction.m_CommunityId2]+1];
        size = partition->m_Communities[partition->m_CommunityIndices[interaction.m_CommunityId2]];
        for( uint32_t i = 0; i < size; ++i ) {
            community.insert(nodes[i]);
            before += partition->m_NodeWCC[nodes[i]];
        }
 /*       for( std::set<uint32_t>::iterator it = community.begin(); it != community.end(); ++it){
            printf("%d ",*it);
        }
        printf("\n");*/
        double64_t after = ComputeWCC(graph,alfa,community);
//        printf("after: %f, before: %f\n", after, before);
        return (after - before);
    }
Пример #2
0
double64_t ComputeWCC(const CGraph * graph, const uint32_t * communities,
                      const uint32_t numCommunities, const uint32_t* labelsIndices,
                      const uint32_t * communitiesInvIndex, double64_t* wccs) {
    double64_t globalWCC = 0;

    #pragma omp parallel for schedule(static, 8) reduction(+:globalWCC)
    for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
        uint32_t communitySize = communitiesInvIndex[labelsIndices[communities[i]]];
        wccs[i] = ComputeWCC(graph, i, communities[i], communities, communitySize);
        globalWCC += wccs[i];
    }
    return globalWCC;
}
Пример #3
0
    /** @brief Initializes a partition structure from a labels to communities array.
     *  @param[in] graph The graph where the partition belongs.
     *  @param[out] partition The partition structure where the partition will be stored.
     *  @param[in] communities The array of nodes to community labels from which the partition is initialized.
     *  @param[in] alfa The alfa parameter controlling the cohesivness of the communities.*/
    static uint32_t InitializeFromLabelsArray(const CGraph* graph, CommunityPartition* partition, const uint32_t* communities, const double64_t alfa) {

        //Initializing default values
        partition->m_NodeLabels = NULL;
        partition->m_CommunityIndices = NULL;
        partition->m_Communities = NULL;
        partition->m_InternalEdges = NULL;
        partition->m_ExternalEdges = NULL;
        partition->m_NodeWCC = NULL;
        partition->m_NumCommunities = 0;
        partition->m_ConnectedInsert = NULL;
        partition->m_ConnectedRemove = NULL;
        partition->m_NotConnectedInsert = NULL;
        partition->m_NotConnectedRemove = NULL;
        partition->m_WCC = 0;

        partition->m_NumNodes = graph->GetNumNodes();
        partition->m_NodeLabels = new uint32_t[graph->GetNumNodes()];
        if (!partition->m_NodeLabels) {
            printf("Error allocating node labels %u.\n", graph->GetNumNodes());
            return 1;
        }

        uint32_t maxNumCommunities = 0;
        for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
            if (communities[i] > maxNumCommunities) {
                maxNumCommunities = communities[i];
            }
        }
        maxNumCommunities++;

        partition->m_NumCommunities = CompressCommunityLabels(graph, communities, partition->m_NodeLabels);


        //Allocating space to store the communities
        partition->m_CommunityIndices = new uint32_t[partition->m_NumCommunities];
        if (!partition->m_CommunityIndices) {
            printf("Error allocating labels indices.\n");
            return 1;
        }
        partition->m_Communities = new uint32_t[partition->m_NumCommunities + graph->GetNumNodes()];
        if (!partition->m_Communities) {
            printf("Error allocating inverted index.\n");
            return 1;
        }

        partition->m_NodeWCC = new double64_t[graph->GetNumNodes()];
        if (!partition->m_NodeWCC) {
            printf("Error allocating node labels %u.\n", graph->GetNumNodes());
            return 1;
        }

        partition->m_ConnectedInsert = new double64_t[graph->GetNumNodes()];
        if (!partition->m_ConnectedInsert) {
            printf("Error allocating connected insert.\n");
            return 1;
        }

        partition->m_ConnectedRemove = new double64_t[graph->GetNumNodes()];
        if (!partition->m_ConnectedRemove) {
            printf("Error allocating connected insert.\n");
            return 1;
        }

        partition->m_NotConnectedInsert = new double64_t[graph->GetNumNodes()];
        if (!partition->m_NotConnectedInsert) {
            printf("Error allocating connected insert.\n");
            return 1;
        }

        partition->m_NotConnectedRemove = new double64_t[graph->GetNumNodes()];
        if (!partition->m_NotConnectedRemove) {
            printf("Error allocating connected insert.\n");
            return 1;
        }

        //Creating the counters the creation of the inverted index
        uint32_t* counters = new uint32_t[partition->m_NumCommunities];
        if (!counters) {
            printf("Error allocating counters: %u\n", partition->m_NumCommunities);
            return 1;
        }

#pragma omp parallel for schedule(SCD_SCHEDULING, SCD_THREAD_BLOCK_SIZE)
        for (uint32_t i = 0; i < partition->m_NumCommunities; i++) {
            counters[i] = 0;
        }
        //Computing community sizes;
        for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
            counters[partition->m_NodeLabels[i]]++;
        }
        //Initializing labels indices.
        uint32_t currentIndex = 0;
        for (uint32_t i = 0; i < partition->m_NumCommunities; i++) {
            if (counters[i] > 0) {
                partition->m_CommunityIndices[i] = currentIndex;
                partition->m_Communities[currentIndex] = counters[i];
                currentIndex += counters[i] + 1;
            } else {
                partition->m_CommunityIndices[i] = SCD_INVALID_COMMUNITY;
            }
            counters[i] = 0;
        }
        //Initializing the inverted index.
        for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
            uint32_t lIndex = partition->m_CommunityIndices[partition->m_NodeLabels[i]];
            assert(lIndex != SCD_INVALID_COMMUNITY);
            assert(counters[partition->m_NodeLabels[i]] < partition->m_Communities[lIndex]);
            partition->m_Communities[lIndex + counters[partition->m_NodeLabels[i]] + 1] = i;
            counters[partition->m_NodeLabels[i]]++;
        }

        for (uint32_t i = 0; i < partition->m_NumCommunities; i++) {
            if (partition->m_CommunityIndices[i] != SCD_INVALID_COMMUNITY) {
                uint32_t lIndex = partition->m_CommunityIndices[i];
                qsort(&(partition->m_Communities[lIndex + 1]), partition->m_Communities[lIndex], sizeof (uint32_t), Compare_Ids);
            }
        }
        delete[] counters;

        partition->m_InternalEdges = new uint32_t[partition->m_NumCommunities];
        if (!partition->m_InternalEdges) {
            printf("Error while allocating internal edges.\n");
            return 1;
        }

        partition->m_ExternalEdges = new uint32_t[partition->m_NumCommunities];
        if (!partition->m_ExternalEdges) {
            printf("Error while allocating external edges.\n");
            return 1;
        }

#pragma omp parallel for schedule(SCD_SCHEDULING, SCD_THREAD_BLOCK_SIZE)
        for (uint32_t i = 0; i < partition->m_NumCommunities; i++) {
            partition->m_InternalEdges[i] = 0;
            partition->m_ExternalEdges[i] = 0;
        }

        for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
            const uint32_t* adjacencies = graph->GetNeighbors(i);
            uint32_t degree = graph->GetDegree(i);
            for (uint32_t j = 0; j < degree; j++) {
                if (i < adjacencies[j]) {
                    if (partition->m_NodeLabels[i] == partition->m_NodeLabels[adjacencies[j]]) {
                        partition->m_InternalEdges[partition->m_NodeLabels[i]]++;
                    } else {
                        partition->m_ExternalEdges[partition->m_NodeLabels[i]]++;
                        partition->m_ExternalEdges[partition->m_NodeLabels[adjacencies[j]]]++;
                    }
                }
            }
        }

        partition->m_WCC = ComputeWCC(graph, alfa, partition->m_NodeLabels, partition->m_NumCommunities, partition->m_CommunityIndices, partition->m_Communities, partition->m_NodeWCC);

        for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
            uint32_t communityLabel = partition->m_NodeLabels[i];
            uint32_t degree = graph->GetDegree(i);
            const uint32_t* adjacencies = graph->GetNeighbors(i);
            uint32_t kin = 0;
            for(uint32_t j = 0; j < degree; ++j){
                uint32_t neighbor = adjacencies[j];
                if( partition->m_NodeLabels[neighbor] == communityLabel ) kin++;
            }
            uint32_t r = partition->m_Communities[partition->m_CommunityIndices[communityLabel]];
            double64_t denom = (double64_t)(degree+alfa*(r-kin-1));
            partition->m_ConnectedInsert[i] = denom > 0.0 ? (kin+1) / denom : 0.0 ;
            partition->m_ConnectedInsert[i]-=partition->m_NodeWCC[i];

            denom = (double64_t)(degree+alfa*(r-1-kin));
            partition->m_ConnectedRemove[i] = denom > 0.0 ? (kin-1) / denom : 0.0 ;
            partition->m_ConnectedRemove[i] -= partition->m_NodeWCC[i];

            denom = (degree+alfa*(r-kin));
            partition->m_NotConnectedInsert[i] = denom > 0.0 ? kin / denom : 0.0;
            partition->m_NotConnectedInsert[i] -= partition->m_NodeWCC[i];

            denom = (degree+alfa*(r-1-1-kin));
            partition->m_NotConnectedRemove[i] = denom > 0.0 ? kin / denom : 0.0;
            partition->m_NotConnectedRemove[i] -= partition->m_NodeWCC[i];
        }

        return 0;
    }