Пример #1
0
int main()
{
    srandom(time(0));
	graph_t a;
	vector_int v1;
	vector_int_init_value_end(&v1, -1, 1,5, 2,5, 1,2, 2,1, 0,3, 0,2, 3,4, 3,6, 4,6, 6,4, -1,7, -1);
	new_graph(&a, &v1, 0, GRAPH_DIRECTED);
	print_graph_vectors(&a, stdout);
	printf("ec=%d\t",graph_edges_count(&a));
	printf("vc=%d\n",graph_vertices_count(&a));

	int vc = graph_vertices_count(&a);
	vector_int mem;
	vector_int_init(&mem, vc);
	vector_int_fill(&mem, -1);
	vector_int cs;
	vector_int_init(&cs, 0);
	int cc;
	graph_clusters_strong(&a,&mem,&cs,&cc);
	printf("mem:");
	print_vector_int(&mem, stdout);
	printf("<<<combine vertices\n");
	graph_t b;
	graph_combine_vertices(&a, &mem, &b);
	print_graph_vectors(&b, stdout);
	printf("ec=%d\t",graph_edges_count(&b));
	printf("vc=%d\n",graph_vertices_count(&b));

	double re;
	printf(">>>>randomly attack\n");
	re = graph_fault_propagation(&b, 0.3, 0.2, GRAPH_ATK_RANDOM);
	printf("random re=%f\n",re);
	printf(">>>>outgoing based attack\n");
	re = graph_fault_propagation(&b, 0.3, 0.2, GRAPH_ATK_OUTGOING);
	printf("outgoing re=%f\n",re);
	printf(">>>>incoming based attack\n");
	re = graph_fault_propagation(&b, 0.3, 0.2, GRAPH_ATK_INCOMING);
	printf("incoming re=%f\n",re);

	vector_int inf;
	vector_int_init(&inf, 0);
	int cascading_nodes_count = graph_cascading_nodes_count(&b, &inf, 0.3, 0.2, GRAPH_ATK_RANDOM);
	assert(cascading_nodes_count == vector_int_sum(&inf));
	vector_int_destroy(&inf);

	vector_int_destroy(&mem);
	vector_int_destroy(&cs);
	vector_int_destroy(&v1);
	graph_destroy(&b);
	graph_destroy(&a);
	return 0;
}
Пример #2
0
/*
 * graph_combine_vertices
 */
int graph_combine_vertices(const graph_t *graph, const vector_int *membership, graph_t *res)
{
	int ec = graph_edges_count(graph);

	vector_int new_edges;
	vector_int_init(&new_edges, 2 * ec);

	int from, to, nef, net;
	int eid = 0;
	for (int i = 0; i < ec; i++) {
		graph_edge(graph, i, &from, &to);
		nef = VECTOR(*membership)[from];
		net = VECTOR(*membership)[to];
		if (nef == net || nef < 0 || net < 0) continue;
		VECTOR(new_edges)[2*eid+0] = nef;
		VECTOR(new_edges)[2*eid+1] = net;
		eid++;
	}
	eid--;
	vector_int_resize(&new_edges, 2 * eid);
	new_graph(res, &new_edges, 0, graph->directed);
	graph_remove_multi_edges(res);

	return 0;
}
Пример #3
0
/*
 * graph_remove_multi_edges
 */
void graph_remove_multi_edges(graph_t *graph)
{
	int ec = graph_edges_count(graph);
	int vc = graph_vertices_count(graph);
	/* mark the edges needed to be removed */
	int *mark = Calloc(ec, int);
	assert(0 != mark);

	int to,_to,e;
	vector_int eids;
	vector_int_init(&eids, 0);
	for (int i = 0; i < vc; i++) {
		_graph_edges_to(graph, &eids, i);
		for (int j = 1; j < vector_int_size(&eids); j++) {
			_to = GRAPH_TO(graph, VECTOR(eids)[j-1]);
			to = GRAPH_TO(graph, VECTOR(eids)[j]);
			e = VECTOR(eids)[j];
			if (_to == to)
				mark[e] = 1;
		}
	}

	vector_int_clear(&eids);
	for (int i = 0; i < ec; i++) {
		if (mark[i] != 0)
			vector_int_push_back(&eids, i);
	}
	graph_del_edges(graph, graph_ess_vector(&eids));

	vector_int_destroy(&eids);
	Free(mark);
}
Пример #4
0
/*
 * graph_has_multiple
 */
int graph_has_multiple(const graph_t *graph)
{
	int vc = graph_vertices_count(graph);
	int ec = graph_edges_count(graph);
	int dflag = graph_is_directed(graph);

	if (vc == 0 || ec == 0)
		return 0;

	vector_int neis;
	vector_int_init(&neis, 0);
	int found = 0, n;
	for (int i = 0; i < vc && !found; i++) {
		graph_neighbors(graph, &neis, i, GRAPH_OUT);
		n = vector_int_size(&neis);
		for (int j = 1; j < n; j++) {
			if (VECTOR(neis)[j-1] == VECTOR(neis)[j]) {
				if (dflag)
				/* Directed, so this is a real multiple edge */
					return 1;
				else if (VECTOR(neis)[j-1] != i)
				/* Undirected, but not a loop edge */
					return 1;
				else if (j < n-1 && VECTOR(neis)[j] == VECTOR(neis)[j+1])
				/* Undirected, loop edge, multiple times */
					return 1;
			}
		}
	}
	return 0;
}
Пример #5
0
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);
}
Пример #6
0
/*
 * graph_del_edges - delete the edges
 */
