Esempio n. 1
0
File: main.c Progetto: Tinix/kruskal
unsigned int graph_connected_components(graph_t g) {
    unsigned int classes_count = 0, n, m, left, right;
    union_find_t uf;
    edge_t *edges;

    n = graph_vertices_count(g);
    m = graph_edges_count(g);
    uf = union_find_create(n);

    edges = graph_edges(g);
    for (unsigned int i = 0; i < m; i++) {
        left = vertex_label(edge_left_vertex(edges[i]));
        right = vertex_label(edge_right_vertex(edges[i]));
        left = union_find_find(uf, left);
        right = union_find_find(uf, right);
        if (!union_find_connected(uf, left, right)) {
            union_find_union(uf, left, right);
        }
        edges[i] = edge_destroy(edges[i]);
    }
    free(edges);
    classes_count = union_find_count(uf);
    uf = union_find_destroy(uf);

    return (classes_count);
}
/* TODO merge with 2D version */
struct MergeTree *compute_merge_tree3d(const struct CtGrid3d *grid,
                                       const struct Scalar sorted_scalars[],
                                       int8_t lookup[][3], const int lookup_size)
{
    /* TODO do sanity checks if memory could be allocated */
    struct UnionFind *uf = union_find_create(grid->len);

    /* lowest vertex of each component */   
    int *lowest_vertex = malloc(grid->len * sizeof(int));

    struct MergeTree *tree = merge_tree_create(grid->len);

    /* set global maximum */
    if (grid->len)
        tree->max_node = sorted_scalars[0].index;

    const struct Header *header = grid3d_header(grid);


    for (int i = 0; i < grid->len; ++i) {
        const int v = sorted_scalars[i].index;
        int v_i, v_j, v_k;
        grid3d_index2pos(grid, v, &v_i, &v_j, &v_k);

        int uf_v = union_find_make_set(uf, v);

        merge_tree_add_node(tree, v, sorted_scalars[i].isovalue);

        /* check all neighbours */
        for (int j = 0; j < lookup_size; ++j) {
            const int n_i = v_i + lookup[j][0];
            const int n_j = v_j + lookup[j][1];
            const int n_k = v_k + lookup[j][2];
            const int n = grid3d_pos2index(grid, n_i, n_j, n_k);
            int uf_n;

            /* check for boundary or if vertex was already processed */
            if ((n_i < 0 || n_i >= header->size[0]) ||
                (n_j < 0 || n_j >= header->size[1]) ||
                (n_k < 0 || n_k >= header->size[2]) ||
                (uf_n = union_find_find(uf, n)) == UNION_FIND_NULL)
                continue;

            /* different components; merge and add arc to tree */
            if (uf_n != uf_v) {
                merge_tree_add_arc(tree, v, lowest_vertex[uf_n], n);
                uf_v = union_find_union(uf, uf_v, uf_n);
            }
        }

        /* we have latest set for vertex v, because union operation returns it */
        lowest_vertex[uf_v] = v;
    }

    union_find_destroy(uf);
    free(lowest_vertex);

    return tree;
}
Esempio n. 3
0
graph_t kruskal(graph_t graph) {
    graph_t result = graph_empty(graph_vertices_count(graph));
    unsigned int L, R, num_edges = graph_edges_count(graph);
    vertex_t l = NULL, r = NULL;
    pqueue_t Q = pqueue_empty(num_edges);
    union_find_t C = union_find_create(graph_vertices_count(graph));
    edge_t E = NULL, *edges = graph_edges(graph);
    for (unsigned int i = 0; i < num_edges; i++) {
        pqueue_enqueue(Q, edges[i]);
    }

    free(edges);
    edges = NULL;

    while (!pqueue_is_empty(Q) && union_find_count(C) > 1) {
        E = edge_copy(pqueue_fst(Q));
        l = edge_left_vertex(E);
        r = edge_right_vertex(E);
        L = union_find_find(C, vertex_label(l));
        R = union_find_find(C, vertex_label(r));

        if (L != R) {
            union_find_union(C, L, R);
            E = edge_set_primary(E, true);
        } else {
            E = edge_set_primary(E, false);
        }
        result = graph_add_edge(result, E);
        pqueue_dequeue(Q);
    }

    while (!pqueue_is_empty(Q)) {
        E = edge_copy(pqueue_fst(Q));
        pqueue_dequeue(Q);
        E = edge_set_primary(E, false);
        result = graph_add_edge(result, E);
    }

    Q = pqueue_destroy(Q);
    C = union_find_destroy(C);

    return result;
}
int main() {
	unsigned int maxSize = 10;
	union_find_t uf = union_find_create(maxSize);
	bool exit = false;
	char *option = NULL;
	unsigned int u,v;
	printf("%u cantidad de nodos.\n",union_find_count(uf));
	do {
		option = print_menu();
		switch(*option) {
			case FIND:
				printf("\nPor favor ingrese el nodo a buscar: ");
				scanf("%u",&u);
				printf("\nEl representante es %u.\n",union_find_find(uf, u));
				break;
			case UNION:
				printf("\nPor favor ingrese los conjuntos a unir: ");
				scanf("%u %u",&u,&v);
				union_find_union(uf, u, v);
				break;
			case CONNECT:
				printf("\nPor favor ingrese los nodos: ");
				scanf("%u %u",&u,&v);
				if(union_find_connected(uf, u, v))
					printf("TRUE\n");
				else
					printf("FALSE\n");
				break;
			case EXIT:
				exit = true;
				break;
			
		}
		free(option);
        option = NULL;
	} while(!exit);
	uf = union_find_destroy(uf);

}
Esempio n. 5
0
File: main.c Progetto: Tinix/kruskal
graph_t kruskal(graph_t graph) {
/* Computes a MST of the given graph.
 *
 * This function returns a copy of the input graph in which
 * only the edges of the MST are marked as primary. The
 * remaining edges are marked as secondary. 
 *
 * The input graph does not change. 
 * 
*/
    graph_t mst;
    union_find_t uf;
    pqueue_t pq;
    edge_t *edges;
    edge_t e;
    unsigned int left, right, n, m;

    /* Inicialización */
    n = graph_vertices_count(graph);
    m = graph_edges_count(graph);
    mst = graph_empty(n);
    uf = union_find_create(n);
    pq = pqueue_empty(m);

    /* Llenar `pq` */
    edges = graph_edges(graph);
    for (unsigned int j = 0; j < m; j++) {
        pqueue_enqueue(pq, edges[j]);
    }
    /* Ahora las aristas están en `pq` */
    free(edges);
    edges = NULL;


    /* Principal */
    while (!pqueue_is_empty(pq) && union_find_count(uf) > 1) {
        e = edge_copy(pqueue_fst(pq));
        left = vertex_label(edge_left_vertex(e));
        right = vertex_label(edge_right_vertex(e));
        left = union_find_find(uf, left);
        right = union_find_find(uf, right);
        if (!union_find_connected(uf, left, right)) {
            e = edge_set_primary(e, true);
            union_find_union(uf, left, right);
        } else {
            e = edge_set_primary(e, false);
        }
        mst = graph_add_edge(mst, e);
        pqueue_dequeue(pq);
    }

    /* Agregar aristas restantes como secundarias */
    while (!pqueue_is_empty(pq)) {
        e = edge_copy(pqueue_fst(pq));
        e = edge_set_primary(e, false);
        mst = graph_add_edge(mst, e);
        pqueue_dequeue(pq);
    }

    /* Destroy */
    uf = union_find_destroy(uf);
    pq = pqueue_destroy(pq);

    return (mst);
}