bool vertex_separator_flow_solver::construct_flow_pb( const PartitionConfig & config, 
                                                      graph_access & G, 
                                                      PartitionID & lhs, 
                                                      PartitionID & rhs, 
                                                      std::vector<NodeID> & lhs_nodes,
                                                      std::vector<NodeID> & rhs_nodes,
                                                      std::vector<NodeID> & new_to_old_ids,              
                                                      long *n_ad, 
                                                      long* m_ad, 
                                                      node** nodes_ad, 
                                                      arc** arcs_ad, 
                                                      long ** cap_ad,
                                                      node** source_ad, 
                                                      node** sink_ad, 
                                                      long* node_min_ad,
                                                      EdgeID & no_edges_in_flow_graph) { 
        
        //very dirty for loading variables :). some time this should all be refactored. for now we can focus on the important stuff.
        #include "../refinement/quotient_graph_refinement/flow_refinement/flow_solving_kernel/convert_ds_variables.h"

        //building up the graph as in parse.h of hi_pr code
        //first we have to count the number of edges 
        // s to lhs + rhs to t + lhs to rhs 
        unsigned no_edges = 0;
        for( unsigned i = 0; i < lhs_nodes.size(); i++) {
                NodeID node = lhs_nodes[i];
                forall_out_edges(G, e, node) {
                        NodeID target = G.getEdgeTarget(e);
                        if(rhs == G.getPartitionIndex(target)) {
                                ++no_edges;
                        }
                } endfor
        }
Esempio n. 2
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
                }
Esempio n. 3
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);

	}
