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; }
/* * graph_neighbor_subgraph - calculate the @subgraph consists of the neighbors of vertex @s * used for calculate the local efficiency. * * @neis: neighbors' id */ int graph_neighbor_subgraph(const graph_t *graph, graph_t *subgraph, vector_int *neis, int s, graph_neimode_t mode) { int vc = graph_vertices_count(graph); graph_neighbors(graph, neis, s, mode); vector_int edges; vector_int_init(&edges, 0); vector_int neis2; vector_int_init(&neis2, 0); int v, w; for (int i = 0; i < vector_int_size(neis); i++) { v = VECTOR(*neis)[i]; if (v == s) continue; graph_neighbors(graph, &neis2, v, GRAPH_OUT); for (int j = 0; j < vector_int_size(&neis2); j++) { w = VECTOR(neis2)[j]; if (w == s || w == v) continue; int wid = vector_int_whereis(neis, w); if (-1 != wid) { vector_int_push_back(&edges, i); vector_int_push_back(&edges, wid); } } } new_graph(subgraph, &edges, vector_int_size(neis), graph_is_directed(graph)); vector_int_destroy(&neis2); vector_int_destroy(&edges); return 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); }
/* * 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; }
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); }
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; }
/* * 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; }
/* * print_graph_ct */ void print_graph_ct(const graph_t *graph, graph_neimode_t mode, FILE *f) { vector_int tmp; vector_int_init(&tmp, 0); for (int i = 0; i < graph_vertices_count(graph); i++) { fprintf(f,"v%d:\n",i); graph_neighbors(graph, &tmp, i, mode); for (int j = 0; j < vector_int_size(&tmp); j++) fprintf(f,"| v%d\n", VECTOR(tmp)[j]); } }
int _graph_edges_to(const graph_t *graph, vector_int *eids, int vid) { assert(vid >= 0); assert(vid < graph_vertices_count(graph)); int length = (VECTOR(graph->os)[vid+1] - VECTOR(graph->os)[vid]); vector_int_resize(eids, length); int idx = 0; int j = VECTOR(graph->os)[vid+1]; for (int i = VECTOR(graph->os)[vid]; i < j; i++) VECTOR(*eids)[idx++] = VECTOR(graph->oi)[i]; return 0; }
int graph_edge_contains(const graph_t *graph, int v, int w, graph_neimode_t mode) { assert(0 != graph); int vc = graph_vertices_count(graph); if (v >= vc || w >= vc) return 0; vector_int neis; vector_int_init(&neis, 0); graph_neighbors(graph, &neis, v, mode); int res = vector_int_contains(&neis, w) ? 1 : 0; vector_int_destroy(&neis); return res; }
/* * 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; }
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; }
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); }
int main(int argc, char *argv[]) { /* setup */ char *path = "./data/ct/"; char *path2 = "/home/gyc/Sources/linux.doc/kernel/"; vector_char str; vector_char_init(&str,100); VECTOR(str)[0] = '\0'; SetupLexer(); dic_setup(); struct dictionary *dict = new_dictionary(10000); graph_t lkn; vector_int edges; catch_function_call_dir(path, dict, &edges); printf("capacity=%d,size=%d\n",dict_capacity(dict), dict_size(dict)); new_graph(&lkn, &edges, 0, GRAPH_DIRECTED); struct dictionary *filedict = new_dictionary(4); vector_funcP flist; vector_funcP_init_(&flist, dict_size(dict)); get_function_filename(path2, dict, filedict, &flist); printf("filedict: capacity=%d,size=%d\n",dict_capacity(filedict), dict_size(filedict)); /* reciprocal */ printf("reciprocal = %f \n", graph_reciprocal(&lkn)); vector_double res; vector_double_init(&res, 0); graph_betweenness(&lkn, &res, graph_vss_all(), GRAPH_DIRECTED); printf("betweenness directed:"); print_vector_double(&(res),stdout); vector_double_destroy(&res); /* degree */ graph_degree(&lkn, &edges, graph_vss_all(), GRAPH_OUT, GRAPH_NO_LOOPS); printf(">>>out, no loops"); int min, max, sum; double ave; graph_degree_minmax_avesum(&lkn, &min, &max, &ave, &sum, GRAPH_OUT, GRAPH_NO_LOOPS); printf("minout=%d\nmaxout=%d\nsumout=%d\naveout=%f\n",min,max,sum,ave); graph_degree_minmax_avesum(&lkn, &min, &max, &ave, &sum, GRAPH_IN, GRAPH_NO_LOOPS); printf("minin=%d\nmaxin=%d\nsumin=%d\navein=%f\n",min,max,sum,ave); /* fast community */ graph_reverse(&lkn); vector_int v1; vector_int_init(&v1,0); int ncom = 0; double modularity = graph_community_fastgreedy(&lkn, &v1, &ncom); printf("modularity = %f,ncom = %d\n",modularity,ncom); FILE *f = fopen("funccom.fc.xlsx","w"); fprintf(f, "comID\tname\n"); for (int i = 0; i < dict_size(dict);i++) { fprintf(f, "%d\t", VECTOR(v1)[i]); struct rb_node* e = dict_ele(dict, i); dic_traceback_string(e, &str); fprintf(f, "%s\n",VECTOR(str)); } fclose(f); f = fopen("comID.fc.xlsx","w"); output_com_filename(&flist, &v1, graph_vertices_count(&lkn), ncom, filedict, f); fclose(f); //print_vector_int(&v1, stdout); print_communities(&lkn, &v1, "community.fc.xlsx", "comedge.fc.xlsx"); vector_funcP_destroy(&flist); vector_int_destroy(&v1); vector_char_destroy(&str); vector_int_destroy(&edges); graph_destroy(&lkn); return 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); }