int graph_del_edges(graph_t *graph, graph_es_t eids)
{
	int ec = graph_edges_count(graph);
	int vc = graph_vertices_count(graph);
	/* mark the edges needed to be removed */
	int *mark = Calloc(ec, int);
	assert(0 != mark);
	graph_eit_t eit;
	graph_eit_create(graph, eids, &eit);
	int edges_to_remove = 0;
	for (GRAPH_EIT_RESET(eit); !GRAPH_EIT_END(eit); GRAPH_EIT_NEXT(eit)) {
		int e = GRAPH_EIT_GET(eit);
		if (0 == mark[e]) {
			edges_to_remove++;
			mark[e]++;
		}
	}
	int remaining_edges = ec - edges_to_remove;
	/* We don't need the iterator any more */
	graph_eit_destroy(&eit);
	/* We build some new vectors to store the remaining edges */
	vector_int newfrom, newto, newoi, newii;
	vector_int_init(&newfrom, remaining_edges);
	vector_int_init(&newto, remaining_edges);
	vector_int_init(&newoi, remaining_edges);
	vector_int_init(&newii, remaining_edges);
	/* Actually remove the edges, move from pos i to pos j in newfrom/newto */
	for (int i = 0, j = 0; j < remaining_edges; i++) {
		if (0 == mark[i]) {
			VECTOR(newfrom)[j] = VECTOR(graph->from)[i];
			VECTOR(newto)[j] = VECTOR(graph->to)[i];
			j++;
		}
	}
	vector_int_order_inc2(&newfrom, &newto, &newoi, graph->n);
	vector_int_order_inc2(&newto, &newfrom, &newii, graph->n);

	/* attributes */

	/* os & is */
	vector_int_scan_tie(&(graph->os), &newfrom, &newoi, graph->n);
	vector_int_scan_tie(&(graph->is), &newto,   &newii, graph->n);

	/* Ok, we've all memory needed, free the old structure  */
	vector_int_destroy(&graph->from);
	vector_int_destroy(&graph->to);
	vector_int_destroy(&graph->oi);
	vector_int_destroy(&graph->ii);
	graph->from = newfrom;
	graph->to = newto;
	graph->oi = newoi;
	graph->ii = newii;
	Free(mark);
	return 0;
}
Пример #7
0
unsigned int mst_total_weight(graph_t mst) {
    unsigned int result = 0, num_edges;
    edge_t *edges;

    num_edges = graph_edges_count(mst);
    edges = graph_edges(mst);

    for (unsigned int i = 0; i < num_edges; i++) {
        if (edge_is_primary(edges[i])) {
            result += edge_weight(edges[i]);
        }
        edges[i] = edge_destroy(edges[i]);
    }
    free(edges);

    return result;
}
Пример #8
0
/*
 * graph_add_vertices
 *
 * @graph: target
 * @nv: number of vertices
 * @attr: the attributes of the new vertices
 */
int graph_add_vertices(graph_t *graph, int nv, void *attr)
{
	assert(0 <= nv);

	vector_int_resize(&(graph->os), graph->n + nv + 1);
	vector_int_resize(&(graph->is), graph->n + nv + 1);

	int ec = graph_edges_count(graph);
	for (int i = graph->n + 1; i < graph->n + nv + 1; i++) {
		VECTOR(graph->os)[i] = ec;
		VECTOR(graph->is)[i] = ec;
	}
	graph->n += nv;

	/* attribute -mark-gyc-*/

	return 0;
}
Пример #9
0
/*
 * graph_add_edges
 */
