Skip to content

Commit

Permalink
version 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Blanca A. Ceballos Martin authored and gaborcsardi committed Nov 19, 2015
0 parents commit acf55ed
Show file tree
Hide file tree
Showing 14 changed files with 558 additions and 0 deletions.
13 changes: 13 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Package: MCDM
Title: Multi-Criteria Decision Making Methods
Version: 1.0
Date: 2015-09-10
Author: Blanca A. Ceballos Martin <[email protected]>
Maintainer: Blanca A. Ceballos Martin <[email protected]>
Description: An R implementation of Four Multi-Criteria Decision Making (MCDM) Methods: Technique for Order of Preference by Similarity to Ideal Solution (TOPSIS), "VIseKriterijumska Optimizacija I Kompromisno Resenje" (VIKOR), both Multi-Objective Optimization by Ratio Analysis and Full Multiplicative Form (Multi-MOORA) and Weighted Aggregated Sum Product ASsessment (WASPAS). In addition, this package provides a MetaRanking function which combines the output of the previous methods.
License: LGPL (>= 3)
URL: http://decsai.ugr.es/index.php?p=miembros&id=19909
NeedsCompilation: no
Packaged: 2015-11-18 16:00:54 UTC; Blanky
Repository: CRAN
Date/Publication: 2015-11-19 11:02:12
13 changes: 13 additions & 0 deletions MD5
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
b301612e520e87ecf367a63d632b0645 *DESCRIPTION
0f714634d9b6e945d6b30e5d6276b22e *NAMESPACE
a6d7468cec7f23a7d52226beb220a609 *R/MMOORA.R
916b563fb195602c830dd3c55b3f1f7e *R/MetaRanking.R
5b246b44eab588a3641bf7288c90f566 *R/TOPSIS.R
6f0bdad34dcfb7883f3dc08ebdecb72e *R/VIKOR.R
f80bef4b19a66218360122eb29b1f0b0 *R/WASPAS.R
e91d631037e23f00c7fd70739a1278c3 *man/MMOORA.Rd
c3d685827adbeb13256720e443d2687a *man/MetaRanking.Rd
a263ae3ec5866104e5736868d3ebbd8e *man/TOPSIS.Rd
73dae3c80f82ad4dd9119924e75ce00d *man/VIKOR.Rd
244851b5223807a97aaceba704f70a8e *man/WASPAS.Rd
9120b7e76ff718096df3feea7dce908d *vignettes/MCDM.pdf
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exportPattern("^[[:alpha:]]+")

91 changes: 91 additions & 0 deletions R/MMOORA.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#' Implementation of MULTIMOORA Method for Multi-Criteria Decision Making Problems.
#'
#' @description The \code{MMOORA} function implements both the Multi-Objetive Optimization by Ration Analysis (MOORA) and the "Full Multiplicative Form" (MULTIMOORA).
#' @param decision The decision matrix (\emph{m} x \emph{n}) with the values of the \emph{m} alternatives, for the \emph{n} criteria.
#' @param weights A vector of length \emph{n}, containing the weights for the criteria. The sum of the weights has to be 1.
#' @param cb A vector of length \emph{n}. Each component is either \code{cb(i)='max'} if the \emph{i-th} criterion is benefit or \code{cb(i)='min'} if the \emph{i-th} criterion is a cost.
#' @return \code{MMOORA} returns a data frame which contains the scores and the four rankings calculated (Ratio System, Reference Point, Multiplicative Form and Multi-MOORA ranking).
#' @references Brauers, W. K. M.; Zavadskas, E. K. Project management by MULTIMOORA as an instrument for transition economies. Technological and Economic Development of Economy, 16(1), 5-24, 2010.
#' @examples
#'
#' d <- matrix(rpois(12, 5), nrow = 4)
#' w <- c(0.2, 0.2, 0.6)
#' cb <- c('max','min','max')
#' MMOORA(d,w,cb)

