Exemple #1
0
void greedy_mis::initial_partition(const unsigned int seed, graph_access & G) {
    random_functions::setSeed(seed);
    NodePermutationMap permutation;
    generate_permutation(G, permutation);

    bucket_array *buckets = new bucket_array(G.number_of_nodes());
    G.set_partition_count(2);

    // Initialize the priority queue
    forall_nodes (G, n) {
        NodeID node = permutation[n];
        EdgeWeight node_degree = G.getNodeDegree(node);
        buckets->increment(node, node_degree);
        G.setPartitionIndex(node, 0);
    } endfor
void bipartition::initial_partition( const PartitionConfig & config, 
                                     const unsigned int seed, 
                                     graph_access & G, 
                                     int* partition_map) {

        timer t;
        t.restart();
        unsigned iterations = config.bipartition_tries;
        EdgeWeight best_cut = std::numeric_limits<EdgeWeight>::max();
        int best_load       = std::numeric_limits<int>::max();

        for( unsigned i = 0; i < iterations; i++) {
                if(config.bipartition_algorithm == BIPARTITION_BFS)  {
                        grow_regions_bfs(config, G);
                } else if( config.bipartition_algorithm == BIPARTITION_FM) {
                        grow_regions_fm(config, G);
                } 

                G.set_partition_count(2);

                post_fm(config, G);

                quality_metrics qm;
                EdgeWeight curcut = qm.edge_cut(G); 

                int lhs_block_weight = 0;
                int rhs_block_weight = 0;

                forall_nodes(G, node) {
                        if(G.getPartitionIndex(node) == 0) {
                                lhs_block_weight += G.getNodeWeight(node);
                        } else {
                                rhs_block_weight += G.getNodeWeight(node);
                        }
                } endfor

                int lhs_overload = std::max(lhs_block_weight - config.target_weights[0],0);
                int rhs_overload = std::max(rhs_block_weight - config.target_weights[1],0);

                if(curcut < best_cut || (curcut == best_cut && lhs_overload + rhs_block_weight < best_load) ) {
                        //store it
                        best_cut  = curcut;
                        best_load = lhs_overload + rhs_overload;

                        forall_nodes(G, n) {
                                partition_map[n] =  G.getPartitionIndex(n);
                        } endfor
                } 
void graph_partitioner::perform_recursive_partitioning_internal(PartitionConfig & config, 
                                                                graph_access & G, 
                                                                PartitionID lb, 
                                                                PartitionID ub) {

        G.set_partition_count(2);
        
        // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        // configuration of bipartitioning
        // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        PartitionConfig bipart_config      = config;
        bipart_config.k                    = 2;
        bipart_config.stop_rule            = STOP_RULE_MULTIPLE_K;
        bipart_config.num_vert_stop_factor = 100;
        double epsilon                     = 0;
        bipart_config.rebalance            = false;
        bipart_config.softrebalance        = true;

        if(config.k < 64) {
                epsilon                     = m_rnd_bal/100.0;
                bipart_config.rebalance     = false;
                bipart_config.softrebalance = false;
        } else {
                epsilon                     = 1/100.0;
        }
        if(m_global_k == 2) {
                epsilon = 3.0/100.0;
        }

        
        bipart_config.upper_bound_partition              = ceil((1+epsilon)*config.largest_graph_weight/(double)bipart_config.k);
        bipart_config.corner_refinement_enabled          = false;
        bipart_config.quotient_graph_refinement_disabled = false;
        bipart_config.refinement_scheduling_algorithm    = REFINEMENT_SCHEDULING_ACTIVE_BLOCKS;
        bipart_config.kway_adaptive_limits_beta          = log(G.number_of_nodes());
        // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        // end configuration
        // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        NodeID new_ub_lhs     = floor((lb+ub)/2);
        NodeID new_lb_rhs     = floor((lb+ub)/2+1);
        NodeID num_blocks_lhs = new_ub_lhs - lb + 1;
        NodeID num_blocks_rhs = ub - new_lb_rhs + 1;

        if(config.k % 2 != 0) {
                //otherwise the block weights have to be 
                bipart_config.target_weights.clear();
                bipart_config.target_weights.push_back((1+epsilon)*num_blocks_lhs/(double)(num_blocks_lhs+num_blocks_rhs)*config.largest_graph_weight);
                bipart_config.target_weights.push_back((1+epsilon)*num_blocks_rhs/(double)(num_blocks_lhs+num_blocks_rhs)*config.largest_graph_weight);
                bipart_config.initial_bipartitioning  = true;
                bipart_config.refinement_type         = REFINEMENT_TYPE_FM; // flows not supported for odd block weights
        } else {

                bipart_config.target_weights.clear();
                bipart_config.target_weights.push_back(bipart_config.upper_bound_partition);
                bipart_config.target_weights.push_back(bipart_config.upper_bound_partition);
                bipart_config.initial_bipartitioning  = false;
        }

        bipart_config.grow_target = ceil(num_blocks_lhs/(double)(num_blocks_lhs+num_blocks_rhs)*config.largest_graph_weight);

        perform_partitioning(bipart_config, G);        

        if( config.k > 2 ) {
               graph_extractor extractor;
 
               graph_access extracted_block_lhs;
               graph_access extracted_block_rhs;
               std::vector<NodeID> mapping_extracted_to_G_lhs; // map the new nodes to the nodes in the old graph G
               std::vector<NodeID> mapping_extracted_to_G_rhs; // map the new nodes to the nodes in the old graph G

               NodeWeight weight_lhs_block = 0;
               NodeWeight weight_rhs_block = 0;

               extractor.extract_two_blocks(G, extracted_block_lhs, 
                                               extracted_block_rhs, 
                                               mapping_extracted_to_G_lhs, 
                                               mapping_extracted_to_G_rhs, 
                                               weight_lhs_block, weight_rhs_block);

               PartitionConfig rec_config = config;
               if(num_blocks_lhs > 1) {
                       rec_config.k = num_blocks_lhs;

                       rec_config.largest_graph_weight = weight_lhs_block;
                       perform_recursive_partitioning_internal( rec_config, extracted_block_lhs, lb, new_ub_lhs);
                       
                       //apply partition
                       forall_nodes(extracted_block_lhs, node) {
                               G.setPartitionIndex(mapping_extracted_to_G_lhs[node], extracted_block_lhs.getPartitionIndex(node));
                       } endfor