int main() {
  
  igraph_t g;
  igraph_vector_t y;  

  /* turn on attribute handling */
  igraph_i_set_attribute_table(&igraph_cattribute_table);

  /* Create a graph, add some attributes and save it as a GraphML file */
  igraph_famous(&g, "Petersen");
  SETGAS(&g, "name", "Petersen's graph");
  SETGAN(&g, "vertices", igraph_vcount(&g));
  SETGAN(&g, "edges", igraph_ecount(&g));

  igraph_vector_init_seq(&y, 1, igraph_vcount(&g));
  SETVANV(&g, "id", &y);
  igraph_vector_destroy(&y);

  SETVAS(&g, "name", 0, "foo");
  SETVAS(&g, "name", 1, "foobar");
  
  igraph_vector_init_seq(&y, 1, igraph_ecount(&g));
  SETEANV(&g, "id", &y);
  igraph_vector_destroy(&y);

  SETEAS(&g, "name", 0, "FOO");
  SETEAS(&g, "name", 1, "FOOBAR");

  igraph_write_graph_gml(&g, stdout, 0, "");
  igraph_write_graph_graphml(&g, stdout);
   
  igraph_destroy(&g);
  
  return 0;
}
Example #2
0
int TMIgraph::readTopology(char *file_name) {
    int ret;
    Bitvector *lid;
    Bitvector *ilid;
    ifstream infile;
    string str;
    size_t found, first, second;
    FILE *instream;
    infile.open(file_name, ifstream::in);
    /*first the Global graph attributes - c igraph does not do it!!*/
    while (infile.good()) {
        getline(infile, str);
        found = str.find("<data key=\"FID_LEN\">");
        if (found != string::npos) {
            first = str.find(">");
            second = str.find("<", first);
            sscanf(str.substr(first + 1, second - first - 1).c_str(), "%d", &fid_len);
        }
        found = str.find("<data key=\"TM\">");
        if (found != string::npos) {
            first = str.find(">");
            second = str.find("<", first);
            nodeID = str.substr(first + 1, second - first - 1);
        }

        found = str.find("<data key=\"TM_MODE\">");
        if (found != string::npos) {
            first = str.find(">");
            second = str.find("<", first);
            mode = str.substr(first + 1, second - first - 1);
        }
    }
    infile.close();
    instream = fopen(file_name, "r");
    ret = igraph_read_graph_graphml(&graph, instream, 0);
    fclose(instream);
    if (ret < 0) {
        return ret;
    }
    cout << "TM: " << igraph_vcount(&graph) << " nodes" << endl;
    cout << "TM: " << igraph_ecount(&graph) << " edges" << endl;
    for (int i = 0; i < igraph_vcount(&graph); i++) {
        string nID = string(igraph_cattribute_VAS(&graph, "NODEID", i));
        string iLID = string(igraph_cattribute_VAS(&graph, "iLID", i));
        reverse_node_index.insert(pair<string, int>(nID, i));
        ilid = new Bitvector(iLID);
        nodeID_iLID.insert(pair<string, Bitvector *>(nID, ilid));
        vertex_iLID.insert(pair<int, Bitvector *>(i, ilid));
        //cout << "node " << i << " has NODEID " << nID << endl;
        //cout << "node " << i << " has ILID " << ilid->to_string() << endl;
    }
    for (int i = 0; i < igraph_ecount(&graph); i++) {
        string LID = string(igraph_cattribute_EAS(&graph, "LID", i));
        reverse_edge_index.insert(pair<string, int>(LID, i));
        lid = new Bitvector(LID);
        edge_LID.insert(pair<int, Bitvector *>(i, lid));
        //cout << "edge " << i << " has LID  " << lid->to_string() << endl;
    }
    return ret;
}
int main() {
  
  igraph_t g;
  igraph_vector_t result;
  long i;
  
  igraph_vector_init(&result, 0);

  igraph_small(&g, 7, 0, 0,1,0,2,0,3,1,2,1,3,2,3,3,4,4,5,4,6,5,6, -1);
  igraph_convergence_degree(&g, &result, 0, 0);
  for (i=0; i<igraph_ecount(&g); i++)
    printf("%.4f ", (float)igraph_vector_e(&result, i));
  printf("\n");
  igraph_destroy(&g);

  igraph_small(&g, 6, 1, 1,0,2,0,3,0,4,0,0,5, -1);
  igraph_convergence_degree(&g, &result, 0, 0);
  for (i=0; i<igraph_ecount(&g); i++)
    printf("%.4f ", (float)igraph_vector_e(&result, i));
  printf("\n");
  igraph_destroy(&g);

  igraph_vector_destroy(&result);
  
  return 0;
}
Example #4
0
int main() {

  igraph_t g;
  igraph_vector_t v;
  int ret;
  igraph_es_t es;

  igraph_vector_init(&v, 8);
  VECTOR(v)[0]=0; VECTOR(v)[1]=1;
  VECTOR(v)[2]=1; VECTOR(v)[3]=2;
  VECTOR(v)[4]=2; VECTOR(v)[5]=3;
  VECTOR(v)[6]=2; VECTOR(v)[7]=2;
  igraph_create(&g, &v, 0, 0);
  
  igraph_es_pairs_small(&es, IGRAPH_DIRECTED, 3,2, -1);
  igraph_delete_edges(&g, es);
  if (igraph_ecount(&g) != 3) {
    return 1;
  }

  /* error test, no such edge to delete */
  igraph_set_error_handler(igraph_error_handler_ignore);
  ret=igraph_delete_edges(&g, es);
  if (ret != IGRAPH_EINVAL) {
    printf("Error code: %i\n", ret);
    return 2;
  } 
  if (igraph_ecount(&g) != 3) {
    return 3;
  }

  /* error test, invalid vertex id */
  igraph_es_destroy(&es);
  igraph_es_pairs_small(&es, IGRAPH_DIRECTED, 10,2, -1);
  ret=igraph_delete_edges(&g, es);
  if (ret != IGRAPH_EINVVID) {
    return 4;
  } 
  if (igraph_ecount(&g) != 3) {
    return 5;
  }
  
  /* error test, invalid (odd) length */
  igraph_es_destroy(&es);
  igraph_es_pairs_small(&es, IGRAPH_DIRECTED, 0,1,2, -1);
  ret=igraph_delete_edges(&g, es);
  if (ret != IGRAPH_EINVAL) {
    return 6;
  } 
  if (igraph_ecount(&g) != 3) {
    return 7;
  }  

  igraph_es_destroy(&es);
  igraph_vector_destroy(&v);
  igraph_destroy(&g);
  
  return 0;
}
int main() {
  
  igraph_t g;
  int ret;

  /* empty directed graph, zero vertices */
  igraph_empty(&g, 0, 1);
  if (igraph_vcount(&g) != 0) {
    return 1;
  }
  if (igraph_ecount(&g) != 0) {
    return 2;
  }
  igraph_destroy(&g);
  
  /* empty undirected graph, zero vertices */
  igraph_empty(&g, 0, 0);
  if (igraph_vcount(&g) != 0) {
    return 3;
  }
  if (igraph_ecount(&g) != 0) {
    return 4;
  }
  igraph_destroy(&g);

  /* empty directed graph, 20 vertices */
  igraph_empty(&g, 20, 1);
  if (igraph_vcount(&g) != 20) {
    return 5;
  }
  if (igraph_ecount(&g) != 0) {
    return 6;
  }
  igraph_destroy(&g);
  
  /* empty undirected graph, 30 vertices */
  igraph_empty(&g, 30, 0);
  if (igraph_vcount(&g) != 30) {
    return 7;
  }
  if (igraph_ecount(&g) != 0) {
    return 8;
  }
  igraph_destroy(&g);

  /* error: negative number of vertices */
  igraph_set_error_handler(igraph_error_handler_ignore);
  ret=igraph_empty(&g, -1, 0);
  if (ret != IGRAPH_EINVAL) {
    return 9;
  }

  return 0;
}
int main() {

  igraph_t g;
  igraph_vector_t eb; 

  igraph_small(&g, 0, IGRAPH_UNDIRECTED, 
	       0,  1,  0,  2,  0,  3,  0,  4,  0,  5,
	       0,  6,  0,  7,  0,  8,  0, 10,  0, 11,
	       0, 12,  0, 13,  0, 17,  0, 19,  0, 21,
	       0, 31,  1,  2,  1,  3,  1,  7,  1, 13,
	       1, 17,  1, 19,  1, 21,  1, 30,  2,  3,
	       2,  7,  2,  8,  2,  9,  2, 13,  2, 27,
	       2, 28,  2, 32,  3,  7,  3, 12,  3, 13,
	       4,  6,  4, 10,  5,  6,  5, 10,  5, 16,
	       6, 16,  8, 30,  8, 32,  8, 33,  9, 33,
	       13, 33, 14, 32, 14, 33, 15, 32, 15, 33,
	       18, 32, 18, 33, 19, 33, 20, 32, 20, 33,
	       22, 32, 22, 33, 23, 25, 23, 27, 23, 29,
	       23, 32, 23, 33, 24, 25, 24, 27, 24, 31,
	       25, 31, 26, 29, 26, 33, 27, 33, 28, 31,
	       28, 33, 29, 32, 29, 33, 30, 32, 30, 33,
	       31, 32, 31, 33, 32, 33,
	       -1);
  
  igraph_vector_init(&eb, igraph_ecount(&g));
  igraph_edge_betweenness(&g, &eb, IGRAPH_UNDIRECTED);
  print_vector(&eb, stdout);
  igraph_vector_destroy(&eb);
  igraph_destroy(&g);

  igraph_small(&g, 0, IGRAPH_UNDIRECTED,
    0, 1, 0, 2, 0, 3, 1, 4, -1);
  igraph_vector_init(&eb, igraph_ecount(&g));
  igraph_edge_betweenness_estimate(&g, &eb, IGRAPH_UNDIRECTED, 2);
  print_vector(&eb, stdout);
  igraph_vector_destroy(&eb);
  igraph_destroy(&g);

  igraph_small(&g, 0, IGRAPH_UNDIRECTED,
    0, 1, 0, 3, 1, 2, 1, 4, 2, 5, 3, 4, 3, 6, 4, 5, 4, 7, 5, 8,
    6, 7, 7, 8, -1);
  igraph_vector_init(&eb, igraph_ecount(&g));
  igraph_edge_betweenness_estimate(&g, &eb, IGRAPH_UNDIRECTED, 2);
  print_vector(&eb, stdout);
  igraph_vector_destroy(&eb);
  igraph_destroy(&g);

  return 0;
}
Example #7
0
/**
 * \function igraph_maximum_bipartite_matching
 * Calculates a maximum matching in a bipartite graph.
 *
 * A matching in a bipartite graph is a partial assignment of vertices
 * of the first kind to vertices of the second kind such that each vertex of
 * the first kind is matched to at most one vertex of the second kind and
 * vice versa, and matched vertices must be connected by an edge in the graph.
 * The size (or cardinality) of a matching is the number of edges.
 * A matching is a maximum matching if there exists no other matching with
 * larger cardinality. For weighted graphs, a maximum matching is a matching
 * whose edges have the largest possible total weight among all possible
 * matchings.
 *
 * </para><para>
 * Maximum matchings in bipartite graphs are found by the push-relabel algorithm
 * with greedy initialization and a global relabeling after every n/2 steps where
 * n is the number of vertices in the graph.
 *
 * </para><para>
 * References: Cherkassky BV, Goldberg AV, Martin P, Setubal JC and Stolfi J:
 * Augment or push: A computational study of bipartite matching and
 * unit-capacity flow algorithms. ACM Journal of Experimental Algorithmics 3,
 * 1998.
 *
 * </para><para>
 * Kaya K, Langguth J, Manne F and Ucar B: Experiments on push-relabel-based
 * maximum cardinality matching algorithms for bipartite graphs. Technical
 * Report TR/PA/11/33 of the Centre Europeen de Recherche et de Formation
 * Avancee en Calcul Scientifique, 2011.
 *
 * \param graph The input graph. It can be directed but the edge directions
 *              will be ignored.
 * \param types Boolean vector giving the vertex types of the graph.
 * \param matching_size The size of the matching (i.e. the number of matched
 *                      vertex pairs will be returned here). It may be \c NULL
 *                      if you don't need this.
 * \param matching_weight The weight of the matching if the edges are weighted,
 *                        or the size of the matching again if the edges are
 *                        unweighted. It may be \c NULL if you don't need this.
 * \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 weights A null pointer (=no edge weights), or a vector giving the
 *                weights of the edges. Note that the algorithm is stable
 *                only for integer weights.
 * \param eps A small real number used in equality tests in the weighted
 *            bipartite matching algorithm. Two real numbers are considered
 *            equal in the algorithm if their difference is smaller than
 *            \c eps. This is required to avoid the accumulation of numerical
 *            errors. It is advised to pass a value derived from the
 *            \c DBL_EPSILON constant in \c float.h here. If you are
 *            running the algorithm with no \c weights vector, this argument
 *            is ignored.
 * \return Error code.
 *
 * Time complexity: O(sqrt(|V|) |E|) for unweighted graphs (according to the
 * technical report referenced above), O(|V||E|) for weighted graphs.
 * 
 * \example examples/simple/igraph_maximum_bipartite_matching.c
 */
