/* call-seq: * graph.clusters(mode) -> Array * * Calculates the (weakly or strongly) connected components in a graph. * Returns an Array of Arrays of vertices. Each sub-Array is a graph component */ VALUE cIGraph_clusters(VALUE self, VALUE mode){ igraph_t *graph; igraph_vector_t membership; igraph_integer_t no; VALUE components; VALUE v,c; int i; igraph_vector_init_int(&membership,0); Data_Get_Struct(self, igraph_t, graph); igraph_clusters(graph, &membership, NULL, &no, NUM2INT(mode)); components = rb_ary_new(); for(i=0;i<no;i++){ rb_ary_push(components,rb_ary_new()); } for(i=0;i<igraph_vector_size(&membership);i++){ v = cIGraph_get_vertex_object(self, i); c = rb_ary_entry(components,VECTOR(membership)[i]); rb_ary_push(c,v); } igraph_vector_destroy(&membership); return components; }
static GError* _tgengraph_parseGraphProperties(TGenGraph* g) { TGEN_ASSERT(g); gint result = 0; tgen_debug("checking graph properties..."); /* IGRAPH_WEAK means the undirected version of the graph is connected * IGRAPH_STRONG means a vertex can reach all others via a directed path */ result = igraph_is_connected(g->graph, &(g->isConnected), IGRAPH_WEAK); if(result != IGRAPH_SUCCESS) { return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "igraph_is_connected return non-success code %i", result); } igraph_integer_t clusterCount; result = igraph_clusters(g->graph, NULL, NULL, &(g->clusterCount), IGRAPH_WEAK); if(result != IGRAPH_SUCCESS) { return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "igraph_clusters return non-success code %i", result); } /* it must be connected */ if(!g->isConnected || g->clusterCount > 1) { return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "graph must be but is not connected"); } g->isDirected = igraph_is_directed(g->graph); tgen_debug("checking graph attributes..."); /* now check list of all attributes */ igraph_strvector_t gnames, vnames, enames; igraph_vector_t gtypes, vtypes, etypes; igraph_strvector_init(&gnames, 25); igraph_vector_init(>ypes, 25); igraph_strvector_init(&vnames, 25); igraph_vector_init(&vtypes, 25); igraph_strvector_init(&enames, 25); igraph_vector_init(&etypes, 25); result = igraph_cattribute_list(g->graph, &gnames, >ypes, &vnames, &vtypes, &enames, &etypes); if(result != IGRAPH_SUCCESS) { return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "igraph_cattribute_list return non-success code %i", result); } gint i = 0; for(i = 0; i < igraph_strvector_size(&gnames); i++) { gchar* name = NULL; igraph_strvector_get(&gnames, (glong) i, &name); tgen_debug("found graph attribute '%s'", name); } for(i = 0; i < igraph_strvector_size(&vnames); i++) { gchar* name = NULL; igraph_strvector_get(&vnames, (glong) i, &name); tgen_debug("found vertex attribute '%s'", name); g->knownAttributes |= _tgengraph_vertexAttributeToFlag(name); } for(i = 0; i < igraph_strvector_size(&enames); i++) { gchar* name = NULL; igraph_strvector_get(&enames, (glong) i, &name); tgen_debug("found edge attribute '%s'", name); g->knownAttributes |= _tgengraph_edgeAttributeToFlag(name); } igraph_strvector_destroy(&gnames); igraph_vector_destroy(>ypes); igraph_strvector_destroy(&vnames); igraph_vector_destroy(&vtypes); igraph_strvector_destroy(&enames); igraph_vector_destroy(&etypes); tgen_info("successfully verified graph properties and attributes"); return NULL; }
static PyObject *ignp_fun_propagate(PyObject *self, PyObject *args) { long int num_active = 0; long int num_susc = 1; long int limit = 30; long int i; float lrAct; PyObject* mem_addr_o; long int mem_addr; /* StateTracker Vars */ PyArrayObject *py_trkr; // 'i64' /* By EdgeID */ PyArrayObject *py_tie_r; // 'f32' /* By NodeID */ PyArrayObject *py_act_n; // 'i8' PyArrayObject *py_thr_n; // 'f32' PyArrayObject *py_exp_n; // 'i64' /* By Infection Order*/ PyArrayObject *py_deg; // i64 PyArrayObject *py_nSuc; // i64 PyArrayObject *py_nAct; // i64 PyArrayObject *py_lrAct; // f32 PyArrayObject *py_hom; // i64 PyArrayObject *py_eComp; // i64 PyArrayObject *py_iComp; // i64 PyArrayObject *py_eTri; // i64 PyArrayObject *py_iTri; // i64 PyArrayObject *py_thr; // i32 PyArrayObject *py_exp; // i64 PyArrayObject *py_cTime; // i64 PyObject *g_obj; igraph_t *g; igraph_t gc; long int randID; long int low = 0; long int high = -1; long int ctime = 0; igraph_rng_t *rGen; igraph_vit_t nbr_iter; igraph_vs_t nbr_sel; igraph_integer_t eid; igraph_integer_t vdeg; igraph_integer_t e_comp = 0; igraph_integer_t i_comp = 0; igraph_integer_t e_tri = 0; igraph_integer_t i_tri = 0; int actv_nbr_count; //int res, j; igraph_vector_t temp; //igraph_vector_t actv_nbrs; //PySys_WriteStdout("Parse Started\n"); if (!PyArg_ParseTuple(args, "OO!O!O!O!O!O!O!O!O!O!O!O!O!O!O!O!O!", &g_obj, &PyArray_Type, &py_trkr, // i64 &PyArray_Type, &py_tie_r, // 'f32' &PyArray_Type, &py_act_n, // 'i8' &PyArray_Type, &py_thr_n, // 'i32' &PyArray_Type, &py_exp_n, // 'i64' &PyArray_Type, &py_deg, // i64 &PyArray_Type, &py_nSuc, // i64 &PyArray_Type, &py_nAct, // i64 &PyArray_Type, &py_lrAct, // f32 &PyArray_Type, &py_hom, // i64 &PyArray_Type, &py_eComp, // i64 &PyArray_Type, &py_iComp, // i64 &PyArray_Type, &py_eTri, // i64 &PyArray_Type, &py_iTri, // i64 &PyArray_Type, &py_thr, // i64 &PyArray_Type, &py_exp, // i64 &PyArray_Type, &py_cTime // i64 )) { printf("Parse Failed\n"); Py_RETURN_NONE; } //PySys_WriteStdout("Getting Tracker Vars\n"); num_active = (long) ax_i64(py_trkr, 0); num_susc = (long) ax_i64(py_trkr, 1); limit = (long) ax_i64(py_trkr, 2); mem_addr_o = PyObject_CallMethod(g_obj, "_raw_pointer", "()"); mem_addr = PyInt_AsLong(mem_addr_o); Py_DECREF(mem_addr_o); if (mem_addr == -1) { printf("PyInt to Long Failed"); return NULL; } g = (igraph_t*) mem_addr; //Setup Vars rGen = igraph_rng_default(); //igraph_rng_init(rGen, time(NULL)); high += (long) igraph_vcount(g); //PySys_WriteStdout("Propagate Starting with %li active of target %li with %li open\n", // num_active, limit, num_susc); //Propagate do { // get random node ctime += 1; randID = igraph_rng_get_integer(rGen, low, high); if ( ax_i8(py_act_n, randID) != 1 && ax_i64(py_exp_n, randID)>=ax_i32(py_thr_n, randID) ){ //activate ax_i8(py_act_n,randID) = 1; lrAct = 0; //update nbrs actv_nbr_count = 0; igraph_vs_adj( &nbr_sel, randID, IGRAPH_ALL); igraph_vit_create(g, nbr_sel, &nbr_iter); igraph_vs_size(g, &nbr_sel, &vdeg); igraph_vector_init(&temp, vdeg); while( !IGRAPH_VIT_END(nbr_iter) ){ i = (long int) IGRAPH_VIT_GET(nbr_iter); ax_i64( py_exp_n, i ) += 1; /* update active nbr count and collect id of active */ if ( ax_i8(py_act_n, i) == i ) { VECTOR(temp)[actv_nbr_count]=i; actv_nbr_count += 1; } /* update num_susc */ if ( ax_i8(py_act_n, i) == 0 && \ ax_i32(py_thr_n, i) > (float) (ax_i64(py_exp_n, i)-1) && \ ax_i32(py_thr_n, i) <= (float) ax_i64(py_exp_n, i) ){ /*PySys_WriteStdout("%li < %i <= %li\n", (ax_i64(py_exp_n, i)-1), ax_i32(py_thr_n, i), ax_i64(py_exp_n, i) );*/ num_susc += 1; } /* Get #active long ties */ if ( ax_i8(py_act_n, i) == 1 ){ igraph_get_eid(g, &eid, randID, i, 0, 1); lrAct += ax_f32( py_tie_r, eid )>2 ; } IGRAPH_VIT_NEXT(nbr_iter); } igraph_vit_destroy(&nbr_iter); igraph_vs_destroy(&nbr_sel); //Compute Components (among all and active nbrs) igraph_vs_adj( &nbr_sel, randID, IGRAPH_ALL); igraph_induced_subgraph(g, &gc, nbr_sel, IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH); igraph_clusters(&gc, NULL, NULL, &e_comp, IGRAPH_WEAK); e_tri = igraph_vcount(&gc); igraph_destroy(&gc); igraph_vs_destroy(&nbr_sel); igraph_induced_subgraph(g, &gc, igraph_vss_vector(&temp), \ IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH); igraph_clusters(&gc, NULL, NULL, &i_comp, IGRAPH_WEAK); i_tri = igraph_vcount(&gc); //Clean up igraph_destroy(&gc); igraph_vector_destroy(&temp); //PySys_WriteStdout("e_comp: %i, i_comp: %i\n", e_comp, i_comp); //PySys_WriteStdout("e_tri: %i, i_tri: %i\n", e_tri, i_tri); //update tracking vars ax_f32( py_lrAct, num_active ) = (npy_float32) lrAct; ax_i32( py_thr, num_active) = ax_i32(py_thr_n, randID); ax_i64( py_deg, num_active) = (npy_int64) vdeg; ax_i64( py_nSuc, num_active) = (npy_int64) num_susc; ax_i64( py_nAct, num_active) = (npy_int64) num_active; //ax_i64( py_hom, num_active) = (npy_int64) num_susc; ax_i64( py_eComp, num_active) = (npy_int64) e_comp; ax_i64( py_iComp, num_active) = (npy_int64) i_comp; ax_i64( py_eTri, num_active) = (npy_int64) e_tri; ax_i64( py_iTri, num_active) = (npy_int64) i_tri; ax_i64( py_exp, num_active) = ax_i64(py_exp_n, randID); ax_i64( py_cTime, num_active) = (npy_int64) ctime; num_active += 1; } } while( num_susc > num_active && num_active < limit); //PySys_WriteStdout("Propagate Finished with %li active of target %li with %li open\n", // num_active, limit, num_susc); //igraph_rng_destroy(rGen); ax_i64(py_trkr, 0) = (npy_int64) num_active; ax_i64(py_trkr, 1) = (npy_int64) num_susc ; ax_i64(py_trkr, 2) = (npy_int64) limit ; Py_RETURN_NONE; }
int main(void) { // This needs to be done *first*. See igraph doc for why. igraph_i_set_attribute_table(&igraph_cattribute_table); printf("sizeof(int)=%d sizeof(long)=%d sizeof(igraph_integer_t)=%d\n", (int) sizeof(int), (int) sizeof(long), (int) sizeof(igraph_integer_t)); pause(); printf("Loading graph from file...\n"); FILE* f = fopen("donnees/arretes.test", "r"); //FILE* f = fopen("graph_a.ncol", "r"); igraph_t gr; igraph_read_graph_ncol(&gr, f, NULL, 1, 0, 0); fclose(f); f = NULL; long vcount = igraph_vcount(&gr); long ecount = igraph_ecount(&gr); printf("Main graph: |V| = %ld, |E| = %ld\n", vcount, ecount); pause(); // get connected components printf("Computing connected components...\n"); igraph_vector_t membership; igraph_vector_t csize; igraph_integer_t cnum = 0; igraph_vector_init(&membership, 1); igraph_vector_init(&csize, 1); igraph_clusters(&gr, &membership, &csize, &cnum, IGRAPH_STRONG); printf("There are %ld connected components.\n", (long) cnum); // work with connected components { printf("Writing connected components to file...\n"); // open file FILE* filout = fopen("groupes", "w"); long membership_size = igraph_vector_size(&membership); if (membership_size != vcount) { fprintf(stderr, "FATAL ERROR: membership_size != vcount\n"); exit(1); } for (long i = 0; i < membership_size; i++) { fprintf(filout, "%ld\t%s\n", // connected component id: (long) igraph_vector_e(&membership , i), // veretex name: igraph_cattribute_VAS(&gr, "name", i)); } fclose(filout); filout = NULL; printf("Connected components written.\n"); } pause(); // free connected components igraph_vector_destroy(&membership); igraph_vector_destroy(&csize); // free main graph igraph_destroy(&gr); printf("Program ends.\n"); pause(); return 0; }