https://hal.archives-ouvertes.fr/hal-02177739
Raw File
Tip revision: b8541bfa2c0f272b08ebd8d19251eb263a8daae4 authored by Software Heritage on 01 January 2009, 00:00:00 UTC
hal: Deposit 318 in collection hal
Tip revision: b8541bf
GenerativeModel.R
###############################################################################
## This abstract class allows representing generative models, i.e. tools
## able to generate networks using a partially random procedure.
## Each model must be implemented/called in a class inheriting from this one.
##
## @author Vincent Labatut
## @version 3
###############################################################################

GenerativeModel <- setRefClass("GenerativeModel",
	fields = list(
		## Name used internally to represent this model.
		## This field is not modifiable.
		internalName="character",
		
		## Named used in filenames to represent this model.
		## This field is not modifiable.
		fileName="character",
		
		## Text appearing in plots to represent this model.
		## This field is not modifiable.
		plotText="character",
		
		## Format used to record the generated network.
		networkFormat="NetworkFormat",
		
		## Format used to record the community structure.
		comstructFormat="ComstructFormat"
	),
	methods = list(
		## Main method, in charge for generating the network and
		## possibly the community structure, and then recording them
		## in appropriate files.
		##
		## @param leaf
		##		The ParameterNode to be used to get the generation parameters
		##		and file paths.
		## @param mute
		##		Optional parameter allowing to prevent returning the network
		##		and community structure, in case it is not needed.
		## @returns
		##		A list containing the generated network (field network) and community
		##		structure (field 'comstruct').
		generate = function(leaf, mute=FALSE)
		{	# generate a network and possibly a community structure
			paramValues <- leaf$getParameterValues()
			data <- do.call(what=.self$generateData, args=paramValues)
			
			# generate the corresponding files
			generateFiles(data=data, leaf=leaf)
			
			if(mute)
				data <- NULL
			
			return(data)
		},
		
		## This method must be overrided in order to implement the 
		## generative procedure.
		## It takes appropriate parameters and returns a list containing
		## a network (igraph object) and possibly a community structure
		## (Comstruct object).
		##
		## @param ...
		##		Whatever model-specific parameters.
		## @returns
		##		A named list containing a 'network' and possibly a 'comstruct' fields.
		generateData = function(...)
		{	return(NA)
		},
		
		## This method is in charge for recording the network and
		## Comstruct objects generated by generateData.
		##
		## @param data
		##		The list returned by generateData (contains a network and possibly a Comstruct)
		## @param leaf
		##		The ParameterNode object used to retrieve the folder path.
		generateFiles = function(data, leaf)
		{	folderPath <- leaf$getFullPath()
			
			# record the network 
			if(!is.null(data$network))
			{	checkFolder(folderPath)
				filePath <- networkFormat$completeFullPath(fullPath=folderPath, folderCheck=TRUE, extCheck=TRUE)
				networkFormat$writeNetwork(network=data$network, fullPath=filePath)
			}
			
			# record the community structure
			if(!is.null(data$comstruct))
			{	checkFolder(folderPath)
				filePath <- comstructFormat$completeFullPath(fullPath=folderPath, folderCheck=TRUE, extCheck=TRUE)
				comstructFormat$writeComstruct(comstruct=data$comstruct, fullPath=filePath)
			}
		},

		## Helper method, can be used by generateData to obtain the
		## community size distribution. See the class GenerativeModelComponentConnect
		## for an example.
		##
		## @param n
		##		Number of nodes in the community structure.
		## @param foo
		##		Function needed to draw the community size distribution.
		## @param ...
		##		Additional parameters. Only those starting with "distrib." are
		##		fetched to the function foo, the others being ignored here.
		## @returns
		##		An integer vector whose each value represents the size of a community.
		drawDistribution = function(n, foo, ...)
		{	# retrieve the relevant parameters
			args <- list(...)
			args <- extractPrefixedValues("distrib.", args)
			
			# draw the distribution, possibly using additional parameters
			result <- do.call(what=foo, args=c(n,args))
			
			# check/correct it when there're too many/not enough nodes
			while(sum(result)!=n)
			{	diff <- n - sum(result)
				s <- sign(diff)
				idx <- min(abs(diff), length(result))
				result[1:idx] <- result[1:idx] + s*1
				result <- result[result>0]
			}
			
			return(result)
		},
		
		## Helper function one can use as the foo parameter when calling 
		## drawDistribution. It draws a distribution of communities
		## with similar sizes (as much as possible, depending on the number
		## of nodes and communities requested).
		##
		## @param n
		##		Number of nodes in the community structure.
		## @param k
		##		Number of communities.
		## @returns
		##		An integer vector whose each value represents the size of a community.
		drawUniformComstruct = function(n, k)
		{	result <- rep(n %/% k, k)
			remaining <- n %% k
			result[1:remaining] <- result[1:remaining] + 1
			return(result)			
		}
	)
)

# load related files
source("Ganetto/generation/internal/GenerativeModelComponentConnect.R")
back to top