int igraph_maximum_bipartite_matching(const igraph_t* graph,
    const igraph_vector_bool_t* types, igraph_integer_t* matching_size,
    igraph_real_t* matching_weight, igraph_vector_long_t* matching,
    const igraph_vector_t* weights, igraph_real_t eps) {

  /* Sanity checks */
  if (igraph_vector_bool_size(types) < igraph_vcount(graph)) {
    IGRAPH_ERROR("types vector too short", IGRAPH_EINVAL);
  }
  if (weights && igraph_vector_size(weights) < igraph_ecount(graph)) {
    IGRAPH_ERROR("weights vector too short", IGRAPH_EINVAL);
  }

  if (weights == 0) {
    IGRAPH_CHECK(igraph_i_maximum_bipartite_matching_unweighted(graph, types,
        matching_size, matching));
    if (matching_weight != 0) {
      *matching_weight = *matching_size;
    }
    return IGRAPH_SUCCESS;
  } else {
    return igraph_i_maximum_bipartite_matching_weighted(graph, types,
        matching_size, matching_weight, matching, weights, eps);
  }
}
void test_unweighted() {
  igraph_t g;
  igraph_vector_t edges, eb;
  long int i;
  long int no_of_edges;

  /* Zachary Karate club */
  igraph_small(&g, 0, IGRAPH_UNDIRECTED, 
	       0,  1,  0,  2,  0,  3,  0,  4,  0,  5,
	       0,  6,  0,  7,  0,  8,  0, 10,  0, 11,
	       0, 12,  0, 13,  0, 17,  0, 19,  0, 21,
	       0, 31,  1,  2,  1,  3,  1,  7,  1, 13,
	       1, 17,  1, 19,  1, 21,  1, 30,  2,  3,
	       2,  7,  2,  8,  2,  9,  2, 13,  2, 27,
	       2, 28,  2, 32,  3,  7,  3, 12,  3, 13,
	       4,  6,  4, 10,  5,  6,  5, 10,  5, 16,
	       6, 16,  8, 30,  8, 32,  8, 33,  9, 33,
	       13, 33, 14, 32, 14, 33, 15, 32, 15, 33,
	       18, 32, 18, 33, 19, 33, 20, 32, 20, 33,
	       22, 32, 22, 33, 23, 25, 23, 27, 23, 29,
	       23, 32, 23, 33, 24, 25, 24, 27, 24, 31,
	       25, 31, 26, 29, 26, 33, 27, 33, 28, 31,
	       28, 33, 29, 32, 29, 33, 30, 32, 30, 33,
	       31, 32, 31, 33, 32, 33,
	       -1);  
  
  igraph_vector_init(&edges, 0);
  igraph_vector_init(&eb, 0);
  igraph_community_edge_betweenness(&g, &edges, &eb, 0 /*merges */,
				    0 /*bridges */, /*modularity=*/ 0,
				    /*membership=*/ 0,
				    IGRAPH_UNDIRECTED,
				    /*weights=*/ 0);
  
  no_of_edges=igraph_ecount(&g);
  for (i=0; i<no_of_edges; i++) {
    printf("%li ", (long int)VECTOR(edges)[i]);
  }
  printf("\n");
  
  for (i=0; i<no_of_edges; i++) {
    printf("%.2f ", VECTOR(eb)[i]);
  }
  printf("\n");

  /* Try it once again without storage space for edges */
  igraph_community_edge_betweenness(&g, 0, &eb, 0 /*merges */,
				    0 /*bridges */, /*modularity=*/ 0,
				    /*membership=*/ 0,
				    IGRAPH_UNDIRECTED,
				    /*weights=*/ 0);
  for (i=0; i<no_of_edges; i++) {
    printf("%.2f ", VECTOR(eb)[i]);
  }
  printf("\n");

  igraph_vector_destroy(&eb);
  igraph_vector_destroy(&edges);
  igraph_destroy(&g);
}
Example #9
0
/**
 * \ingroup python_interface_edge
 * \brief Checks whether the index in the given edge object is a valid one.
 * \return nonzero if the edge object is valid. Raises an appropriate Python
 *   exception and returns zero if the edge object is invalid.
 */
