Sir/madam,
Can we use igraph package to plot zero divisor graph of Graph Theory.? Please let me know
Thanking You.
You can plot any arbitrary graph with igraph
(up to the point where it makes sense to plot it; e.g., if you have millions of vertices and edges then it probably does not make much sense any more), but you need to construct the graph yourself.
Not Understood.Could you explain in more detail?
igraph has no function that computes a zero-divisor graph of a ring.
Thanks for reply. Then which software is most suitable for Graph Theory?
## What is required is an example of a ring
## Example Z2 x Z4.
## See: https://en.wikipedia.org/wiki/Zero-divisor_graph
##
## Pseudo code
## Z2 = (0, 1), equivalence classes modulo 2
## Z4 = (0..3), equivalence classes modulo 4
## Z2Z4 = Z2 x Z4, Cartesian product
## Z2Z4 x Z2Z4, pairwise multiplication, filter nontrivial zero divisors
## build graph
##
library(igraph)
n <- 2; m <- 4
ll <- list()
## build Z2 x Z4
for (i in seq(n)-1) {
for (k in seq(m)-1) {
ll <- append(ll, list(c(i,k)) )
}
}
## multiply in ring
rmult <- function(x, y) {
c( (x[1] * y[1]) %% n, (((x[2] * y[2]) %% m)))
}
## test if zero
zero <- function(zz) {all(zz == c(0,0)) }
## calculate product in ring and filter nontrivial zero divisers
vp <- c() # vertex pairs
for (d1 in ll) {
for (d2 in ll) {
if (!zero(d1) && !zero(d2)) { # exclude trivial divisors
if (zero(rmult(d1, d2))){ # non trivial zero divisor
vp <- append( vp
, c(paste0(d1, collapse=",")
, paste0(d2, collapse=","))
) # collect
}
}
}
}
## plot graph as tree
vp |>
make_graph(directed=FALSE) |>
simplify() -> g
g |> plot(layout=layout_with_sugiyama)
## [1] 0,1--1,0 1,0--0,2 1,0--0,3 0,2--1,2
# eliminate for loops by crossproduct and filter function
## ------------------------------------------------------------------- second attempt
## What is required is an example of an algebra
## Example Z2 x Z4.
## See: https://en.wikipedia.org/wiki/Zero-divisor_graph
##
## Pseudo code
## Z2 = (0, 1), equivalence classes modulo 2
## Z4 = (0..3), equivalence classes modulo 4
## Z2Z4 = Z2 x Z4, cartesian product
## Z2Z4 x Z2Z4, pairwise multiplication, filter nontrivial zero divisors
## build graph
##
require(igraph)
cat(rm(list = ls())) # remove all objects
n <- 2; m <- 4
## multiply in ring
rmult <- function(x, y) {
c( (x[1] * y[1]) %% n, (((x[2] * y[2]) %% m)))
}
## test product of x,y is zero divisor
zerodiv <- function(x, y){
return(all(rmult(x, y) == c(0,0) ))
}
## crossproduct, filter and append to list
crossf <- function(x, y, .filter) {
cp <- list()
for (d1 in x) {
for (d2 in y) {
if ( missing(.filter) || .filter(d1, d2) ) {
cp <- append( cp, list(c(d1, d2))) # and collect
}
}
}
return(cp)
}
ZnZm <- crossf(seq(n)-1, seq(m)-1) # build Zn x Zm
ZnZm <- ZnZm[-1] # and remove zero
## crossproduct all non-zero elements of the ring by itself
## and filter zero divisors
cp <- unlist(crossf(ZnZm, ZnZm, zerodiv)) # vector of d1, d2
cp <- matrix(cp, nrow =2) # convert to
vp <- paste0(cp[1,], cp[2,], sep="" ) # series of vertex pairs
## plot graph with sugiyama
vp |>
make_graph(directed=FALSE) |> simplify() -> g # remove multiple and loop edges
g$main <- paste0("zero divisors of Z", n, "×Z", m)
g$label <- sprintf("%02d",seq_len(ecount(g)))
g |> plot(layout=layout_with_sugiyama)
g
## [1] 01--10 10--02 10--03 02--12 (n=2, m=4)
In the code below, we use a data frame and expand.grid.
The code is more concise, but all data should be in memory. It is not clear to me how to merge and subset at the same time in R base.
## Find zero divisors in Zn x Zm.
require(igraph)
## crossproduct Zn x Zm * Zn x Zm.
## find zero products in Zn,Zm * Zn,Zm.
## and keep nontrivial products: both left and right element in the product are nonzero.
n <- 2; m <- 4
CpZnZm <- expand.grid( n1 = seq(n)-1, m1 = seq(m)-1, n2=seq(n)-1, m2 = seq(m)-1)
zdivs <- subset(CpZnZm, ((n1 * n2) %% n) == 0 & ((m1 * m2) %% m) ==0)
zdivs <- subset(zdivs, !( (n1==0 & m1 == 0) | (n2==0 & m2 == 0)) )
## build edges
ff <- paste0(zdivs[, "n1"], zdivs[,"m1"], sep="" ) # from.
tt <- paste0(zdivs[, "n2"], zdivs[,"m2"], sep="" ) # to.
vp <- c(rbind(ff, tt)) # sequence of vertex pairs.
## plot graph with sugiyama
vp |> make_graph(directed=FALSE) |> simplify() -> g # remove multiple and loop edges.
g$main <- paste0("zero divisors of Z", n, "×Z", m)
g$label <- sprintf("%02d",seq_len(ecount(g)))
g |> plot(layout=layout_with_sugiyama); g
Regarding Crossf() in the previous post:
implies copying list cp. Faster and recommended is:
cp[[i <- i+1L]] <- list(c(d1, d2)) # and collect inline
Also see this chapter from Hadley Wickham’s Advanced R on growing objects.