Ejemplo n.º 1
0
    uint32_t InitializeSimplePartition(const CGraph* graph, CommunityPartition* partition, const double64_t alfa) {

        //Computing the clustering coefficient of each node of the graph.
        NodeClustering* nC = new NodeClustering[graph->GetNumNodes()];
        if (!nC) {
            printf("Error allocating node clustering array.");
            return 1;
        }
        for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
            nC[i].m_NodeId = i;
            nC[i].m_Degree = graph->GetDegree(i);
            nC[i].m_CC = graph->GetTotalTriangles(i) / (double64_t) (nC[i].m_Degree * (nC[i].m_Degree - 1));
        }
        qsort(nC, graph->GetNumNodes(), sizeof (NodeClustering), Compare_NodeClusterings);
        //Creating a vector to track which nodes have already been visited.
        bool * visited = new bool[graph->GetNumNodes()];
        if (!visited) {
            printf("Error allocating visited array.");
            return 1;
        }

        memset(visited, false, graph->GetNumNodes() );

        uint32_t* communities = new uint32_t[graph->GetNumNodes()];
        if (!communities) {
            printf("Error allocating communities array.\n");
            return 1;
        }

        uint32_t nextLabel = 0;
        for (uint32_t i = 0; i < graph->GetNumNodes(); i++) {
            NodeClustering* nodeClustering = &nC[i];
            //          printf("%f\n", nodeClustering->m_CC);
            if (!visited[nodeClustering->m_NodeId]) {
                visited[nodeClustering->m_NodeId] = true;
                communities[nodeClustering->m_NodeId] = nextLabel;
                const uint32_t* adjacencies1 = graph->GetNeighbors(nodeClustering->m_NodeId);
                uint32_t degree = graph->GetDegree(nodeClustering->m_NodeId);

                for (uint32_t j = 0; j < degree; j++) {
                    if (!visited[adjacencies1[j]]) {                        
                        visited[adjacencies1[j]] = true;
                        communities[adjacencies1[j]] = nextLabel;                       
                    }
                }
                nextLabel++;
            }
        }
        delete [] visited;
        delete [] nC;

        InitializeFromLabelsArray(graph, partition, communities, alfa);
        delete [] communities;
        return 0;
    }
Ejemplo n.º 2
0
    uint32_t    LoadPartition( const CGraph* graph, CommunityPartition* partition, const char_t* partitionFileName, const double64_t alfa ) {

        std::map<uint32_t, uint32_t> oldToNew;
        const uint32_t* newToOld = graph->GetMap();
        for( uint32_t i = 0; i < graph->GetNumNodes(); ++i ) {
            oldToNew.insert(std::pair<uint32_t, uint32_t>(newToOld[i],i));
        }

        uint32_t* communities = new uint32_t[graph->GetNumNodes()];
        memset(communities,0xff,sizeof(uint32_t)*graph->GetNumNodes());
        if (!communities) {
            printf("Unable to allocate partition\n");
            return 1;
        }

        std::ifstream partitionFile;
        partitionFile.open(partitionFileName);
        if(!partitionFile.is_open()) {
            printf("Unable to load partition file.\n");
            return 1;
        }
        std::string line;
        uint32_t nextLabel = 0;
        while(std::getline(partitionFile,line)) {
            std::istringstream stream(line);
            uint32_t node;
            while( stream >> node ) {
                communities[oldToNew[node]] = nextLabel;
            }
            ++nextLabel;
        }
        for( uint32_t i=0; i<graph->GetNumNodes(); ++i) {
            if( communities[i] == 0xffffffff ) {
                communities[i] = nextLabel++;
            }
        }
        partitionFile.close();
        InitializeFromLabelsArray(graph,partition,communities, alfa);
        delete [] communities;
        return 0;
    }
