@@ -7813,6 +7813,65 @@ PyObject *igraphmodule_Graph_minimum_cycle_basis(
78137813 return result_o;
78147814}
78157815
7816+
7817+ PyObject *igraphmodule_Graph_simple_cycles(
7818+ igraphmodule_GraphObject *self, PyObject *args, PyObject *kwds
7819+ ) {
7820+ PyObject *mode_o = Py_None;
7821+ PyObject *output_o = Py_None;
7822+ PyObject *min_cycle_length_o = Py_None;
7823+ PyObject *max_cycle_length_o = Py_None;
7824+
7825+ // argument defaults: no cycle limits
7826+ igraph_integer_t mode = IGRAPH_OUT;
7827+ igraph_integer_t min_cycle_length = -1;
7828+ igraph_integer_t max_cycle_length = -1;
7829+ igraph_bool_t use_edges = false;
7830+
7831+ static char *kwlist[] = { "mode", "min_cycle_length", "max_cycle_length", "output" NULL };
7832+
7833+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO", kwlist, &mode_o, &min_cycle_length_o, &max_cycle_length_o, &output_o))
7834+ return NULL;
7835+
7836+ if (mode_o != Py_None && igraphmodule_PyObject_to_integer_t(mode_o, &mode))
7837+ return NULL;
7838+
7839+ if (min_cycle_length_o != Py_None && igraphmodule_PyObject_to_integer_t(min_cycle_length_o, &min_cycle_length))
7840+ return NULL;
7841+
7842+ if (max_cycle_length_o != Py_None && igraphmodule_PyObject_to_integer_t(max_cycle_length_o, &max_cycle_length))
7843+ return NULL;
7844+
7845+ if (igraphmodule_PyObject_to_vpath_or_epath(output_o, &use_edges))
7846+ return NULL;
7847+
7848+ igraph_vector_int_list_t vertices;
7849+ igraph_vector_int_list_init(&vertices, 0);
7850+ igraph_vector_int_list_t edges;
7851+ igraph_vector_int_list_init(&edges, 0);
7852+
7853+ if (igraph_simple_cycles(
7854+ &self->g, use_edges ? NULL : &vertices, use_edges ? &edges : NULL, mode, min_cycle_length, max_cycle_length
7855+ )) {
7856+ igraph_vector_int_list_destroy(&vertices);
7857+ igraph_vector_int_list_destroy(&edges);
7858+ igraphmodule_handle_igraph_error();
7859+ return NULL;
7860+ }
7861+
7862+ PyObject *result_o;
7863+
7864+ if (use_edges) {
7865+ result_o = igraphmodule_vector_int_list_t_to_PyList_of_tuples(&edges);
7866+ } else {
7867+ result_vertices_o = igraphmodule_vector_int_list_t_to_PyList_of_tuples(&vertices);
7868+ }
7869+ igraph_vector_int_list_destroy(&edges);
7870+ igraph_vector_int_list_destroy(&vertices);
7871+
7872+ return result_o;
7873+ }
7874+
78167875/**********************************************************************
78177876 * Graph layout algorithms *
78187877 **********************************************************************/
@@ -16563,6 +16622,24 @@ struct PyMethodDef igraphmodule_Graph_methods[] = {
1656316622 " no guarantees are given about the ordering of edge IDs within cycles.\n"
1656416623 "@return: the cycle basis as a list of tuples containing edge IDs"
1656516624 },
16625+ {"simple_cycles", (PyCFunction) igraphmodule_Graph_simple_cycles,
16626+ METH_VARARGS | METH_KEYWORDS,
16627+ "simple_cycles(mode=None, min_cycle_length=0, max_cycle_length=-1, output=\"vpath\")\n--\n\n"
16628+ "Finds simple cycles in a graph\n\n"
16629+ "@param mode: for directed graphs, specifies how the edge directions\n"
16630+ " should be taken into account. C{\"all\"} means that the edge directions\n"
16631+ " must be ignored, C{\"out\"} means that the edges must be oriented away\n"
16632+ " from the root, C{\"in\"} means that the edges must be oriented\n"
16633+ " towards the root. Ignored for undirected graphs.\n"
16634+ "@param min_cycle_length: the minimum number of vertices in a cycle\n"
16635+ " for it to be returned.\n"
16636+ "@param max_cycle_length: the maximum number of vertices in a cycle\n"
16637+ " for it to be considered.\n"
16638+ "@param output: determines what should be returned. If this is\n"
16639+ " C{\"vpath\"}, a list of tuples of vertex IDs will be returned. If this is\n"
16640+ " C{\"epath\"}, edge IDs are returned instead of vertex IDs.\n"
16641+ "@return: see the documentation of the C{output} parameter.\n"
16642+ },
1656616643
1656716644 /********************/
1656816645 /* LAYOUT FUNCTIONS */
0 commit comments