Esempio n. 1
0
int main() {
  
  igraph_t g;
  igraph_vector_t v1, v2;
  int ret;
  
  /* simple use */
  igraph_vector_init(&v1, 8);
  VECTOR(v1)[0]=0; VECTOR(v1)[1]=1;
  VECTOR(v1)[2]=1; VECTOR(v1)[3]=2;
  VECTOR(v1)[4]=2; VECTOR(v1)[5]=3;
  VECTOR(v1)[6]=2; VECTOR(v1)[7]=2;
  igraph_create(&g, &v1, 0, 0);
  if (igraph_vcount(&g) != 4) {
    return 1;
  }
  igraph_vector_init(&v2, 0);
  igraph_get_edgelist(&g, &v2, 0);
  igraph_vector_sort(&v1);
  igraph_vector_sort(&v2);
  if (!igraph_vector_all_e(&v1, &v2)) {
    return 2;
  }
  igraph_destroy(&g);
  
  /* higher number of vertices */
  igraph_create(&g, &v1, 10, 0);
  if (igraph_vcount(&g) != 10) {
    return 1;
  }
  igraph_get_edgelist(&g, &v2, 0);
  igraph_vector_sort(&v1);
  igraph_vector_sort(&v2);
  if (!igraph_vector_all_e(&v1, &v2)) {
    return 3;
  }
  igraph_destroy(&g);

  /* error: IGRAPH_EINVEVECTOR */
  igraph_set_error_handler(igraph_error_handler_ignore);
  igraph_vector_resize(&v1, 9);
  VECTOR(v1)[8]=0;
  ret=igraph_create(&g, &v1, 0, 0);
  if (ret != IGRAPH_EINVEVECTOR) {
    return 4;
  }
  
  /* error: IGRAPH_EINVVID */
  igraph_vector_resize(&v1, 8);
  VECTOR(v1)[7]=-1;
  ret=igraph_create(&g, &v1, 10, 1);
  if (ret != IGRAPH_EINVVID) {
    return 5;
  }
  igraph_vector_destroy(&v1);
  igraph_vector_destroy(&v2);

  return 0;
}
Esempio n. 2
0
/* Takes a pointer vector of vectors. Sorts each vector, then sorts the pointer vector */
void canonicalize_list(igraph_vector_ptr_t *list) {
    long i, len;
    len = igraph_vector_ptr_size(list);
    for (i=0; i<len; ++i) {
        igraph_vector_sort((igraph_vector_t *) VECTOR(*list)[i]);
    }
    qsort(&(VECTOR(*list)[0]), len, sizeof(void *), &compare_vectors);
}
Esempio n. 3
0
void sort_cliques(igraph_vector_ptr_t *cliques) {
  int i, n=igraph_vector_ptr_size(cliques);
  for (i=0; i<n; i++) {
    igraph_vector_t *v=VECTOR(*cliques)[i];
    igraph_vector_sort(v);
  }
  igraph_qsort(VECTOR(*cliques), (size_t) n,
	       sizeof(igraph_vector_t *), sort_cmp);
}
Esempio n. 4
0
int igraph_i_separators_store(igraph_vector_ptr_t *separators, 
			      const igraph_adjlist_t *adjlist,
			      igraph_vector_t *components, 
			      igraph_vector_t *leaveout, 
			      unsigned long int *mark, 
			      igraph_vector_t *sorter) {
  
  /* We need to stote N(C), the neighborhood of C, but only if it is 
   * not already stored among the separators.
   */
  
  long int cptr=0, next, complen=igraph_vector_size(components);

  while (cptr < complen) {
    long int saved=cptr;
    igraph_vector_clear(sorter);

    /* Calculate N(C) for the next C */

    while ( (next=(long int) VECTOR(*components)[cptr++]) != -1) {
      VECTOR(*leaveout)[next] = *mark;
    }
    cptr=saved;

    while ( (next=(long int) VECTOR(*components)[cptr++]) != -1) {
      igraph_vector_int_t *neis=igraph_adjlist_get(adjlist, next);
      long int j, nn=igraph_vector_int_size(neis);
      for (j=0; j<nn; j++) {
	long int nei=(long int) VECTOR(*neis)[j];
	if (VECTOR(*leaveout)[nei] != *mark) {
	  igraph_vector_push_back(sorter, nei);
	  VECTOR(*leaveout)[nei] = *mark;
	}
      }    
    }
    igraph_vector_sort(sorter);

    UPDATEMARK();

    /* Add it to the list of separators, if it is new */

    if (igraph_i_separators_newsep(separators, sorter)) {
      igraph_vector_t *newc=igraph_Calloc(1, igraph_vector_t);
      if (!newc) {
	IGRAPH_ERROR("Cannot calculate minimal separators", IGRAPH_ENOMEM);
      }
      IGRAPH_FINALLY(igraph_free, newc);
      igraph_vector_copy(newc, sorter);
      IGRAPH_FINALLY(igraph_vector_destroy, newc);
      IGRAPH_CHECK(igraph_vector_ptr_push_back(separators, newc));
      IGRAPH_FINALLY_CLEAN(2);      
    }
  } /* while cptr < complen */

  return 0;
}
Esempio n. 5
0
int cliques_load_unordered_maximal_cliques_list(cliques *c, const char *path) {
    FILE *input;
    igraph_vector_t *k_clique_v;
    int size, node_id;
    int max_size=0,cur_size=0;
    if (c == NULL || path == NULL)
        return -1;

    if ((input = fopen(path, "r")) == NULL)
        return -2;

    k_clique_v = (igraph_vector_t*) malloc(sizeof (igraph_vector_t));
    igraph_vector_init(k_clique_v, 0);
    // read the file and compute the maximum size
    // of the cliques
    while (fscanf(input, "%i", &node_id) != EOF) {
      if (node_id == -1){
	if(cur_size > max_size)
	  max_size = cur_size;
        cur_size=0;
      } else
        cur_size++;
    }

    // initialize cliques structure internal vectors
    // according to the size of the maximum clique
    if((cliques_init_member_vectors(c, max_size)) < 0)
      return -3;

    // reset the file position indicator to the beginning of the file
    fseek(input, 0L, SEEK_SET);
    // load maximal cliques from the file


    while (fscanf(input, "%i", &node_id) != EOF) {
      if (node_id != -1){
        igraph_vector_push_back(k_clique_v, node_id);
      }else {
        size = igraph_vector_size(k_clique_v);
        igraph_vector_sort(k_clique_v);
        igraph_vector_ptr_push_back(VECTOR(c->maximal_cliques_v_ptr)[size], k_clique_v);
        
        k_clique_v = (igraph_vector_t*) malloc(sizeof (igraph_vector_t));
        igraph_vector_init(k_clique_v, 0);
      }
    }
    cliques_order_cliques_by_decreasing_k(c, NULL);
    igraph_vector_destroy(k_clique_v);
    return 0;
}
int igraph_dfsd(const igraph_t *graph, igraph_integer_t root,
	       igraph_neimode_t mode, igraph_bool_t unreachable, 
	       igraph_vector_t *order,
	       igraph_vector_t *order_out, igraph_vector_t *father,
	       igraph_vector_t *dist, igraph_dfshandler_t *in_callback,
	       igraph_dfshandler_t *out_callback,
	       void *extra) {
  
  long int no_of_nodes=igraph_vcount(graph);
  igraph_lazy_adjlist_t adjlist;
  igraph_stack_t stack;
  igraph_vector_char_t added;
  igraph_vector_long_t nptr;
  long int actroot;
  long int act_rank=0;
  long int rank_out=0;
  long int act_dist=0;

  if (root < 0 || root >= no_of_nodes) { 
    IGRAPH_ERROR("Invalid root vertex for DFS", IGRAPH_EINVAL);
  }

  if (mode != IGRAPH_OUT && mode != IGRAPH_IN && 
      mode != IGRAPH_ALL) {
    IGRAPH_ERROR("Invalid mode argument", IGRAPH_EINVMODE);
  }
  
  if (!igraph_is_directed(graph)) { mode=IGRAPH_ALL; }

  IGRAPH_CHECK(igraph_vector_char_init(&added, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_char_destroy, &added);
  IGRAPH_CHECK(igraph_stack_init(&stack, 100));
  IGRAPH_FINALLY(igraph_stack_destroy, &stack);
  IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, /*simplify=*/ 0));  
  IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist);
  IGRAPH_CHECK(igraph_vector_long_init(&nptr, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_long_destroy, &nptr);

# define FREE_ALL() do { 			\
  igraph_vector_long_destroy(&nptr);            \
  igraph_lazy_adjlist_destroy(&adjlist);        \
  igraph_stack_destroy(&stack);                 \
  igraph_vector_char_destroy(&added);           \
  IGRAPH_FINALLY_CLEAN(4); } while (0)

  /* Resize result vectors and fill them with IGRAPH_NAN */
  
