コード例 #1
0
ファイル: separators.c プロジェクト: dacapo1142/igraph
int igraph_is_minimal_separator(const igraph_t *graph,
				const igraph_vs_t candidate, 
				igraph_bool_t *res) {

  long int no_of_nodes=igraph_vcount(graph);
  igraph_vector_bool_t removed;
  igraph_dqueue_t Q;
  igraph_vector_t neis;
  long int candsize;
  igraph_vit_t vit;
  
  IGRAPH_CHECK(igraph_vit_create(graph, candidate, &vit));
  IGRAPH_FINALLY(igraph_vit_destroy, &vit);
  candsize=IGRAPH_VIT_SIZE(vit);

  IGRAPH_CHECK(igraph_vector_bool_init(&removed, no_of_nodes));
  IGRAPH_FINALLY(igraph_vector_bool_destroy, &removed);
  IGRAPH_CHECK(igraph_dqueue_init(&Q, 100));
  IGRAPH_FINALLY(igraph_dqueue_destroy, &Q);
  IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);

  /* Is it a separator at all? */
  IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, -1, res, &removed, 
				     &Q, &neis, no_of_nodes));
  if (!(*res)) {
    /* Not a separator at all, nothing to do, *res is already set */
  } else if (candsize == 0) {
    /* Nothing to do, minimal, *res is already set */
  } else {
    /* General case, we need to remove each vertex from 'candidate'
     * and check whether the remainder is a separator. If this is
     * false for all vertices, then 'candidate' is a minimal
     * separator.
     */
    long int i;
    for (i=0, *res=0; i<candsize && (!*res); i++) {
      igraph_vector_bool_null(&removed);
      IGRAPH_CHECK(igraph_i_is_separator(graph, &vit, i, res, &removed, 
					 &Q, &neis, no_of_nodes));    
    }
    (*res) = (*res) ? 0 : 1;	/* opposite */
  }
  
  igraph_vector_destroy(&neis);
  igraph_dqueue_destroy(&Q);
  igraph_vector_bool_destroy(&removed);
  igraph_vit_destroy(&vit);
  IGRAPH_FINALLY_CLEAN(4);

  return 0;
}
コード例 #2
0
ファイル: cohesive_blocks.c プロジェクト: cran/igraph
int igraph_cohesive_blocks(const igraph_t *graph,
			   igraph_vector_ptr_t *blocks,
			   igraph_vector_t *cohesion,
			   igraph_vector_t *parent,
			   igraph_t *block_tree) {

  /* Some implementation comments. Everything is relatively
     straightforward, except, that we need to follow the vertex ids
     of the various subgraphs, without having to store two-way
     mappings at each level. The subgraphs can overlap, this
     complicates things a bit.

     The 'Q' vector is used as a double ended queue and it contains
     the subgraphs to work on in the future. Some other vectors are
     associated with it. 'Qparent' gives the parent graph of a graph
     in Q. Qmapping gives the mapping of the vertices from the graph
     to the parent graph. Qcohesion is the vertex connectivity of the 
     graph. 

     Qptr is an integer and points to the next graph to work on.
  */
  
  igraph_vector_ptr_t Q;
  igraph_vector_ptr_t Qmapping;
  igraph_vector_long_t Qparent;
  igraph_vector_long_t Qcohesion;
  igraph_vector_bool_t Qcheck;
  long int Qptr=0;
  igraph_integer_t conn;
  igraph_bool_t is_simple;

  igraph_t *graph_copy;
  
  igraph_vector_ptr_t separators;
  igraph_vector_t compvertices;
  igraph_vector_long_t components;
  igraph_vector_bool_t marked;

  igraph_vector_long_t compid;
  igraph_dqueue_t bfsQ;
  igraph_vector_t neis;

  if (igraph_is_directed(graph)) {
    IGRAPH_ERROR("Cohesive blocking only works on undirected graphs",
		 IGRAPH_EINVAL);
  }

  IGRAPH_CHECK(igraph_is_simple(graph, &is_simple));
  if (!is_simple) {
    IGRAPH_ERROR("Cohesive blocking only works on simple graphs",
		 IGRAPH_EINVAL);
  }

  IGRAPH_STATUS("Starting cohesive block calculation.\n", 0);

  if (blocks)   { igraph_vector_ptr_clear(blocks); }
  if (cohesion) { igraph_vector_clear(cohesion);   }
  if (parent)   { igraph_vector_clear(parent);     }

  IGRAPH_CHECK(igraph_vector_ptr_init(&Q, 1));
  IGRAPH_FINALLY(igraph_vector_ptr_destroy, &Q);
  IGRAPH_FINALLY(igraph_i_cohesive_blocks_free, &Q);

  IGRAPH_CHECK(igraph_vector_ptr_init(&Qmapping, 1));
  IGRAPH_FINALLY(igraph_vector_ptr_destroy, &Qmapping);
  IGRAPH_FINALLY(igraph_i_cohesive_blocks_free2, &Qmapping);

  IGRAPH_CHECK(igraph_vector_long_init(&Qparent, 1));
  IGRAPH_FINALLY(igraph_vector_long_destroy, &Qparent);

  IGRAPH_CHECK(igraph_vector_long_init(&Qcohesion, 1));
  IGRAPH_FINALLY(igraph_vector_long_destroy, &Qcohesion);

  IGRAPH_CHECK(igraph_vector_bool_init(&Qcheck, 1));
  IGRAPH_FINALLY(igraph_vector_bool_destroy, &Qcheck);
  
  IGRAPH_CHECK(igraph_vector_ptr_init(&separators, 0));
  IGRAPH_FINALLY(igraph_vector_ptr_destroy, &separators);

  IGRAPH_VECTOR_INIT_FINALLY(&compvertices, 0);
  IGRAPH_CHECK(igraph_vector_bool_init(&marked, 0));
  IGRAPH_FINALLY(igraph_vector_bool_destroy, &marked);
  IGRAPH_VECTOR_INIT_FINALLY(&neis, 0);
  IGRAPH_CHECK(igraph_dqueue_init(&bfsQ, 100));
  IGRAPH_FINALLY(igraph_dqueue_destroy, &bfsQ);
  IGRAPH_CHECK(igraph_vector_long_init(&compid, 0));
  IGRAPH_FINALLY(igraph_vector_long_destroy, &compid);
  IGRAPH_CHECK(igraph_vector_long_init(&components, 0));
  IGRAPH_FINALLY(igraph_vector_long_destroy, &components);
  
  /* Put the input graph in the queue */
  graph_copy=igraph_Calloc(1, igraph_t);
  if (!graph_copy) { 
    IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM);
  }
  IGRAPH_CHECK(igraph_copy(graph_copy, graph));
  VECTOR(Q)[0] = graph_copy;
  VECTOR(Qmapping)[0] = 0;	/* Identity mapping */
  VECTOR(Qparent)[0] = -1;	/* Has no parent */
  IGRAPH_CHECK(igraph_vertex_connectivity(graph, &conn, /*checks=*/ 1));
  VECTOR(Qcohesion)[0] = conn;
  VECTOR(Qcheck)[0] = 0;  

  /* Then work until the queue is empty */
  while (Qptr < igraph_vector_ptr_size(&Q)) {
    igraph_t *mygraph=VECTOR(Q)[Qptr];
    igraph_bool_t mycheck=VECTOR(Qcheck)[Qptr];
    long int mynodes=igraph_vcount(mygraph);
    long int i, nsep;
    long int no, kept=0;
    long int cptr=0;
    long int nsepv=0;
    igraph_bool_t addedsep=0;

    IGRAPH_STATUSF(("Candidate %li: %li vertices,", 
		    0, Qptr, mynodes));
    IGRAPH_ALLOW_INTERRUPTION();

    /* Get the separators */
    IGRAPH_CHECK(igraph_minimum_size_separators(mygraph, &separators));
    IGRAPH_FINALLY(igraph_i_cohesive_blocks_free3, &separators);
    nsep=igraph_vector_ptr_size(&separators);
    
    IGRAPH_STATUSF((" %li separators,", 0, nsep));

    /* Remove them from the graph, also mark them */    
    IGRAPH_CHECK(igraph_vector_bool_resize(&marked, mynodes));
    igraph_vector_bool_null(&marked);
    for (i=0; i<nsep; i++) {
      igraph_vector_t *v=VECTOR(separators)[i];
      long int j, n=igraph_vector_size(v);
      for (j=0; j<n; j++) {
	long int vv=(long int) VECTOR(*v)[j];
	if (!VECTOR(marked)[vv]) {
	  nsepv++;
	  VECTOR(marked)[vv] = 1;
	}
      }
    }
    
    /* Find the connected components, omitting the separator vertices, 
       but including the neighboring separator vertices
     */
    IGRAPH_CHECK(igraph_i_cb_components(mygraph, &marked, 
					&components, &no,
					&compid, &bfsQ, &neis));

    /* Add the separator vertices themselves, as another component,
       but only if there is at least one vertex not included in any 
       separator. */
    if (nsepv != mynodes) {
      addedsep=1;
      for (i=0; i<mynodes; i++) {
	if (VECTOR(marked)[i]) {
	  IGRAPH_CHECK(igraph_vector_long_push_back(&components, i));
	}
      }
      IGRAPH_CHECK(igraph_vector_long_push_back(&components, -1));
      no++;
    }

    IGRAPH_STATUSF((" %li new candidates,", 0, no));

    for (i=0; i<no; i++) {
      igraph_vector_t *newmapping;
      igraph_t *newgraph;
      igraph_integer_t maxdeg;

      igraph_vector_clear(&compvertices);
      
      while (1) {
	long int v=VECTOR(components)[cptr++];
	if (v < 0) { break; }
	IGRAPH_CHECK(igraph_vector_push_back(&compvertices, v));
      }
      
      newmapping=igraph_Calloc(1, igraph_vector_t);
      if (!newmapping) {
	IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM);
      }
      IGRAPH_FINALLY(igraph_free, newmapping);
      IGRAPH_VECTOR_INIT_FINALLY(newmapping, 0);
      newgraph=igraph_Calloc(1, igraph_t);
      if (!newgraph) { 
	IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM);
      }
      IGRAPH_FINALLY(igraph_free, newgraph);
      IGRAPH_CHECK(igraph_induced_subgraph_map(mygraph, newgraph, 
					igraph_vss_vector(&compvertices),
					IGRAPH_SUBGRAPH_AUTO,
					/*map=*/ 0,
					/*invmap=*/ newmapping));
      IGRAPH_FINALLY(igraph_destroy, newgraph);

      IGRAPH_CHECK(igraph_maxdegree(newgraph, &maxdeg, igraph_vss_all(),
				    IGRAPH_ALL, IGRAPH_LOOPS));
      if (maxdeg > VECTOR(Qcohesion)[Qptr]) {
	igraph_integer_t newconn;
	kept++;
	IGRAPH_CHECK(igraph_vector_ptr_push_back(&Q, newgraph));
	IGRAPH_FINALLY_CLEAN(2);
	IGRAPH_CHECK(igraph_vector_ptr_push_back(&Qmapping, newmapping));
	IGRAPH_FINALLY_CLEAN(2);
	IGRAPH_CHECK(igraph_vertex_connectivity(newgraph, &newconn, 
						/*checks=*/ 1));
	IGRAPH_CHECK(igraph_vector_long_push_back(&Qcohesion, newconn));
	IGRAPH_CHECK(igraph_vector_long_push_back(&Qparent, Qptr));
	IGRAPH_CHECK(igraph_vector_bool_push_back(&Qcheck, 
						  mycheck || addedsep));
      } else {
	igraph_destroy(newgraph);
	igraph_free(newgraph);
	igraph_vector_destroy(newmapping);
	igraph_free(newmapping);
	IGRAPH_FINALLY_CLEAN(4);
      }
    }

    IGRAPH_STATUSF((" keeping %li.\n", 0, kept));

    igraph_destroy(mygraph);
    igraph_free(mygraph);
    VECTOR(Q)[Qptr] = 0;
    igraph_i_cohesive_blocks_free3(&separators);
    IGRAPH_FINALLY_CLEAN(1);

    Qptr++;
  }

  igraph_vector_long_destroy(&components);
  igraph_vector_long_destroy(&compid);
  igraph_dqueue_destroy(&bfsQ);
  igraph_vector_destroy(&neis);
  igraph_vector_bool_destroy(&marked);
  igraph_vector_destroy(&compvertices);
  igraph_vector_ptr_destroy(&separators);
  IGRAPH_FINALLY_CLEAN(7);

  if (blocks || cohesion || parent || block_tree) {
    igraph_integer_t noblocks=(igraph_integer_t) Qptr, badblocks=0;
    igraph_vector_bool_t removed;
    long int i, resptr=0;
    igraph_vector_long_t rewritemap;
    
    IGRAPH_CHECK(igraph_vector_bool_init(&removed, noblocks));
    IGRAPH_FINALLY(igraph_vector_bool_destroy, &removed);
    IGRAPH_CHECK(igraph_vector_long_init(&rewritemap, noblocks));
    IGRAPH_FINALLY(igraph_vector_long_destroy, &rewritemap);

    for (i=1; i<noblocks; i++) {
      long int p=VECTOR(Qparent)[i];
      while (VECTOR(removed)[p]) { p=VECTOR(Qparent)[p]; }
      if (VECTOR(Qcohesion)[p] >= VECTOR(Qcohesion)[i]) {
	VECTOR(removed)[i]=1;
	badblocks++;
      }
    }

    /* Rewrite the mappings */
    for (i=1; i<Qptr; i++) {
      long int p=VECTOR(Qparent)[i];
      igraph_vector_t *mapping=VECTOR(Qmapping)[i];
      igraph_vector_t *pmapping=VECTOR(Qmapping)[p];
      long int j, n=igraph_vector_size(mapping);

      if (!pmapping) { continue; }
      for (j=0; j<n; j++) {
	long int v=(long int) VECTOR(*mapping)[j];
	VECTOR(*mapping)[j] = VECTOR(*pmapping)[v];
      }
    }

    /* Because we also put the separator vertices in the queue, it is 
       not ensured that the found blocks are not subsets of each other.
       We check this now. */
    for (i=1; i<noblocks; i++) {
      long int j, ic;
      igraph_vector_t *ivec;
      if (!VECTOR(Qcheck)[i] || VECTOR(removed)[i]) { continue; }
      ivec=VECTOR(Qmapping)[i];
      ic=VECTOR(Qcohesion)[i];
      for (j=1; j<noblocks; j++) {
	igraph_vector_t *jvec;
	long int jc;
	if (j==i || !VECTOR(Qcheck)[j] || VECTOR(removed)[j]) { continue; }
	jvec=VECTOR(Qmapping)[j];
	jc=VECTOR(Qcohesion)[j];
	if (igraph_i_cb_isin(ivec, jvec) && jc >= ic) { 
	  badblocks++; 
	  VECTOR(removed)[i]=1;
	  break;
	}
      }
    }
	  
    noblocks -= badblocks;

    if (blocks) { IGRAPH_CHECK(igraph_vector_ptr_resize(blocks, noblocks)); }
    if (cohesion) { IGRAPH_CHECK(igraph_vector_resize(cohesion, noblocks)); }
    if (parent) { IGRAPH_CHECK(igraph_vector_resize(parent, noblocks)); }

    for (i=0; i<Qptr; i++) {
      if (VECTOR(removed)[i]) { 
	IGRAPH_STATUSF(("Candidate %li ignored.\n", 0, i));
	continue; 
      } else {
	IGRAPH_STATUSF(("Candidate %li is a cohesive (sub)block\n", 0, i));
      }
      VECTOR(rewritemap)[i] = resptr;
      if (cohesion) { VECTOR(*cohesion)[resptr]=VECTOR(Qcohesion)[i]; }
      if (parent || block_tree) {
	long int p=VECTOR(Qparent)[i];
	while (p>=0 && VECTOR(removed)[p]) { p=VECTOR(Qparent)[p]; }
	if (p>=0) { p=VECTOR(rewritemap)[p]; }
	VECTOR(Qparent)[i]=p;
	if (parent) { VECTOR(*parent)[resptr]=p; }
      }
      if (blocks) {
	VECTOR(*blocks)[resptr]=VECTOR(Qmapping)[i];
	VECTOR(Qmapping)[i]=0;
      }
      resptr++;
    }

    /* Plus the original graph */
    if (blocks) {
      igraph_vector_t *orig=igraph_Calloc(1, igraph_vector_t);
      if (!orig) { 
	IGRAPH_ERROR("Cannot do cohesive blocking", IGRAPH_ENOMEM); 
      }
      IGRAPH_FINALLY(igraph_free, orig);
      IGRAPH_CHECK(igraph_vector_init_seq(orig, 0, igraph_vcount(graph)-1));
      VECTOR(*blocks)[0]=orig;
      IGRAPH_FINALLY_CLEAN(1);
    }

    if (block_tree) {
      igraph_vector_t edges;
      long int eptr=0;
      IGRAPH_VECTOR_INIT_FINALLY(&edges, noblocks*2-2);
      for (i=1; i<Qptr; i++) {
	if (VECTOR(removed)[i]) { continue; }
	VECTOR(edges)[eptr++] = VECTOR(Qparent)[i];
	VECTOR(edges)[eptr++] = VECTOR(rewritemap)[i];
      }
      
      IGRAPH_CHECK(igraph_create(block_tree, &edges, noblocks, 
				 IGRAPH_DIRECTED));
      igraph_vector_destroy(&edges);
      IGRAPH_FINALLY_CLEAN(1);
    }

    igraph_vector_long_destroy(&rewritemap);
    igraph_vector_bool_destroy(&removed);
    IGRAPH_FINALLY_CLEAN(2);

  }

  igraph_vector_bool_destroy(&Qcheck);
  igraph_vector_long_destroy(&Qcohesion);
  igraph_vector_long_destroy(&Qparent);
  igraph_i_cohesive_blocks_free2(&Qmapping);
  IGRAPH_FINALLY_CLEAN(4);
  
  igraph_vector_ptr_destroy(&Qmapping);
  igraph_vector_ptr_destroy(&Q);
  IGRAPH_FINALLY_CLEAN(3);  	/* + the elements of Q, they were
				   already destroyed */

  IGRAPH_STATUS("Cohesive blocking done.\n", 0);

  return 0;
}
コード例 #3
0
ファイル: bipartite.c プロジェクト: FEYoung/rigraph
int igraph_bipartite_game_gnm(igraph_t *graph, igraph_vector_bool_t *types,
			      igraph_integer_t n1, igraph_integer_t n2, 
			      igraph_integer_t m, igraph_bool_t directed, 
			      igraph_neimode_t mode) {
  igraph_vector_t edges;
  igraph_vector_t s;
  int retval=0;

  if (n1 < 0 || n2 < 0) { 
    IGRAPH_ERROR("Invalid number of vertices", IGRAPH_EINVAL);
  }
  if (m < 0) { 
    IGRAPH_ERROR("Invalid number of edges", IGRAPH_EINVAL);
  }

  if (types) {
    long int i;
    IGRAPH_CHECK(igraph_vector_bool_resize(types, n1 + n2));
    igraph_vector_bool_null(types);
    for (i=n1; i<n1+n2; i++) {
      VECTOR(*types)[i] = 1;
    }
  }
  
  if (m == 0 || n1 * n2 == 0) {
    IGRAPH_CHECK(retval=igraph_empty(graph, n1 + n2, directed));
  } else {
    
    long int i;
    double maxedges;
    if (!directed || mode != IGRAPH_ALL) {
      maxedges = n1 * n2;
    } else {
      maxedges = 2 * n1 * n2;
    }
    
    if (m > maxedges) {
      IGRAPH_ERROR("Invalid number (too large) of edges", IGRAPH_EINVAL);
    }
    
    if (maxedges == m) {
      IGRAPH_CHECK(retval=igraph_full_bipartite(graph, types, n1, n2, 
						directed, mode));
    } else {

      long int to, from;
      IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
      IGRAPH_VECTOR_INIT_FINALLY(&s, 0);
      IGRAPH_CHECK(igraph_random_sample(&s, 0, maxedges-1, m));
      IGRAPH_CHECK(igraph_vector_reserve(&edges, igraph_vector_size(&s)*2));

      for (i=0; i<m; i++) {
	if (!directed || mode != IGRAPH_ALL) {
	  to=(long) floor(VECTOR(s)[i]/n1);
	  from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1);
	  to += n1;
	} else {
	  long int n1n2 = n1 * n2;
	  if (VECTOR(s)[i] < n1n2) {
	    to=(long) floor(VECTOR(s)[i]/n1);
	    from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1);
	    to += n1;
	  } else {
	    to=(long) floor( (VECTOR(s)[i]-n1n2) /n2);
	    from=(long) (VECTOR(s)[i] - n1n2 - ((igraph_real_t) to) * n2);
	    from += n1;
	  }
	}

	if (mode != IGRAPH_IN) {
	  igraph_vector_push_back(&edges, from);
	  igraph_vector_push_back(&edges, to);
	} else {
	  igraph_vector_push_back(&edges, to);
	  igraph_vector_push_back(&edges, from);	
	}
      }

      igraph_vector_destroy(&s);
      IGRAPH_FINALLY_CLEAN(1);
      IGRAPH_CHECK(retval=igraph_create(graph, &edges, n1+n2, directed));
      igraph_vector_destroy(&edges);
      IGRAPH_FINALLY_CLEAN(1);
    }
  }  

  return retval;
}
コード例 #4
0
ファイル: bipartite.c プロジェクト: FEYoung/rigraph
int igraph_bipartite_game_gnp(igraph_t *graph, igraph_vector_bool_t *types,
			      igraph_integer_t n1, igraph_integer_t n2, 
			      igraph_real_t p, igraph_bool_t directed, 
			      igraph_neimode_t mode) {

  int retval=0;
  igraph_vector_t edges, s;
  int i;

  if (p < 0.0 || p > 1.0) {
    IGRAPH_ERROR("Invalid connection probability", IGRAPH_EINVAL);
  }

  if (types) {
    IGRAPH_CHECK(igraph_vector_bool_resize(types, n1 + n2));
    igraph_vector_bool_null(types);
    for (i=n1; i<n1+n2; i++) {
      VECTOR(*types)[i] = 1;
    }
  }

  if (p == 0 || n1 * n2 < 1) {
    IGRAPH_CHECK(retval=igraph_empty(graph, n1 + n2, directed));
  } else if (p == 1.0) {
    IGRAPH_CHECK(retval=igraph_full_bipartite(graph, types, n1, n2, directed,
					      mode));
  } else {

    long int to, from, slen;
    double maxedges, last;
    if (!directed || mode != IGRAPH_ALL) {
      maxedges = n1 * n2;
    } else {
      maxedges = 2 * n1 * n2;
    }
    
    IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
    IGRAPH_VECTOR_INIT_FINALLY(&s, 0);
    IGRAPH_CHECK(igraph_vector_reserve(&s, (long) (maxedges*p*1.1)));
    
    RNG_BEGIN();

    last=RNG_GEOM(p);
    while (last < maxedges) {
      IGRAPH_CHECK(igraph_vector_push_back(&s, last));
      last += RNG_GEOM(p);
      last += 1;
    }
    
    RNG_END();

    slen=igraph_vector_size(&s);
    IGRAPH_CHECK(igraph_vector_reserve(&edges, slen * 2));

    for (i=0; i<slen; i++) {
      if (!directed || mode != IGRAPH_ALL) {
	to=(long) floor(VECTOR(s)[i]/n1);
	from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1);
	to += n1;
      } else {
	long int n1n2 = n1 * n2;
	if (VECTOR(s)[i] < n1n2) {
	  to=(long) floor(VECTOR(s)[i]/n1);
	  from=(long) (VECTOR(s)[i] - ((igraph_real_t) to) * n1);
	  to += n1;
	} else {
	  to=(long) floor( (VECTOR(s)[i]-n1n2) /n2);
	  from=(long) (VECTOR(s)[i] - n1n2 - ((igraph_real_t) to) * n2);
	  from += n1;	  
	}
      }

      if (mode != IGRAPH_IN) {
	igraph_vector_push_back(&edges, from);
	igraph_vector_push_back(&edges, to);
      } else {
	igraph_vector_push_back(&edges, to);
	igraph_vector_push_back(&edges, from);	
      }
    }

    igraph_vector_destroy(&s);
    IGRAPH_FINALLY_CLEAN(1);
    IGRAPH_CHECK(retval=igraph_create(graph, &edges, n1+n2, directed));
    igraph_vector_destroy(&edges);
    IGRAPH_FINALLY_CLEAN(1);
  }

  return retval;
}
コード例 #5
0
ファイル: bipartite.c プロジェクト: FEYoung/rigraph
int igraph_incidence(igraph_t *graph, igraph_vector_bool_t *types,
		     const igraph_matrix_t *incidence, 
		     igraph_bool_t directed,
		     igraph_neimode_t mode, igraph_bool_t multiple) {
  
  igraph_integer_t n1=(igraph_integer_t) igraph_matrix_nrow(incidence);
  igraph_integer_t n2=(igraph_integer_t) igraph_matrix_ncol(incidence);
  igraph_integer_t no_of_nodes=n1+n2;
  igraph_vector_t edges;
  long int i, j, k;

  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);

  if (multiple) { 

    for (i=0; i<n1; i++) {
      for (j=0; j<n2; j++) { 
	long int elem=(long int) MATRIX(*incidence, i, j);
	long int from, to;
	
	if (!elem) { continue; }
	
	if (mode == IGRAPH_IN) {
	  from=n1+j;
	  to=i;
	} else {
	  from=i;
	  to=n1+j;
	}
	
	if (mode != IGRAPH_ALL || !directed) {
	  for (k=0; k<elem; k++) {
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, from));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, to));
	  }
	} else {
	  for (k=0; k<elem; k++) {
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, from));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, to));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, to));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, from));
	  }
	}	  
      }
    }

  } else {
    
    for (i=0; i<n1; i++) {
      for (j=0; j<n2; j++) { 
	long int from, to;
	
	if (MATRIX(*incidence, i, j) != 0) {
	  if (mode == IGRAPH_IN) {
	    from=n1+j;
	    to=i;
	  } else {
	    from=i;
	    to=n1+j;
	  }
	  if (mode != IGRAPH_ALL || !directed) {
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, from));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, to));
	  } else {
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, from));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, to));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, to));
	    IGRAPH_CHECK(igraph_vector_push_back(&edges, from));
	  }	    
	}
      }
    }
    
  }
  
  IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, directed));
  igraph_vector_destroy(&edges); 
  IGRAPH_FINALLY_CLEAN(1);
  IGRAPH_FINALLY(igraph_destroy, graph);
  
  if (types) {
    IGRAPH_CHECK(igraph_vector_bool_resize(types, no_of_nodes));
    igraph_vector_bool_null(types);
    for (i=n1; i<no_of_nodes; i++) {
      VECTOR(*types)[i] = 1;
    }
  }
  
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
コード例 #6
0
ファイル: bipartite.c プロジェクト: FEYoung/rigraph
int igraph_full_bipartite(igraph_t *graph, 
			  igraph_vector_bool_t *types,
			  igraph_integer_t n1, igraph_integer_t n2,
			  igraph_bool_t directed, 
			  igraph_neimode_t mode) {
  
  igraph_integer_t nn1=n1, nn2=n2;
  igraph_integer_t no_of_nodes=nn1+nn2;
  igraph_vector_t edges;
  long int no_of_edges;
  long int ptr=0;
  long int i, j;
  
  if (!directed) {
    no_of_edges=nn1 * nn2;
  } else if (mode==IGRAPH_OUT || mode==IGRAPH_IN) {
    no_of_edges=nn1 * nn2;
  } else { /* mode==IGRAPH_ALL */
    no_of_edges=nn1 * nn2 * 2;
  }

  IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges*2);

  if (!directed || mode==IGRAPH_OUT) {

    for (i=0; i<nn1; i++) {
      for (j=0; j<nn2; j++) {
	VECTOR(edges)[ptr++]=i;
	VECTOR(edges)[ptr++]=nn1+j;
      }
    }
    
  } else if (mode==IGRAPH_IN) {

    for (i=0; i<nn1; i++) {
      for (j=0; j<nn2; j++) {
	VECTOR(edges)[ptr++]=nn1+j;
	VECTOR(edges)[ptr++]=i;
      }
    }
    
  } else {
    
    for (i=0; i<nn1; i++) {
      for (j=0; j<nn2; j++) {
	VECTOR(edges)[ptr++]=i;
	VECTOR(edges)[ptr++]=nn1+j;
	VECTOR(edges)[ptr++]=nn1+j;
	VECTOR(edges)[ptr++]=i;
      }
    }
  }
  
  IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, directed));
  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);
  IGRAPH_FINALLY(igraph_destroy, graph);

  if (types) {
    IGRAPH_CHECK(igraph_vector_bool_resize(types, no_of_nodes));
    igraph_vector_bool_null(types);
    for (i=nn1; i<no_of_nodes; i++) {
      VECTOR(*types)[i] = 1;
    }
  }
  
  IGRAPH_FINALLY_CLEAN(1);
  
  return 0;
}