SNAP - Sociospatial Network Analysis Package
##' Berlaz's heuristic algorithm for graph vertex coloring.
##'
##' Berlaz's heuristic algorithm for graph vertex coloring.
##'
##' @title Berlaz.Coloring
##' @param ngbrObj an object returned by poly2nb function in spdep package
##' @param inCols a vector of base colors, at least four. It will be recycled if the number is not big enough. If NULL, a series of indices will be returned.
##' @param startNodeIndex the polygon ID used to start/initialize the iteration
##' @param withRandom how to break tie when multiple nodes/vertices are available for next step. If FALSE, the first ourance will be used.
##' @return A vector of colors or indicies for all objects in ngbrObj.
##' @export
##' @references \url{http://sunsp.net}
##' @examples
##' rsltShpData <- readShapePoly(shpFileName)
##' spatialNght <- poly2nb(rsltShpData)
##' polyCols <- Berlaz.Coloring(spatialNght, cols)
##' plot(rsltShpData,col=polyCols)
##' @author Shipeng Sun
Berlaz.Coloring <- function(ngbrObj, inCols = NULL, startNodeIndex = 1, withRandom = F) {
numNode <- length(ngbrObj) # the number of nodes/vertices
nodeIndex <- seq(1, numNode)
colIndex <- rep(0,numNode) # the vector used to save the index of assigned colors
nodeIndex <- seq(1, numNode)
colIndex[startNodeIndex] = 1
coloredNgbrNum <- rep(0,numNode)
nodeDegree <- rep(0,numNode)
for(d in 1:numNode) {
if(ngbrObj[[d]][1] > 0) {
nodeDegree[d] = length(ngbrObj[[d]])
}
}
colIndex[nodeDegree == 0] <- 1
while(min(colIndex) == 0) {
# get the nodes/vertices with maximum colored neighbors
for(i in 1:numNode) {
if(ngbrObj[[i]][1] > 0) {
coloredNgbrNum[i] = length(ngbrObj[[i]][colIndex[ngbrObj[[i]]] > 0])
}
}
#coloredNgbrNum == max(coloredNgbrNum)
maxColoredNghbrsIndex = nodeIndex[coloredNgbrNum == max(coloredNgbrNum[colIndex <= 0]) & colIndex <= 0]
# get the one with the maximum degree
chosenIndex = maxColoredNghbrsIndex[nodeDegree[maxColoredNghbrsIndex] == max(nodeDegree[maxColoredNghbrsIndex])]
# use the first one or randomly choose one
if(withRandom) {
nextIndex = chosenIndex[which.max(runif(length(chosenIndex)))]
} else
{
nextIndex = chosenIndex[1]
}
# Get a color for this "nextIndex"
ngbrCols <- c(0)
for(j in 1:nodeDegree[nextIndex]) {
ngbrCols <- cbind(ngbrCols, colIndex[ngbrObj[[nextIndex]][j]])
}
usedCols <- sort(unique(ngbrCols[ngbrCols > 0]))
colIndex[nextIndex] = 1
if(length(usedCols) <= 0) next
for(k in 1:length(usedCols)) {
if(usedCols[k] == colIndex[nextIndex])
{
colIndex[nextIndex] = k + 1
} else
{
break
}
}
}
if(is.null(inCols)) {
return(colIndex)
} else
{
numCols = length(unique(colIndex))
inCols <- rep(inCols, ceiling(numCols/length(inCols)))
return(inCols[colIndex])
}
}
# This page is rendered by SyntaxHighlighter at http://alexgorbatchev.com/SyntaxHighlighter/