# define VINIT(v) if (v) {                      \
    igraph_vector_resize(v, no_of_nodes);       \
    igraph_vector_fill(v, IGRAPH_NAN); }
  
  VINIT(order);
  VINIT(order_out);
  VINIT(father);
  VINIT(dist);

# undef VINIT

  IGRAPH_CHECK(igraph_stack_push(&stack, root));
  VECTOR(added)[(long int)root] = 1;
  if (father) { VECTOR(*father)[(long int)root] = -1; }
  if (order) { VECTOR(*order)[act_rank++] = root; }
  if (dist) { VECTOR(*dist)[(long int)root] = 0; }
  if (in_callback) {
    igraph_bool_t terminate=in_callback(graph, root, 0, extra);
    if (terminate) { FREE_ALL(); return 0; }
  }

  for (actroot=0; actroot<no_of_nodes; actroot++) {

    /* 'root' first, then all other vertices */
    if (igraph_stack_empty(&stack)) {
      if (!unreachable) { break; }
      if (VECTOR(added)[actroot]) { continue; }
      IGRAPH_CHECK(igraph_stack_push(&stack, actroot));
      VECTOR(added)[actroot] = 1;
      if (father) { VECTOR(*father)[actroot] = -1; }
      if (order) { VECTOR(*order)[act_rank++] = actroot; }
      if (dist) { VECTOR(*dist)[actroot] = 0; }

      if (in_callback) {
	igraph_bool_t terminate=in_callback(graph, (igraph_integer_t) actroot,
					    0, extra);
	if (terminate) { FREE_ALL(); return 0; }
      }
    }
    
    while (!igraph_stack_empty(&stack)) {
      long int actvect=(long int) igraph_stack_top(&stack);
      igraph_vector_t *neis=igraph_lazy_adjlist_get(&adjlist, 
						    (igraph_integer_t) actvect);
      long int n=igraph_vector_size(neis);
      long int *ptr=igraph_vector_long_e_ptr(&nptr, actvect);
      igraph_vector_sort(neis);
      /* Search for a neighbor that was not yet visited */
      igraph_bool_t any=0;
      long int nei;
      while (!any && (*ptr) <n) {
	nei=(long int) VECTOR(*neis)[(*ptr)];
	any=!VECTOR(added)[nei];
	(*ptr) ++;
      }
      if (any) {
	/* There is such a neighbor, add it */
	IGRAPH_CHECK(igraph_stack_push(&stack, nei));
	VECTOR(added)[nei] = 1;
	if (father) { VECTOR(*father)[ nei ] = actvect; }
	if (order) { VECTOR(*order)[act_rank++] = nei; }
	act_dist++;
	if (dist) { VECTOR(*dist)[nei] = act_dist; }

	if (in_callback) {
	  igraph_bool_t terminate=in_callback(graph, (igraph_integer_t) nei,
					      (igraph_integer_t) act_dist, 
					      extra);
	  if (terminate) { FREE_ALL(); return 0; }
	}

      } else {
	/* There is no such neighbor, finished with the subtree */
	igraph_stack_pop(&stack);
	if (order_out) { VECTOR(*order_out)[rank_out++] = actvect; }
	act_dist--;

	if (out_callback) {
	  igraph_bool_t terminate=out_callback(graph, (igraph_integer_t) 
					       actvect, (igraph_integer_t) 
					       act_dist, extra);
	  if (terminate) { FREE_ALL(); return 0; }
	}
      }
    }      
  }

  FREE_ALL();