MMOORA <- function(decision, #matrix with all the alternatives
weights, #vector with the numeric values of the weights
cb #vector with the "type" of the criteria (benefit = "max", cost = "min")
)
{
#Checking the arguments
if(! is.matrix(decision))
stop("'decision' must be a matrix with the values of the alternatives")
if(missing(weights))
stop("a vector containing n weigths, adding up to 1, should be provided")
if(sum(weights) != 1)
stop("The sum of 'weights' is not equal to 1")
if(! is.character(cb))
stop("'cb' must be a character vector with the type of the criteria")
if(! all(cb == "max" | cb == "min"))
stop("'cb' should contain only 'max' or 'min'")
if(length(weights) != ncol(decision))
stop("length of 'weights' does not match the number of the criteria")
if(length(cb) != ncol(decision))
stop("length of 'cb' does not match the number of the criteria")


#MMOORA method

#1. Normalization and weighting
d = sqrt(colSums(decision^2))
NW <- matrix(nrow = nrow(decision), ncol = ncol(decision))
for(j in 1:ncol(decision)){
NW[,j] <- (decision[,j] / d[j]) * weights[j]
}

#2. Ration system
NR <- NW
for(j in 1:ncol(decision)){
if (cb[j] == 'min'){
NR[,j] <- NW[,j]*(-1)
}
}
RS <- apply(NR, 1, sum)

#3. Reference point
Ref <- as.integer(cb == "max") * apply(NW, 2, max) +
as.integer(cb == "min") * apply(NW, 2, min)
RefP <- matrix(nrow = nrow(decision), ncol = ncol(decision))
for(j in 1:ncol(decision)){
RefP[,j] <- abs(Ref[j]-NW[,j])
}
RP <- apply(RefP, 1, max)

#4. Multiplicative form
NEW <- matrix(nrow = nrow(decision), ncol = ncol(decision))
for(j in 1:ncol(decision)){
NEW[,j] <- (decision[,j] / d[j]) ^ weights[j]
}

max <- NEW
min <- NEW
for (j in 1:ncol(NEW)){
if (cb[j] == 'max'){
min[,j] <- 1
}else{
max[,j] <- 1
}
}
A <- apply(max, 1, prod)
B <- apply(min, 1, prod)
M <- A/B

#5. Ranking the alternatives
Rrs <- rank(-RS)
Rrp <- rank(RP)
Rm <- rank(-M)
R <- Rrs + Rrp + Rm
return(data.frame(Alternatives = 1:nrow(decision), RatioSystem = RS, Ranking = rank(-RS, ties.method= "random"), ReferencePoint = RP, Ranking = rank(RP, ties.method= "random"), MultiplicativeForm = M, Ranking = rank(-M, ties.method= "random"), MultiMooraRanking = rank(R, ties.method= "random")))

}
63 changes: 63 additions & 0 deletions R/MetaRanking.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#' Implementation of MetaRanking function for Multi-Criteria Decision Making Problems.
#'
#' @description The \code{MetaRanking} function internally calls functions \code{MMOORA}, \code{TOPSIS}, \code{VIKOR} and \code{WASPAS} and then calculates a sum of the their rankings.
#' @param decision The decision matrix (\emph{m} x \emph{n}) with the values of the \emph{m} alternatives, for the \emph{n} criteria.
#' @param weights A vector of length \emph{n}, containing the weights for the criteria. The sum of the weights has to be 1.
#' @param cb A vector of length \emph{n}. Each component is either \code{cb(i)='max'} if the \emph{i-th} criterion is benefit or \code{cb(i)='min'} if the \emph{i-th} criterion is a cost.
#' @param lambda A value in [0,1]. It is used in the calculation of the W index for WASPAS method.
#' @param v A value in [0,1]. It is used in the calculation of the Q index for VIKOR method.
#' @return \code{MetaRanking} returns a data frame which contains the rankings of the Multi-MOORA, TOPSIS, VIKOR, WASPAS Methods and the MetaRanking of the alternatives.
#' @examples
#'
#' d <- matrix(rpois(12, 5), nrow = 4)
#' w <- c(0.2, 0.2, 0.6)
#' cb <- c('max','min','max')
#' lambda <- 0.5
#' v <- 0.5
#' MetaRanking(d,w,cb,lambda,v)