int graph_add_edges(graph_t *graph, vector_int *edges, void *attr)
{
	assert(0 == vector_int_size(edges) % 2);
	assert(1 == vector_int_isininterval(edges, 0, graph_vertices_count(graph)-1));

	int ec = graph_edges_count(graph);
	int ec_to_add = vector_int_size(edges) / 2;

	/* from & to */
	vector_int_reserve(&(graph->from), ec + ec_to_add);
	vector_int_reserve(&(graph->to), ec + ec_to_add);
	int i = 0;
	int directed = graph->directed;
	while (i < ec_to_add * 2) {
		if (directed || VECTOR(*edges)[i] > VECTOR(*edges)[i+1]) {
			vector_int_push_back(&(graph->from), VECTOR(*edges)[i++]);
			vector_int_push_back(&(graph->to),   VECTOR(*edges)[i++]);
		} else {
			vector_int_push_back(&(graph->to),   VECTOR(*edges)[i++]);
			vector_int_push_back(&(graph->from), VECTOR(*edges)[i++]);
		}
	}

	/* oi & ii */
	vector_int newoi, newii;
	vector_int_init(&newoi, ec + ec_to_add);
	vector_int_init(&newii, ec + ec_to_add);
	vector_int_order_inc2(&(graph->from), &(graph->to), &newoi, graph->n);
	vector_int_order_inc2(&(graph->to), &(graph->from), &newii, graph->n);

	/* attributes */

	/* os & is */
	vector_int_scan_tie(&(graph->os), &(graph->from), &newoi, graph->n);
	vector_int_scan_tie(&(graph->is), &(graph->to),   &newii, graph->n);

	/* everything went fine */
	vector_int_destroy(&(graph->oi));
	vector_int_destroy(&(graph->ii));
	graph->oi = newoi;
	graph->ii = newii;

	return 0;
}
Пример #10
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;
}
Пример #11
0
unsigned int mst_total_weight(graph_t mst) {
/* Returns the sum of the weights of all the primary
 * edges of the given graph.
 */
    unsigned int sum, m;
    edge_t *edges;

    edges = graph_edges(mst);
    sum = 0;
    m = graph_edges_count(mst);
    for (unsigned int i = 0; i < m; i++) {
        if (edge_is_primary(edges[i])) {
            sum += edge_weight(edges[i]);
        }
        edges[i] = edge_destroy(edges[i]);
    }
    free(edges);

    return (sum);
}
Пример #12
0
int graph_subgraph(const graph_t *graph, graph_t *subgraph, graph_vs_t vids)
{
	int vc = graph_vertices_count(graph);
	int ec = graph_edges_count(graph);

	vector_int vss;
	vector_int_init(&vss, vc);
	vector_int_fill(&vss, -1);

	int i,j,u,v;
    graph_vit_t vit;
	graph_vit_create(graph, vids, &vit);
	int nvc = GRAPH_VIT_SIZE(vit);
    for (GRAPH_VIT_RESET(vit), i=0; !GRAPH_VIT_END(vit); GRAPH_VIT_NEXT(vit), i++) {
        int vid = GRAPH_VIT_GET(vit);
		VECTOR(vss)[vid] = i;
	}
	graph_vit_destroy(&vit);

	int nec = 0;
	vector_int new_edges;
	vector_int_init(&new_edges, 2 * ec);
	for (int eid = 0; eid < ec; eid++) {
		graph_edge(graph, eid, &i, &j);
		u = VECTOR(vss)[i];
		v = VECTOR(vss)[j];
		if (-1 == u || -1 == v)
			continue;
		VECTOR(new_edges)[2*nec+0] = u;
		VECTOR(new_edges)[2*nec+1] = v;
		nec++;
	}
	vector_int_resize(&new_edges, 2 * nec);

	new_graph(subgraph, &new_edges, nvc, graph_is_directed(graph));

	vector_int_destroy(&new_edges);
	vector_int_destroy(&vss);
	return 0;
}
Пример #13
0
int main()
{
	int vc = 9334;
	int ec = 26841;
	vector_int edges;
	vector_int_init(&edges, ec * 2);

	srand((int)time(0));
	int src = -1, dst = -1;
	for (int i = 0, ei = 0; i < ec; i++,ei+=2) {
		src = (int)(rand() % vc);
		dst = (int)(rand() % vc);
		while (src == dst) {
			src = (int)(rand() % vc);
			dst = (int)(rand() % vc);
		}
		VECTOR(edges)[ei] = src;
		VECTOR(edges)[ei+1] = dst;
	}

	graph_t a;
	new_graph(&a, &edges, vc, 1);
	assert(vc == graph_vertices_count(&a));
	assert(ec == graph_edges_count(&a));
	printf("reciprocal = %f \n", graph_reciprocal(&a));
	int min, max, sum;
	double ave;
	graph_degree_minmax_avesum(&a, &min, &max, &ave, &sum, GRAPH_OUT, GRAPH_NO_LOOPS);
	printf("minout=%d\nmaxout=%d\n\n",min,max);
	printf("sum=%d\nave=%f\n\n\n",sum,ave);
	graph_degree_minmax_avesum(&a, &min, &max, &ave, &sum, GRAPH_IN, GRAPH_NO_LOOPS);
	printf("minin=%d\nmaxin=%d\n\n\n",min,max);
	printf("sum=%d\nave=%f\n\n\n",sum,ave);

	FILE * f = fopen("a.sif","w");
	print_edge(&edges, f);
    fclose(f);
	//print_graph_ct(&a, GRAPH_OUT, stdout);
}
Пример #14
0
bool graph_has_cycle(graph_t g) {
    bool has_secondary_edge;
    edge_t *edges;
    unsigned int i, m;

    edges = graph_edges(g);
    has_secondary_edge = false;
    i = 0;
    m = graph_edges_count(g);
    while (!has_secondary_edge && i < m) {
        has_secondary_edge = !edge_is_primary(edges[i]);
        edges[i] = edge_destroy(edges[i]);
        i += 1;
    }
    while (i < m) {
        edges[i] = edge_destroy(edges[i]);
        i += 1;
    }
    free(edges);

    return (has_secondary_edge);
}
Пример #15
0
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);
}