int igraph_adjlist_init(const igraph_t *graph, igraph_adjlist_t *al, igraph_neimode_t mode) { long int i; if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) { IGRAPH_ERROR("Cannot create adjlist view", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; } al->length=igraph_vcount(graph); al->adjs=igraph_Calloc(al->length, igraph_vector_t); if (al->adjs == 0) { IGRAPH_ERROR("Cannot create adjlist view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_adjlist_destroy, al); for (i=0; i<al->length; i++) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_vector_init(&al->adjs[i], 0)); IGRAPH_CHECK(igraph_neighbors(graph, &al->adjs[i], i, mode)); } IGRAPH_FINALLY_CLEAN(1); return 0; }
/* call-seq: * graph.neighbours(vertex,mode) -> Array * * Returns an Array of the neighbouring vertices to vertex. mode defines * the way adjacent vertices are searched for directed graphs. It can have * the following values: IGraph::OUT, vertices reachable by an edge from the * specified vertex are searched, IGraph::IN, vertices from which the * specified vertex is reachable are searched. IGraph::ALL, both kind of * vertices are searched. This parameter is ignored for undirected graphs. * * Example: * * g = IGraph.new([1,2,3,4],true) * g.neighbours(1,IGraph::ALL) # returns [2] * */ VALUE cIGraph_neighbors(VALUE self, VALUE v, VALUE mode){ igraph_t *graph; igraph_integer_t pnode; igraph_neimode_t pmode = NUM2INT(mode); igraph_vector_t neis; int i; VALUE neighbors = rb_ary_new(); igraph_vector_init_int(&neis,0); Data_Get_Struct(self, igraph_t, graph); pnode = cIGraph_get_vertex_id(self,v); igraph_neighbors(graph,&neis,pnode,pmode); for(i=0;i<igraph_vector_size(&neis);i++){ rb_ary_push(neighbors,cIGraph_get_vertex_object(self,VECTOR(neis)[i])); } igraph_vector_destroy(&neis); return neighbors; }
igraph_vector_t *igraph_lazy_adjlist_get_real(igraph_lazy_adjlist_t *al, igraph_integer_t pno) { long int no=pno; int ret; if (al->adjs[no] == 0) { al->adjs[no] = igraph_Calloc(1, igraph_vector_t); if (al->adjs[no] == 0) { igraph_error("Lazy adjlist failed", __FILE__, __LINE__, IGRAPH_ENOMEM); } ret=igraph_vector_init(al->adjs[no], 0); if (ret != 0) { igraph_error("", __FILE__, __LINE__, ret); } ret=igraph_neighbors(al->graph, al->adjs[no], no, al->mode); if (ret != 0) { igraph_error("", __FILE__, __LINE__, ret); } if (al->simplify == IGRAPH_SIMPLIFY) { igraph_vector_t *v=al->adjs[no]; long int i, p=0, n=igraph_vector_size(v); for (i=0; i<n; i++) { if (VECTOR(*v)[i] != no && (i==n-1 || VECTOR(*v)[i+1] != VECTOR(*v)[i])) { VECTOR(*v)[p]=VECTOR(*v)[i]; p++; } } igraph_vector_resize(v, p); } } return al->adjs[no]; }
static gboolean _tgengraph_hasSelfLoop(TGenGraph* g, igraph_integer_t vertexIndex) { TGEN_ASSERT(g); gboolean isLoop = FALSE; igraph_vector_t* resultNeighborVertices = g_new0(igraph_vector_t, 1); gint result = igraph_vector_init(resultNeighborVertices, 0); if(result == IGRAPH_SUCCESS) { result = igraph_neighbors(g->graph, resultNeighborVertices, vertexIndex, IGRAPH_OUT); if(result == IGRAPH_SUCCESS) { glong nVertices = igraph_vector_size(resultNeighborVertices); for (gint i = 0; i < nVertices; i++) { igraph_integer_t dstVertexIndex = igraph_vector_e(resultNeighborVertices, i); if(vertexIndex == dstVertexIndex) { isLoop = TRUE; break; } } } } igraph_vector_destroy(resultNeighborVertices); g_free(resultNeighborVertices); return isLoop; }
int igraph_i_cb_components(igraph_t *graph, const igraph_vector_bool_t *excluded, igraph_vector_long_t *components, long int *no, /* working area follows */ igraph_vector_long_t *compid, igraph_dqueue_t *Q, igraph_vector_t *neis) { long int no_of_nodes=igraph_vcount(graph); long int i; long int cno=0; igraph_vector_long_clear(components); igraph_dqueue_clear(Q); IGRAPH_CHECK(igraph_vector_long_resize(compid, no_of_nodes)); igraph_vector_long_null(compid); for (i=0; i<no_of_nodes; i++) { if (VECTOR(*compid)[i]) { continue; } if (VECTOR(*excluded)[i]) { continue; } IGRAPH_CHECK(igraph_dqueue_push(Q, i)); IGRAPH_CHECK(igraph_vector_long_push_back(components, i)); VECTOR(*compid)[i] = ++cno; while (!igraph_dqueue_empty(Q)) { igraph_integer_t node=(igraph_integer_t) igraph_dqueue_pop(Q); long int j, n; IGRAPH_CHECK(igraph_neighbors(graph, neis, node, IGRAPH_ALL)); n=igraph_vector_size(neis); for (j=0; j<n; j++) { long int v=(long int) VECTOR(*neis)[j]; if (VECTOR(*excluded)[v]) { if (VECTOR(*compid)[v] != cno) { VECTOR(*compid)[v] = cno; IGRAPH_CHECK(igraph_vector_long_push_back(components, v)); } } else { if (!VECTOR(*compid)[v]) { VECTOR(*compid)[v] = cno; /* could be anything positive */ IGRAPH_CHECK(igraph_vector_long_push_back(components, v)); IGRAPH_CHECK(igraph_dqueue_push(Q, v)); } } } } /* while !igraph_dqueue_empty */ IGRAPH_CHECK(igraph_vector_long_push_back(components, -1)); } /* for i<no_of_nodes */ *no=cno; return 0; }
int igraph_adjlist_init_complementer(const igraph_t *graph, igraph_adjlist_t *al, igraph_neimode_t mode, igraph_bool_t loops) { long int i, j, k, n; igraph_bool_t* seen; igraph_vector_t vec; if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) { IGRAPH_ERROR("Cannot create complementer adjlist view", IGRAPH_EINVMODE); } if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; } al->length=igraph_vcount(graph); al->adjs=igraph_Calloc(al->length, igraph_vector_t); if (al->adjs == 0) { IGRAPH_ERROR("Cannot create complementer adjlist view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_adjlist_destroy, al); n=al->length; seen=igraph_Calloc(n, igraph_bool_t); if (seen==0) { IGRAPH_ERROR("Cannot create complementer adjlist view", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, seen); IGRAPH_VECTOR_INIT_FINALLY(&vec, 0); for (i=0; i<al->length; i++) { IGRAPH_ALLOW_INTERRUPTION(); igraph_neighbors(graph, &vec, i, mode); memset(seen, 0, sizeof(igraph_bool_t)*al->length); n=al->length; if (!loops) { seen[i] = 1; n--; } for (j=0; j<igraph_vector_size(&vec); j++) { if (! seen [ (long int) VECTOR(vec)[j] ] ) { n--; seen[ (long int) VECTOR(vec)[j] ] = 1; } } IGRAPH_CHECK(igraph_vector_init(&al->adjs[i], n)); for (j=0, k=0; k<n; j++) { if (!seen[j]) { VECTOR(al->adjs[i])[k++] = j; } } } igraph_Free(seen); igraph_vector_destroy(&vec); IGRAPH_FINALLY_CLEAN(3); return 0; }
int igraph_i_maximum_bipartite_matching_unweighted_relabel(const igraph_t* graph, const igraph_vector_bool_t* types, igraph_vector_t* labels, igraph_vector_long_t* match, igraph_bool_t smaller_set) { long int i, j, n, no_of_nodes = igraph_vcount(graph), matched_to; igraph_dqueue_long_t q; igraph_vector_t neis; debug("Running global relabeling.\n"); /* Set all the labels to no_of_nodes first */ igraph_vector_fill(labels, no_of_nodes); /* Allocate vector for neighbors */ IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* Create a FIFO for the BFS and initialize it with the unmatched rows * (i.e. members of the larger set) */ IGRAPH_CHECK(igraph_dqueue_long_init(&q, 0)); IGRAPH_FINALLY(igraph_dqueue_long_destroy, &q); for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i] != smaller_set && VECTOR(*match)[i] == -1) { IGRAPH_CHECK(igraph_dqueue_long_push(&q, i)); VECTOR(*labels)[i] = 0; } } /* Run the BFS */ while (!igraph_dqueue_long_empty(&q)) { long int v = igraph_dqueue_long_pop(&q); long int w; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v, IGRAPH_ALL)); n = igraph_vector_size(&neis); //igraph_vector_shuffle(&neis); for (j = 0; j < n; j++) { w = (long int) VECTOR(neis)[j]; if (VECTOR(*labels)[w] == no_of_nodes) { VECTOR(*labels)[w] = VECTOR(*labels)[v] + 1; matched_to = VECTOR(*match)[w]; if (matched_to != -1 && VECTOR(*labels)[matched_to] == no_of_nodes) { IGRAPH_CHECK(igraph_dqueue_long_push(&q, matched_to)); VECTOR(*labels)[matched_to] = VECTOR(*labels)[w] + 1; } } } } printf("Inside relabel : "); igraph_vector_print(labels); igraph_dqueue_long_destroy(&q); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; }
int igraph_complementer(igraph_t *res, const igraph_t *graph, igraph_bool_t loops) { long int no_of_nodes=igraph_vcount(graph); igraph_vector_t edges; igraph_vector_t neis; long int i, j; long int zero=0, *limit; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); if (igraph_is_directed(graph)) { limit=&zero; } else { limit=&i; } for (i=0; i<no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_OUT)); if (loops) { for (j=no_of_nodes-1; j>=*limit; j--) { if (igraph_vector_empty(&neis) || j>igraph_vector_tail(&neis)) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } else { igraph_vector_pop_back(&neis); } } } else { for (j=no_of_nodes-1; j>=*limit; j--) { if (igraph_vector_empty(&neis) || j>igraph_vector_tail(&neis)) { if (i!=j) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } } else { igraph_vector_pop_back(&neis); } } } } IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) no_of_nodes, igraph_is_directed(graph))); igraph_vector_destroy(&edges); igraph_vector_destroy(&neis); IGRAPH_I_ATTRIBUTE_DESTROY(res); IGRAPH_I_ATTRIBUTE_COPY(res, graph, /*graph=*/1, /*vertex=*/1, /*edge=*/0); IGRAPH_FINALLY_CLEAN(2); return 0; }
int igraph_is_connected_weak(const igraph_t *graph, igraph_bool_t *res) { long int no_of_nodes=igraph_vcount(graph); char *already_added; igraph_vector_t neis=IGRAPH_VECTOR_NULL; igraph_dqueue_t q=IGRAPH_DQUEUE_NULL; long int i, j; if (no_of_nodes == 0) { *res = 1; return IGRAPH_SUCCESS; } already_added=igraph_Calloc(no_of_nodes, char); if (already_added==0) { IGRAPH_ERROR("is connected (weak) failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, already_added); /* TODO: hack */ IGRAPH_DQUEUE_INIT_FINALLY(&q, 10); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* Try to find at least two clusters */ already_added[0]=1; IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); j=1; while ( !igraph_dqueue_empty(&q)) { long int actnode=(long int) igraph_dqueue_pop(&q); IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) actnode, IGRAPH_ALL)); for (i=0; i <igraph_vector_size(&neis); i++) { long int neighbor=(long int) VECTOR(neis)[i]; if (already_added[neighbor] != 0) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); j++; already_added[neighbor]++; } } /* Connected? */ *res = (j == no_of_nodes); igraph_Free(already_added); igraph_dqueue_destroy(&q); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(3); return 0; }
GQueue* tgengraph_getNextActions(TGenGraph* g, TGenAction* action) { TGEN_ASSERT(g); /* given an action, get all of the next actions in the dependency graph */ gpointer key = tgenaction_getKey(action); igraph_integer_t srcVertexIndex = (igraph_integer_t) GPOINTER_TO_INT(key); /* initialize a vector to hold the result neighbor vertices for this action */ igraph_vector_t* resultNeighborVertices = g_new0(igraph_vector_t, 1); /* initialize with 0 entries, since we dont know how many neighbors we have */ gint result = igraph_vector_init(resultNeighborVertices, 0); if(result != IGRAPH_SUCCESS) { tgen_critical("igraph_vector_init return non-success code %i", result); g_free(resultNeighborVertices); return FALSE; } /* now get all outgoing 1-hop neighbors of the given action */ result = igraph_neighbors(g->graph, resultNeighborVertices, srcVertexIndex, IGRAPH_OUT); if(result != IGRAPH_SUCCESS) { tgen_critical("igraph_neighbors return non-success code %i", result); igraph_vector_destroy(resultNeighborVertices); g_free(resultNeighborVertices); return NULL; } /* handle the results */ glong nVertices = igraph_vector_size(resultNeighborVertices); tgen_debug("found %li neighbors to vertex %i", nVertices, (gint)srcVertexIndex); GQueue* nextActions = g_queue_new(); for (gint i = 0; i < nVertices; i++) { igraph_integer_t dstVertexIndex = igraph_vector_e(resultNeighborVertices, i); TGenAction* nextAction = _tgengraph_getAction(g, dstVertexIndex); if(nextAction) { g_queue_push_tail(nextActions, nextAction); } } /* cleanup */ igraph_vector_destroy(resultNeighborVertices); g_free(resultNeighborVertices); return nextActions; }
static GError* _tgengraph_parseSynchronizeVertex(TGenGraph* g, const gchar* idStr, igraph_integer_t vertexIndex) { TGEN_ASSERT(g); tgen_debug("found vertex %li (%s)", (glong)vertexIndex, idStr); /* Count up the total incoming edges */ /* initialize a vector to hold the result neighbor vertices for this action */ igraph_vector_t* resultNeighborVertices = g_new0(igraph_vector_t, 1); /* initialize with 0 entries, since we dont know how many neighbors we have */ gint result = igraph_vector_init(resultNeighborVertices, 0); if(result != IGRAPH_SUCCESS) { tgen_critical("igraph_vector_init return non-success code %i", result); g_free(resultNeighborVertices); return FALSE; } /* now get all incoming 1-hop neighbors of the given action */ result = igraph_neighbors(g->graph, resultNeighborVertices, vertexIndex, IGRAPH_IN); if(result != IGRAPH_SUCCESS) { tgen_critical("igraph_neighbors return non-success code %i", result); igraph_vector_destroy(resultNeighborVertices); g_free(resultNeighborVertices); return NULL; } /* handle the results */ glong totalIncoming = igraph_vector_size(resultNeighborVertices); tgen_debug("found %li neighbors to vertex %i", totalIncoming, (gint)vertexIndex); /* cleanup */ igraph_vector_destroy(resultNeighborVertices); g_free(resultNeighborVertices); GError* error = NULL; TGenAction* a = tgenaction_newSynchronizeAction(totalIncoming, &error); if(a) { _tgengraph_storeAction(g, a, vertexIndex); } return error; }
/** * \function igraph_is_maximal_matching * Checks whether a matching in a graph is maximal. * * A matching is maximal if and only if there exists no unmatched vertex in a * graph such that one of its neighbors is also unmatched. * * \param graph The input graph. It can be directed but the edge directions * will be ignored. * \param types If the graph is bipartite and you are interested in bipartite * matchings only, pass the vertex types here. If the graph is * non-bipartite, simply pass \c NULL. * \param matching The matching itself. It must be a vector where element i * contains the ID of the vertex that vertex i is matched to, * or -1 if vertex i is unmatched. * \param result Pointer to a boolean variable, the result will be returned * here. * * \sa \ref igraph_is_matching() if you are only interested in whether a * matching vector is valid for a given graph. * * Time complexity: O(|V|+|E|) where |V| is the number of vertices and * |E| is the number of edges. * * \example examples/simple/igraph_maximum_bipartite_matching.c */ int igraph_is_maximal_matching(const igraph_t* graph, const igraph_vector_bool_t* types, const igraph_vector_long_t* matching, igraph_bool_t* result) { long int i, j, n, no_of_nodes = igraph_vcount(graph); igraph_vector_t neis; igraph_bool_t valid; IGRAPH_CHECK(igraph_is_matching(graph, types, matching, &valid)); if (!valid) { *result = 0; return IGRAPH_SUCCESS; } IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); valid = 1; for (i = 0; i < no_of_nodes; i++) { j = VECTOR(*matching)[i]; if (j != -1) continue; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { if (VECTOR(*matching)[(long int)VECTOR(neis)[j]] == -1) { if (types == 0 || VECTOR(*types)[i] != VECTOR(*types)[(long int)VECTOR(neis)[j]]) { valid = 0; break; } } } } igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(1); *result = valid; return IGRAPH_SUCCESS; }
int igraph_to_undirected(igraph_t *graph, igraph_to_undirected_t mode) { long int no_of_nodes=igraph_vcount(graph); long int no_of_edges=igraph_ecount(graph); igraph_vector_t edges; igraph_t newgraph; if (mode != IGRAPH_TO_UNDIRECTED_EACH && mode != IGRAPH_TO_UNDIRECTED_COLLAPSE) { IGRAPH_ERROR("Cannot undirect graph, invalid mode", IGRAPH_EINVAL); } if (!igraph_is_directed(graph)) { return 0; } IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); if (mode==IGRAPH_TO_UNDIRECTED_EACH) { igraph_es_t es; igraph_eit_t eit; IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges*2)); IGRAPH_CHECK(igraph_es_all(&es, IGRAPH_EDGEORDER_ID)); IGRAPH_FINALLY(igraph_es_destroy, &es); IGRAPH_CHECK(igraph_eit_create(graph, es, &eit)); IGRAPH_FINALLY(igraph_eit_destroy, &eit); while (!IGRAPH_EIT_END(eit)) { long int edge=IGRAPH_EIT_GET(eit); igraph_integer_t from, to; igraph_edge(graph, edge, &from, &to); IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_EIT_NEXT(eit); } igraph_eit_destroy(&eit); igraph_es_destroy(&es); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(&newgraph, &edges, no_of_nodes, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); igraph_vector_destroy(&edges); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1,1,1); IGRAPH_FINALLY_CLEAN(2); igraph_destroy(graph); *graph=newgraph; } else if (mode==IGRAPH_TO_UNDIRECTED_COLLAPSE) { igraph_vector_t seen, nei; long int i,j; IGRAPH_CHECK(igraph_vector_reserve(&edges, no_of_edges*2)); IGRAPH_VECTOR_INIT_FINALLY(&seen, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&nei, 0); for (i=0; i<no_of_nodes; i++) { IGRAPH_CHECK(igraph_neighbors(graph, &nei, i, IGRAPH_ALL)); for (j=0; j<igraph_vector_size(&nei); j++) { long int node=VECTOR(nei)[j]; if (VECTOR(seen)[node] != i+1 && node >= i) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, node)); VECTOR(seen)[node]=i+1; } } } igraph_vector_destroy(&nei); igraph_vector_destroy(&seen); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_create(&newgraph, &edges, no_of_nodes, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); igraph_vector_destroy(&edges); IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1,1,0); /* no edge attributes */ IGRAPH_FINALLY_CLEAN(2); igraph_destroy(graph); *graph=newgraph; } return 0; }
int igraph_i_maximum_bipartite_matching_unweighted(const igraph_t* graph, const igraph_vector_bool_t* types, igraph_integer_t* matching_size, igraph_vector_long_t* matching) { long int i, j, k, n, no_of_nodes = igraph_vcount(graph); long int num_matched; /* number of matched vertex pairs */ igraph_vector_long_t match; /* will store the matching */ igraph_vector_t labels; /* will store the labels */ igraph_vector_t neis; /* used to retrieve the neighbors of a node */ igraph_dqueue_long_t q; /* a FIFO for push ordering */ igraph_bool_t smaller_set; /* denotes which part of the bipartite graph is smaller */ long int label_changed = 0; /* Counter to decide when to run a global relabeling */ long int relabeling_freq = no_of_nodes / 2; /* We will use: * - FIFO push ordering * - global relabeling frequency: n/2 steps where n is the number of nodes * - simple greedy matching for initialization */ /* (1) Initialize data structures */ IGRAPH_CHECK(igraph_vector_long_init(&match, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_long_destroy, &match); IGRAPH_VECTOR_INIT_FINALLY(&labels, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_long_init(&q, 0)); IGRAPH_FINALLY(igraph_dqueue_long_destroy, &q); /* (2) Initially, every node is unmatched */ igraph_vector_long_fill(&match, -1); /* (3) Find an initial matching in a greedy manner. * At the same time, find which side of the graph is smaller. */ num_matched = 0; j = 0; for (i = 0; i < no_of_nodes; i++) { if (VECTOR(*types)[i]) j++; if (MATCHED(i)) continue; IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) i, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (j = 0; j < n; j++) { k = (long int) VECTOR(neis)[j]; if (UNMATCHED(k)) { /* We match vertex i to vertex VECTOR(neis)[j] */ VECTOR(match)[k] = i; VECTOR(match)[i] = k; num_matched++; break; } } } smaller_set = (j <= no_of_nodes/2); /* (4) Set the initial labeling -- lines 1 and 2 in the tech report */ IGRAPH_CHECK(igraph_i_maximum_bipartite_matching_unweighted_relabel( graph, types, &labels, &match, smaller_set)); /* (5) Fill the push queue with the unmatched nodes from the smaller set. */ for (i = 0; i < no_of_nodes; i++) { if (UNMATCHED(i) && VECTOR(*types)[i] == smaller_set) IGRAPH_CHECK(igraph_dqueue_long_push(&q, i)); } /* (6) Main loop from the referenced tech report -- lines 4--13 */ label_changed = 0; while (!igraph_dqueue_long_empty(&q)) { long int v = igraph_dqueue_long_pop(&q); /* Line 13 */ long int u = -1, label_u = 2 * no_of_nodes; long int w; if (label_changed >= relabeling_freq) { /* Run global relabeling */ IGRAPH_CHECK(igraph_i_maximum_bipartite_matching_unweighted_relabel( graph, types, &labels, &match, smaller_set)); label_changed = 0; } debug("Considering vertex %ld\n", v); /* Line 5: find row u among the neighbors of v s.t. label(u) is minimal */ IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) v, IGRAPH_ALL)); n = igraph_vector_size(&neis); for (i = 0; i < n; i++) { if (VECTOR(labels)[(long int)VECTOR(neis)[i]] < label_u) { u = (long int) VECTOR(neis)[i]; label_u = (long int) VECTOR(labels)[u]; label_changed++; } } debug(" Neighbor with smallest label: %ld (label=%ld)\n", u, label_u); if (label_u < no_of_nodes) { /* Line 6 */ VECTOR(labels)[v] = VECTOR(labels)[u] + 1; /* Line 7 */ if (MATCHED(u)) { /* Line 8 */ w = VECTOR(match)[u]; debug(" Vertex %ld is matched to %ld, performing a double push\n", u, w); if (w != v) { VECTOR(match)[u] = -1; VECTOR(match)[w] = -1; /* Line 9 */ IGRAPH_CHECK(igraph_dqueue_long_push(&q, w)); /* Line 10 */ debug(" Unmatching & activating vertex %ld\n", w); num_matched--; } } VECTOR(match)[u] = v; VECTOR(match)[v] = u; /* Line 11 */ num_matched++; VECTOR(labels)[u] += 2; /* Line 12 */ label_changed++; } printf("MATCH: "); igraph_vector_long_print(&match); printf("LABELS "); igraph_vector_print(&labels); } /* Fill the output parameters */ if (matching != 0) { IGRAPH_CHECK(igraph_vector_long_update(matching, &match)); } if (matching_size != 0) { *matching_size = (igraph_integer_t) num_matched; } /* Release everything */ igraph_dqueue_long_destroy(&q); igraph_vector_destroy(&neis); igraph_vector_destroy(&labels); igraph_vector_long_destroy(&match); IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; }
int igraph_i_find_k_cliques(const igraph_t *graph, long int size, const igraph_real_t *member_storage, igraph_real_t **new_member_storage, long int old_clique_count, long int *clique_count, igraph_vector_t *neis, igraph_bool_t independent_vertices) { long int j, k, l, m, n, new_member_storage_size; const igraph_real_t *c1, *c2; igraph_real_t v1, v2; igraph_bool_t ok; /* Allocate the storage */ *new_member_storage=igraph_Realloc(*new_member_storage, size*old_clique_count, igraph_real_t); if (*new_member_storage == 0) { IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); } new_member_storage_size = size*old_clique_count; IGRAPH_FINALLY(igraph_free, *new_member_storage); m=n=0; /* Now consider all pairs of i-1-cliques and see if they can be merged */ for (j=0; j<old_clique_count; j++) { for (k=j+1; k<old_clique_count; k++) { IGRAPH_ALLOW_INTERRUPTION(); /* Since cliques are represented by their vertex indices in increasing * order, two cliques can be merged iff they have exactly the same * indices excluding one AND there is an edge between the two different * vertices */ c1 = member_storage+j*(size-1); c2 = member_storage+k*(size-1); /* Find the longest prefixes of c1 and c2 that are equal */ for (l=0; l<size-1 && c1[l] == c2[l]; l++) (*new_member_storage)[m++]=c1[l]; /* Now, if l == size-1, the two vectors are totally equal. This is a bug */ if (l == size-1) { IGRAPH_WARNING("possible bug in igraph_cliques"); m=n; } else { /* Assuming that j<k, c1[l] is always less than c2[l], since cliques * are ordered alphabetically. Now add c1[l] and store c2[l] in a * dummy variable */ (*new_member_storage)[m++]=c1[l]; v1=c1[l]; v2=c2[l]; l++; /* Copy the remaining part of the two vectors. Every member pair * found in the remaining parts satisfies the following: * 1. If they are equal, they should be added. * 2. If they are not equal, the smaller must be equal to the * one stored in the dummy variable. If not, the two vectors * differ in more than one place. The larger will be stored in * the dummy variable again. */ ok=1; for (; l<size-1; l++) { if (c1[l] == c2[l]) { (*new_member_storage)[m++]=c1[l]; ok=0; } else if (ok) { if (c1[l] < c2[l]) { if (c1[l] == v1) { (*new_member_storage)[m++]=c1[l]; v2 = c2[l]; } else break; } else { if (ok && c2[l] == v1) { (*new_member_storage)[m++]=c2[l]; v2 = c1[l]; } else break; } } else break; } /* Now, if l != size-1, the two vectors had a difference in more than * one place, so the whole clique is invalid. */ if (l != size-1) { /* Step back in new_member_storage */ m=n; } else { /* v1 and v2 are the two different vertices. Check for an edge * if we are looking for cliques and check for the absence of an * edge if we are looking for independent vertex sets */ IGRAPH_CHECK(igraph_neighbors(graph, neis, v1, IGRAPH_ALL)); l=igraph_vector_search(neis, 0, v2, 0); if ((l && !independent_vertices) || (!l && independent_vertices)) { /* Found a new clique, step forward in new_member_storage */ if (m==n || v2>(*new_member_storage)[m-1]) { (*new_member_storage)[m++]=v2; n=m; } else { m=n; } } else { m=n; } } /* See if new_member_storage is full. If so, reallocate */ if (m == new_member_storage_size) { IGRAPH_FINALLY_CLEAN(1); *new_member_storage = igraph_Realloc(*new_member_storage, new_member_storage_size*2, igraph_real_t); if (*new_member_storage == 0) IGRAPH_ERROR("cliques failed", IGRAPH_ENOMEM); new_member_storage_size *= 2; IGRAPH_FINALLY(igraph_free, *new_member_storage); } } } } /* Calculate how many cliques have we found */ *clique_count = n/size; IGRAPH_FINALLY_CLEAN(1); return 0; }
main (int argc,char *argv[]) { int ia,ib,ic,id,it,inow,ineigh,icont; int in,ia2,ia3,irun,icurrent,ORTOGONALFLAG; int RP, P,L,N,NRUNS,next,sweep,SHOWFLAG; double u,field1,field2,field0,q,aux1,aux2; double alfa,aux,Q1,Q2,QZ,RZQ,rho,R; double pm,D,wmax,mQ,wx,wy,h_sigma,h_mean; double TOL,MINLOGF,E; double DELTA; double E_new,Ex,DeltaE,ER; double EW,meanhist,hvalue,wE,aratio; double logG_old,logG_new,lf; size_t i_old,i_new; long seed; double lGvR,lGv,DlG; size_t iL,iR,i1,i2; int I_endpoint[NBINS]; double lower,upper; size_t i0; FILE * wlsrange; FILE * dos; FILE * thermodynamics; FILE * canonical; FILE * logfile; //FILE * pajek; //*********************************** // Help //*********************************** if (argc<15){ help(); return(1); } else{ DELTA = atof(argv[1]); P = atoi(argv[2]); RP = atoi(argv[3]); L = atoi(argv[4]); N = atoi(argv[5]); TOL = atof(argv[6]); MINLOGF = atof(argv[7]); } wlsrange=fopen(argv[8],"w"); dos=fopen(argv[9],"w"); thermodynamics=fopen(argv[10],"w"); canonical=fopen(argv[11],"w"); logfile=fopen(argv[12],"w"); SHOWFLAG = atoi(argv[13]); ORTOGONALFLAG = atoi(argv[14]); if ((ORTOGONALFLAG==1) && (P>L)) P=L; //maximum number of orthogonal issues if (SHOWFLAG==1){ printf("# parameters are DELTA=%1.2f P=%d ",DELTA,P); printf("D=%d L=%d M=%d TOL=%1.2f MINLOGF=%g \n",L,N,RP,TOL,MINLOGF); } fprintf(logfile,"# parameters are DELTA=%1.2f P=%d D=%d",DELTA,P,L); fprintf(logfile,"L=%d M=%d TOL=%1.2f MINLOGF=%g\n",L,RP,TOL,MINLOGF); //********************************************************************** // Alocate matrices //********************************************************************** gsl_matrix * sociedade = gsl_matrix_alloc(SIZE,L); gsl_matrix * issue = gsl_matrix_alloc(P,L); gsl_vector * current_issue = gsl_vector_alloc(L); gsl_vector * v0 = gsl_vector_alloc(L); gsl_vector * v1 = gsl_vector_alloc(L); gsl_vector * Z = gsl_vector_alloc(L); gsl_vector * E_borda = gsl_vector_alloc(NBINS); //********************************************************************** // Inicialization //********************************************************************** const gsl_rng_type * T; gsl_rng * r; gsl_rng_env_setup(); T = gsl_rng_default; r=gsl_rng_alloc (T); seed = time (NULL) * getpid(); //seed = 13188839657852; gsl_rng_set(r,seed); igraph_t graph; igraph_vector_t neighbors; igraph_vector_t result; igraph_vector_t dim_vector; igraph_real_t res; igraph_bool_t C; igraph_vector_init(&neighbors,1000); igraph_vector_init(&result,0); igraph_vector_init(&dim_vector,DIMENSION); for(ic=0;ic<DIMENSION;ic++) VECTOR(dim_vector)[ic]=N; gsl_histogram * HE = gsl_histogram_alloc (NBINS); gsl_histogram * logG = gsl_histogram_alloc (NBINS); gsl_histogram * LG = gsl_histogram_alloc (NBINS); //******************************************************************** // Social Graph //******************************************************************** //Barabasi-Alberts network igraph_barabasi_game(&graph,SIZE,RP,&result,1,0); /* for (inow=0;inow<SIZE;inow++){ igraph_neighbors(&graph,&neighbors,inow,IGRAPH_OUT); printf("%d ",inow); for(ic=0;ic<igraph_vector_size(&neighbors);ic++) { ineigh=(int)VECTOR(neighbors)[ic]; printf("%d ",ineigh); } printf("\n"); }*/ //pajek=fopen("graph.xml","w"); // igraph_write_graph_graphml(&graph,pajek); //igraph_write_graph_pajek(&graph, pajek); //fclose(pajek); //********************************************************************** //Quenched issues set and Zeitgeist //********************************************************************** gsl_vector_set_zero(Z); gera_config(Z,issue,P,L,r,1.0); if (ORTOGONALFLAG==1) gsl_matrix_set_identity(issue); for (ib=0;ib<P;ib++) { gsl_matrix_get_row(current_issue,issue,ib); gsl_blas_ddot(current_issue,current_issue,&Q1); gsl_vector_scale(current_issue,1/sqrt(Q1)); gsl_vector_add(Z,current_issue); } gsl_blas_ddot(Z,Z,&QZ); gsl_vector_scale(Z,1/sqrt(QZ)); //********************************************************************** // Ground state energy //********************************************************************** double E0; gera_config(Z,sociedade,SIZE,L,r,0); E0 = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); double EMIN=E0; double EMAX=-E0; double E_old=E0; gsl_histogram_set_ranges_uniform (HE,EMIN,EMAX); gsl_histogram_set_ranges_uniform (logG,EMIN,EMAX); if (SHOWFLAG==1) printf("# ground state: %3.0f\n",E0); fprintf(logfile,"# ground state: %3.0f\n",E0); //********************************************************************** // Find sampling interval //********************************************************************** //printf("#finding the sampling interval...\n"); lf=1; sweep=0; icont=0; int iflag=0; int TMAX=NSWEEPS; while(sweep<=TMAX){ if (icont==10000) { //printf("%d sweeps\n",sweep); icont=0; } for(it=0;it<SIZE;it++){ igraph_vector_init(&neighbors,SIZE); //choose a random site do{ inow=gsl_rng_uniform_int(r,SIZE); }while((inow<0)||(inow>=SIZE)); gsl_matrix_get_row(v1,sociedade,inow); igraph_neighbors(&graph,&neighbors,inow,IGRAPH_OUT); //generates a random vector v1 gsl_vector_memcpy(v0,v1); gera_vetor(v1,L,r); //calculates energy change when v0->v1 // in site inow DeltaE=variacaoE(v0,v1,inow,sociedade, issue,N,L,P,DELTA,graph,neighbors); E_new=E_old+DeltaE; //WL: accepts in [EMIN,EMAX] if ((E_new>EMIN) && (E_new<EMAX)) { gsl_histogram_find(logG,E_old,&i_old); logG_old=gsl_histogram_get(logG,i_old); gsl_histogram_find(logG,E_new,&i_new); logG_new=gsl_histogram_get(logG,i_new); wE = GSL_MIN(exp(logG_old-logG_new),1); if (gsl_rng_uniform(r)<wE){ E_old=E_new; gsl_matrix_set_row(sociedade,inow,v1); } } //WL: update histograms gsl_histogram_increment(HE,E_old); gsl_histogram_accumulate(logG,E_old,lf); igraph_vector_destroy(&neighbors); } sweep++; icont++; } gsl_histogram_fprintf(wlsrange,HE,"%g","%g"); double maxH=gsl_histogram_max_val(HE); //printf("ok\n"); Ex=0; hvalue=maxH; while((hvalue>TOL*maxH)&&(Ex>EMIN)){ gsl_histogram_find(HE,Ex,&i0); hvalue=gsl_histogram_get(HE,i0); Ex-=1; if(Ex<=EMAX)TMAX+=10000; } EMIN=Ex; Ex=0; hvalue=maxH; while((hvalue>TOL*maxH)&&(Ex<EMAX)) { gsl_histogram_find(HE,Ex,&i0); hvalue=gsl_histogram_get(HE,i0); Ex+=1; if(Ex>=EMAX)TMAX+=10000; } EMAX=Ex; EMAX=GSL_MIN(10.0,Ex); if (SHOWFLAG==1) printf("# the sampling interval is [%3.0f,%3.0f] found in %d sweeps \n\n" ,EMIN,EMAX,sweep); fprintf(logfile, "# the sampling interval is [%3.0f,%3.0f] found in %d sweeps \n\n" ,EMIN,EMAX,sweep); gsl_histogram_set_ranges_uniform (HE,EMIN-1,EMAX+1); gsl_histogram_set_ranges_uniform (logG,EMIN-1,EMAX+1); gsl_histogram_set_ranges_uniform (LG,EMIN-1,EMAX+1); //********************************************************************** // WLS //********************************************************************** int iE,itera=0; double endpoints[NBINS]; double w = WINDOW; //(EMAX-EMIN)/10.0; //printf("W=%f\n",w); lf=1; //RESOLUTION ----> <------RESOLUTION***** do{ int iverify=0,iborda=0,flat=0; sweep=0; Ex=EMAX; EW=EMAX; E_old=EMAX+1; iE=0; endpoints[iE]=EMAX; iE++; gsl_histogram_reset(LG); //WINDOWS --> <--WINDOWS******* while((Ex>EMIN)&&(sweep<MAXSWEEPS)){ //initial config gera_config(Z,sociedade,SIZE,L,r,0); E_old = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); while( (E_old<EMIN+1)||(E_old>Ex) ){ //printf("%d %3.1f\n",E_old); do{ inow=gsl_rng_uniform_int(r,SIZE); }while((inow<0)||(inow>=SIZE)); gsl_matrix_get_row(v0,sociedade,inow); gera_vetor(v1,L,r); gsl_matrix_set_row(sociedade,inow,v1); E_old = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); if (E_old>Ex){ gsl_matrix_set_row(sociedade,inow,v0); E_old = hamiltoneana(sociedade,issue,SIZE,L,P,DELTA,graph); } //printf("%3.1f %3.1f %3.1f\n",EMIN+1,E_old, Ex); } if (SHOWFLAG==1){ printf("# sampling [%f,%f]\n",EMIN,Ex); printf("# walking from E=%3.0f\n",E_old); } fprintf(logfile,"# sampling [%f,%f]\n",EMIN,Ex); fprintf(logfile,"# walking from E=%3.0f\n",E_old); do{ //FLAT WINDOW------> <------FLAT WINDOW***** //MC sweep ----> <------MC sweep******** for(it=0;it<SIZE;it++){ igraph_vector_init(&neighbors,SIZE); //escolhe sítio aleatoriamente do{ inow=gsl_rng_uniform_int(r,SIZE); }while((inow<0)||(inow>=SIZE)); gsl_matrix_get_row(v1,sociedade,inow); igraph_neighbors(&graph,&neighbors,inow,IGRAPH_OUT); //gera vetor aleatorio v1 gsl_vector_memcpy(v0,v1); gera_vetor(v1,L,r); //calculates energy change when //v0->v1 in site inow DeltaE=variacaoE(v0,v1,inow,sociedade,issue, N,L,P,DELTA,graph,neighbors); E_new=E_old+DeltaE; //WL: accepts in [EMIN,Ex] if ((E_new>EMIN) && (E_new<Ex)) { gsl_histogram_find(logG,E_old,&i_old); logG_old=gsl_histogram_get(logG,i_old); gsl_histogram_find(logG,E_new,&i_new); logG_new=gsl_histogram_get(logG,i_new); wE = GSL_MIN(exp(logG_old-logG_new),1); if (gsl_rng_uniform(r)<wE){ E_old=E_new; gsl_matrix_set_row(sociedade,inow,v1); } } //WL: updates histograms gsl_histogram_increment(HE,E_old); gsl_histogram_accumulate(logG,E_old,lf); itera++; igraph_vector_destroy(&neighbors); } //MC sweep ----> <--------MC sweep**** sweep++; iverify++; if( (EMAX-EMIN)<NDE*DE ) { EW=EMIN; }else{ EW=GSL_MAX(Ex-w,EMIN); } if (iverify==CHECK){//Verify flatness if (SHOWFLAG==1) printf(" #verificando flatness em [%f,%f]\n",EW,Ex); fprintf(logfile," #verificando flatness em [%f,%f]\n" ,EW,Ex); iverify=0; flat=flatness(HE,EW,Ex,TOL,itera,meanhist,hvalue); if (SHOWFLAG==1) printf("#minH= %8.0f\t k<H>=%8.0f\t %d sweeps\t ", hvalue,TOL*meanhist,sweep,flat); fprintf(logfile, "#minH= %8.0f\t k<H>=%8.0f\t %d sweeps\t ", hvalue,TOL*meanhist,sweep,flat); } }while(flat==0);// <------FLAT WINDOW****** flat=0; //Find ER //printf("# EMAX=%f EMIN = %f Ex =%f\n",EMAX, EMIN, Ex); if( (EMAX-EMIN)<NDE*DE ) { Ex=EMIN; endpoints[iE]=EMIN; } else { if (EW>EMIN){ ER=flatwindow(HE,EW,TOL,meanhist); if (SHOWFLAG==1) printf("# extending flatness to[%f,%f]\n",ER,Ex); fprintf(logfile, "# extending flatness to [%f,%f]\n",ER,Ex); if((ER-EMIN)<1){ ER=EMIN; Ex=EMIN; endpoints[iE]=EMIN; }else{ endpoints[iE]=GSL_MIN(ER+DE,EMAX); Ex=GSL_MIN(ER+2*DE,EMAX); } } else{ endpoints[iE]=EMIN; Ex=EMIN; ER=EMIN; } } if (SHOWFLAG==1) printf("# window %d [%3.0f,%3.0f] is flat after %d sweeps \n", iE,endpoints[iE],endpoints[iE-1],sweep); fprintf(logfile,"# window %d [%3.0f,%3.0f] is flat after %d sweeps\n", iE,endpoints[iE],endpoints[iE-1],sweep); //saves histogram if (iE==1){ gsl_histogram_find(logG,endpoints[iE],&i1); gsl_histogram_find(logG,endpoints[iE-1],&i2); for(i0=i1;i0<=i2;i0++){ lGv=gsl_histogram_get(logG,i0); gsl_histogram_get_range(logG,i0,&lower,&upper); E=0.5*(upper+lower); gsl_histogram_accumulate(LG,E,lGv); } }else{ gsl_histogram_find(logG,endpoints[iE],&i1); gsl_histogram_find(logG,endpoints[iE-1],&i2); lGv=gsl_histogram_get(logG,i2); lGvR=gsl_histogram_get(LG,i2); DlG=lGvR-lGv; //printf("i1=%d i2=%d lGv=%f lGvR=%f DlG=%f\n",i1,i2,lGv,lGvR,DlG); for(i0=i1;i0<i2;i0++){ lGv=gsl_histogram_get(logG,i0); lGv=lGv+DlG; gsl_histogram_get_range(logG,i0,&lower,&upper); E=(upper+lower)*0.5; //printf("i0=%d E=%f lGv=%f\n",i0,E,lGv); gsl_histogram_accumulate(LG,E,lGv); } } //printf("#########################################\n"); //gsl_histogram_fprintf(stdout,LG,"%g","%g"); //printf("#########################################\n"); iE++; if((Ex-EMIN)>NDE*DE) { if (SHOWFLAG==1) printf("# random walk is now restricted to [%3.0f,%3.0f]\n" ,EMIN,Ex); fprintf(logfile,"# random walk is now restricted to [%3.0f,%3.0f]\n" ,EMIN,Ex); } gsl_histogram_reset(HE); } //WINDOWS --> if(sweep<MAXSWEEPS){ if (SHOWFLAG==1) printf("# log(f)=%f converged within %d sweeps\n\n",lf,sweep); fprintf(logfile,"# log(f)=%f converged within %d sweeps\n\n",lf,sweep); lf=lf/2.0; gsl_histogram_reset(HE); gsl_histogram_memcpy(logG,LG); }else { if (SHOWFLAG==1) printf("# FAILED: no convergence has been attained."); fprintf(logfile, "# FAILED: no convergence has been attained. Simulation ABANDONED."); return(1); } }while(lf>MINLOGF); //RESOLUTION --> <-----RESOLUTION**** //***************************************************************** //Density of states //***************************************************************** double minlogG=gsl_histogram_min_val(logG); gsl_histogram_shift(logG,-minlogG); gsl_histogram_fprintf(dos,logG,"%g","%g"); //***************************************************************** //Thermodynamics //***************************************************************** double beta,A,wT,Zmin_beta; double lGvalue,maxA,betaC,CTMAX=0; double Z_beta,U,U2,CT,F,S; for (beta=0.01;beta<=30;beta+=0.01) { //****************************************************************** //Energy, free-energy, entropy, specific heat and Tc //****************************************************************** maxA=0; for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E; if (A>maxA) maxA=A; } gsl_histogram_find(logG,EMIN,&i0); Z_beta=0;U=0;U2=0; for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E-maxA; Z_beta+=exp(A); U+=E*exp(A); U2+=E*E*exp(A); if(ia2==i0) Zmin_beta=exp(A); } wT=Zmin_beta/Z_beta; F=-log(Z_beta)/beta - maxA/beta; U=U/Z_beta; S= (U-F)*beta; U2=U2/Z_beta; CT=(U2-U*U)*beta*beta; if(CT>CTMAX){ CTMAX=CT; betaC=beta; } fprintf(thermodynamics,"%f %f %f %f %f %f %f \n" ,beta,1/beta,F/(double)(SIZE),S/(double)(SIZE), U/(double)(SIZE),CT/(double)(SIZE),wT); } if (SHOWFLAG==1) printf("# BETAc: %f Tc:%f \n",betaC,1/betaC); fprintf(logfile,"# BETAc: %f Tc:%f \n",betaC,1/betaC); //****************************************************************** //canonical distribuition at Tc //****************************************************************** beta=betaC; double distr_canonica; maxA=0; for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E; if (A>maxA) maxA=A; } for (ia2=0; ia2<NBINS;ia2++) { lGvalue=gsl_histogram_get(logG,ia2); gsl_histogram_get_range(logG,ia2,&lower,&upper); E=(lower+upper)/2; A=lGvalue-beta*E-maxA; distr_canonica=exp(A); fprintf(canonical,"%f %f %f\n", E/(double)(SIZE),distr_canonica,A); } //***************************************************************** // Finalization //***************************************************************** igraph_destroy(&graph); igraph_vector_destroy(&neighbors); igraph_vector_destroy(&result); gsl_matrix_free(issue); gsl_vector_free(current_issue); gsl_vector_free(v1); gsl_vector_free(v0); gsl_matrix_free(sociedade); gsl_rng_free(r); fclose(wlsrange); fclose(dos); fclose(thermodynamics); fclose(canonical); fclose(logfile); return(0); }
int igraph_clusters_weak(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no) { long int no_of_nodes=igraph_vcount(graph); char *already_added; long int first_node, act_cluster_size=0, no_of_clusters=1; igraph_dqueue_t q=IGRAPH_DQUEUE_NULL; long int i; igraph_vector_t neis=IGRAPH_VECTOR_NULL; already_added=igraph_Calloc(no_of_nodes,char); if (already_added==0) { IGRAPH_ERROR("Cannot calculate clusters", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_DQUEUE_INIT_FINALLY(&q, no_of_nodes > 100000 ? 10000 : no_of_nodes/10); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); /* Memory for result, csize is dynamically allocated */ if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); } if (csize) { igraph_vector_clear(csize); } /* The algorithm */ for (first_node=0; first_node < no_of_nodes; ++first_node) { if (already_added[first_node]==1) continue; IGRAPH_ALLOW_INTERRUPTION(); already_added[first_node]=1; act_cluster_size=1; if (membership) { VECTOR(*membership)[first_node]=no_of_clusters-1; } IGRAPH_CHECK(igraph_dqueue_push(&q, first_node)); while ( !igraph_dqueue_empty(&q) ) { long int act_node=(long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) act_node, IGRAPH_ALL)); for (i=0; i<igraph_vector_size(&neis); i++) { long int neighbor=(long int) VECTOR(neis)[i]; if (already_added[neighbor]==1) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); already_added[neighbor]=1; act_cluster_size++; if (membership) { VECTOR(*membership)[neighbor]=no_of_clusters-1; } } } no_of_clusters++; if (csize) { IGRAPH_CHECK(igraph_vector_push_back(csize, act_cluster_size)); } } /* Cleaning up */ if (no) { *no = (igraph_integer_t) no_of_clusters-1; } igraph_Free(already_added); igraph_dqueue_destroy(&q); igraph_vector_destroy(&neis); IGRAPH_FINALLY_CLEAN(3); return 0; }
void Graph::neighbors(Vector* result, long int vertex, NeighborMode mode) const { assert(m_pGraph); IGRAPH_TRY(igraph_neighbors(m_pGraph, result->c_vector(), vertex, mode)); }
int igraph_is_bipartite(const igraph_t *graph, igraph_bool_t *res, igraph_vector_bool_t *type) { /* We basically do a breadth first search and label the vertices along the way. We stop as soon as we can find a contradiction. In the 'seen' vector 0 means 'not seen yet', 1 means type 1, 2 means type 2. */ long int no_of_nodes=igraph_vcount(graph); igraph_vector_char_t seen; igraph_dqueue_t Q; igraph_vector_t neis; igraph_bool_t bi=1; long int i; IGRAPH_CHECK(igraph_vector_char_init(&seen, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_char_destroy, &seen); IGRAPH_DQUEUE_INIT_FINALLY(&Q, 100); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); for (i=0; bi && i<no_of_nodes; i++) { if (VECTOR(seen)[i]) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&Q, i)); VECTOR(seen)[i]=1; while (bi && !igraph_dqueue_empty(&Q)) { long int n, j; igraph_integer_t actnode=(igraph_integer_t) igraph_dqueue_pop(&Q); char acttype=VECTOR(seen)[actnode]; IGRAPH_CHECK(igraph_neighbors(graph, &neis, actnode, IGRAPH_ALL)); n=igraph_vector_size(&neis); for (j=0; j<n; j++) { long int nei=(long int) VECTOR(neis)[j]; if (VECTOR(seen)[nei]) { long int neitype=VECTOR(seen)[nei]; if (neitype == acttype) { bi=0; break; } } else { VECTOR(seen)[nei] = 3 - acttype; IGRAPH_CHECK(igraph_dqueue_push(&Q, nei)); } } } } igraph_vector_destroy(&neis); igraph_dqueue_destroy(&Q); IGRAPH_FINALLY_CLEAN(2); if (res) { *res=bi; } if (type && bi) { IGRAPH_CHECK(igraph_vector_bool_resize(type, no_of_nodes)); for (i=0; i<no_of_nodes; i++) { VECTOR(*type)[i] = VECTOR(seen)[i] - 1; } } igraph_vector_char_destroy(&seen); IGRAPH_FINALLY_CLEAN(1); return 0; }
int igraph_decompose(const igraph_t *graph, igraph_vector_ptr_t *components, igraph_connectedness_t mode, long int maxcompno, long int minelements) { long int actstart; long int no_of_nodes=igraph_vcount(graph); long int resco=0; /* number of graphs created so far */ char *already_added; igraph_dqueue_t q; igraph_vector_t verts; igraph_vector_t neis; long int i; igraph_t *newg; if (!igraph_is_directed(graph)) { mode=IGRAPH_WEAK; } if (mode != IGRAPH_WEAK) { IGRAPH_ERROR("only 'IGRAPH_WEAK' is implemented", IGRAPH_EINVAL); } if (maxcompno<0) { maxcompno=LONG_MAX; } igraph_vector_ptr_clear(components); IGRAPH_FINALLY(igraph_decompose_destroy, components); already_added=igraph_Calloc(no_of_nodes, char); if (already_added==0) { IGRAPH_ERROR("Cannot decompose graph", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, already_added); IGRAPH_CHECK(igraph_dqueue_init(&q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q); IGRAPH_VECTOR_INIT_FINALLY(&verts, 0); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); for(actstart=0; resco<maxcompno && actstart < no_of_nodes; actstart++) { if (already_added[actstart]) { continue; } IGRAPH_ALLOW_INTERRUPTION(); igraph_vector_clear(&verts); already_added[actstart]=1; IGRAPH_CHECK(igraph_vector_push_back(&verts, actstart)); IGRAPH_CHECK(igraph_dqueue_push(&q, actstart)); while (!igraph_dqueue_empty(&q) ) { long int actvert=(long int) igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) actvert, IGRAPH_ALL)); for (i=0; i<igraph_vector_size(&neis); i++) { long int neighbor=(long int) VECTOR(neis)[i]; if (already_added[neighbor]==1) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_vector_push_back(&verts, neighbor)); already_added[neighbor]=1; } } /* ok, we have a component */ if (igraph_vector_size(&verts)<minelements) { continue; } newg=igraph_Calloc(1, igraph_t); if (newg==0) { IGRAPH_ERROR("Cannot decompose graph", IGRAPH_ENOMEM); } IGRAPH_CHECK(igraph_vector_ptr_push_back(components, newg)); IGRAPH_CHECK(igraph_induced_subgraph(graph, newg, igraph_vss_vector(&verts), IGRAPH_SUBGRAPH_AUTO)); resco++; } /* for actstart++ */ igraph_vector_destroy(&neis); igraph_vector_destroy(&verts); igraph_dqueue_destroy(&q); igraph_free(already_added); IGRAPH_FINALLY_CLEAN(5); /* + components */ return 0; }
int igraph_layout_gem(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t temp_max, igraph_real_t temp_min, igraph_real_t temp_init) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_vector_int_t perm; igraph_vector_float_t impulse_x, impulse_y, temp, skew_gauge; igraph_integer_t i; float temp_global; igraph_integer_t perm_pointer = 0; float barycenter_x = 0.0, barycenter_y = 0.0; igraph_vector_t phi; igraph_vector_t neis; const float elen_des2 = 128 * 128; const float gamma = 1/16.0; const float alpha_o = M_PI; const float alpha_r = M_PI / 3.0; const float sigma_o = 1.0 / 3.0; const float sigma_r = 1.0 / 2.0 / no_nodes; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negative in GEM layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 2)) { IGRAPH_ERROR("Invalid start position matrix size in GEM layout", IGRAPH_EINVAL); } if (temp_max <= 0) { IGRAPH_ERROR("Maximum temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_min <= 0) { IGRAPH_ERROR("Minimum temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_init <= 0) { IGRAPH_ERROR("Initial temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_max < temp_init || temp_init < temp_min) { IGRAPH_ERROR("Minimum <= Initial <= Maximum temperature is required " "in GEM layout", IGRAPH_EINVAL); } if (no_nodes == 0) { return 0; } IGRAPH_CHECK(igraph_vector_float_init(&impulse_x, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &impulse_x); IGRAPH_CHECK(igraph_vector_float_init(&impulse_y, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &impulse_y); IGRAPH_CHECK(igraph_vector_float_init(&temp, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &temp); IGRAPH_CHECK(igraph_vector_float_init(&skew_gauge, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &skew_gauge); IGRAPH_CHECK(igraph_vector_int_init_seq(&perm, 0, no_nodes-1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &perm); IGRAPH_VECTOR_INIT_FINALLY(&phi, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 10); RNG_BEGIN(); /* Initialization */ igraph_degree(graph, &phi, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS); if (!use_seed) { const igraph_real_t width_half=no_nodes*100, height_half=width_half; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); for (i=0; i<no_nodes; i++) { MATRIX(*res, i, 0) = RNG_UNIF(-width_half, width_half); MATRIX(*res, i, 1) = RNG_UNIF(-height_half, height_half); barycenter_x += MATRIX(*res, i, 0); barycenter_y += MATRIX(*res, i, 1); VECTOR(phi)[i] *= (VECTOR(phi)[i] / 2.0 + 1.0); } } else { for (i=0; i<no_nodes; i++) { barycenter_x += MATRIX(*res, i, 0); barycenter_y += MATRIX(*res, i, 1); VECTOR(phi)[i] *= (VECTOR(phi)[i] / 2.0 + 1.0); } } igraph_vector_float_fill(&temp, temp_init); temp_global = temp_init * no_nodes; while (temp_global > temp_min * no_nodes && maxiter > 0) { /* choose a vertex v to update */ igraph_integer_t u, v, nlen, j; float px, py, pvx, pvy; if (!perm_pointer) { igraph_vector_int_shuffle(&perm); perm_pointer=no_nodes-1; } v=VECTOR(perm)[perm_pointer--]; /* compute v's impulse */ px = (barycenter_x/no_nodes - MATRIX(*res, v, 0)) * gamma * VECTOR(phi)[v]; py = (barycenter_y/no_nodes - MATRIX(*res, v, 1)) * gamma * VECTOR(phi)[v]; px += RNG_UNIF(-32.0, 32.0); py += RNG_UNIF(-32.0, 32.0); for (u = 0; u < no_nodes; u++) { float dx, dy, dist2; if (u == v) { continue; } dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0); dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1); dist2=dx * dx + dy * dy; if (dist2 != 0) { px += dx * elen_des2 / dist2; py += dy * elen_des2 / dist2; } } IGRAPH_CHECK(igraph_neighbors(graph, &neis, v, IGRAPH_ALL)); nlen=igraph_vector_size(&neis); for (j = 0; j < nlen; j++) { igraph_integer_t u=VECTOR(neis)[j]; float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dist2= dx * dx + dy * dy; px -= dx * dist2 / (elen_des2 * VECTOR(phi)[v]); py -= dy * dist2 / (elen_des2 * VECTOR(phi)[v]); } /* update v's position and temperature */ if (px != 0 || py != 0) { float plen = sqrtf(px * px + py * py); px *= VECTOR(temp)[v] / plen; py *= VECTOR(temp)[v] / plen; MATRIX(*res, v, 0) += px; MATRIX(*res, v, 1) += py; barycenter_x += px; barycenter_y += py; } pvx=VECTOR(impulse_x)[v]; pvy=VECTOR(impulse_y)[v]; if (pvx != 0 || pvy != 0) { float beta = atan2f(pvy - py, pvx - px); float sin_beta = sinf(beta); float sign_sin_beta = (sin_beta > 0) ? 1 : ((sin_beta < 0) ? -1 : 0); float cos_beta = cosf(beta); float abs_cos_beta = fabsf(cos_beta); float old_temp=VECTOR(temp)[v]; if (sin(beta) >= sin(M_PI_2 + alpha_r / 2.0)) { VECTOR(skew_gauge)[v] += sigma_r * sign_sin_beta; } if (abs_cos_beta >= cosf(alpha_o / 2.0)) { VECTOR(temp)[v] *= sigma_o * cos_beta; } VECTOR(temp)[v] *= (1 - fabsf(VECTOR(skew_gauge)[v])); if (VECTOR(temp)[v] > temp_max) { VECTOR(temp)[v] = temp_max; } VECTOR(impulse_x)[v] = px; VECTOR(impulse_y)[v] = py; temp_global += VECTOR(temp)[v] - old_temp; } maxiter--; } /* while temp && iter */ RNG_END(); igraph_vector_destroy(&neis); igraph_vector_destroy(&phi); igraph_vector_int_destroy(&perm); igraph_vector_float_destroy(&skew_gauge); igraph_vector_float_destroy(&temp); igraph_vector_float_destroy(&impulse_y); igraph_vector_float_destroy(&impulse_x); IGRAPH_FINALLY_CLEAN(7); return 0; }
int igraph_clusters_strong(const igraph_t *graph, igraph_vector_t *membership, igraph_vector_t *csize, igraph_integer_t *no) { long int no_of_nodes=igraph_vcount(graph); igraph_vector_t next_nei=IGRAPH_VECTOR_NULL; long int i; igraph_dqueue_t q=IGRAPH_DQUEUE_NULL; long int no_of_clusters=1; long int act_cluster_size; igraph_vector_t out=IGRAPH_VECTOR_NULL; igraph_vector_t tmp=IGRAPH_VECTOR_NULL; /* The result */ IGRAPH_VECTOR_INIT_FINALLY(&next_nei, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&out, 0); IGRAPH_DQUEUE_INIT_FINALLY(&q, 100); IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0); if (membership) { IGRAPH_CHECK(igraph_vector_resize(membership, no_of_nodes)); } IGRAPH_CHECK(igraph_vector_reserve(&out, no_of_nodes)); igraph_vector_null(&out); if (csize) { igraph_vector_clear(csize); } for (i=0; i<no_of_nodes; i++) { IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &tmp, (igraph_integer_t) i, IGRAPH_OUT)); if (VECTOR(next_nei)[i] > igraph_vector_size(&tmp)) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, i)); while (!igraph_dqueue_empty(&q)) { long int act_node=(long int) igraph_dqueue_back(&q); IGRAPH_CHECK(igraph_neighbors(graph, &tmp, (igraph_integer_t) act_node, IGRAPH_OUT)); if (VECTOR(next_nei)[act_node]==0) { /* this is the first time we've met this vertex */ VECTOR(next_nei)[act_node]++; } else if (VECTOR(next_nei)[act_node] <= igraph_vector_size(&tmp)) { /* we've already met this vertex but it has more children */ long int neighbor=(long int) VECTOR(tmp)[(long int) VECTOR(next_nei)[act_node]-1]; if (VECTOR(next_nei)[neighbor] == 0) { IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); } VECTOR(next_nei)[act_node]++; } else { /* we've met this vertex and it has no more children */ IGRAPH_CHECK(igraph_vector_push_back(&out, act_node)); igraph_dqueue_pop_back(&q); } } /* while q */ } /* for */ /* OK, we've the 'out' values for the nodes, let's use them in decreasing order with the help of a heap */ igraph_vector_null(&next_nei); /* mark already added vertices */ while (!igraph_vector_empty(&out)) { long int grandfather=(long int) igraph_vector_pop_back(&out); IGRAPH_ALLOW_INTERRUPTION(); if (VECTOR(next_nei)[grandfather] != 0) { continue; } VECTOR(next_nei)[grandfather]=1; act_cluster_size=1; if (membership) { VECTOR(*membership)[grandfather]=no_of_clusters-1; } IGRAPH_CHECK(igraph_dqueue_push(&q, grandfather)); while (!igraph_dqueue_empty(&q)) { long int act_node=(long int) igraph_dqueue_pop_back(&q); IGRAPH_CHECK(igraph_neighbors(graph, &tmp, (igraph_integer_t) act_node, IGRAPH_IN)); for (i=0; i<igraph_vector_size(&tmp); i++) { long int neighbor=(long int) VECTOR(tmp)[i]; if (VECTOR(next_nei)[neighbor] != 0) { continue; } IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); VECTOR(next_nei)[neighbor]=1; act_cluster_size++; if (membership) { VECTOR(*membership)[neighbor]=no_of_clusters-1; } } } no_of_clusters++; if (csize) { IGRAPH_CHECK(igraph_vector_push_back(csize, act_cluster_size)); } } if (no) { *no=(igraph_integer_t) no_of_clusters-1; } /* Clean up, return */ igraph_vector_destroy(&out); igraph_vector_destroy(&tmp); igraph_dqueue_destroy(&q); igraph_vector_destroy(&next_nei); IGRAPH_FINALLY_CLEAN(4); return 0; }
int igraph_cocitation_real(const igraph_t *graph, igraph_matrix_t *res, igraph_vs_t vids, igraph_neimode_t mode, igraph_vector_t *weights) { long int no_of_nodes=igraph_vcount(graph); long int no_of_vids; long int from, i, j, k, l, u, v; igraph_vector_t neis=IGRAPH_VECTOR_NULL; igraph_vector_t vid_reverse_index; igraph_vit_t vit; IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); no_of_vids = IGRAPH_VIT_SIZE(vit); /* Create a mapping from vertex IDs to the row of the matrix where * the result for this vertex will appear */ IGRAPH_VECTOR_INIT_FINALLY(&vid_reverse_index, no_of_nodes); igraph_vector_fill(&vid_reverse_index, -1); for (IGRAPH_VIT_RESET(vit), i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { v = IGRAPH_VIT_GET(vit); if (v < 0 || v >= no_of_nodes) IGRAPH_ERROR("invalid vertex ID in vertex selector", IGRAPH_EINVAL); VECTOR(vid_reverse_index)[v] = i; } IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_vids, no_of_nodes)); igraph_matrix_null(res); /* The result */ for (from=0; from<no_of_nodes; from++) { igraph_real_t weight = 1; IGRAPH_ALLOW_INTERRUPTION(); IGRAPH_CHECK(igraph_neighbors(graph, &neis, (igraph_integer_t) from, mode)); if (weights) weight = VECTOR(*weights)[from]; for (i=0; i < igraph_vector_size(&neis)-1; i++) { u = (long int) VECTOR(neis)[i]; k = (long int) VECTOR(vid_reverse_index)[u]; for (j=i+1; j<igraph_vector_size(&neis); j++) { v = (long int) VECTOR(neis)[j]; l = (long int) VECTOR(vid_reverse_index)[v]; if (k != -1) MATRIX(*res, k, v) += weight; if (l != -1) MATRIX(*res, l, u) += weight; } } } /* Clean up */ igraph_vector_destroy(&neis); igraph_vector_destroy(&vid_reverse_index); igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(3); return 0; }
/** * Loops through the graph and spreads the infection * from sick individuals to their neighbors */ void spread_infection(igraph_t *graph, igraph_t *new_graph) { igraph_vector_t neighbors; double T; float random; // Random number to compare against transmission probability T to see if the infection is passed on int num_neighbors; // Loop through all vertices looking for infected individuals for(int i = 0; i < NETWORK_SIZE; i++) { // LATENT if(state_get(graph, i) == LATENT) { // If it is after its first day in latent state, become infectious if(state_counter_get(graph, i) == DAYS_LATENT) { state_set(&new_graph, i, INFECTIOUS); state_counter_set(&new_graph, i, 0); } } // INFECTIOUS else if(state_get(graph, i) == INFECTIOUS) { // If it has been infectious for the specified time, move to recovered class if(state_counter_get(graph, i) == DAYS_INFECTIOUS) { state_set(&new_graph, i, RECOVERED); state_counter_set(&new_graph, i, 0); } else { igraph_neighbors(graph, &neighbors, i, IGRAPH_ALL); num_neighbors = igraph_vector_size(&neighbors); // The probability of the disease spreading to a given neighbor // is a function of the infected vertex's degree. // // The function: T = 1 - (1 - R0/k) * (1/d) // // Where T is the transmission probability // R0 is a fixed constant representing the R0 of the disease // k is the degree // and d is the number of days spent in the infectious class T = 1 - (1 - ((R0/num_neighbors) / (double)DAYS_INFECTIOUS)); // Loop through the neighbors of the infected individual for(int n = 0; n < num_neighbors; n++) { // Only infect the neighbor if they are susceptible if(state_get(graph, (int)VECTOR(neighbors)[n]) == SUSCEPTIBLE) { // Generates float from 0.0-1.0 inclusive random = (float)rand()/(float)RAND_MAX; // Pass on the transmission with probability T if(random < T) { state_set(&new_graph, (int)VECTOR(neighbors)[n], LATENT); state_counter_set(&new_graph, (int)VECTOR(neighbors)[n], 0); } } } } } // RECOVERED else if(state_get(graph, i) == RECOVERED) { if(state_counter_get(graph, i) == DAYS_RECOVERED) { state_set(&new_graph, i, SUSCEPTIBLE); state_counter_set(&new_graph, i, 0); } } } igraph_vector_destroy(&neighbors); state_counter_increment(&new_graph); igraph_copy(graph, &new_graph); igraph_destroy(&new_graph); }
int igraph_bfs(igraph_t *graph, igraph_integer_t vid, igraph_neimode_t mode, igraph_vector_t *vids, igraph_vector_t *layers, igraph_vector_t *parents) { igraph_dqueue_t q; long int vidspos=0; igraph_vector_t neis; long int no_of_nodes=igraph_vcount(graph); long int i; char *added; long int lastlayer=-1; if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; } if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } /* temporary storage */ added=igraph_Calloc(no_of_nodes, char); if (added==0) { IGRAPH_ERROR("Cannot calculate BFS", IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, added); IGRAPH_VECTOR_INIT_FINALLY(&neis, 0); IGRAPH_CHECK(igraph_dqueue_init(&q, 100)); IGRAPH_FINALLY(igraph_dqueue_destroy, &q); /* results */ IGRAPH_CHECK(igraph_vector_resize(vids, no_of_nodes)); igraph_vector_clear(layers); IGRAPH_CHECK(igraph_vector_resize(parents, no_of_nodes)); /* ok start with vid */ IGRAPH_CHECK(igraph_dqueue_push(&q, vid)); IGRAPH_CHECK(igraph_dqueue_push(&q, 0)); IGRAPH_CHECK(igraph_vector_push_back(layers, vidspos)); VECTOR(*vids)[vidspos++]=vid; VECTOR(*parents)[(long int)vid]=vid; added[(long int)vid]=1; while (!igraph_dqueue_empty(&q)) { long int actvect=igraph_dqueue_pop(&q); long int actdist=igraph_dqueue_pop(&q); IGRAPH_CHECK(igraph_neighbors(graph, &neis, actvect, mode)); for (i=0; i<igraph_vector_size(&neis); i++) { long int neighbor=VECTOR(neis)[i]; if (added[neighbor]==0) { added[neighbor]=1; VECTOR(*parents)[neighbor]=actvect; IGRAPH_CHECK(igraph_dqueue_push(&q, neighbor)); IGRAPH_CHECK(igraph_dqueue_push(&q, actdist+1)); if (lastlayer != actdist+1) { IGRAPH_CHECK(igraph_vector_push_back(layers, vidspos)); } VECTOR(*vids)[vidspos++]=neighbor; lastlayer=actdist+1; } } /* for i in neis */ } /* while ! dqueue_empty */ IGRAPH_CHECK(igraph_vector_push_back(layers, vidspos)); igraph_vector_destroy(&neis); igraph_dqueue_destroy(&q); igraph_Free(added); IGRAPH_FINALLY_CLEAN(3); return 0; }
int igraph_i_is_separator(const igraph_t *graph, igraph_vit_t *vit, long int except, igraph_bool_t *res, igraph_vector_bool_t *removed, igraph_dqueue_t *Q, igraph_vector_t *neis, long int no_of_nodes) { long int start=0; if (IGRAPH_VIT_SIZE(*vit) >= no_of_nodes-1) { /* Just need to check that we really have at least n-1 vertices in it */ igraph_vector_bool_t hit; long int nohit=0; IGRAPH_CHECK(igraph_vector_bool_init(&hit, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &hit); for (IGRAPH_VIT_RESET(*vit); !IGRAPH_VIT_END(*vit); IGRAPH_VIT_NEXT(*vit)) { long int v=IGRAPH_VIT_GET(*vit); if (!VECTOR(hit)[v]) { nohit++; VECTOR(hit)[v] = 1; } } igraph_vector_bool_destroy(&hit); IGRAPH_FINALLY_CLEAN(1); if (nohit >= no_of_nodes-1) { *res = 0; return 0; } } /* Remove the given vertices from the graph, do a breadth-first search and check the number of components */ if (except < 0) { for (IGRAPH_VIT_RESET(*vit); !IGRAPH_VIT_END(*vit); IGRAPH_VIT_NEXT(*vit)) { VECTOR(*removed)[ (long int) IGRAPH_VIT_GET(*vit) ] = 1; } } else { /* There is an exception */ long int i; for (i=0, IGRAPH_VIT_RESET(*vit); i<except; i++, IGRAPH_VIT_NEXT(*vit)) { VECTOR(*removed)[ (long int) IGRAPH_VIT_GET(*vit) ] = 1; } for (IGRAPH_VIT_NEXT(*vit); !IGRAPH_VIT_END(*vit); IGRAPH_VIT_NEXT(*vit)) { VECTOR(*removed)[ (long int) IGRAPH_VIT_GET(*vit) ] = 1; } } /* Look for the first node that is not removed */ while (start < no_of_nodes && VECTOR(*removed)[start]) start++; if (start==no_of_nodes) { IGRAPH_ERROR("All vertices are included in the separator", IGRAPH_EINVAL); } igraph_dqueue_push(Q, start); VECTOR(*removed)[start]=1; while (!igraph_dqueue_empty(Q)) { long int node=(long int) igraph_dqueue_pop(Q); long int j, n; igraph_neighbors(graph, neis, (igraph_integer_t) node, IGRAPH_ALL); n=igraph_vector_size(neis); for (j=0; j<n; j++) { long int nei=(long int) VECTOR(*neis)[j]; if (!VECTOR(*removed)[nei]) { IGRAPH_CHECK(igraph_dqueue_push(Q, nei)); VECTOR(*removed)[nei]=1; } } } /* Look for the next node that was neighter removed, not visited */ while (start < no_of_nodes && VECTOR(*removed)[start]) start++; /* If there is another component, then we have a separator */ *res = (start < no_of_nodes); return 0; }
int igraph_dijkstra_shortest_paths(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vector_t *wghts, igraph_neimode_t mode) { long int no_of_nodes=igraph_vcount(graph); long int no_of_from; igraph_real_t *shortest; igraph_real_t min,alt; int i, j, uj, included; igraph_integer_t eid, u,v; igraph_vector_t q; igraph_vit_t fromvit; igraph_vector_t neis; IGRAPH_CHECK(igraph_vit_create(graph, from, &fromvit)); IGRAPH_FINALLY(igraph_vit_destroy, &fromvit); no_of_from=IGRAPH_VIT_SIZE(fromvit); if (mode != IGRAPH_OUT && mode != IGRAPH_IN && mode != IGRAPH_ALL) { IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE); } shortest=calloc(no_of_nodes, sizeof(igraph_real_t)); if (shortest==0) { IGRAPH_ERROR("shortest paths failed", IGRAPH_ENOMEM); } IGRAPH_FINALLY(free, shortest); IGRAPH_CHECK(igraph_matrix_resize(res, no_of_from, no_of_nodes)); igraph_matrix_null(res); for (IGRAPH_VIT_RESET(fromvit), i=0; !IGRAPH_VIT_END(fromvit); IGRAPH_VIT_NEXT(fromvit), i++) { //Start shortest and previous for(j=0;j<no_of_nodes;j++){ shortest[j] = INFINITY; //memset(previous,NAN, no_of_nodes); } shortest[(int)IGRAPH_VIT_GET(fromvit)] = 0; igraph_vector_init_seq(&q,0,no_of_nodes-1); while(igraph_vector_size(&q) != 0){ min = INFINITY; u = no_of_nodes; uj = igraph_vector_size(&q); for(j=0;j<igraph_vector_size(&q);j++){ v = VECTOR(q)[j]; if(shortest[(int)v] < min){ min = shortest[(int)v]; u = v; uj = j; } } if(min == INFINITY) break; igraph_vector_remove(&q,uj); igraph_vector_init(&neis,0); igraph_neighbors(graph,&neis,u,mode); for(j=0;j<igraph_vector_size(&neis);j++){ v = VECTOR(neis)[j]; //v must be in Q included = 0; for(j=0;j<igraph_vector_size(&q);j++){ if(v == VECTOR(q)[j]){ included = 1; break; } } if(!included) continue; igraph_get_eid(graph,&eid,u,v,1); alt = shortest[(int)u] + VECTOR(*wghts)[(int)eid]; if(alt < shortest[(int)v]){ shortest[(int)v] = alt; } } igraph_vector_destroy(&neis); } for(j=0;j<no_of_nodes;j++){ MATRIX(*res,i,j) = shortest[j]; } igraph_vector_destroy(&q); } /* Clean */ free(shortest); igraph_vit_destroy(&fromvit); IGRAPH_FINALLY_CLEAN(2); return 0; }