MetaRanking <- function(decision, #matrix with all the alternatives
weights, #vector with the numeric values of the weights
cb, #vector with the "type" of the criteria (benefit = "max", cost = "min")
lambda, #value with the real number of the 'lambda' parameter to calculate W
v #value with the real number of the 'v' parameter to calculate Q
)
{
#Checking the arguments
if(! is.matrix(decision))
stop("'decision' must be a matrix with the values of the alternatives")
if(missing(weights))
stop("a vector containing n weigths, adding up to 1, should be provided")
if(sum(weights) != 1)
stop("The sum of 'weights' is not equal to 1")
if(! is.character(cb))
stop("'cb' must be a character vector with the type of the criteria")
if(! all(cb == "max" | cb == "min"))
stop("'cb' should contain only 'max' or 'min'")
if(length(weights) != ncol(decision))
stop("length of 'weights' does not match the number of the criteria")
if(length(cb) != ncol(decision))
stop("length of 'cb' does not match the number of the criteria")
if(missing(lambda))
stop("a value for 'lambda' in [0,1] should be provided")
if(missing(v))
stop("a value for 'v' in [0,1] should be provided")


#Multi-MOORA method
MMoora = MMOORA(decision,weights,cb)

#TOPSIS method
Topsis = TOPSIS(decision,weights,cb)

#VIKOR method
Vikor = VIKOR(decision,weights,cb,v)

#WASPAS method
Waspas = WASPAS(decision,weights,cb,lambda)

#Meta-Ranking
MetaR = MMoora[,8]+Topsis[,3]+Vikor[,5]+Waspas[,3]
return(data.frame(Alternatives = 1:nrow(decision), MMOORA = MMoora[,8], TOPSIS = Topsis[,3], VIKOR = Vikor[,5], WASPAS = Waspas[,3], METARANKING = rank(MetaR, ties.method= "random")))

}
66 changes: 66 additions & 0 deletions R/TOPSIS.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#' Implementation of TOPSIS Method for Multi-Criteria Decision Making Problems.
#'
#' @description The \code{TOPSIS} function implements the Technique for Order of Preference by Similarity to Ideal Solution (TOPSIS) Method.
#' @param decision The decision matrix (\emph{m} x \emph{n}) with the values of the \emph{m} alternatives, for the \emph{n} criteria.
#' @param weights A vector of length \emph{n}, containing the weights for the criteria. The sum of the weights has to be 1.
#' @param cb A vector of length \emph{n}. Each component is either \code{cb(i)='max'} if the \emph{i-th} criterion is benefit or \code{cb(i)='min'} if the \emph{i-th} criterion is a cost.
#' @return \code{TOPSIS} returns a data frame which contains the score of the R index and the ranking of the alternatives.
#' @references Hwang, C.L.; Yoon, K. Multiple Attribute Decision Making. In: Lecture Notes in Economics and Mathematical Systems 186. Springer-Verlag, Berlin, 1981.
#' @examples
#'
#' d <- matrix(rpois(12, 5), nrow = 4)
#' w <- c(0.2, 0.2, 0.6)
#' cb <- c('max','min','max')
#' TOPSIS(d,w,cb)

