Example #1
0
void mis_permutation::construct(graph_access & G) {
    inconsistencies = 0;
    solution_size = 0;
    free_size = 0;
    total_size = G.number_of_nodes();
    nodes.clear();
    tightness.clear();
    position.clear();
    nodes.resize(total_size);
    tightness.resize(total_size);
    position.resize(total_size);
    onetight_all.init(G.number_of_nodes());

    // Insert solution nodes
    forall_nodes(G, n) {
        nodes[n] = n;
        position[n] = n;
        unsigned int index = G.getPartitionIndex(n);
        // Maybe implement tightness calculations here
        if (index == 1) {
            move_to_solution(n, G);
        } else {
            int tight = calculate_tightness(n, G);
            tightness[n] = tight;
            if (tight == 0) move_to_free(n, G);
            else move_to_non_free(n, G);
            if (tight == 1) onetight_all.insert(n);
        }
    } endfor
Example #2
0
void cycle_search::find_random_cycle(graph_access & G, std::vector<NodeID> & cycle) {
	//first perform a bfs starting from a random node and build the parent array
        std::deque<NodeID>* bfsqueue = new std::deque<NodeID>;
	NodeID v = random_functions::nextInt(0, G.number_of_nodes()-1);
	bfsqueue->push_back(v); 

	std::vector<bool>   touched(G.number_of_nodes(),false);
	std::vector<bool>   is_leaf(G.number_of_nodes(),false);
	std::vector<NodeID> parent(G.number_of_nodes(),0);
	std::vector<NodeID> leafes;
	touched[v] = true;
	parent[v]  = v;

	while(!bfsqueue->empty()) {
		NodeID source = bfsqueue->front();
		bfsqueue->pop_front();

		bool is_leaf = true;
		forall_out_edges(G, e, source) {
			NodeID target = G.getEdgeTarget(e);
			if(!touched[target]) {
				is_leaf         = false;
				touched[target] = true; 
				parent[target]  = source;
				bfsqueue->push_back(target);
			}
		} endfor

		if(is_leaf) 
			leafes.push_back(source);

	}
void topological_sort::sort( graph_access & G, std::vector<NodeID> & sorted_sequence) {
        std::vector<int> dfsnum(G.number_of_nodes(), -1);
        int dfscount = 0;

        std::vector<NodeID> nodes(G.number_of_nodes());
        random_functions::permutate_vector_good(nodes, true);

        forall_nodes(G, node) {
                NodeID curNode = nodes[node];
                if(dfsnum[curNode] == -1) {
                        sort_dfs(curNode, G, dfsnum, dfscount, sorted_sequence); 
                }
        } endfor
int wcycle_partitioner::perform_partitioning(const PartitionConfig & config, graph_access & G) {
        PartitionConfig  cfg = config; 

        if(config.stop_rule == STOP_RULE_SIMPLE) {
                m_coarsening_stop_rule = new simple_stop_rule(cfg, G.number_of_nodes());
        } else {
                m_coarsening_stop_rule = new multiple_k_stop_rule(cfg, G.number_of_nodes());
        }

        int improvement = (int) perform_partitioning_recursive(cfg, G, NULL); 
        delete m_coarsening_stop_rule;

        return improvement;
}
Example #5
0
bool augmented_Qgraph_fabric::build_augmented_quotient_graph( PartitionConfig & config, 
                                                              graph_access & G, 
                                                              complete_boundary & boundary, 
                                                              augmented_Qgraph & aqg, 
                                                              unsigned & s, bool rebalance, bool plus) {

        graph_access G_bar;
        boundary.getUnderlyingQuotientGraph(G_bar); 
        if(m_eligible.size() != G.number_of_nodes()) {
                m_eligible.resize(G.number_of_nodes());
                forall_nodes(G, node) {
                        m_eligible[node] = true;
                } endfor
        } else {
void fast_construct_mapping::construct_initial_mapping_bottomup_internal( PartitionConfig & config, graph_access & C, matrix & D, int idx,  std::vector< NodeID > & perm_rank) {

        PartitionID num_parts = C.number_of_nodes()/config.group_sizes[idx];
        partition_C_perfectly_balanced( config, C, num_parts);

        if( idx ==(int)(config.group_sizes.size() - 1) ) {
                // build initial offsets 
                int nodes_per_block = m_tmp_num_nodes / config.group_sizes[idx];
                perm_rank[0] = 0;
                for( unsigned int block = 1; block < perm_rank.size(); block++) {
                        perm_rank[block] = perm_rank[block-1]+nodes_per_block;
                }
        } else {
                //contract partitioned graph
                graph_access Q; complete_boundary bnd(&C);
                bnd.build();
                bnd.getUnderlyingQuotientGraph(Q);
               
                std::vector< NodeID > rec_ranks( num_parts, 0);
                construct_initial_mapping_bottomup_internal( config, Q, D, idx+1, rec_ranks);

                //recompute offsets 
                forall_nodes(C, node) {
                        PartitionID block = C.getPartitionIndex(node);
                        perm_rank[node]   = rec_ranks[block];
                        rec_ranks[block] += C.getNodeWeight(node);
                } endfor
        }
void parallel_mh_async::perform_partitioning(const PartitionConfig & partition_config, graph_access & G) {
        m_time_limit      = partition_config.time_limit;
        m_island          = new population(m_communicator, partition_config);
        m_best_global_map = new PartitionID[G.number_of_nodes()];

        srand(partition_config.seed*m_size+m_rank);
        random_functions::setSeed(partition_config.seed*m_size+m_rank);

        PartitionConfig ini_working_config  = partition_config; 
        initialize( ini_working_config, G);

        m_t.restart();
        exchanger ex(m_communicator);
        do {
                PartitionConfig working_config  = partition_config; 

                working_config.graph_allready_partitioned  = false;
                if(!partition_config.strong)
                        working_config.no_new_initial_partitioning = false;

                working_config.mh_pool_size = ini_working_config.mh_pool_size;
                if(m_rounds == 0 && working_config.mh_enable_quickstart) {
                        ex.quick_start( working_config, G, *m_island );
                }

                perform_local_partitioning( working_config, G );
                if(m_rank == ROOT) {
                        std::cout <<  "t left " <<  (m_time_limit - m_t.elapsed()) << std::endl;
                }

                //push and recv 
                if( m_t.elapsed() <= m_time_limit && m_size > 1) {
                        unsigned messages = ceil(log(m_size));
                        for( unsigned i = 0; i < messages; i++) {
                                ex.push_best( working_config, G, *m_island );
                                ex.recv_incoming( working_config, G, *m_island );
                        }
                }

                m_rounds++;
        } while( m_t.elapsed() <= m_time_limit );

        collect_best_partitioning(G, partition_config);
        m_island->print();

        //print logfile (for convergence plots)
        if( partition_config.mh_print_log ) {
                std::stringstream filename_stream;
                filename_stream << "log_"<<  partition_config.graph_filename <<   
                        "_m_rank_" <<  m_rank <<  
                        "_file_" <<  
                        "_seed_" <<  partition_config.seed <<  
                        "_k_" <<  partition_config.k;

                std::string filename(filename_stream.str());
                m_island->write_log(filename);
        }

        delete m_island;
}
Example #8
0
void population_mis::set_mis_for_individuum(MISConfig & config, graph_access & G, individuum_mis & ind, bool secondary) {
    G.resizeSecondPartitionIndex(G.number_of_nodes());
    forall_nodes(G, node) {
        if (!secondary) G.setPartitionIndex(node, ind.solution[node]);
        else G.setSecondPartitionIndex(node, ind.solution[node]);
    } endfor
}
Example #9
0
void graph_extractor::extract_block(graph_access & G, 
                                    graph_access & extracted_block, 
                                    PartitionID block, 
                                    std::vector<NodeID> & mapping) {

        // build reverse mapping
        std::vector<NodeID> reverse_mapping;
        NodeID nodes = 0;
        NodeID dummy_node = G.number_of_nodes() + 1;
        forall_nodes(G, node) {
                if(G.getPartitionIndex(node) == block) {
                        reverse_mapping.push_back(nodes++);
                } else {
                        reverse_mapping.push_back(dummy_node);
                }
        } endfor

        extracted_block.start_construction(nodes, G.number_of_edges());

        forall_nodes(G, node) {
                if(G.getPartitionIndex(node) == block) {
                        NodeID new_node = extracted_block.new_node();
                        mapping.push_back(node);
                        extracted_block.setNodeWeight( new_node, G.getNodeWeight(node));

                        forall_out_edges(G, e, node) {
                                NodeID target = G.getEdgeTarget(e);
                                if( G.getPartitionIndex( target ) == block ) {
                                        EdgeID new_edge = extracted_block.new_edge(new_node, reverse_mapping[target]);
                                        extracted_block.setEdgeWeight(new_edge, G.getEdgeWeight(e));
                                }
                        } endfor
                }
Example #10
0
EdgeWeight tabu_search::perform_refinement(PartitionConfig & config, graph_access & G, complete_boundary & boundary) {
        quality_metrics qm;
        EdgeWeight input_cut = qm.edge_cut(G);
        EdgeWeight cur_cut   = input_cut;
        EdgeWeight best_cut  = input_cut;
        std::vector< PartitionID > bestmap(G.number_of_nodes(), 0);
        forall_nodes(G, node) {
                bestmap[node] = G.getPartitionIndex(node);
        } endfor
Example #11
0
int graph_io::writeGraphWeighted(graph_access & G, std::string filename) {
        std::ofstream f(filename.c_str());
        f << G.number_of_nodes() <<  " " <<  G.number_of_edges()/2 <<  " 11" <<  std::endl;

        forall_nodes(G, node) {
                f <<  G.getNodeWeight(node) ;
                forall_out_edges(G, e, node) {
                        f << " " <<   (G.getEdgeTarget(e)+1) <<  " " <<  G.getEdgeWeight(e) ;
                } endfor 
Example #12
0
void population_mis::mutate(MISConfig & config, graph_access & G, individuum_mis & ind) {
    set_mis_for_individuum(config, G, ind);
    delete [] ind.solution;
    ind.solution = NULL;

    ils iterate;
    iterate.perform_ils(config, G, config.ils_iterations);

    // Create solution for the individuum
    NodeID *solution = new NodeID[G.number_of_nodes()];
    unsigned int solution_size = create_solution(G, solution);
    ind.solution = solution;
    ind.solution_size = solution_size;
}
Example #13
0
void graph_communication::broadcast_graph( graph_access & G, unsigned root) {
        int rank       = MPI::COMM_WORLD.Get_rank();

        //first B-Cast number of nodes and number of edges 
        unsigned number_of_nodes = 0;
        unsigned number_of_edges = 0;
 
        std::vector< int > buffer(2,0);
        if(rank == (int)root) {
               buffer[0] = G.number_of_nodes();
               buffer[1] = G.number_of_edges();
        }
        MPI::COMM_WORLD.Bcast(&buffer[0], 2, MPI_INT, root);

        number_of_nodes = buffer[0];
        number_of_edges = buffer[1];

        int* xadj;        
        int* adjncy;
        int* vwgt;        
        int* adjwgt;

        if( rank == (int)root) {
                xadj           = G.UNSAFE_metis_style_xadj_array();
                adjncy         = G.UNSAFE_metis_style_adjncy_array();

                vwgt           = G.UNSAFE_metis_style_vwgt_array();
                adjwgt         = G.UNSAFE_metis_style_adjwgt_array();
        } else {
                xadj   = new int[number_of_nodes+1];
                adjncy = new int[number_of_edges];

                vwgt   = new int[number_of_nodes];
                adjwgt = new int[number_of_edges];
        }

        MPI::COMM_WORLD.Bcast(xadj,   number_of_nodes+1, MPI_INT, root);
        MPI::COMM_WORLD.Bcast(adjncy, number_of_edges  , MPI_INT, root);
        MPI::COMM_WORLD.Bcast(vwgt,   number_of_nodes  , MPI_INT, root);
        MPI::COMM_WORLD.Bcast(adjwgt, number_of_edges  , MPI_INT, root);

        G.build_from_metis_weighted( number_of_nodes, xadj, adjncy, vwgt, adjwgt); 

        delete[] xadj;
        delete[] adjncy;
        delete[] vwgt;
        delete[] adjwgt;
 
}
Example #14
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
Example #15
0
EdgeWeight parallel_mh_async::collect_best_partitioning(graph_access & G) {
        //perform partitioning locally
	EdgeWeight min_objective = 0;
        m_island->apply_fittest(G, min_objective);

        int best_local_objective  = min_objective;
        int best_global_objective = 0; 

        PartitionID* best_local_map = new PartitionID[G.number_of_nodes()];
	std::vector< NodeWeight > block_sizes(G.get_partition_count(),0);

        forall_nodes(G, node) {
                best_local_map[node] = G.getPartitionIndex(node);
		block_sizes[G.getPartitionIndex(node)]++;
        } endfor
void most_balanced_minimum_cuts::compute_good_balanced_min_cut( graph_access & residualGraph, 
                                                                const PartitionConfig & config,
                                                                NodeWeight & perfect_rhs_weight, 
                                                                std::vector< NodeID > & new_rhs_nodes ) {

        strongly_connected_components scc;
        std::vector<int> components(residualGraph.number_of_nodes());
        int comp_count = scc.strong_components(residualGraph,components);
        
        std::vector< std::vector<NodeID> > comp_nodes(comp_count);
        std::vector< NodeWeight > comp_weights(comp_count, 0);
        
        forall_nodes(residualGraph, node) {
               comp_nodes[components[node]].push_back(node);
               comp_weights[components[node]] += residualGraph.getNodeWeight(node); 
        } endfor
Example #17
0
void population_mis::create_individuum(MISConfig & config, graph_access & G, individuum_mis & ind) {

    // Build solution
    int initial = random_functions::nextInt(0, 1);
    if (initial == 0) {
        random_mis init_solution;
        init_solution.initial_partition(config.seed, G);
    }
    else if (initial == 1) {
        greedy_mis init_solution;
        init_solution.initial_partition(config.seed, G);
    }
    // else if (initial == 2) {
    //     greedy_vertex init_solution;
    //     init_solution.initial_partition(config.seed, G);
    // }

    // Create solution for the individuum
    NodeID *solution = new NodeID[G.number_of_nodes()];
    unsigned int solution_size = create_solution(G, solution);
    ind.solution = solution;
    ind.solution_size = solution_size;
}
Example #18
0
EdgeWeight kway_graph_refinement::perform_refinement(PartitionConfig & config, graph_access & G, 
                                                     complete_boundary & boundary) {

        commons = kway_graph_refinement_commons::getInstance(config);
        kway_graph_refinement_core refinement_core;
        
        EdgeWeight overall_improvement = 0;
        int max_number_of_swaps        = (int)(G.number_of_nodes());
        bool sth_changed               = config.no_change_convergence;

        for( unsigned i = 0; i < config.kway_rounds || sth_changed; i++) {
                EdgeWeight improvement = 0;    

                boundary_starting_nodes start_nodes;
                setup_start_nodes(config, G, boundary, start_nodes);

                if(start_nodes.size() == 0) return 0; // nothing to refine

                //metis steplimit
                int step_limit = (int)((config.kway_fm_search_limit/100.0)*max_number_of_swaps);
                step_limit = std::max(step_limit, 15);

                vertex_moved_hashtable moved_idx; 
                improvement += refinement_core.single_kway_refinement_round(config, G, boundary, 
                                                                            start_nodes, step_limit, 
                                                                            moved_idx);

                sth_changed = improvement != 0 && config.no_change_convergence;
                if(improvement == 0) break; 
                overall_improvement += improvement; 

        } 

        ASSERT_TRUE(overall_improvement >= 0); 

        return (EdgeWeight) overall_improvement; 
}
void fast_construct_mapping::construct_initial_mapping_bottomup( PartitionConfig & config, graph_access & C, matrix & D, std::vector< NodeID > & perm_rank) {
        m_tmp_num_nodes = C.number_of_nodes();
        construct_initial_mapping_bottomup_internal( config, C, D, 0, perm_rank);
}
Example #20
0
void local_optimizer::run_maxent_optimization_internal( const Config & config, graph_access & G ) {
        if(G.number_of_edges() == 0) return;

        std::vector< coord_t > new_coord(G.number_of_nodes());
        CoordType alpha = config.maxent_alpha;
        int iterations  = config.maxent_inner_iterations;
        CoordType q     = config.q;

        std::vector<CoordType> distances(G.number_of_edges(),0); 
        configure_distances( config, G, distances);

        for( int i = 0; i < config.maxent_outer_iterations; i++) {

                CoordType norm_coords = 0;
                CoordType norm_diff = 0;
                do {
                        forall_nodes_parallel(G, node) {
                                CoordType rho_i = 0; // assume graph is connected?
                                if(G.getNodeDegree(node) == 0) continue;
                                forall_out_edges(G, e, node) {
                                        CoordType distance = distances[e];
                                        rho_i += 1/(distance*distance);
                                } endfor
                                rho_i = 1/rho_i;

                                CoordType S_x = 0;
                                CoordType S_y = 0;

                                CoordType n_S_x = 0;
                                CoordType n_S_y = 0;
                                forall_out_edges(G, e, node) {
                                        NodeID target      = G.getEdgeTarget(e);
                                        CoordType diffX       = G.getX(node) - G.getX(target);
                                        CoordType diffY       = G.getY(node) - G.getY(target);
                                        CoordType dist_square = diffX*diffX+diffY*diffY;
                                        CoordType distance    = distances[e];
                                        CoordType dist        = sqrt(dist_square);

                                        CoordType scaled_distance = distance/dist;
                                        CoordType squared_distance = distance*distance;

                                        S_x += (G.getX(target) + scaled_distance*diffX)/(squared_distance);
                                        S_y += (G.getY(target) + scaled_distance*diffY)/(squared_distance);

                                        CoordType dist_q = pow(dist, q+2);
                                        n_S_x -= diffX/dist_q;
                                        n_S_y -= diffY/dist_q;
                                } endfor

                                S_x *= rho_i;
                                S_y *= rho_i;

                                forall_nodes(G, target) {
                                        if( node == target ) continue;

                                        CoordType diffX       = G.getX(node) - G.getX(target);
                                        CoordType diffY       = G.getY(node) - G.getY(target);
                                        CoordType dist_square = diffX*diffX+diffY*diffY;
                                        CoordType dist        = sqrt(dist_square);

                                        CoordType dist_q = pow(dist, q+2);
                                        n_S_x += diffX/dist_q;
                                        n_S_y += diffY/dist_q;
                                } endfor
                                CoordType mult_factor = alpha*rho_i;

                                n_S_x *= mult_factor;
                                n_S_y *= mult_factor;

                                new_coord[node].x = S_x + sgn(q)*n_S_x;
                                new_coord[node].y = S_y + sgn(q)*n_S_y;
                        } endfor
Example #21
0
// implements our version of gal combine
// compute a matching between blocks (greedily) 
// extend to partition
// apply our refinements and tabu search
void gal_combine::perform_gal_combine( PartitionConfig & config, graph_access & G) {
        //first greedily compute a matching of the partitions
        std::vector< std::unordered_map<PartitionID, unsigned> > counters(config.k);
        forall_nodes(G, node) {
                //boundary_pair bp;
                if(counters[G.getPartitionIndex(node)].find(G.getSecondPartitionIndex(node)) != counters[G.getPartitionIndex(node)].end()) {
                        counters[G.getPartitionIndex(node)][G.getSecondPartitionIndex(node)] += 1;
                } else {
                        counters[G.getPartitionIndex(node)][G.getSecondPartitionIndex(node)] = 1;
                }
        } endfor

        std::vector< PartitionID > permutation(config.k);
        for( unsigned i = 0; i < permutation.size(); i++) {
                permutation[i] = i;
        }

        random_functions::permutate_vector_good_small(permutation); 
        std::vector<bool> rhs_matched(config.k, false);
        std::vector<PartitionID> bipartite_matching(config.k);
        for( unsigned i = 0; i < permutation.size(); i++) {
                PartitionID cur_partition   = permutation[i];
                PartitionID best_unassigned = config.k;
                NodeWeight  best_value      = 0;

                for( std::unordered_map<PartitionID, unsigned>::iterator it = counters[cur_partition].begin(); 
                     it != counters[cur_partition].end(); ++it) {
                        if( rhs_matched[it->first] == false && it->second > best_value ) {
                                best_unassigned = it->first; 
                                best_value = it->second;
                        }
                }

                bipartite_matching[cur_partition] = best_unassigned;
                if( best_unassigned != config.k ) {
                        rhs_matched[best_unassigned] = true;
                }
        }

        std::vector<bool> blocked_vertices(G.number_of_nodes(), false);
        forall_nodes(G, node) {
                if( bipartite_matching[G.getPartitionIndex(node)] == G.getSecondPartitionIndex(node) ){
                        blocked_vertices[node] = true;
                } else {
                        // we will reassign this vertex since the partitions do not agree on it
                        G.setPartitionIndex(node, config.k); 
                }
        } endfor

        construct_partition cp;
        cp.construct_starting_from_partition( config, G );

        refinement* refine = new mixed_refinement();

        double real_epsilon = config.imbalance/100.0;
        double epsilon = random_functions::nextDouble(real_epsilon+0.005,real_epsilon+config.kabaE_internal_bal); 
        PartitionConfig copy = config;
        copy.upper_bound_partition = (1+epsilon)*ceil(config.largest_graph_weight/(double)config.k);

        complete_boundary boundary(&G);
        boundary.build();

        tabu_search ts;
        ts.perform_refinement( copy, G, boundary);
        
        //now obtain the quotient graph
        complete_boundary boundary2(&G);
        boundary2.build();

        copy = config;
        copy.upper_bound_partition = (1+epsilon)*ceil(config.largest_graph_weight/(double)config.k);

        refine->perform_refinement( copy, G, boundary2);

        copy = config;
        cycle_refinement cr;
        cr.perform_refinement(config, G, boundary2);
        delete refine;

        
}
int wcycle_partitioner::perform_partitioning_recursive( PartitionConfig & partition_config, 
                                                        graph_access & G, 
                                                        complete_boundary ** c_boundary) {

        //if graph not small enough
        //      perform matching two times
        //      perform coarsening two times
        //      call rekursive
        //else 
        //      initial partitioning
        //
        //refinement
        NodeID no_of_coarser_vertices = G.number_of_nodes();
        NodeID no_of_finer_vertices   = G.number_of_nodes();
        int improvement = 0;

        edge_ratings rating(partition_config);
        CoarseMapping* coarse_mapping =  new CoarseMapping();

        graph_access* finer                      = &G;
        matching* edge_matcher                   = NULL;
        contraction* contracter                  = new contraction();
        PartitionConfig copy_of_partition_config = partition_config;
        graph_access* coarser                    = new graph_access();

        Matching edge_matching;
        NodePermutationMap permutation;

        coarsening_configurator coarsening_config;
        coarsening_config.configure_coarsening(partition_config, &edge_matcher, m_level);
        
        rating.rate(*finer, m_level);

        edge_matcher->match(partition_config, *finer, edge_matching, *coarse_mapping, no_of_coarser_vertices, permutation);
        delete edge_matcher; 

        if(partition_config.graph_allready_partitioned) {
                contracter->contract_partitioned(partition_config, *finer, 
                                                 *coarser, edge_matching, 
                                                 *coarse_mapping, no_of_coarser_vertices, 
                                                 permutation);
        } else {
                contracter->contract(partition_config, *finer, 
                                     *coarser, edge_matching, 
                                     *coarse_mapping, no_of_coarser_vertices, 
                                     permutation);
        }

        coarser->set_partition_count(partition_config.k);
        complete_boundary* coarser_boundary =  NULL;
        refinement* refine = NULL;

        if(!partition_config.label_propagation_refinement) {
                coarser_boundary = new complete_boundary(coarser);
                refine = new mixed_refinement();
        } else {
                refine = new label_propagation_refinement();
        }

        if(!m_coarsening_stop_rule->stop(no_of_finer_vertices, no_of_coarser_vertices)) {

                PartitionConfig cfg; cfg = partition_config;

                double factor = partition_config.balance_factor;
                cfg.upper_bound_partition = (factor +1.0)*partition_config.upper_bound_partition;

	        initial_partitioning init_part;
		init_part.perform_initial_partitioning(cfg, *coarser);

                if(!partition_config.label_propagation_refinement) coarser_boundary->build();

                //PRINT(std::cout <<  "upper bound " <<  cfg.upper_bound_partition  << std::endl;)
                improvement += refine->perform_refinement(cfg, *coarser, *coarser_boundary);
                m_deepest_level = m_level + 1;
        } else {
                m_level++;

                improvement += perform_partitioning_recursive( partition_config, *coarser, &coarser_boundary); 
                partition_config.graph_allready_partitioned = true;

                if(m_level % partition_config.level_split == 0 ) {

                        if(!partition_config.use_fullmultigrid 
                        || m_have_been_level_down.find(m_level) == m_have_been_level_down.end())  { 

                                if(!partition_config.label_propagation_refinement) {
                                        delete coarser_boundary;

                                        coarser_boundary                = new complete_boundary(coarser);
                                }
                                m_have_been_level_down[m_level] = true;

                                // configurate the algorithm to use the same amount
                                // of imbalance as was allowed on this level 
                                PartitionConfig cfg;
                                cfg = partition_config;
                                cfg.set_upperbound = false;

                                double cur_factor = partition_config.balance_factor/(m_deepest_level-m_level);
                                cfg.upper_bound_partition = ( (m_level != 0) * cur_factor+1.0)*partition_config.upper_bound_partition;

                                // do the next arm of the F-cycle
                                improvement += perform_partitioning_recursive( cfg, *coarser, &coarser_boundary); 
                        }
                }

                m_level--;

        }

        if(partition_config.use_balance_singletons && !partition_config.label_propagation_refinement) {
                coarser_boundary->balance_singletons( partition_config, *coarser );
        }
        
        //project
        graph_access& fRef = *finer;
        graph_access& cRef = *coarser;
        forall_nodes(fRef, n) {
                NodeID coarser_node              = (*coarse_mapping)[n];
                PartitionID coarser_partition_id = cRef.getPartitionIndex(coarser_node);
                fRef.setPartitionIndex(n, coarser_partition_id);
        } endfor
EdgeWeight kway_graph_refinement_core::single_kway_refinement_round_internal(PartitionConfig & config, 
                                                                    graph_access & G, 
                                                                    complete_boundary & boundary, 
                                                                    boundary_starting_nodes & start_nodes, 
                                                                    int step_limit,
                                                                    vertex_moved_hashtable & moved_idx,
                                                                    bool compute_touched_partitions,
                                                                    std::unordered_map<PartitionID, PartitionID> &  touched_blocks) {

        commons = kway_graph_refinement_commons::getInstance(config);
        refinement_pq* queue = NULL;
        if(config.use_bucket_queues) {
                EdgeWeight max_degree = G.getMaxDegree();
                queue                 = new bucket_pq(max_degree);
        } else {
                queue                 = new maxNodeHeap(); 
        }

        init_queue_with_boundary(config, G, start_nodes, queue, moved_idx);  
        
        if(queue->empty()) {delete queue; return 0;}

        std::vector<NodeID> transpositions;
        std::vector<PartitionID> from_partitions;
        std::vector<PartitionID> to_partitions;

        int max_number_of_swaps = (int)(G.number_of_nodes());
        int min_cut_index       = -1;

        EdgeWeight cut         = std::numeric_limits<int>::max()/2; // so we dont need to compute the edge cut
        EdgeWeight initial_cut = cut;

        //roll forwards
        EdgeWeight best_cut = cut;
        int number_of_swaps = 0;
        int movements       = 0;

        kway_stop_rule* stopping_rule = NULL;
        switch(config.kway_stop_rule) {
                case KWAY_SIMPLE_STOP_RULE: 
                        stopping_rule = new kway_simple_stop_rule(config);
                        break;
                case KWAY_ADAPTIVE_STOP_RULE: 
                        stopping_rule = new kway_adaptive_stop_rule(config);
                        break;

        }

        for(number_of_swaps = 0, movements = 0; movements < max_number_of_swaps; movements++, number_of_swaps++) {
                if( queue->empty() ) break;
                if( stopping_rule->search_should_stop(min_cut_index, number_of_swaps, step_limit) ) break;

                Gain gain = queue->maxValue();
                NodeID node = queue->deleteMax();

#ifndef NDEBUG
                PartitionID maxgainer;
                EdgeWeight ext_degree;
                ASSERT_TRUE(moved_idx[node].index == NOT_MOVED);
                ASSERT_EQ(gain, commons->compute_gain(G, node, maxgainer, ext_degree));
                ASSERT_TRUE(ext_degree > 0);
#endif

                PartitionID from = G.getPartitionIndex(node); 
                bool successfull = move_node(config, G, node, moved_idx, queue, boundary);

                if(successfull) {
                        cut -= gain;
                        stopping_rule->push_statistics(gain);

                        bool accept_equal = random_functions::nextBool();
                        if( cut < best_cut || ( cut == best_cut && accept_equal )) {
                                best_cut = cut;
                                min_cut_index = number_of_swaps;
                                if(cut < best_cut)
                                        stopping_rule->reset_statistics();
                        }

                        from_partitions.push_back(from);
                        to_partitions.push_back(G.getPartitionIndex(node));
                        transpositions.push_back(node);
                } else {
                        number_of_swaps--; //because it wasnt swaps
                }
                moved_idx[node].index = MOVED;
                ASSERT_TRUE(boundary.assert_bnodes_in_boundaries());
                ASSERT_TRUE(boundary.assert_boundaries_are_bnodes());

        } 

        ASSERT_TRUE(boundary.assert_bnodes_in_boundaries());
        ASSERT_TRUE(boundary.assert_boundaries_are_bnodes());

        //roll backwards
        for(number_of_swaps--; number_of_swaps>min_cut_index; number_of_swaps--) {
                ASSERT_TRUE(transpositions.size() > 0);

                NodeID node = transpositions.back();
                transpositions.pop_back();

                PartitionID to = from_partitions.back();
                from_partitions.pop_back();
                to_partitions.pop_back();

                move_node_back(config, G, node, to,  moved_idx, queue, boundary);
        }

       
        //reconstruct the touched partitions
        if(compute_touched_partitions) {
                ASSERT_EQ(from_partitions.size(), to_partitions.size());
                for(unsigned i = 0; i < from_partitions.size(); i++) {
                        touched_blocks[from_partitions[i]] = from_partitions[i];
                        touched_blocks[to_partitions[i]]   = to_partitions[i];
                }
        }

        ASSERT_TRUE(boundary.assert_bnodes_in_boundaries());
        ASSERT_TRUE(boundary.assert_boundaries_are_bnodes());

        delete queue;
        delete stopping_rule;
        return initial_cut - best_cut; 
}
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
Example #25
0
void coarsening::perform_coarsening(const PartitionConfig & partition_config, graph_access & G, graph_hierarchy & hierarchy) {

        NodeID no_of_coarser_vertices = G.number_of_nodes();
        NodeID no_of_finer_vertices   = G.number_of_nodes();

        edge_ratings rating(partition_config);
        CoarseMapping* coarse_mapping = NULL;

        graph_access* finer                      = &G;
        matching* edge_matcher                   = NULL;
        contraction* contracter                  = new contraction();
        PartitionConfig copy_of_partition_config = partition_config;

        stop_rule* coarsening_stop_rule = NULL;
        if( partition_config.mode_node_separators ) {
                coarsening_stop_rule = new separator_simple_stop_rule(copy_of_partition_config, G.number_of_nodes());
        } else {
                if(partition_config.stop_rule == STOP_RULE_SIMPLE) {
                        coarsening_stop_rule = new simple_stop_rule(copy_of_partition_config, G.number_of_nodes());
                } else if(partition_config.stop_rule == STOP_RULE_MULTIPLE_K) {
                        coarsening_stop_rule = new multiple_k_stop_rule(copy_of_partition_config, G.number_of_nodes());
                } else {
                        coarsening_stop_rule = new strong_stop_rule(copy_of_partition_config, G.number_of_nodes());
                }
        }

        coarsening_configurator coarsening_config;

        unsigned int level    = 0;
        bool contraction_stop = false;
        do {
                graph_access* coarser = new graph_access();
                coarse_mapping        = new CoarseMapping();
                Matching edge_matching;
                NodePermutationMap permutation;

                coarsening_config.configure_coarsening(copy_of_partition_config, &edge_matcher, level);
                rating.rate(*finer, level);

                edge_matcher->match(copy_of_partition_config, *finer, edge_matching, 
                                    *coarse_mapping, no_of_coarser_vertices, permutation);

                delete edge_matcher; 

                if(partition_config.graph_allready_partitioned) {
                        contracter->contract_partitioned(copy_of_partition_config, *finer, *coarser, edge_matching, 
                                                         *coarse_mapping, no_of_coarser_vertices, permutation);
                } else {
                        contracter->contract(copy_of_partition_config, *finer, *coarser, edge_matching, 
                                             *coarse_mapping, no_of_coarser_vertices, permutation);
                }

                hierarchy.push_back(finer, coarse_mapping);
                contraction_stop = coarsening_stop_rule->stop(no_of_finer_vertices, no_of_coarser_vertices);
              
                no_of_finer_vertices = no_of_coarser_vertices;
                std::cout <<  "no of coarser vertices " << no_of_coarser_vertices <<  " and no of edges " <<  coarser->number_of_edges() << std::endl;

                finer = coarser;

                level++;
        } while( contraction_stop ); 

        hierarchy.push_back(finer, NULL); // append the last created level

        delete contracter;
        delete coarsening_stop_rule;
}
Example #26
0
int wcycle_partitioner::perform_partitioning_recursive( PartitionConfig & partition_config, 
                                                        graph_access & G, 
                                                        complete_boundary ** c_boundary) {

        //if graph not small enough
        //      perform matching two times
        //      perform coarsening two times
        //      call rekursive
        //else 
        //      initial partitioning
        //
        //refinement
        NodeID no_of_coarser_vertices = G.number_of_nodes();
        NodeID no_of_finer_vertices   = G.number_of_nodes();
        int improvement = 0;

        edge_ratings rating(partition_config);
        CoarseMapping* coarse_mapping =  new CoarseMapping();

        graph_access* finer                      = &G;
        matching* edge_matcher                   = NULL;
        contraction* contracter                  = new contraction();
        PartitionConfig copy_of_partition_config = partition_config;
        graph_access* coarser                    = new graph_access();

        Matching edge_matching;
        NodePermutationMap permutation;

        coarsening_configurator coarsening_config;
        coarsening_config.configure_coarsening(partition_config, &edge_matcher, m_level);
        
        rating.rate(*finer, m_level);

        edge_matcher->match(partition_config, *finer, edge_matching, *coarse_mapping, no_of_coarser_vertices, permutation);
        delete edge_matcher; 

        if(partition_config.graph_allready_partitioned) {
                contracter->contract_partitioned(partition_config, *finer, 
                                                 *coarser, edge_matching, 
                                                 *coarse_mapping, no_of_coarser_vertices, 
                                                 permutation);
        } else {
                contracter->contract(partition_config, *finer, 
                                     *coarser, edge_matching, 
                                     *coarse_mapping, no_of_coarser_vertices, 
                                     permutation);
        }

        coarser->set_partition_count(partition_config.k);
        complete_boundary* coarser_boundary =  NULL;
        refinement* refine = NULL;

        coarser_boundary = new complete_boundary(coarser);
        refine = new mixed_refinement();

        if(!m_coarsening_stop_rule->stop(no_of_finer_vertices, no_of_coarser_vertices)) {
	        initial_partitioning init_part;
		init_part.perform_initial_partitioning(partition_config, *coarser);

                coarser_boundary->build();
                improvement += refine->perform_refinement(partition_config, *coarser, *coarser_boundary);
        } else {
                m_level++;

                improvement += perform_partitioning_recursive( partition_config, *coarser, &coarser_boundary); 
                partition_config.graph_allready_partitioned = true;

                if(m_level % partition_config.level_split == 0 ) {

                        if(!partition_config.use_fullmultigrid 
                        || m_have_been_level_down.find(m_level) == m_have_been_level_down.end())  { 

                                delete coarser_boundary;
                                coarser_boundary                = new complete_boundary(coarser);
                                m_have_been_level_down[m_level] = true;

                                improvement += perform_partitioning_recursive( partition_config, *coarser, &coarser_boundary); 
                        }
                }

                m_level--;

        }

        if(partition_config.use_balance_singletons) {
                coarser_boundary->balance_singletons( partition_config, *coarser );
        }
        
        //project
        graph_access& fRef = *finer;
        graph_access& cRef = *coarser;
        forall_nodes(fRef, n) {
                NodeID coarser_node              = (*coarse_mapping)[n];
                PartitionID coarser_partition_id = cRef.getPartitionIndex(coarser_node);
                fRef.setPartitionIndex(n, coarser_partition_id);
        } endfor