# undef FREE_ALL

  return 0;
}
Esempio n. 7
0
/**
 * \ingroup communities
 * \function igraph_i_community_multilevel_step
 * \brief Performs a single step of the multi-level modularity optimization method
 *
 * This function implements a single step of the multi-level modularity optimization
 * algorithm for finding community structure, see VD Blondel, J-L Guillaume,
 * R Lambiotte and E Lefebvre: Fast unfolding of community hierarchies in large
 * networks, http://arxiv.org/abs/0803.0476 for the details.
 *
 * This function was contributed by Tom Gregorovic.
 *
 * \param graph   The input graph. It must be an undirected graph.
 * \param weights Numeric vector containing edge weights. If \c NULL, every edge
 *     has equal weight. The weights are expected to be non-negative.
 * \param membership The membership vector, the result is returned here.
 *     For each vertex it gives the ID of its community.
 * \param modularity The modularity of the partition is returned here.
 *     \c NULL means that the modularity is not needed.
 * \return Error code.
 *
 * Time complexity: in average near linear on sparse graphs.
 */
int igraph_i_community_multilevel_step(igraph_t *graph,
  igraph_vector_t *weights, igraph_vector_t *membership,
  igraph_real_t *modularity) {
  
  long int i, j;
  long int vcount = igraph_vcount(graph);
  long int ecount = igraph_ecount(graph);
  igraph_integer_t ffrom, fto;
  igraph_real_t q, pass_q;
  int pass;
  igraph_bool_t changed = 0;
  igraph_vector_t links_community;
  igraph_vector_t links_weight;
  igraph_vector_t edges;
  igraph_vector_t temp_membership;
  igraph_i_multilevel_community_list communities;

  /* Initial sanity checks on the input parameters */
  if (igraph_is_directed(graph)) {
    IGRAPH_ERROR("multi-level community detection works for undirected graphs only",
        IGRAPH_UNIMPLEMENTED);
  }
  if (igraph_vector_size(weights) < igraph_ecount(graph))
    IGRAPH_ERROR("multi-level community detection: weight vector too short", IGRAPH_EINVAL);
  if (igraph_vector_any_smaller(weights, 0))
    IGRAPH_ERROR("weights must be positive", IGRAPH_EINVAL);

  /* Initialize data structures */
  IGRAPH_VECTOR_INIT_FINALLY(&links_community, 0);
  IGRAPH_VECTOR_INIT_FINALLY(&links_weight, 0);
  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
  IGRAPH_VECTOR_INIT_FINALLY(&temp_membership, vcount);
  IGRAPH_CHECK(igraph_vector_resize(membership, vcount));
 
  /* Initialize list of communities from graph vertices */
  communities.vertices_no = vcount;
  communities.communities_no = vcount;
  communities.weights = weights;
  communities.weight_sum = 2 * igraph_vector_sum(weights);
  communities.membership = membership;
  communities.item = igraph_Calloc(vcount, igraph_i_multilevel_community);
  if (communities.item == 0) {
    IGRAPH_ERROR("multi-level community structure detection failed", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(igraph_free, communities.item);

  /* Still initializing the communities data structure */
  for (i=0; i < vcount; i++) {
    VECTOR(*communities.membership)[i] = i;
    communities.item[i].size = 1;
    communities.item[i].weight_inside = 0;
    communities.item[i].weight_all = 0;
  }

  /* Some more initialization :) */
  for (i = 0; i < ecount; i++) {
    igraph_real_t weight = 1;
    igraph_edge(graph, (igraph_integer_t) i, &ffrom, &fto);

    weight = VECTOR(*weights)[i];
    communities.item[(long int) ffrom].weight_all += weight;
    communities.item[(long int) fto].weight_all += weight;
    if (ffrom == fto)
      communities.item[(long int) ffrom].weight_inside += 2*weight;
  }

  q = igraph_i_multilevel_community_modularity(&communities);
  pass = 1;

  do { /* Pass begin */
    long int temp_communities_no = communities.communities_no;

    pass_q = q;
    changed = 0;
    
    /* Save the current membership, it will be restored in case of worse result */
    IGRAPH_CHECK(igraph_vector_update(&temp_membership, communities.membership));

    for (i = 0; i < vcount; i++) {
      /* Exclude vertex from its current community */
      igraph_real_t weight_all = 0;
      igraph_real_t weight_inside = 0;
      igraph_real_t weight_loop = 0;
      igraph_real_t max_q_gain = 0;
      igraph_real_t max_weight;
      long int old_id, new_id, n;

      igraph_i_multilevel_community_links(graph, &communities, 
					  (igraph_integer_t) i, &edges,
					  &weight_all, &weight_inside, 
					  &weight_loop, &links_community,
					  &links_weight);
      old_id = (long int)VECTOR(*(communities.membership))[i];
      new_id = old_id;

      /* Update old community */
      igraph_vector_set(communities.membership, i, -1);
      communities.item[old_id].size--;
      if (communities.item[old_id].size == 0) {communities.communities_no--;}
      communities.item[old_id].weight_all -= weight_all;
      communities.item[old_id].weight_inside -= 2*weight_inside + weight_loop;

      /* debug("Remove %ld all: %lf Inside: %lf\n", i, -weight_all, -2*weight_inside + weight_loop); */

      /* Find new community to join with the best modification gain */
      max_q_gain = 0;
      max_weight = weight_inside;
      n = igraph_vector_size(&links_community);
   
      igraph_vector_sort(&links_community);
    
      for (j = 0; j < n; j++) {
        long int c = (long int) VECTOR(links_community)[j];
        igraph_real_t w = VECTOR(links_weight)[j];

        igraph_real_t q_gain = 
	  igraph_i_multilevel_community_modularity_gain(&communities, 
							(igraph_integer_t) c, 
							(igraph_integer_t) i,
							weight_all, w);
        /* debug("Link %ld -> %ld weight: %lf gain: %lf\n", i, c, (double) w, (double) q_gain); */
        if (q_gain > max_q_gain) {
          new_id = c;
          max_q_gain = q_gain;
          max_weight = w;
        }
      }

      /* debug("Added vertex %ld to community %ld (gain %lf).\n", i, new_id, (double) max_q_gain); */

      /* Add vertex to "new" community and update it */
      igraph_vector_set(communities.membership, i, new_id);
      if (communities.item[new_id].size == 0) {communities.communities_no++;}
      communities.item[new_id].size++;
      communities.item[new_id].weight_all += weight_all;
      communities.item[new_id].weight_inside += 2*max_weight + weight_loop;

      if (new_id != old_id) {
        changed++;
      }
       
    }
        
    q = igraph_i_multilevel_community_modularity(&communities);

    if (changed && (q > pass_q)) { 
      /* debug("Pass %d (changed: %d) Communities: %ld Modularity from %lf to %lf\n",
        pass, changed, communities.communities_no, (double) pass_q, (double) q); */
      pass++;
    } else {
      /* No changes or the modularity became worse, restore last membership */
      IGRAPH_CHECK(igraph_vector_update(communities.membership, &temp_membership));
      communities.communities_no = temp_communities_no;
      break;
    }

    IGRAPH_ALLOW_INTERRUPTION();
  } while (changed && (q > pass_q)); /* Pass end */

  if (modularity) {
    *modularity = q;
  }

  /* debug("Result Communities: %ld Modularity: %lf\n",
    communities.communities_no, (double) q); */

  IGRAPH_CHECK(igraph_reindex_membership(membership, 0));

  /* Shrink the nodes of the graph according to the present community structure
   * and simplify the resulting graph */

  /* TODO: check if we really need to copy temp_membership */
  IGRAPH_CHECK(igraph_vector_update(&temp_membership, membership));
  IGRAPH_CHECK(igraph_i_multilevel_shrink(graph, &temp_membership));
  igraph_vector_destroy(&temp_membership);
  IGRAPH_FINALLY_CLEAN(1);  
  
  /* Update edge weights after shrinking and simplification */
  /* Here we reuse the edges vector as we don't need the previous contents anymore */
  /* TODO: can we use igraph_simplify here? */
  IGRAPH_CHECK(igraph_i_multilevel_simplify_multiple(graph, &edges));

  /* We reuse the links_weight vector to store the old edge weights */
  IGRAPH_CHECK(igraph_vector_update(&links_weight, weights));
  igraph_vector_fill(weights, 0);
   
  for (i = 0; i < ecount; i++) {
    VECTOR(*weights)[(long int)VECTOR(edges)[i]] += VECTOR(links_weight)[i];
  }

  igraph_free(communities.item);
  igraph_vector_destroy(&links_community);
  igraph_vector_destroy(&links_weight);
  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(4);
  
  return 0;
}
int main() {
  igraph_real_t d;
  igraph_vector_t u, v;
  int ret;
  long int i, k, n;

  /********************************
   * Example usage
   ********************************/

  /* Sequences with one element. Such sequences are trivially permuted.
   * The result of any Fisher-Yates shuffle on a sequence with one element
   * must be the original sequence itself.
   */
  n = 1;
  igraph_vector_init(&v, n);
  igraph_rng_seed(igraph_rng_default(), time(0));
  k = R_INTEGER(-1000, 1000);
  VECTOR(v)[0] = k;
  igraph_vector_shuffle(&v);
  if (VECTOR(v)[0] != k) {
    return 1;
  }
  d = R_UNIF(-1000.0, 1000.0);

  VECTOR(v)[0] = d;
  igraph_vector_shuffle(&v);
  if (VECTOR(v)[0] != d) {
    return 2;
  }
  igraph_vector_destroy(&v);

  /* Sequences with multiple elements. A Fisher-Yates shuffle of a sequence S
   * is a random permutation \pi(S) of S. Thus \pi(S) must have the same
   * length and elements as the original sequence S. A major difference between
   * S and its random permutation \pi(S) is that the order in which elements
   * appear in \pi(S) is probably different from how elements are ordered in S.
   * If S has length n = 1, then both \pi(S) and S are equivalent sequences in
   * that \pi(S) is merely S and no permutation has taken place. If S has
   * length n > 1, then there are n! possible permutations of S. Assume that
   * each such permutation is equally likely to appear as a result of the
   * Fisher-Yates shuffle. As n increases, the probability that S is different
   * from \pi(S) also increases. We have a probability of 1 / n! that S and
   * \pi(S) are equivalent sequences.
   */
  n = 100;
  igraph_vector_init(&u, n);
  igraph_vector_init(&v, n);

  for (i = 0; i < n; i++) {
    k = R_INTEGER(-1000, 1000);
    VECTOR(u)[i] = k;
    VECTOR(v)[i] = k;
  }

  igraph_vector_shuffle(&v);
  /* must have same length */
  if (igraph_vector_size(&v) != n) {
    return 3;
  }
  if (igraph_vector_size(&u) != igraph_vector_size(&v)) {
    return 4;
  }
  /* must have same elements */
  igraph_vector_sort(&u);
  igraph_vector_sort(&v);
  if (!igraph_vector_all_e(&u, &v)) {
    return 5;
  }
  igraph_vector_destroy(&u);
  igraph_vector_destroy(&v);

  /* empty sequence */
  igraph_vector_init(&v, 0);
  ret = igraph_vector_shuffle(&v);
  igraph_vector_destroy(&v);

  return ret == 0 ? 0 : 6;
}
Esempio n. 9
0
void igraph_adjlist_sort(igraph_adjlist_t *al) {
  long int i;
  for (i=0; i<al->length; i++)
    igraph_vector_sort(&al->adjs[i]);
}
Esempio n. 10
0
int igraph_i_minimum_spanning_tree_unweighted(const igraph_t* graph,
    igraph_vector_t* res) {

  long int no_of_nodes=igraph_vcount(graph);
  long int no_of_edges=igraph_ecount(graph);
  char *already_added;
  char *added_edges;
  
  igraph_dqueue_t q=IGRAPH_DQUEUE_NULL;
  igraph_vector_t tmp=IGRAPH_VECTOR_NULL;
  long int i, j;

  igraph_vector_clear(res);

  added_edges=igraph_Calloc(no_of_edges, char);
  if (added_edges==0) {
    IGRAPH_ERROR("unweighted spanning tree failed", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(igraph_free, added_edges);
  already_added=igraph_Calloc(no_of_nodes, char);
  if (already_added==0) {
    IGRAPH_ERROR("unweighted spanning tree failed", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(igraph_free, already_added);
  IGRAPH_VECTOR_INIT_FINALLY(&tmp, 0);
  IGRAPH_DQUEUE_INIT_FINALLY(&q, 100);
  
  for (i=0; i<no_of_nodes; i++) {
    if (already_added[i]>0) { continue; }

    IGRAPH_ALLOW_INTERRUPTION();

    already_added[i]=1;
    IGRAPH_CHECK(igraph_dqueue_push(&q, i));
    while (! igraph_dqueue_empty(&q)) {
      long int act_node=(long int) igraph_dqueue_pop(&q);
      IGRAPH_CHECK(igraph_incident(graph, &tmp, (igraph_integer_t) act_node,
				   IGRAPH_ALL));
      igraph_vector_sort(&tmp);
      for (j=0; j<igraph_vector_size(&tmp); j++) {
        long int edge=(long int) VECTOR(tmp)[j];
        if (added_edges[edge]==0) {
          igraph_integer_t from, to;
          igraph_edge(graph, (igraph_integer_t) edge, &from, &to);
          if (act_node==to) { to=from; }
          if (already_added[(long int) to]==0) {
            already_added[(long int) to]=1;
            added_edges[edge]=1;
            IGRAPH_CHECK(igraph_vector_push_back(res, edge));
            IGRAPH_CHECK(igraph_dqueue_push(&q, to));
          }
        }
      }
    }
  }
  
  igraph_dqueue_destroy(&q);
  igraph_Free(already_added);
  igraph_vector_destroy(&tmp);
  igraph_Free(added_edges);
  IGRAPH_FINALLY_CLEAN(4);

  return IGRAPH_SUCCESS;
}
Esempio n. 11
0
int check_multi() {

  igraph_t g;
  igraph_vector_t vec;
  igraph_vector_t eids, eids2;
  int ret;
  long int i;

  igraph_real_t q1[] = { 0,1, 0,1 };
  igraph_real_t q2[] = { 0,1, 0,1, 0,1 };
  igraph_real_t q3[] = { 1,0, 3,4, 1,0, 0,1, 3,4, 0,1 };

  igraph_vector_init(&eids, 0);

  /*********************************/
  igraph_small(&g, /*n=*/ 10, /*directed=*/ 1, 
	       0,1, 0,1, 1,0, 1,2, 3,4, 3,4, 3,4, 3,5, 3,7, 
	       9,8,
	       -1);

  igraph_vector_view(&vec, q1, sizeof(q1) / sizeof(igraph_real_t));
  igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 1, /*error=*/ 1);
  igraph_vector_sort(&eids);
  print_vector(&eids, stdout);

  igraph_vector_view(&vec, q2, sizeof(q2) / sizeof(igraph_real_t));
  igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 0, /*error=*/ 1);
  igraph_vector_sort(&eids);
  print_vector(&eids, stdout);

  igraph_vector_view(&vec, q2, sizeof(q2) / sizeof(igraph_real_t));
  igraph_set_error_handler(igraph_error_handler_ignore);
  ret=igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 1, /*error=*/1);
  if (ret != IGRAPH_EINVAL) { return 1; } 
  igraph_set_error_handler(igraph_error_handler_abort);

  igraph_destroy(&g);
  /*********************************/

  /*********************************/
  igraph_small(&g, /*n=*/10, /*directed=*/0, 
	       0,1, 1,0, 0,1, 3,4, 3,4, 5,4, 9,8, 
	       -1);
  
  igraph_vector_view(&vec, q1, sizeof(q1) / sizeof(igraph_real_t));
  igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/1, /*error=*/ 1);
  igraph_vector_sort(&eids);
  print_vector(&eids, stdout);

  igraph_vector_view(&vec, q3, sizeof(q3) / sizeof(igraph_real_t));
  igraph_set_error_handler(igraph_error_handler_ignore);
  ret=igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/0, /*error=*/ 1);
  if (ret != IGRAPH_EINVAL) { return 2; }
  igraph_set_error_handler(igraph_error_handler_abort);
  
  igraph_destroy(&g);

  /*********************************/

  igraph_vector_destroy(&eids);

  /*********************************/
  /* Speed tests */

#define NODES 10000
  igraph_barabasi_game(&g, /*n=*/ NODES, /*power=*/ 1.0, /*m=*/ 3, 
		       /*outseq=*/ 0, /*outpref=*/ 0, /*A=*/ 1,
		       /*directed=*/ 1, IGRAPH_BARABASI_BAG,
		       /*start_from=*/ 0);
  igraph_simplify(&g, /*multiple=*/ 1, /*loops=*/ 0, /*edge_comb=*/ 0);

  igraph_vector_init(&eids, NODES/2);
  igraph_random_sample(&eids, 0, igraph_ecount(&g)-1, NODES/2);
  igraph_vector_init(&vec, NODES);
  for (i=0; i<NODES/2; i++) {
    VECTOR(vec)[2*i]   = IGRAPH_FROM(&g, VECTOR(eids)[i]);
    VECTOR(vec)[2*i+1] = IGRAPH_TO(&g, VECTOR(eids)[i]);
  }
  igraph_vector_init(&eids2, 0);
  igraph_get_eids_multi(&g, &eids2, &vec, 0, /*directed=*/ 1, /*error=*/ 1);
  if (!igraph_vector_all_e(&eids, &eids2)) {
    return 3;
  }

  /**/

  for (i=0; i<NODES/2; i++) {
    VECTOR(vec)[2*i]   = IGRAPH_TO(&g, VECTOR(eids)[i]);
    VECTOR(vec)[2*i+1] = IGRAPH_FROM(&g, VECTOR(eids)[i]);
  }
  igraph_get_eids_multi(&g, &eids2, &vec, 0, /*directed=*/ 0, /*error=*/ 1);
  if (!igraph_vector_all_e(&eids, &eids2)) {
    return 4;
  }

  igraph_vector_destroy(&eids);
  igraph_vector_destroy(&eids2);
  igraph_vector_destroy(&vec);
  igraph_destroy(&g);
		  
  /*********************************/

  return 0;
}