int igraphmodule_Edge_Validate(PyObject* obj) {
  igraph_integer_t n;
  igraphmodule_EdgeObject *self;
  igraphmodule_GraphObject *graph;

  if (!igraphmodule_Edge_Check(obj)) {
    PyErr_SetString(PyExc_TypeError, "object is not an Edge");
    return 0;
  }

  self = (igraphmodule_EdgeObject*)obj;
  graph = self->gref;

  if (graph == 0) {
    PyErr_SetString(PyExc_ValueError, "Edge object refers to a null graph");
    return 0;
  }

  if (self->idx < 0) {
    PyErr_SetString(PyExc_ValueError, "Edge object refers to a negative edge index");
    return 0;
  }

  n = igraph_ecount(&graph->g);

  if (self->idx >= n) {
    PyErr_SetString(PyExc_ValueError, "Edge object refers to a nonexistent edge");
    return 0;
  }

  return 1;
}
/**
 * \ingroup interface
 * \function igraph_add_vertices
 * \brief Adds vertices to a graph. 
 *
 * </para><para>
 * This function invalidates all iterators.
 *
 * \param graph The graph object to extend.
 * \param nv Non-negative integer giving the number of 
 *           vertices to add.
 * \param attr The attributes of the new vertices, only used by 
 *           high level interfaces, you can supply 0 here.
 * \return Error code: 
 *         \c IGRAPH_EINVAL: invalid number of new
 *         vertices. 
 *
 * Time complexity: O(|V|) where
 * |V| is 
 * the number of vertices in the \em new, extended graph.
 */
