# IGraph R package
# Copyright (C) 2006-2012 Gabor Csardi <csardi.gabor@gmail.com>
# 334 Harvard street, Cambridge, MA 02139 USA
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
#
###################################################################
#' The functions find cliques, ie. complete subgraphs in a graph
#'
#' These functions find all, the largest or all the maximal cliques in an
#' undirected graph. The size of the largest clique can also be calculated.
#'
#' \code{cliques} find all complete subgraphs in the input graph, obeying the
#' size limitations given in the \code{min} and \code{max} arguments.
#'
#' \code{largest_cliques} finds all largest cliques in the input graph. A
#' clique is largest if there is no other clique including more vertices.
#'
#' \code{max_cliques} finds all maximal cliques in the input graph. A
#' clique in maximal if it cannot be extended to a larger clique. The largest
#' cliques are always maximal, but a maximal clique is not neccessarily the
#' largest.
#'
#' \code{count_max_cliques} counts the maximal cliques.
#'
#' \code{clique_num} calculates the size of the largest clique(s).
#'
#' The current implementation of these functions searches for maximal
#' independent vertex sets (see \code{\link{ivs}}) in the
#' complementer graph.
#'
#' @aliases cliques largest_cliques maximal.cliques maximal.cliques.count
#' clique.number clique_num largest.cliques count_max_cliques max_cliques
#' @param graph The input graph, directed graphs will be considered as
#' undirected ones, multiple edges and loops are ignored.
#' @param min Numeric constant, lower limit on the size of the cliques to find.
#' \code{NULL} means no limit, ie. it is the same as 0.
#' @param max Numeric constant, upper limit on the size of the cliques to find.
#' \code{NULL} means no limit.
#' @return \code{cliques}, \code{largest_cliques} and \code{clique_num}
#' return a list containing numeric vectors of vertex ids. Each list element is
#' a clique.
#'
#' \code{max_cliques} returns \code{NULL}, invisibly, if its \code{file}
#' argument is not \code{NULL}. The output is written to the specified file in
#' this case.
#'
#' \code{clique_num} and \code{count_max_cliques} return an integer
#' scalar.
#' @author Tamas Nepusz \email{ntamas@@gmail.com} and Gabor Csardi
#' \email{csardi.gabor@@gmail.com}
#' @seealso \code{\link{ivs}}
#' @references For maximal cliques the following algorithm is implemented:
#' David Eppstein, Maarten Loffler, Darren Strash: Listing All Maximal Cliques
#' in Sparse Graphs in Near-optimal Time. \url{http://arxiv.org/abs/1006.5440}
#' @export
#' @keywords graphs
#' @examples
#'
#' # this usually contains cliques of size six
#' g <- sample_gnp(100, 0.3)
#' clique_num(g)
#' cliques(g, min=6)
#' largest_cliques(g)
#'
#' # To have a bit less maximal cliques, about 100-200 usually
#' g <- sample_gnp(100, 0.03)
#' max_cliques(g)
#'
#'
cliques <- function(graph, min=NULL, max=NULL) {
if (!is_igraph(graph)) {
stop("Not a graph object")
}
if (is.null(min)) {
min <- 0
}
if (is.null(max)) {
max <- 0
}
on.exit( .Call(C_R_igraph_finalizer) )
res <- .Call(C_R_igraph_cliques, graph, as.numeric(min), as.numeric(max))
res <- lapply(res, function(x) x+1)
if (igraph_opt("return.vs.es")) {
res <- lapply(res, create_vs, graph = graph)
}
res
}
#' @export
largest_cliques <- function(graph) {
if (!is_igraph(graph)) {
stop("Not a graph object")
}
on.exit( .Call(C_R_igraph_finalizer) )
res <- .Call(C_R_igraph_largest_cliques, graph)
res <- lapply(res, function(x) x+1)
if (igraph_opt("return.vs.es")) {
res <- lapply(res, create_vs, graph = graph)
}
res
}
#' @rdname cliques
#' @param subset If not \code{NULL}, then it must be a vector of vertex ids,
#' numeric or symbolic if the graph is named. The algorithm is run from these
#' vertices only, so only a subset of all maximal cliques is returned. See the
#' Eppstein paper for details. This argument makes it possible to easily
#' parallelize the finding of maximal cliques.
#' @param file If not \code{NULL}, then it must be a file name, i.e. a
#' character scalar. The output of the algorithm is written to this file. (If
#' it exists, then it will be overwritten.) Each clique will be a separate line
#' in the file, given with the numeric ids of its vertices, separated by
#' whitespace.
#' @export
max_cliques <- function(graph, min=NULL, max=NULL,
subset=NULL, file=NULL) {
if (!is_igraph(graph)) {
stop("Not a graph object");
}
if (is.null(min)) { min <- 0 }
if (is.null(max)) { max <- 0 }
if (!is.null(subset)) {
subset <- as.integer(as.igraph.vs(graph, subset)-1)
}
if (!is.null(file)) {
if (!is.character(file) ||
length(grep("://", file, fixed=TRUE)) > 0 ||
length(grep("~", file, fixed=TRUE)) > 0) {
tmpfile <- TRUE
origfile <- file
file <- tempfile()
} else {
tmpfile <- FALSE
}
on.exit( .Call(C_R_igraph_finalizer) )
res <- .Call(C_R_igraph_maximal_cliques_file, graph, subset, file,
as.numeric(min), as.numeric(max))
if (tmpfile) {
buffer <- read.graph.toraw(file)
write.graph.fromraw(buffer, origfile)
}
invisible(NULL)
} else {
on.exit( .Call(C_R_igraph_finalizer) )
res <- .Call(C_R_igraph_maximal_cliques, graph, subset,
as.numeric(min), as.numeric(max))
res <- lapply(res, function(x) x+1)
if (igraph_opt("return.vs.es")) {
res <- lapply(res, create_vs, graph = graph)
}
res
}
}
#' @export
count_max_cliques <- function(graph, min=NULL, max=NULL,
subset=NULL) {
# Argument checks
if (!is_igraph(graph)) { stop("Not a graph object") }
if (is.null(min)) { min <- 0 }
if (is.null(max)) { max <- 0 }
min <- as.integer(min)
max <- as.integer(max)
if (!is.null(subset)) {
subset <- as.integer(as.igraph.vs(graph, subset)-1)
}
on.exit( .Call(C_R_igraph_finalizer) )
# Function call
res <- .Call(C_R_igraph_maximal_cliques_count, graph, subset, min, max)
res
}
#' @export
clique_num <- function(graph) {
if (!is_igraph(graph)) {
stop("Not a graph object");
}
on.exit( .Call(C_R_igraph_finalizer) )
.Call(C_R_igraph_clique_number, graph)
}
#' Independent vertex sets
#'
#' A vertex set is called independent if there no edges between any two
#' vertices in it. These functions find independent vertex sets in undirected
#' graphs
#'
#' \code{ivs} finds all independent vertex sets in the
#' network, obeying the size limitations given in the \code{min} and \code{max}
#' arguments.
#'
#' \code{largest_ivs} finds the largest independent vertex
#' sets in the graph. An independent vertex set is largest if there is no
#' independent vertex set with more vertices.
#'
#' \code{maximal_ivs} finds the maximal independent vertex
#' sets in the graph. An independent vertex set is maximal if it cannot be
#' extended to a larger independent vertex set. The largest independent vertex
#' sets are maximal, but the opposite is not always true.
#'
#' \code{independece.number} calculate the size of the largest independent
#' vertex set(s).
#'
#' These functions use the algorithm described by Tsukiyama et al., see
#' reference below.
#'
#' @aliases independent.vertex.sets largest.independent.vertex.sets
#' maximal.independent.vertex.sets independence.number ivs_size ivs
#' largest_ivs maximal_ivs
#' @param graph The input graph, directed graphs are considered as undirected,
#' loop edges and multiple edges are ignored.
#' @param min Numeric constant, limit for the minimum size of the independent
#' vertex sets to find. \code{NULL} means no limit.
#' @param max Numeric constant, limit for the maximum size of the independent
#' vertex sets to find. \code{NULL} means no limit.
#' @return \code{ivs},
#' \code{largest_ivs} and
#' \code{maximal_ivs} return a list containing numeric
#' vertex ids, each list element is an independent vertex set.
#'
#' \code{ivs_size} returns an integer constant.
#' @author Tamas Nepusz \email{ntamas@@gmail.com} ported it from the Very Nauty
#' Graph Library by Keith Briggs (\url{http://keithbriggs.info/}) and Gabor
#' Csardi \email{csardi.gabor@@gmail.com} wrote the R interface and this manual
#' page.
#' @seealso \code{\link{cliques}}
#' @references S. Tsukiyama, M. Ide, H. Ariyoshi and I. Shirawaka. A new
#' algorithm for generating all the maximal independent sets. \emph{SIAM J
#' Computing}, 6:505--517, 1977.
#' @export
#' @keywords graphs
#' @examples
#'
#' # Do not run, takes a couple of seconds
#' \dontrun{
#'
#' # A quite dense graph
#' set.seed(42)
#' g <- sample_gnp(100, 0.9)
#' ivs_size(g)
#' ivs(g, min=ivs_size(g))
#' largest_ivs(g)
#' # Empty graph
#' induced_subgraph(g, largest_ivs(g)[[1]])
#'
#' length(maximal_ivs(g))
#' }
ivs <- function(graph, min=NULL, max=NULL) {
if (!is_igraph(graph)) {
stop("Not a graph object");
}
if (is.null(min)) {
min <- 0
}
if (is.null(max)) {
max <- 0
}
on.exit( .Call(C_R_igraph_finalizer) )
res <- .Call(C_R_igraph_independent_vertex_sets, graph, as.numeric(min),
as.numeric(max))
res <- lapply(res, function(x) x+1)
if (igraph_opt("return.vs.es")) {
res <- lapply(res, create_vs, graph = graph)
}
res
}
#' @export
largest_ivs <- function(graph) {
if (!is_igraph(graph)) {
stop("Not a graph object");
}
on.exit( .Call(C_R_igraph_finalizer) )
res <- .Call(C_R_igraph_largest_independent_vertex_sets, graph)
res <- lapply(res, function(x) x+1)
if (igraph_opt("return.vs.es")) {
res <- lapply(res, create_vs, graph = graph)
}
res
}
#' @export
maximal_ivs <- function(graph) {
if (!is_igraph(graph)) {
stop("Not a graph object");
}
on.exit( .Call(C_R_igraph_finalizer) )
res <- .Call(C_R_igraph_maximal_independent_vertex_sets, graph)
res <- lapply(res, function(x) x+1)
if (igraph_opt("return.vs.es")) {
res <- lapply(res, create_vs, graph = graph)
}
res
}
#' @export
ivs_size <- function(graph) {
if (!is_igraph(graph)) {
stop("Not a graph object");
}
on.exit( .Call(C_R_igraph_finalizer) )
.Call(C_R_igraph_independence_number, graph)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.