TOPSIS <- function(decision, #matrix with all the alternatives
weights, #vector with the numeric values of the weights
cb #vector with the "type" of the criteria (benefit = "max", cost = "min")
)
{
#Checking the arguments
if(! is.matrix(decision))
stop("'decision' must be a matrix with the values of the alternatives")
if(missing(weights))
stop("a vector containing n weigths, adding up to 1, should be provided")
if(sum(weights) != 1)
stop("The sum of 'weights' is not equal to 1")
if(! is.character(cb))
stop("'cb' must be a character vector with the type of the criteria")
if(! all(cb == "max" | cb == "min"))
stop("'cb' should contain only 'max' or 'min'")
if(length(weights) != ncol(decision))
stop("length of 'weights' does not match the number of the criteria")
if(length(cb) != ncol(decision))
stop("length of 'cb' does not match the number of the criteria")


#TOPSIS method

#1. Normalization and weighting
d = sqrt(colSums(decision^2))
NW <- matrix(nrow = nrow(decision), ncol = ncol(decision))
for(j in 1:ncol(decision)){
NW[,j] <- (decision[,j] / d[j]) * weights[j]
}

#2. Ideal solutions
posI <- as.integer(cb == "max") * apply(NW, 2, max) +
as.integer(cb == "min") * apply(NW, 2, min)
negI <- as.integer(cb == "min") * apply(NW, 2, max) +
as.integer(cb == "max") * apply(NW, 2, min)

#3. Distances to the ideal solutions
distance =function(x,y){
sqrt(sum((x - y) ^ 2))
}
posDis <- apply(NW, 1, distance, posI)
negDis <- apply(NW, 1, distance, negI)

#4. R index
R <- negDis/(negDis+posDis)

#5. Rank the alternatives
return(data.frame(Alternatives = 1:nrow(decision), R = R, Ranking = rank(-R, ties.method= "random")))

}
66 changes: 66 additions & 0 deletions R/VIKOR.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#' Implementation of VIKOR Method for Multi-Criteria Decision Making Problems.
#'
#' @description The \code{VIKOR} function implements the "VIseKriterijumska Optimizacija I Kompromisno Resenje" (VIKOR) Method.
#' @param decision The decision matrix (\emph{m} x \emph{n}) with the values of the \emph{m} alternatives, for the \emph{n} criteria.
#' @param weights A vector of length \emph{n}, containing the weights for the criteria. The sum of the weights has to be 1.
#' @param cb A vector of length \emph{n}. Each component is either \code{cb(i)='max'} if the \emph{i-th} criterion is benefit or \code{cb(i)='min'} if the \emph{i-th} criterion is a cost.
#' @param v A value in [0,1]. It is used in the calculation of the Q index.
#' @return \code{VIKOR} returns a data frame which contains the score of the S, R and Q indixes and the ranking of the alternatives according to Q index.
#' @references Opricovic, S.; Tzeng, G.H. Compromise solution by MCDM methods: A comparative analysis of VIKOR and TOPSIS. European Journal of Operational Research, 156(2), 445-455, 2004.
#' @examples
#'
#' d <- matrix(rpois(12, 5), nrow = 4)
#' w <- c(0.2, 0.2, 0.6)
#' cb <- c('max','min','max')
#' v <- 0.5
#' VIKOR(d,w,cb,v)

VIKOR <- function(decision, #matrix with all the alternatives
weights, #vector with the numeric values of the weights
cb, #vector with the "type" of the criteria (benefit = "max", cost = "min")
v #value with the real number of the 'v' parameter to calculate Q
)
{
#Checking the arguments
if(! is.matrix(decision))
stop("'decision' must be a matrix with the values of the alternatives")
if(missing(weights))
stop("a vector containing n weigths, adding up to 1, should be provided")
if(sum(weights) != 1)
stop("The sum of 'weights' is not equal to 1")
if(! is.character(cb))
stop("'cb' must be a character vector with the type of the criteria")
if(! all(cb == "max" | cb == "min"))
stop("'cb' should contain only 'max' or 'min'")
if(length(weights) != ncol(decision))
stop("length of 'weights' does not match the number of the criteria")
if(length(cb) != ncol(decision))
stop("length of 'cb' does not match the number of the criteria")
if(missing(v))
stop("a value for 'v' in [0,1] should be provided")


#VIKOR method

#1. Ideal solutions
posI <- as.integer(cb == "max") * apply(decision, 2, max) +
as.integer(cb == "min") * apply(decision, 2, min)
negI <- as.integer(cb == "min") * apply(decision, 2, max) +
as.integer(cb == "max") * apply(decision, 2, min)

#2. S and R index
norm =function(x,w,p,n){
w*((p-x)/(p-n))
}
SAux <- apply(decision, 1, norm, weights, posI, negI)
S <- apply(SAux, 2, sum)
R <- apply(SAux, 2, max)


#3. Q index
Q <- v*(S-min(S))/(max(S)-min(S))+(1-v)*(R-min(R))/(max(R)-min(R))

#4. Ranking the alternatives
return(data.frame(Alternatives = 1:nrow(decision), S = S, R = R, Q = Q, Ranking = rank(Q, ties.method= "random")))

}
Loading

0 comments on commit acf55ed

Please sign in to comment.