int igraph_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr) {
  long int ec=igraph_ecount(graph);
  long int i;

  if (nv < 0) {
    IGRAPH_ERROR("cannot add negative number of vertices", IGRAPH_EINVAL);
  }

  IGRAPH_CHECK(igraph_vector_reserve(&graph->os, graph->n+nv+1));
  IGRAPH_CHECK(igraph_vector_reserve(&graph->is, graph->n+nv+1));
  
  igraph_vector_resize(&graph->os, graph->n+nv+1); /* reserved */
  igraph_vector_resize(&graph->is, graph->n+nv+1); /* reserved */
  for (i=graph->n+1; i<graph->n+nv+1; i++) {
    VECTOR(graph->os)[i]=ec;
    VECTOR(graph->is)[i]=ec;
  }
  
  graph->n += nv;   
  
  if (graph->attr) {
    IGRAPH_CHECK(igraph_i_attribute_add_vertices(graph, nv, attr));
  }

  return 0;
}
Example #11
0
static inline void
rvine_tree_cleanup(igraph_t *tree)
{
    igraph_integer_t e, a;

    for (a = 0; a < igraph_vcount(tree); a++) {
        if (VAP(tree, "h", a) != VAP(tree, "hrev", a)) {
            gsl_vector_free(VAP(tree, "h", a));
            gsl_vector_free(VAP(tree, "hrev", a));
            gsl_permutation_free(VAP(tree, "hrank", a));
            gsl_permutation_free(VAP(tree, "hrevrank", a));
        } else if (VAP(tree, "h", a) != NULL) {
            gsl_vector_free(VAP(tree, "h", a));
            gsl_permutation_free(VAP(tree, "hrank", a));
        } else {
            gsl_vector_free(VAP(tree, "hrev", a));
            gsl_permutation_free(VAP(tree, "hrevrank", a));
        }
    }
    DELVAS(tree);

    for (e = 0; e < igraph_ecount(tree); e++) {
        gsl_vector_short_free(EAP(tree, "Ue", e));
        dml_measure_free(EAP(tree, "measure", e));
    }
    DELEA(tree, "Ue");
    DELEA(tree, "weight");
    DELEA(tree, "measure");
}
Example #12
0
void dump_graph(const char* header, const igraph_t* g) {
  fputs(header, stdout);
  printf("Vertices: %li\n", (long int) igraph_vcount(g));
  printf("Edges: %li\n", (long int) igraph_ecount(g));
  printf("Directed: %i\n", (int) igraph_is_directed(g));
  igraph_write_graph_edgelist(g, stdout);
}
int igraph_get_edgelist(const igraph_t *graph, igraph_vector_t *res, igraph_bool_t bycol) {

  igraph_eit_t edgeit;
  long int no_of_edges=igraph_ecount(graph);
  long int vptr=0;
  igraph_integer_t from, to;
  
  IGRAPH_CHECK(igraph_vector_resize(res, no_of_edges*2));
  IGRAPH_CHECK(igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID),
				 &edgeit));
  IGRAPH_FINALLY(igraph_eit_destroy, &edgeit);
  
  if (bycol) {
    while (!IGRAPH_EIT_END(edgeit)) {
      igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &from, &to);
      VECTOR(*res)[vptr]=from;
      VECTOR(*res)[vptr+no_of_edges]=to;
      vptr++;
      IGRAPH_EIT_NEXT(edgeit);
    }
  } else {
    while (!IGRAPH_EIT_END(edgeit)) {
      igraph_edge(graph, IGRAPH_EIT_GET(edgeit), &from, &to);
      VECTOR(*res)[vptr++]=from;
      VECTOR(*res)[vptr++]=to;
      IGRAPH_EIT_NEXT(edgeit);
    }
  }
  
  igraph_eit_destroy(&edgeit);
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
Example #14
0
/** \ingroup python_interface_edge
 * \brief Sets the corresponding value of a given attribute of the edge
 * \param self the edge object
 * \param k the attribute name to be set
 * \param v the value to be set
 * \return 0 if everything's ok, -1 in case of error
 */
int igraphmodule_Edge_set_attribute(igraphmodule_EdgeObject* self, PyObject* k, PyObject* v) {
  igraphmodule_GraphObject *o=self->gref;
  PyObject* result;
  int r;
  
  if (o==0) return -1;

  if (v==NULL)
    // we are deleting attribute
    return PyDict_DelItem(((PyObject**)o->g.attr)[2], k);
  
  result=PyDict_GetItem(((PyObject**)o->g.attr)[2], k);
  if (result) {
    /* result is a list, so set the element with index self->idx */
    if (!PyList_Check(result)) {
      PyErr_SetString(igraphmodule_InternalError, "Vertex attribute dict member is not a list");
      return -1;
    }
    /* we actually don't own a reference here to v, so we must increase
     * its reference count, because PyList_SetItem will "steal" a reference!
     * It took me 1.5 hours between London and Manchester to figure it out */
    Py_INCREF(v);
    r=PyList_SetItem(result, self->idx, v);
    if (r == -1) { Py_DECREF(v); }
    return r;
  }
  
  /* result is NULL, check whether there was an error */
  if (!PyErr_Occurred()) {
    /* no, there wasn't, so we must simply add the attribute */
    int n=(int)igraph_ecount(&o->g), i;
    result=PyList_New(n);
    for (i=0; i<n; i++) {
      if (i != self->idx) {
    Py_INCREF(Py_None);
    if (PyList_SetItem(result, i, Py_None) == -1) {
      Py_DECREF(Py_None);
      Py_DECREF(result);
      return -1;
    }
      } else {
    /* Same game with the reference count here */
    Py_INCREF(v);
    if (PyList_SetItem(result, i, v) == -1) {
      Py_DECREF(v);
      Py_DECREF(result);
      return -1;
    }
      }
    }
    if (PyDict_SetItem(((PyObject**)o->g.attr)[2], k, result) == -1) {
      Py_DECREF(result); /* TODO: is it needed here? maybe not! */
      return -1;
    }
    Py_DECREF(result); /* compensating for PyDict_SetItem */
    return 0;
  }
  
  return -1;
}
int GraphRepresentation::buildIGraphTopology() {
    int source_vertex_id, destination_vertex_id;
    igraph_i_set_attribute_table(&igraph_cattribute_table);
    igraph_empty(&igraph, 0, true);
    //cout << "iGraph: number of nodes: " << dm->number_of_nodes << endl;
    //cout << "iGraph: number number_of_connections nodes: " << dm->number_of_connections << endl;
    for (int i = 0; i < dm->network_nodes.size(); i++) {
        NetworkNode *nn = dm->network_nodes[i];
        for (int j = 0; j < nn->connections.size(); j++) {
            NetworkConnection *nc = nn->connections[j];
            map <string, int>::iterator index_it;
            /*find that node - if exists*/
            index_it = reverse_node_index.find(nc->src_label);
            /*check if the source node exists in the reverse index*/
            if (index_it == reverse_node_index.end()) {
                /*it does not exist...add it*/
                source_vertex_id = igraph_vcount(&igraph);
                igraph_add_vertices(&igraph, 1, 0);
                reverse_node_index.insert(pair<string, int>(nc->src_label, source_vertex_id));
                igraph_cattribute_VAS_set(&igraph, "NODEID", source_vertex_id, nc->src_label.c_str());
                //cout << "added node " << nc->src_label << " in the igraph" << endl;
            } else {
                source_vertex_id = (*index_it).second;
            }
            index_it = reverse_node_index.find(nc->dst_label);
            /*check if the destination node exists in the reverse index*/
            if (index_it == reverse_node_index.end()) {
                /*it does not exist...add it*/
                destination_vertex_id = igraph_vcount(&igraph);
                igraph_add_vertices(&igraph, 1, 0);
                reverse_node_index.insert(pair<string, int>(nc->dst_label, destination_vertex_id));
                igraph_cattribute_VAS_set(&igraph, "NODEID", destination_vertex_id, nc->dst_label.c_str());
                //cout << "added node " << nc->dst_label << " in the igraph" << endl;
            } else {
                destination_vertex_id = (*index_it).second;
            }
            /*add an edge in the graph*/
            igraph_add_edge(&igraph, source_vertex_id, destination_vertex_id);
            igraph_cattribute_EAS_set(&igraph, "LID", igraph_ecount(&igraph) - 1, nc->LID.to_string().c_str());
            reverse_edge_index.insert(pair<string, int>(nc->LID.to_string(), igraph_ecount(&igraph) - 1));
        }
    }
    for (int i = 0; i < dm->network_nodes.size(); i++) {
        NetworkNode *nn = dm->network_nodes[i];
        igraph_cattribute_VAS_set(&igraph, "iLID", i, nn->iLid.to_string().c_str());
    }
}
Example #16
0
/**
 * \ingroup python_interface_edgeseq
 * \brief Initialize a new edge sequence object for a given graph
 * \return the initialized PyObject
 */
