extern "C" void* MST(graph_t *G) { trees.clear(); edge_type nearest_edge; vector <uint8_t> marked_vert_in_forest(G->n, 0); bool non_visited_tree = true; vertex_id_t root = 0; vertex_id_t numTrees = 0; while (non_visited_tree) { vector <vertex_id_t> q_marked; q_marked.push_back(root); marked_vert_in_forest[root] = 1; bool non_visited_vert_in_tree = true; trees.push_back(vector <edge_id_t> ()); while (non_visited_vert_in_tree) { non_visited_vert_in_tree = false; nearest_edge.w = DBL_MAX; for (vertex_id_t i = 0; i < q_marked.size(); i++) { for (edge_id_t j = G->rowsIndices[q_marked[i]]; j < G->rowsIndices[q_marked[i]+1]; j++) { if (!marked_vert_in_forest[G->endV[j]]) { non_visited_vert_in_tree = true; if (nearest_edge.w == DBL_MAX || G->weights[j] < nearest_edge.w) { nearest_edge.startV = q_marked[i]; nearest_edge.endV = G->endV[j]; nearest_edge.w = G->weights[j]; nearest_edge.edge_id = j; } } } } if (nearest_edge.w != DBL_MAX) { marked_vert_in_forest[nearest_edge.endV] = 1; trees[numTrees].push_back(nearest_edge.edge_id); q_marked.push_back(nearest_edge.endV); } } non_visited_tree = false; for (vertex_id_t i = 0; i < G->n ; i++) { if (!marked_vert_in_forest[i]) { non_visited_tree = true; root = i; numTrees++; break; } } } return &trees; }
void query_node(box2d<double> const& box, result_t & result, node * node_) const { if (node_) { box2d<double> const& node_extent = node_->extent(); if (box.intersects(node_extent)) { for (auto & n : *node_) { result.push_back(std::ref(n)); } for (int k = 0; k < 4; ++k) { query_node(box,result,node_->children_[k]); } } } }
void query_node(box2d<double> const& box, result_t & result, node * node_) const { if (node_) { box2d<double> const& node_extent = node_->extent(); if (box.intersects(node_extent)) { node_data_iterator i=node_->begin(); node_data_iterator end=node_->end(); while ( i!=end) { result.push_back(&(*i)); ++i; } for (int k = 0; k < 4; ++k) { query_node(box,result,node_->children_[k]); } } } }
/* MPI MST reference implementation. Prim's algorithm */ extern "C" void* MST(graph_t *G) { trees.clear(); int rank = G->rank, size = G->nproc; vertex_id_t TotVertices = G->n; // marked edges are those that lead to vertices already in the tree vector<uint8_t> marked_edges(G->local_m, 0); // marked vertices are local edges already in the tree vector<uint8_t> marked_vertices(G->local_n, 0); // start with first vertex on first node vertex_id_t root = 0; do { // start a new tree trees.push_back(vector<edge_id_t>()); // local queue of vertices vector<vertex_id_t> queue; // keep track of last added edge to mark edges vertex_id_t last_vertex = root; while (true) { if (VERTEX_OWNER(last_vertex, TotVertices, size) == G->rank) { // last vertex is ours - put it in the queue and mark vertex_id_t last_local_vertex = VERTEX_LOCAL(last_vertex, TotVertices, size, rank); marked_vertices[last_local_vertex] = 1; queue.push_back(last_local_vertex); } // mark edges that lead to the last added vertex for (edge_id_t j = 0; j < G->local_m; j++) { if (G->endV[j] == last_vertex) { marked_edges[j] = 1; } } // determine our best candidate edge struct { double weight; int rank; edge_id_t edge; } best; best.weight = DBL_MAX; for (vertex_id_t i = 0; i < queue.size(); i++) { for (edge_id_t j = G->rowsIndices[queue[i]]; j < G->rowsIndices[queue[i] + 1]; j++) { // skip marked edges if (!marked_edges[j]) { // check if this edge is better than what we have up to now if (best.weight == DBL_MAX || G->weights[j] < best.weight) { best.weight = G->weights[j]; best.edge = j; } } } } // reduce and determine global best edge best.rank = G->rank; MPI_Allreduce(MPI_IN_PLACE, &best, 1, MPI_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD); if (best.weight == DBL_MAX) { // no suitable edge found, finish this tree break; } else { if (best.rank == G->rank) { // we have the best edge trees.back().push_back(edge_to_global(best.edge,G)); last_vertex = G->endV[best.edge]; } MPI_Bcast(&last_vertex, 1, MPI_UINT32_T, best.rank, MPI_COMM_WORLD); } } // find root of a new tree root = UINT32_MAX; for (vertex_id_t i = 0; i < G->local_n; i++) { if (!marked_vertices[i]) { root = VERTEX_TO_GLOBAL(i, TotVertices, size, rank); break; } } MPI_Allreduce(MPI_IN_PLACE, &root, 1, MPI_UINT32_T, MPI_MIN, MPI_COMM_WORLD); } while (root!=UINT32_MAX); return &trees; }
query_iterator query_end() { return query_result_.end(); }
query_iterator query_in_box(Envelope<double> const& box) { query_result_.clear(); query_node(box,query_result_,root_); return query_result_.begin(); }