Ejemplo n.º 3
0
    /** @brief Performs an improvement step, that is, checks for movements for all the nodes and
      and computes the new partitions.
      @param[in] graph The graph.
      @param[out] partition The current partition. It will be modified with the new partition.
      @param[in] alfa The alfa parameter controlling the cohesivness of the communities.*/
    static uint32_t PerformImprovementStep(const CGraph* graph, CommunityPartition* partition, const double64_t alfa) {
        std::vector<Movement>* movements = new std::vector<Movement>[num_threads];
        uint32_t N = graph->GetNumNodes();

#pragma omp parallel for schedule(SCD_SCHEDULING,SCD_THREAD_BLOCK_SIZE) 
        for (uint32_t i = 0; i < N; i++) {
            int thread = omp_get_thread_num();
            if (i % 100000 == 0) {
                printf("Thread %d: Checked movements of %d nodes.\n", thread, i);
            }
            Movement movement;
            movement = CheckForBestMovement(graph, i, partition, alfa);
            if (movement.m_MovementType != E_NO_MOVEMENT) {
                movements[thread].push_back(movement);
            }
        }
        printf("All movements checked\n");

        uint32_t* tempNodeLabels = new uint32_t[partition->m_NumNodes];
        memcpy(&tempNodeLabels[0], &partition->m_NodeLabels[0], sizeof (uint32_t) * partition->m_NumNodes);
        uint32_t totalMovements = 0;

        //uint32_t nextLabel = partition->m_NumCommunities;
        uint32_t removeMovements = 0;
        uint32_t removeAndInsertMovements = 0;
        uint32_t insertMovements = 0;


#pragma omp parallel for schedule(static,1)   
        for (uint32_t thread = 0; thread < num_threads; thread++) {
            uint32_t numMovements = movements[thread].size();
            totalMovements += numMovements;
            uint32_t nextLabelThread = partition->m_NumCommunities + numMovements * thread;            

            for (uint32_t i = 0; i < numMovements; i++) {
                Movement movement = (movements[thread])[i];
                switch (movement.m_MovementType) {
                    case E_REMOVE:
                        tempNodeLabels[movement.m_NodeId] = nextLabelThread;
                        removeMovements++;
                        nextLabelThread++;
                        break;
                    case E_REMOVE_AND_INSERT:
                        tempNodeLabels[movement.m_NodeId] = movement.m_Community;
                        if (partition->m_Communities[partition->m_CommunityIndices[partition->m_NodeLabels[movement.m_NodeId]]] == 1) {
                            insertMovements++;
                        } else {
                            removeAndInsertMovements++;
                        }
                        break;
                }
            }
        }
        delete [] movements;
        printf(" Number of removes performed: %d\n", removeMovements);
        printf(" Number of remove and insert performed: %d\n", removeAndInsertMovements);
        printf(" Number of insert performed: %d\n", insertMovements);
        FreeResources(partition);

        if (InitializeFromLabelsArray(graph, partition, tempNodeLabels, alfa)) {
            printf("Error initializing from label array.\n");
            return 1;
        }
        delete [] tempNodeLabels;

        return 0;
    }
Ejemplo n.º 4
0
    static uint32_t MergeCommunities(const CGraph* graph, CommunityPartition* partition, const double64_t alfa) {
        // Look for community interactions.
        InteractionsSet candidateMerges(CompareById);
        uint32_t N = graph->GetNumNodes();
        for( uint32_t i = 0; i < N; ++i ) {
            uint32_t communityLabel1 = partition->m_NodeLabels[i];
            uint32_t degree = graph->GetDegree(i);
            const uint32_t* adjacencies = graph->GetNeighbors(i);
            for( uint32_t j = 0; j < degree; ++j ) {
                uint32_t communityLabel2 = partition->m_NodeLabels[adjacencies[j]];
                if( communityLabel1 != communityLabel2 ) {
                    CommunityInteraction cI;
                    cI.degree = 0;
                    if( communityLabel1 < communityLabel2 ) {
                        cI.m_CommunityId1 = communityLabel1;
                        cI.m_CommunityId2 = communityLabel2;
                    } else {
                        cI.m_CommunityId2 = communityLabel1;
                        cI.m_CommunityId1 = communityLabel2;
                    }
                    candidateMerges.insert(cI);
                }
            }
        }
        std::vector<CommunityInteraction> filteredInteractions;
        uint32_t earlyFilter = 0;
        // Test each community interaction and rank it.
        for( InteractionsSet::iterator it = candidateMerges.begin(); it != candidateMerges.end(); ++it ) {
            CommunityInteraction cI = *it;
            if( partition->m_Communities[partition->m_CommunityIndices[cI.m_CommunityId1]] > 2 &&
                    partition->m_Communities[partition->m_CommunityIndices[cI.m_CommunityId2]] > 2 ) {
                    earlyFilter++;
                    double64_t improvement = TestMerge(graph, partition, alfa, cI);
                    if( improvement > 0.0 ) {
                        cI.m_Improvement = improvement;
                        filteredInteractions.push_back(cI);
                    }
            }
        } 
        std::cout << earlyFilter << " " << filteredInteractions.size() << " " << candidateMerges.size() << std::endl;
        // Sort community interactions by improvement.
        uint32_t* tempNodeLabels = new uint32_t[partition->m_NumNodes];
        memcpy(tempNodeLabels, partition->m_NodeLabels, sizeof(uint32_t)*partition->m_NumNodes);
        std::sort(filteredInteractions.begin(), filteredInteractions.end(), CompareByImprovement);
        std::set<uint32_t> touched;
        uint32_t numInteractions = filteredInteractions.size();
        for( uint32_t i = 0; i < numInteractions; ++i ) {
            if( (touched.find(filteredInteractions[i].m_CommunityId1) == touched.end()) && 
                    (touched.find(filteredInteractions[i].m_CommunityId2) == touched.end()) ) {
                uint32_t communitySize = partition->m_Communities[partition->m_CommunityIndices[filteredInteractions[i].m_CommunityId1]];
                const uint32_t* community = &partition->m_Communities[partition->m_CommunityIndices[filteredInteractions[i].m_CommunityId1]+1];
                for( uint32_t j = 0; j < communitySize; ++j ) {
                    tempNodeLabels[community[j]] = filteredInteractions[i].m_CommunityId2;
                }
                touched.insert(filteredInteractions[i].m_CommunityId1);
                touched.insert(filteredInteractions[i].m_CommunityId2);
            }
        }

        // Perform interactions constrained by independence and create a new labels array to create a partition from.
        FreeResources(partition);
        if (InitializeFromLabelsArray(graph, partition, tempNodeLabels, alfa)) {
            printf("Error initializing from label array.\n");
            return 1;
        }
        delete [] tempNodeLabels;
        return 0;
    }