int igraphmodule_EdgeSeq_init(igraphmodule_EdgeSeqObject *self,
  PyObject *args, PyObject *kwds) {
  static char *kwlist[] = { "graph", "edges", NULL };
  PyObject *g, *esobj=Py_None;
  igraph_es_t es;

  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|O", kwlist,
    &igraphmodule_GraphType, &g, &esobj))
      return -1;

  if (esobj == Py_None) {
    /* If es is None, we are selecting all the edges */
    igraph_es_all(&es, IGRAPH_EDGEORDER_ID);
  } else if (PyInt_Check(esobj)) {
    /* We selected a single edge */
    long int idx = PyInt_AsLong(esobj);
    if (idx < 0 || idx >= igraph_ecount(&((igraphmodule_GraphObject*)g)->g)) {
      PyErr_SetString(PyExc_ValueError, "edge index out of range");
      return -1;
    }
    igraph_es_1(&es, (igraph_integer_t)idx);
  } else {
	/* We selected multiple edges */
    igraph_vector_t v;
    igraph_integer_t n = igraph_ecount(&((igraphmodule_GraphObject*)g)->g);
    if (igraphmodule_PyObject_to_vector_t(esobj, &v, 1))
      return -1;
    if (!igraph_vector_isininterval(&v, 0, n-1)) {
      igraph_vector_destroy(&v);
      PyErr_SetString(PyExc_ValueError, "edge index out of range");
      return -1;
    }
    if (igraph_es_vector_copy(&es, &v)) {
      igraphmodule_handle_igraph_error();
      igraph_vector_destroy(&v);
      return -1;
    }
    igraph_vector_destroy(&v);
  }

  self->es = es;
  Py_INCREF(g);
  self->gref = (igraphmodule_GraphObject*)g;

  return 0;
}
Example #17
0
void print_edges(const igraph_t *graph) {
    long ecount = igraph_ecount(graph);
    long i;

    for (i=0; i < ecount; ++i)
        printf("%d %d\n", IGRAPH_FROM(graph, i), IGRAPH_TO(graph, i));
    printf("\n");
}
Example #18
0
int main() {
  
  igraph_t g;
  /* long int i; */
  /* struct tms time; */
  /* clock_t current_time,start_time; */
  /* long int runs=100, n=10000; */
  /* igraph_real_t r=0.01; */
  
  /* Empty graph */
  igraph_grg_game(&g, 100, 0, 0, 0, 0);
  if (igraph_ecount(&g) != 0) {
    return 1;
  }
  igraph_destroy(&g);
  
  /* Full graph */
  igraph_grg_game(&g, 10, sqrt(2.0)/2, 1, 0, 0);
  if (igraph_ecount(&g) != igraph_vcount(&g) * (igraph_vcount(&g)-1)/2) {
    return 2;
  }
  igraph_destroy(&g);

  /* Measure running time */
/*   tps=sysconf(_SC_CLK_TCK); // clock ticks per second  */
/*   times(&time); start_time=time.tms_utime; */
/*   for (i=0; i<runs; i++) { */
/*     igraph_grg_game2(&g, n, r, 1);  */
/*     igraph_destroy(&g); */
/*   } */
/*   times(&time); current_time=time.tms_utime; */
/*   fprintf(stdout,"    sorted: time=%.3fs\n",(current_time-start_time)/(double)tps); */

/*   tps=sysconf(_SC_CLK_TCK); // clock ticks per second  */
/*   times(&time); start_time=time.tms_utime; */
/*   for (i=0; i<runs; i++) { */
/*     igraph_grg_game(&g, n, r, 1); */
/*     igraph_destroy(&g); */
/*   } */
/*   times(&time); current_time=time.tms_utime; */
/*   fprintf(stdout,"non-sorted: time=%.3fs\n", */
/* 	  (current_time-start_time)/(double)tps); */


  return 0;
}
Example #19
0
int main()
{
	igraph_t *g;
	gsl_rng *r;

	r = gsl_rng_alloc(gsl_rng_mt19937);
	assert(r != NULL);

	// all ggen methods return NULL on invalid parameters
	assert(ggen_generate_erdos_lbl(NULL,10,0.5,5) == NULL); // no rng
	assert(ggen_generate_erdos_lbl(r,10,-1,5) == NULL); // wrong p
	assert(ggen_generate_erdos_lbl(r,10,2,5) == NULL); // wrong p
	assert(ggen_generate_erdos_lbl(r,10,0.5,20) == NULL); // wrong nbl
	assert(ggen_generate_erdos_lbl(r,10,0.5,0) == NULL); // wrong nbl

	// if nbl equals one the graph should have zero edges
	g = ggen_generate_erdos_lbl(r,10,0.5,1);
	assert(g != NULL);
	assert(igraph_ecount(g) == 0);
	igraph_destroy(g);
	free((void *)g);

	// if p equals zero the graph should have zero edges
	g = ggen_generate_erdos_lbl(r,10,0,10);
	assert(g != NULL);
	assert(igraph_ecount(g) == 0);
	igraph_destroy(g);
	free((void *)g);

	// if p equals one the graph should have nbl*(nbl-1)/2 edges
	g = ggen_generate_erdos_lbl(r,10,1,10);
	assert(g != NULL);
	assert(igraph_ecount(g) == 45);
	igraph_destroy(g);
	free((void *)g);

	// a "normal" call should work too
	g = ggen_generate_erdos_lbl(r,10,0.5,5);
	assert(g != NULL);
	igraph_destroy(g);
	free((void *)g);

	gsl_rng_free(r);
	return 0;
}
Example #20
0
int igraph_disjoint_union_many(igraph_t *res, 
			       const igraph_vector_ptr_t *graphs) {
  long int no_of_graphs=igraph_vector_ptr_size(graphs);
  igraph_bool_t directed=1;
  igraph_vector_t edges;
  long int no_of_edges=0;
  long int shift=0;
  igraph_t *graph;
  long int i, j;
  igraph_integer_t from, to;
  
  if (no_of_graphs != 0) {
    graph=VECTOR(*graphs)[0];
    directed=igraph_is_directed(graph);
    for (i=0; i<no_of_graphs; i++) {      
      graph=VECTOR(*graphs)[i];
      no_of_edges += igraph_ecount(graph);
      if (directed != igraph_is_directed(graph)) {
	IGRAPH_ERROR("Cannot union directed and undirected graphs", 
		     IGRAPH_EINVAL);
      }
    }
  }
  
  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
  IGRAPH_CHECK(igraph_vector_reserve(&edges, 2*no_of_edges));
  
  for (i=0; i<no_of_graphs; i++) {
    long int ec;
    graph=VECTOR(*graphs)[i];    
    ec=igraph_ecount(graph);
    for (j=0; j<ec; j++) {
      igraph_edge(graph, (igraph_integer_t) j, &from, &to);
      igraph_vector_push_back(&edges, from+shift);
      igraph_vector_push_back(&edges, to+shift);
    }
    shift += igraph_vcount(graph);
  }
  
  IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) shift, directed));
  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
