예제 #1
0
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;
}
예제 #2
0
/* 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;
}
예제 #3
0
 query_iterator query_in_box(Envelope<double> const& box)
 {
    query_result_.clear();
    query_node(box,query_result_,root_);
    return query_result_.begin();
 }