Esempio n. 4
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 
Esempio n. 5
0
int mis_permutation::calculate_tightness(NodeID node, graph_access & G) {
    int tightness = 0;
    forall_out_edges(G, edge, node) {
        NodeID target = G.getEdgeTarget(edge);
        bool target_index = G.getPartitionIndex(target);
        if (target_index == 1) {
            tightness++;
        }
    } endfor
Esempio n. 6
0
EdgeWeight quality_metrics::edge_cut(graph_access & G) {
        EdgeWeight edgeCut = 0;
        forall_nodes(G, n) { 
                PartitionID partitionIDSource = G.getPartitionIndex(n);
                forall_out_edges(G, e, n) {
                        NodeID targetNode = G.getEdgeTarget(e);
                        PartitionID partitionIDTarget = G.getPartitionIndex(targetNode);

                        if (partitionIDSource != partitionIDTarget) {
                                edgeCut += G.getEdgeWeight(e);
                        }
                } endfor 
Esempio n. 7
0
EdgeID edge_cut_flow_solver::regions_no_edges( graph_access & G,
                                               std::vector<NodeID> & lhs_boundary_stripe,
                                               std::vector<NodeID> & rhs_boundary_stripe,
                                               PartitionID & lhs, 
                                               PartitionID & rhs,
                                               std::vector<NodeID> & outer_lhs_boundary_nodes,
                                               std::vector<NodeID> & outer_rhs_boundary_nodes ) {

        EdgeID no_of_edges = 0;
        unsigned idx = 0;
        for( unsigned i = 0; i < lhs_boundary_stripe.size(); i++, idx++) {
                NodeID node = lhs_boundary_stripe[i];
                bool is_outer_boundary = false;
                forall_out_edges(G, e, node) {
                        if(G.getPartitionIndex(G.getEdgeTarget(e)) == BOUNDARY_STRIPE_NODE) no_of_edges++;
                        else is_outer_boundary = true;
                } endfor
                if(is_outer_boundary) {
                        outer_lhs_boundary_nodes.push_back(idx);
                }
        }

        for( unsigned i = 0; i < rhs_boundary_stripe.size(); i++, idx++) {
                NodeID node = rhs_boundary_stripe[i];
                bool is_outer_boundary = false;
                forall_out_edges(G, e, node) {
                        if(G.getPartitionIndex(G.getEdgeTarget(e)) == BOUNDARY_STRIPE_NODE) no_of_edges++;
                        else is_outer_boundary = true;
                } endfor
                if(is_outer_boundary) {
                        outer_rhs_boundary_nodes.push_back(idx);
                }
        }

        return no_of_edges; 
}
Esempio n. 8
0
// for documentation see technical reports of christian schulz  
void contraction::contract(const PartitionConfig & partition_config, 
                           graph_access & G, 
                           graph_access & coarser, 
                           const Matching & edge_matching,
                           const CoarseMapping & coarse_mapping,
                           const NodeID & no_of_coarse_vertices,
                           const NodePermutationMap & permutation) const {

        if(partition_config.combine) {
                coarser.resizeSecondPartitionIndex(no_of_coarse_vertices);
        }

        std::vector<NodeID> new_edge_targets(G.number_of_edges());
        forall_edges(G, e) {
                new_edge_targets[e] = coarse_mapping[G.getEdgeTarget(e)];
        } endfor

        std::vector<EdgeID> edge_positions(no_of_coarse_vertices, UNDEFINED_EDGE);

        //we dont know the number of edges jet, so we use the old number for 
        //construction of the coarser graph and then resize the field according
        //to the number of edges we really got
        coarser.start_construction(no_of_coarse_vertices, G.number_of_edges());

        NodeID cur_no_vertices = 0;

        forall_nodes(G, n) {
                NodeID node = permutation[n];
                //we look only at the coarser nodes
                if(coarse_mapping[node] != cur_no_vertices) 
                        continue;
                
                NodeID coarseNode = coarser.new_node();
                coarser.setNodeWeight(coarseNode, G.getNodeWeight(node));

                if(partition_config.combine) {
                        coarser.setSecondPartitionIndex(coarseNode, G.getSecondPartitionIndex(node));
                }

                // do something with all outgoing edges (in auxillary graph)
                forall_out_edges(G, e, node) {
                        visit_edge(G, coarser, edge_positions, coarseNode, e, new_edge_targets);                        
                } endfor
Esempio n. 9
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
Esempio n. 10
0
EdgeWeight edge_cut_flow_solver::convert_ds( const PartitionConfig & config, 
                                             graph_access & G, 
                                             PartitionID & lhs, 
                                             PartitionID & rhs, 
                                             std::vector<NodeID> & lhs_boundary_stripe,
                                             std::vector<NodeID> & rhs_boundary_stripe,
                                             std::vector<NodeID> & new_to_old_ids,              
                                             long *n_ad, 
                                             long* m_ad, 
                                             node** nodes_ad, 
                                             arc** arcs_ad, 
                                             long ** cap_ad,
                                             node** source_ad, 
                                             node** sink_ad, 
                                             long* node_min_ad,
                                             EdgeID & no_edges_in_flow_graph) {

        //should soon be refactored
        #include "convert_ds_variables.h"

        //building up the graph as in parse.h of hi_pr code
        NodeID idx = 0;
        new_to_old_ids.resize(lhs_boundary_stripe.size() + rhs_boundary_stripe.size());
        std::unordered_map<NodeID, NodeID> old_to_new;
        for( unsigned i = 0; i < lhs_boundary_stripe.size(); i++) {
                G.setPartitionIndex(lhs_boundary_stripe[i], BOUNDARY_STRIPE_NODE);
                new_to_old_ids[idx]                = lhs_boundary_stripe[i];
                old_to_new[lhs_boundary_stripe[i]] = idx++ ;
        }
        for( unsigned i = 0; i < rhs_boundary_stripe.size(); i++) {
                G.setPartitionIndex(rhs_boundary_stripe[i], BOUNDARY_STRIPE_NODE); 
                new_to_old_ids[idx]                = rhs_boundary_stripe[i];
                old_to_new[rhs_boundary_stripe[i]] = idx++;
        }

        std::vector<NodeID>  outer_lhs_boundary;
        std::vector<NodeID>  outer_rhs_boundary;
        EdgeID no_edges = regions_no_edges(G, lhs_boundary_stripe, rhs_boundary_stripe, 
                                              lhs, rhs, 
                                              outer_lhs_boundary, outer_rhs_boundary);
        no_edges_in_flow_graph = no_edges;
        
        if(outer_lhs_boundary.size() == 0 || outer_rhs_boundary.size() == 0) return false;
        n = lhs_boundary_stripe.size() + rhs_boundary_stripe.size() + 2; //+source and target
        m = no_edges + outer_lhs_boundary.size() + outer_rhs_boundary.size(); 

        nodes    = (node*) calloc ( n+2, sizeof(node) );
        arcs     = (arc*)  calloc ( 2*m+1, sizeof(arc) );
        arc_tail = (long*) calloc ( 2*m,   sizeof(long) ); 
        arc_first= (long*) calloc ( n+2, sizeof(long) );
        acap     = (long*) calloc ( 2*m, sizeof(long) );
        arc_current = arcs;

        node_max = 0;
        node_min = n;

        unsigned nodeoffset = 1;
        source              = n - 2 + nodeoffset;
        sink                = source+1;
        idx                 = 0;
        for( unsigned i = 0; i < lhs_boundary_stripe.size(); i++, idx++) {
                NodeID node = lhs_boundary_stripe[i];
                NodeID sourceID = idx + nodeoffset;
                forall_out_edges(G, e, node) {
                        if(G.getPartitionIndex(G.getEdgeTarget(e)) == BOUNDARY_STRIPE_NODE)  {
                                NodeID targetID     = old_to_new[G.getEdgeTarget(e)] + nodeoffset;
                                EdgeWeight capacity = G.getEdgeWeight(e);
                                tail                = sourceID;
                                head                = targetID;
                                cap                 = capacity;
                        
                                createEdge()                        
                        }
                } endfor
        }
Esempio n. 11
0
void two_way_fm::move_node_back(const PartitionConfig & config, 
                                graph_access & G,
                                const NodeID & node,
                                vertex_moved_hashtable & moved_idx,
                                refinement_pq * from_queue,
                                refinement_pq * to_queue,
                                PartitionID from, 
                                PartitionID to,
                                boundary_pair * pair,         
                                NodeWeight * from_part_weight,
                                NodeWeight * to_part_weight,
                                complete_boundary & boundary) {

        ASSERT_NEQ(from, to);
        ASSERT_EQ(from, G.getPartitionIndex(node));

        //move node
        G.setPartitionIndex(node, to);         
        boundary.deleteNode(node, from, pair);

        EdgeWeight int_degree_node = 0;
        EdgeWeight ext_degree_node = 0;
        bool update_difficult = int_ext_degree(G, node, to, from, int_degree_node, ext_degree_node);

        if(ext_degree_node > 0) {
                boundary.insert(node, to, pair);
        }

        if(update_difficult) {
                boundary.postMovedBoundaryNodeUpdates(node, pair, true, false);
        }

        NodeWeight this_nodes_weight = G.getNodeWeight(node);
        (*from_part_weight) -= this_nodes_weight; 
        (*to_part_weight)   += this_nodes_weight; 

        //update neighbors
        forall_out_edges(G, e, node) {
                NodeID target = G.getEdgeTarget(e);
                PartitionID targets_partition = G.getPartitionIndex(target);

                if((targets_partition != from && targets_partition != to)) {
                        //at most difficult update nec.
                        continue; //they dont need to be updated during this refinement
                }

                EdgeWeight int_degree = 0;
                EdgeWeight ext_degree = 0;

                PartitionID other_partition = targets_partition == from ? to : from;
                int_ext_degree(G, target, targets_partition, other_partition, int_degree, ext_degree); 

                if(boundary.contains(target, targets_partition, pair)) {
                        if(ext_degree == 0) {
                                boundary.deleteNode(target, targets_partition, pair);
                        } 
                } else {
                        if(ext_degree > 0) {
                                boundary.insert(target, targets_partition, pair);
                        }
                }

        } endfor
Esempio n. 12
0
void two_way_fm::move_node(const PartitionConfig & config, 
                           graph_access & G,
                           const NodeID & node,
                           vertex_moved_hashtable & moved_idx,
                           refinement_pq * from_queue,
                           refinement_pq * to_queue,
                           PartitionID from, 
                           PartitionID to,
                           boundary_pair * pair,         
                           NodeWeight * from_part_weight,
                           NodeWeight * to_part_weight,
                           complete_boundary & boundary) {
        //move node
        G.setPartitionIndex(node, to);        
        boundary.deleteNode(node, from, pair);

        EdgeWeight int_degree_node = 0;
        EdgeWeight ext_degree_node = 0;
        bool difficult_update      = int_ext_degree(G, node, to, from, int_degree_node, ext_degree_node);


        if(ext_degree_node > 0) {
                boundary.insert(node, to, pair);
        }

        if(difficult_update)
                boundary.postMovedBoundaryNodeUpdates(node, pair, true, false);


        NodeWeight this_nodes_weight = G.getNodeWeight(node);
        (*from_part_weight) -= this_nodes_weight; 
        (*to_part_weight)   += this_nodes_weight; 

        //update neighbors
        forall_out_edges(G, e, node) {
                NodeID target = G.getEdgeTarget(e);
                PartitionID targets_partition = G.getPartitionIndex(target);

                if((targets_partition != from && targets_partition != to)) {
                        continue; 
                }

                EdgeWeight int_degree = 0;
                EdgeWeight ext_degree = 0;

                PartitionID other_partition = targets_partition == from ? to : from;
                int_ext_degree(G, target, targets_partition, other_partition, int_degree, ext_degree); 

                refinement_pq * queue_to_update = 0;
                if(targets_partition == from) {
                        queue_to_update = from_queue;
                } else {
                        queue_to_update = to_queue;
                }

                Gain gain = ext_degree - int_degree;
                if(queue_to_update->contains(target)) {
                        if(ext_degree == 0) {
                                queue_to_update->deleteNode(target);
                                boundary.deleteNode(target, targets_partition, pair);
                        } else {
                                queue_to_update->changeKey(target, gain);
                        }
                } else {
                        if(ext_degree > 0) {
                                if(moved_idx[target].index == NOT_MOVED) {
                                        queue_to_update->insert(target, gain);
                                }
                                boundary.insert(target, targets_partition, pair);
                        } else {
                                boundary.deleteNode(target, targets_partition, pair);
                        }
                }

        } endfor