Example #21
0
/* removes multiple edges and returns new edge id's for each edge in |E|log|E| */
int igraph_i_multilevel_simplify_multiple(igraph_t *graph, igraph_vector_t *eids) {
  long int ecount = igraph_ecount(graph);
  long int i, l = -1, last_from = -1, last_to = -1;
  igraph_bool_t directed = igraph_is_directed(graph);
  igraph_integer_t from, to;
  igraph_vector_t edges;
  igraph_i_multilevel_link *links;

  /* Make sure there's enough space in eids to store the new edge IDs */
  IGRAPH_CHECK(igraph_vector_resize(eids, ecount));

  links = igraph_Calloc(ecount, igraph_i_multilevel_link);
  if (links == 0) {
    IGRAPH_ERROR("multi-level community structure detection failed", IGRAPH_ENOMEM);
  }
  IGRAPH_FINALLY(free, links);

  for (i = 0; i < ecount; i++) {
    igraph_edge(graph, (igraph_integer_t) i, &from, &to);
    links[i].from = from;
    links[i].to = to;
    links[i].id = i;
  }  

  qsort((void*)links, (size_t) ecount, sizeof(igraph_i_multilevel_link),
      igraph_i_multilevel_link_cmp);

  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
  for (i = 0; i < ecount; i++) {
    if (links[i].from == last_from && links[i].to == last_to) {
      VECTOR(*eids)[links[i].id] = l;
      continue;
    }

    last_from = links[i].from;
    last_to = links[i].to;

    igraph_vector_push_back(&edges, last_from);
    igraph_vector_push_back(&edges, last_to);

    l++;

    VECTOR(*eids)[links[i].id] = l;
  }

  free(links);
  IGRAPH_FINALLY_CLEAN(1);

  igraph_destroy(graph);
  IGRAPH_CHECK(igraph_create(graph, &edges, igraph_vcount(graph), directed));

  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
Example #22
0
int main()
{
	igraph_t *g;
	gsl_rng *r;

	r = gsl_rng_alloc(gsl_rng_mt19937);
	assert(r != NULL);

	// all ggen methods return NULL on invalid parameters
	assert(ggen_generate_erdos_gnp(r,10,-1) == NULL);
	assert(ggen_generate_erdos_gnp(r,10,2) == NULL);
	assert(ggen_generate_erdos_gnp(NULL,10,0.5) == NULL);

	// if p equals zero the graph should have zero edges
	g = ggen_generate_erdos_gnp(r,10,0);
	assert(g != NULL);
	assert(igraph_ecount(g) == 0);
	igraph_destroy(g);
	free((void *)g);

	// if p equals one the graph should have n*(n-1)/2 edges
	g = ggen_generate_erdos_gnp(r,10,1);
	assert(g != NULL);
	assert(igraph_ecount(g) == 45);
	igraph_destroy(g);
	free((void *)g);

	// if n equals zero everything should still work (even if that doesn't make sense)
	g = ggen_generate_erdos_gnp(r,0,0.5);
	assert(g != NULL);
	assert(igraph_vcount(g) == 0);
	igraph_destroy(g);
	free((void *)g);

	// a "normal" call should word too
	g = ggen_generate_erdos_gnp(r,10,0.5);
	assert(g != NULL);
	igraph_destroy(g);
	free((void *)g);

	gsl_rng_free(r);
	return 0;
}
Example #23
0
void iterate(igraph_t *graph, double th)
{
    igraph_integer_t x, y, z = -1.0, xy;
    
    xy = rand() % (int) igraph_ecount(graph);
    igraph_edge(graph, xy, &x, &y);

    //flip increasing orientation with pr 1/2
    if(rand() % 2)
    {
        igraph_integer_t buffer = y;
        y = x;
        x = buffer;
    }

    igraph_vector_t degrees;
    igraph_vector_init(&degrees, 1); 
    all_degrees(graph, &degrees);


    double d_mean = get_d_mean(graph);
    double random = 1.0 * rand() / RAND_MAX;
    int w;
    double total = 0.0;
    double denom = get_denom(graph, &degrees, th, x, y); 

    for(w = 0; w < igraph_vector_size(&degrees); w++)
    {
        if(w != (int) x && w != (int) y)
        {
            total += f(VECTOR(degrees)[w], d_mean, th) / denom; 

            if(random < total)
            {
                z = (igraph_integer_t) w;
                break;
            }
        }
    }

    igraph_vector_destroy(&degrees);

    if(z > -.5)
    {
        igraph_es_t es;

        igraph_es_1(&es, xy);
        igraph_delete_edges(graph, es);
        igraph_es_destroy(&es);

        igraph_add_edge(graph, x, z);
    } 
}
Example #24
0
int igraph_disjoint_union(igraph_t *res, const igraph_t *left, 
			  const igraph_t *right) {

  long int no_of_nodes_left=igraph_vcount(left);
  long int no_of_nodes_right=igraph_vcount(right);
  long int no_of_edges_left=igraph_ecount(left);
  long int no_of_edges_right=igraph_ecount(right);
  igraph_vector_t edges;
  igraph_bool_t directed_left=igraph_is_directed(left);
  igraph_integer_t from, to;
  long int i;
  
  if (directed_left != igraph_is_directed(right)) {
    IGRAPH_ERROR("Cannot union directed and undirected graphs",
		 IGRAPH_EINVAL);
  }

  IGRAPH_VECTOR_INIT_FINALLY(&edges, 0);
  IGRAPH_CHECK(igraph_vector_reserve(&edges, 
				     2*(no_of_edges_left+no_of_edges_right)));
  for (i=0; i<no_of_edges_left; i++) {
    igraph_edge(left, (igraph_integer_t) i, &from, &to);
    igraph_vector_push_back(&edges, from);
    igraph_vector_push_back(&edges, to);
  }
  for (i=0; i<no_of_edges_right; i++) {
    igraph_edge(right, (igraph_integer_t) i, &from, &to);
    igraph_vector_push_back(&edges, from+no_of_nodes_left);
    igraph_vector_push_back(&edges, to+no_of_nodes_left);
  }
  
  IGRAPH_CHECK(igraph_create(res, &edges, (igraph_integer_t) 
			     (no_of_nodes_left+no_of_nodes_right), 
			     directed_left));
  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);
  return 0;
}
int main() {
  
  igraph_t g;
  igraph_vector_t edges, eb;
  long int i;
  long int no_of_edges;

  /* Zachary Karate club */
  igraph_small(&g, 0, IGRAPH_UNDIRECTED, 
	       0,  1,  0,  2,  0,  3,  0,  4,  0,  5,
	       0,  6,  0,  7,  0,  8,  0, 10,  0, 11,
	       0, 12,  0, 13,  0, 17,  0, 19,  0, 21,
	       0, 31,  1,  2,  1,  3,  1,  7,  1, 13,
	       1, 17,  1, 19,  1, 21,  1, 30,  2,  3,
	       2,  7,  2,  8,  2,  9,  2, 13,  2, 27,
	       2, 28,  2, 32,  3,  7,  3, 12,  3, 13,
	       4,  6,  4, 10,  5,  6,  5, 10,  5, 16,
	       6, 16,  8, 30,  8, 32,  8, 33,  9, 33,
	       13, 33, 14, 32, 14, 33, 15, 32, 15, 33,
	       18, 32, 18, 33, 19, 33, 20, 32, 20, 33,
	       22, 32, 22, 33, 23, 25, 23, 27, 23, 29,
	       23, 32, 23, 33, 24, 25, 24, 27, 24, 31,
	       25, 31, 26, 29, 26, 33, 27, 33, 28, 31,
	       28, 33, 29, 32, 29, 33, 30, 32, 30, 33,
	       31, 32, 31, 33, 32, 33,
	       -1);  
  
  igraph_vector_init(&edges, 0);
  igraph_vector_init(&eb, 0);
  igraph_community_edge_betweenness(&g, &edges, &eb, 0 /*merges */,
				    0 /*bridges */,
				    IGRAPH_UNDIRECTED);
  
  no_of_edges=igraph_ecount(&g);
  for (i=0; i<no_of_edges; i++) {
    printf("%li ", (long int)VECTOR(edges)[i]);
  }
  printf("\n");
  
  for (i=0; i<no_of_edges; i++) {
    printf("%.2f ", VECTOR(eb)[i]);
  }
  printf("\n");

  igraph_vector_destroy(&eb);
  igraph_vector_destroy(&edges);
  igraph_destroy(&g);
  
  return 0;
}
int main() {

  igraph_t g;
  igraph_vector_t v;
  int ret;

  /* without edges */
  igraph_empty(&g, 5, IGRAPH_DIRECTED);
  igraph_add_vertices(&g, 2, 0);
  igraph_add_vertices(&g, 3, 0);
  igraph_add_vertices(&g, 1, 0);
  igraph_add_vertices(&g, 4, 0);
  if (igraph_vcount(&g) != 15)  {
    return 1;
  }
  igraph_delete_vertices(&g, igraph_vss_1(2));
  if (igraph_vcount(&g) != 14)  {
    return 2;
  }
  igraph_destroy(&g);
   
  igraph_vector_init(&v, 8);
  VECTOR(v)[0]=0; VECTOR(v)[1]=1;
  VECTOR(v)[2]=1; VECTOR(v)[3]=2;
  VECTOR(v)[4]=2; VECTOR(v)[5]=3;
  VECTOR(v)[6]=2; VECTOR(v)[7]=2;
  igraph_create(&g, &v, 0, 0);
  igraph_vector_destroy(&v);

  /* resize vector */
  igraph_delete_vertices(&g, igraph_vss_1(2));
  if (igraph_vcount(&g) != 3) {
    return 3;
  }
  if (igraph_ecount(&g) != 1) {
    return 4;
  }

  /* error test */
  igraph_set_error_handler(igraph_error_handler_ignore);
  ret=igraph_delete_vertices(&g, igraph_vss_1(3));
  if (ret != IGRAPH_EINVVID) {
    return 5;
  }
  
  igraph_destroy(&g);

  return 0;
}
Example #27
0
int main() {
    igraph_t graph;
    igraph_vector_t walk, weights;
    igraph_integer_t ec, i;

    igraph_rng_seed(igraph_rng_default(), 137);

    igraph_vector_init(&walk, 0);
    igraph_vector_init(&weights, 0);

    /* This directed graph has loop edges.
       It also has multi-edges when considered as undirected. */
    igraph_de_bruijn(&graph, 3, 2);
    ec = igraph_ecount(&graph);

    /* unweighted, directed */
    igraph_random_edge_walk(&graph, NULL, &walk, 0, IGRAPH_OUT, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    /* unweighted, undirected */
    igraph_random_edge_walk(&graph, NULL, &walk, 0, IGRAPH_ALL, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    igraph_vector_resize(&weights, ec);
    for (i=0; i < ec; ++i)
        VECTOR(weights)[i] = igraph_rng_get_unif01(igraph_rng_default());

    /* weighted, directed */
    igraph_random_edge_walk(&graph, &weights, &walk, 0, IGRAPH_OUT, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    /* weighted, undirecetd */
    igraph_random_edge_walk(&graph, &weights, &walk, 0, IGRAPH_ALL, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 1000);

    igraph_destroy(&graph);

    /* 1-vertex graph, should get stuck */
    igraph_empty(&graph, 1, /* directed = */ 0);
    igraph_random_edge_walk(&graph, NULL, &walk, 0, IGRAPH_OUT, 1000, IGRAPH_RANDOM_WALK_STUCK_RETURN);
    assert(igraph_vector_size(&walk) == 0);
    igraph_destroy(&graph);

    igraph_vector_destroy(&weights);
    igraph_vector_destroy(&walk);

    return 0;
}
void print(igraph_t *g) {
  igraph_vector_t el;
  long int i, j, n;
  char ch = igraph_is_directed(g) ? '>' : '-';

  igraph_vector_init(&el, 0);
  igraph_get_edgelist(g, &el, 0);
  n = igraph_ecount(g);

  for (i=0, j=0; i<n; i++, j+=2) {
    printf("%ld --%c %ld: %ld\n",
      (long)VECTOR(el)[j], ch, (long)VECTOR(el)[j+1], (long)EAN(g, "weight", i)); 
  }
  printf("\n");

  igraph_vector_destroy(&el);
}
Example #29
0
/* Shrinks communities into single vertices, keeping all the edges.
 * This method is internal because it destroys the graph in-place and
 * creates a new one -- this is fine for the multilevel community
 * detection where a copy of the original graph is used anyway.
 * The membership vector will also be rewritten by the underlying
 * igraph_membership_reindex call */
int igraph_i_multilevel_shrink(igraph_t *graph, igraph_vector_t *membership) {
  igraph_vector_t edges;
  long int no_of_nodes = igraph_vcount(graph);
  long int no_of_edges = igraph_ecount(graph);
  igraph_bool_t directed = igraph_is_directed(graph);

  long int i;
  igraph_eit_t eit;

  if (no_of_nodes == 0)
    return 0;

  if (igraph_vector_size(membership) < no_of_nodes) {
    IGRAPH_ERROR("cannot shrink graph, membership vector too short",
        IGRAPH_EINVAL);
  }

  IGRAPH_VECTOR_INIT_FINALLY(&edges, no_of_edges * 2);

  IGRAPH_CHECK(igraph_reindex_membership(membership, 0));

  /* Create the new edgelist */
  igraph_eit_create(graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &eit);
  IGRAPH_FINALLY(igraph_eit_destroy, &eit);
  i = 0;
  while (!IGRAPH_EIT_END(eit)) {
    igraph_integer_t from, to;
    IGRAPH_CHECK(igraph_edge(graph, IGRAPH_EIT_GET(eit), &from, &to));
    VECTOR(edges)[i++] = VECTOR(*membership)[(long int) from];
    VECTOR(edges)[i++] = VECTOR(*membership)[(long int) to];
    IGRAPH_EIT_NEXT(eit);
  }
  igraph_eit_destroy(&eit);
  IGRAPH_FINALLY_CLEAN(1);

  /* Create the new graph */
  igraph_destroy(graph);
  no_of_nodes = (long int) igraph_vector_max(membership)+1;
  IGRAPH_CHECK(igraph_create(graph, &edges, (igraph_integer_t) no_of_nodes,
			     directed));

  igraph_vector_destroy(&edges);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
int main() {
  
  igraph_t g, tree;
  igraph_vector_t eb, edges;
  long int i;
  
  igraph_small(&g, 0, IGRAPH_UNDIRECTED, 
	       0,  1,  0,  2,  0,  3,  0,  4,  0,  5,
	       0,  6,  0,  7,  0,  8,  0, 10,  0, 11,
	       0, 12,  0, 13,  0, 17,  0, 19,  0, 21,
	       0, 31,  1,  2,  1,  3,  1,  7,  1, 13,
	       1, 17,  1, 19,  1, 21,  1, 30,  2,  3,
	       2,  7,  2,  8,  2,  9,  2, 13,  2, 27,
	       2, 28,  2, 32,  3,  7,  3, 12,  3, 13,
	       4,  6,  4, 10,  5,  6,  5, 10,  5, 16,
	       6, 16,  8, 30,  8, 32,  8, 33,  9, 33,
	       13, 33, 14, 32, 14, 33, 15, 32, 15, 33,
	       18, 32, 18, 33, 19, 33, 20, 32, 20, 33,
	       22, 32, 22, 33, 23, 25, 23, 27, 23, 29,
	       23, 32, 23, 33, 24, 25, 24, 27, 24, 31,
	       25, 31, 26, 29, 26, 33, 27, 33, 28, 31,
	       28, 33, 29, 32, 29, 33, 30, 32, 30, 33,
	       31, 32, 31, 33, 32, 33,
	       -1);
  
  igraph_vector_init(&eb, igraph_ecount(&g));
  igraph_edge_betweenness(&g, &eb, IGRAPH_UNDIRECTED, /*weights=*/ 0);
  for (i=0; i<igraph_vector_size(&eb); i++) {
    VECTOR(eb)[i] = -VECTOR(eb)[i];
  }

  igraph_minimum_spanning_tree_prim(&g, &tree, &eb);
  igraph_write_graph_edgelist(&tree, stdout);

  igraph_vector_init(&edges, 0);
  igraph_minimum_spanning_tree(&g, &edges, &eb);
  igraph_vector_print(&edges);
  igraph_vector_destroy(&edges);

  igraph_destroy(&tree);
  igraph_destroy(&g);
  igraph_vector_destroy(&eb);
  
  return 0;
}