Skip to content

Commit

Permalink
feat: is_clique() and is_independent_vertex_set()
Browse files Browse the repository at this point in the history
  • Loading branch information
szhorvat committed Jun 28, 2024
1 parent 0d30ebb commit 8c14bfe
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
87 changes: 87 additions & 0 deletions src/_igraph/graphobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,77 @@ PyObject *igraphmodule_Graph_is_complete(igraphmodule_GraphObject* self, PyObjec
}


/** \ingroup python_interface_graph
* \brief Checks whether a given vertex set forms a clique
*/
PyObject *igraphmodule_Graph_is_clique(igraphmodule_GraphObject * self,
PyObject * args, PyObject * kwds)
{
PyObject *list = Py_None;
PyObject *directed = Py_False;
igraph_bool_t res;
igraph_vs_t vs;

static char *kwlist[] = { "vertices", "directed", NULL };

if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, &list, &directed)) {
return NULL;
}

if (igraphmodule_PyObject_to_vs_t(list, &vs, &self->g, NULL, NULL)) {
return NULL;
}

if (igraph_is_clique(&self->g, vs, PyObject_IsTrue(directed), &res)) {
igraphmodule_handle_igraph_error();
igraph_vs_destroy(&vs);
return NULL;
}

igraph_vs_destroy(&vs);

if (res)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}


/** \ingroup python_interface_graph
* \brief Checks whether a the given vertices form an independent set
*/
PyObject *igraphmodule_Graph_is_independent_vertex_set(igraphmodule_GraphObject * self,
PyObject * args, PyObject * kwds)
{
PyObject *list = Py_None;
igraph_bool_t res;
igraph_vs_t vs;

static char *kwlist[] = { "vertices", NULL };

if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &list)) {
return NULL;
}

if (igraphmodule_PyObject_to_vs_t(list, &vs, &self->g, NULL, NULL)) {
return NULL;
}

if (igraph_is_independent_vertex_set(&self->g, vs, &res)) {
igraphmodule_handle_igraph_error();
igraph_vs_destroy(&vs);
return NULL;
}

igraph_vs_destroy(&vs);

if (res)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}


/** \ingroup python_interface_graph
* \brief Determines whether a graph is a (directed or undirected) tree
* \sa igraph_is_tree
Expand Down Expand Up @@ -13705,6 +13776,22 @@ struct PyMethodDef igraphmodule_Graph_methods[] = {
"@return: C{True} if it is complete, C{False} otherwise.\n"
"@rtype: boolean"},

{"is_clique", (PyCFunction) igraphmodule_Graph_is_clique,
METH_VARARGS | METH_KEYWORDS,
"is_clique(vertices, directed=False)\n--\n\n"
"Decides whether a set of vertices is a clique, i.e. a fully connected subgraph.\n\n"
"@param vertices: a list of vertex IDs\n"
"@param directed: whether to require mutual connections between vertex pairs\n"
" in directed graphs.\n"
"@return: C{True} is the given vertex set is a clique, C{False} if not.\n"},

{"is_independent_vertex_set", (PyCFunction) igraphmodule_Graph_is_independent_vertex_set,
METH_VARARGS | METH_KEYWORDS,
"is_independent_vertex_set(vertices)\n--\n\n"
"Decides whether no two vertices within a set are adjacent.\n\n"
"@param vertices: a list of vertex IDs\n"
"@return: C{True} is the given vertices form an independent set, C{False} if not.\n"},

/* interface to igraph_is_tree */
{"is_tree", (PyCFunction) igraphmodule_Graph_is_tree,
METH_VARARGS | METH_KEYWORDS,
Expand Down
4 changes: 4 additions & 0 deletions tests/test_cliques.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ def testLargestCliques(self):
self.assertEqual(
sorted(map(sorted, self.g.largest_cliques())), [[1, 2, 3, 4], [1, 2, 4, 5]]
)
self.assertTrue(all(map(self.g.is_clique, self.g.largest_cliques())))

def testMaximalCliques(self):
self.assertEqual(
sorted(map(sorted, self.g.maximal_cliques())),
[[0, 3, 4], [0, 4, 5], [1, 2, 3, 4], [1, 2, 4, 5]],
)
self.assertTrue(all(map(self.g.is_clique, self.g.maximal_cliques())))
self.assertEqual(
sorted(map(sorted, self.g.maximal_cliques(min=4))),
[[1, 2, 3, 4], [1, 2, 4, 5]],
Expand Down Expand Up @@ -136,6 +138,7 @@ def testLargestIndependentVertexSets(self):
self.assertEqual(
self.g1.largest_independent_vertex_sets(), [(0, 3, 4), (2, 3, 4)]
)
self.assertTrue(all(map(self.g1.is_independent_vertex_set, self.g1.largest_independent_vertex_sets())))

def testMaximalIndependentVertexSets(self):
self.assertEqual(
Expand All @@ -152,6 +155,7 @@ def testMaximalIndependentVertexSets(self):
(2, 4, 7, 8),
],
)
self.assertTrue(all(map(self.g2.is_independent_vertex_set, self.g2.maximal_independent_vertex_sets())))

def testIndependenceNumber(self):
self.assertEqual(self.g2.independence_number(), 6)
Expand Down

0 comments on commit 8c14bfe

Please sign in to comment.