RoleSim

RoleSim (Jin et al. 2014) is a generalization of SimRank that computes similarity using maximum matching between neighbor sets, making it sensitive to automorphic similarity.

Reference

  • Jin, R., Lee, V. E., & Li, L. (2014). Scalable and axiomatic ranking of network role similarity. ACM Transactions on Knowledge Discovery from Data (TKDD), 8(1), 1-37.

Optimized Source Code

This optimized version pre-calculates neighbor lists and uses a more robust approach to matching neighbor similarities, significantly improving performance and reliability.

RoleSim <- function(w, beta = 0.5) {
  n <- nrow(w)
  do <- rowSums(w)
  di <- colSums(w)
  
  # Pre-calculate neighbor indices
  out_neigh <- lapply(1:n, function(i) which(w[i, ] == 1))
  in_neigh  <- lapply(1:n, function(i) which(w[, i] == 1))
  
  z <- matrix(1, n, n)
  delta <- 1
  
  while (delta > 1e-10) {
    z_o <- z
    z_new <- matrix(0, n, n)
    
    for (i in 1:n) {
      for (j in i:n) {
        if (i == j) {
          z_new[i, j] <- 1
          next
        }
        
        # Calculate similarity contribution from neighbors
        mu_o <- 0
        if (length(out_neigh[[i]]) > 0 && length(out_neigh[[j]]) > 0) {
          sub_o <- z_o[out_neigh[[i]], out_neigh[[j]], drop = FALSE]
          # Match neighbors
          mu_o <- sum(apply(sub_o, 1, max)) + sum(apply(sub_o, 2, max))
          mu_o <- mu_o / 2 
        }
        
        mu_i <- 0
        if (length(in_neigh[[i]]) > 0 && length(in_neigh[[j]]) > 0) {
          sub_i <- z_o[in_neigh[[i]], in_neigh[[j]], drop = FALSE]
          mu_i <- sum(apply(sub_i, 1, max)) + sum(apply(sub_i, 2, max))
          mu_i <- mu_i / 2
        }
        
        denom <- max(do[i], do[j]) + max(di[i], di[j])
        z_new[i, j] <- if(denom > 0) (beta * (mu_o + mu_i) / denom) + (1 - beta) else (1 - beta)
      }
    }
    # Reflect and update
    z_new[lower.tri(z_new)] <- t(z_new)[lower.tri(z_new)]
    delta <- sum(abs(z_new - z_o))
    z <- z_new
  }
  return(z)
}