Introduction

The package consists several S4 objects that are used in set of functions. For each object various validation conditions are checked in order to ensure that objects are valid and that their usage in functions will provide valid result. Each problem that can occur is described as best as possible in the error message which should help with solving the issue.

AHP (non fuzzy)

Pairwise Comparison Matrix Creation

The pairwise comparison matrix can either be loaded from a file or inputed manually. Since the version 0.6.9 the values can be represented as either character or double. However, the character representation seem as slightly better idea because it allows printing more comprehensible output. The matrix needs to be squared reciprocal matrix with maximal value smaller or equall to 9.

The matrix in text file can have the following form.

;"crit1";"crit2";"crit3"
"crit1";"1";"9";"5" 
"crit2";"1/9";"1";"1/3"
"crit3";"1/5";"3";"1"

The loading is then done as:

matrixFile =  "comparison_matrix.csv"
comparisonMatrix = read.csv(matrixFile, sep = ";",
                   stringsAsFactors = FALSE, header = TRUE, row.names = 1, strip.white = TRUE)
comparisonMatrix = as.matrix(comparisonMatrix)

If the matrix is inputed manually then it can be done by following commands:

comparisonMatrixValues = c(1,9,5,
                           1/9,1,1/3,
                           1/5,3,1)
comparisonMatrix = matrix(comparisonMatrixValues, nrow = 3, ncol = 3, byrow = TRUE)

In the case that the values are represented as double. If the values are represented as character then the code looks like this:

comparisonMatrixValues = c("1","9","5",
                           "1/9","1","1/3",
                           "1/5","3","1")
comparisonMatrix = matrix(comparisonMatrixValues, nrow = 3, ncol = 3, byrow = TRUE)

Either way the comparsion matrix is created using command pairwiseComparisonMatrix. After printing we can see that the S4 object contains two representation of the matrix, One as characters and other one as numeric.

comparisonMatrix = pairwiseComparisonMatrix(comparisonMatrix)
print(comparisonMatrix)
##      [,1]  [,2] [,3] 
## [1,] "1"   "9"  "5"  
## [2,] "1/9" "1"  "1/3"
## [3,] "1/5" "3"  "1"

Testing consistency of Pairwise Comparison Matrix

There are three consistency checks impelemnted in FuzzyAHP package. The first is consistency ratio as defined by T. Saaty (1980). The functions output short message summarizing the calculation and provides value of the consistency ratio. The consistency ration can be calculated for matrices with size up to \(15 \times 15\) according to T. L. Saaty and Tran (2007).

CR = consistencyRatio(comparisonMatrix)
## Consistency ratio is: 0.0279459296138796. The pairwise comparison matrix is consistent for calculations.

Another check is a weak consistency that checks if for \(a_{ij}>1\) and \(a_{jk}>1\) applies that \(a_{ik}>=\max(a_{ij},a_{jk})\) for every \(i,j,k = 1,2,\dots,n\), where \(n\) is a size of matrix \(a\) (Stoklasa, Jandová, and Talašová 2013). The functions returns TRUE if the matrix passes the test or FALSE if it fails and print short message (warning message summarazing the issues, if they exist, is printed as well).

weakConsistency = weakConsistency(comparisonMatrix)
## The comparison matrix is weakly consistent.

Strict consistency is much stronger prerequsion that is generally true only for absolutely consistent evaluator. It might be problematic to fulfill this codition for more complex matricies. However, it seems reasonable to try this verification just to study the outcome. The strict consistency checks that \(a_{ik} = a_{ij} \times a_{jk}\) for every \(i,j,k = 1,2,\dots,n\), where \(n\) is a size of matrix \(a\) (Basile and D’Apuzzo 1997). Again TRUE or FALSE value is returned along with short message.

strictConsistency = strictConsistency(comparisonMatrix)
## Comparison matrix isn't strictly consistent. These indeces violate the condition: 
## [1,3] != ([1,2]*[2,3]) -- 5 != 3
## [1,2] != ([1,3]*[3,2]) -- 9 != 15
## [2,3] != ([2,1]*[1,3]) -- 0.333333333333333 != 0.555555555555556
## [2,1] != ([2,3]*[3,1]) -- 0.111111111111111 != 0.0666666666666667
## [3,2] != ([3,1]*[1,2]) -- 3 != 1.8
## [3,1] != ([3,2]*[2,1]) -- 0.2 != 0.333333333333333

Calculations with Pairwise Comparison Matrix

If the matrix is consistent for calculation accoring to users conditions subsequent calculations can be made. First step is obtaining weights of criteria. The weights are calculated as geometric mean of each row of the pairwise comparison matrix.

weights = calculateWeights(comparisonMatrix)
print(weights)
##     w1     w2     w3 
## 0.7514 0.0704 0.1782

To calculate the AHP some data are needed. As mentioned in the description the FuzzyAHP package is prepared for data that uses scale (categorical) ranking of alternatives (the higher the value the better). In order to calculate AHP we need matrix of data that has the same number of colums as there are weights.

Data that have even one element equal to NA are to taken into account at all, the result is automatically determined as NA.

values = c(4,5,3,
1,3,9,
8,6,4,
3,2,7,
6,7,5,
4,5,3,
NA,9,9,
NA,NA,NA)
values = matrix(values, nrow = length(values)/length(weights@weights), ncol = length(weights@weights), byrow = TRUE)

Now we can calculate the result according to the weights. The values with higher resulting value are better solutions of the AHP problem.

result = calculateAHP(weights, values)
print(result)
##        result
## [1,] 3.892240
## [2,] 2.566257
## [3,] 7.146454
## [4,] 3.642293
## [5,] 5.892240
## [6,] 3.892240
## [7,]       NA
## [8,]       NA

If we wan to rank solutions from the best to the worst, we can do that.

rank = compareResults(result)
print(rank)
##      [,1]
## [1,]    5
## [2,]    8
## [3,]    3
## [4,]    7
## [5,]    4
## [6,]    5
## [7,]   NA
## [8,]   NA

It is also possible to put the results together to produce better outcome.

result = cbind(values, result, rank)
colnames(result) = c("crit1", "crit2", "crit3", "result_value", "ranking")
print(result)
##      crit1 crit2 crit3 result_value ranking
## [1,]     4     5     3     3.892240       5
## [2,]     1     3     9     2.566257       8
## [3,]     8     6     4     7.146454       3
## [4,]     3     2     7     3.642293       7
## [5,]     6     7     5     5.892240       4
## [6,]     4     5     3     3.892240       5
## [7,]    NA     9     9           NA      NA
## [8,]    NA    NA    NA           NA      NA

Obviously, since AHP is a hierarchical process the result from one calculation can be merged with outcomes from another calculation (ie. using cbind command) and used as input to another AHP calculation.

Fuzzy AHP

Fuzzy Pairwise Comparison Matrix Creation

The fuzzy pairwise comparison matrix is an extended version of pairwise comparison matrix constructed with respect to fuzzy scale. Details about fuzzy AHP are provided in several articles by Laarhoven and Pedrycz (1983) and Chang (1996).

comparisonMatrixValues = c("1","9","5",
                       "1/9","1","1/3",
                       "1/5","3","1")
comparisonMatrix = matrix(comparisonMatrixValues, nrow = 3, ncol = 3, byrow = TRUE)
comparisonMatrix = pairwiseComparisonMatrix(comparisonMatrix)

Due to the fact, that checking of fuzzy comparsion matrix consistency is relatively complicated, it is simpler to check the non fuzzy matrix and assume that if non fuzzy matrix is consistend than so is the fuzzy matrix. The checks are described above.

The comparison matrix is fuzzified with respect to the fuzzy scale. Default fuzzy scale ranging from 1 to 9 with width of fuzzy number equal to 2 is provided. However, user can specify his own fuzzy scale. For the details please see documentation.

fuzzyComparisonMatrix = fuzzyPairwiseComparisonMatrix(comparisonMatrix)
print(fuzzyComparisonMatrix)
##      [,1]                    [,2]      [,3]               
## [1,] "(1;1;1)"               "(8;9;9)" "(4;5;6)"          
## [2,] "(0.1111;0.1111;0.125)" "(1;1;1)" "(0.25;0.3333;0.5)"
## [3,] "(0.1667;0.2;0.25)"     "(2;3;4)" "(1;1;1)"

Calculations with Fuzzy Pairwise Comparison Matrix

With the fuzzy comparion matrix the result of AHP process can be calculated in the same way as with classic comparison matrix. The weights of fuzzy comparison matrix are calculated by approach desribed by Krejčí, Pavlačka, and Talašová (2016).

result = calculateAHP(fuzzyComparisonMatrix, values)

The resulting values have issue of representing uncertaint value. Such values are hard to present to user directly. Even though it is possible. The user can extract singe fuzzy numbers from the set.

fuzzyNumer = getFuzzyNumber(result, as.integer(2))
print(fuzzyNumer)
##      minimal    modal  maximal
## [1,] 2.17584 2.566257 3.055858

It might be reasonable for user to either defuzzify the values into single output or rank then using fuzzy ranking methods. Defuzzification can be done using several approaches, here Yager’s index is used as described by Tesfamariam and Sadiq (2006). The results of defuzzification can be ranked as classic results of AHP.

defuzzified = defuzziffy(result, "Yager")
print(defuzzified)
##          [,1]
## [1,] 3.897250
## [2,] 2.599318
## [3,] 7.135438
## [4,] 3.654089
## [5,] 5.899425
## [6,] 3.897250
## [7,]       NA
## [8,]       NA
rank = (nrow(values)+1) - rank(defuzzified, na.last = FALSE, ties.method= "max")
print(rank)
## [1] 3 6 1 5 2 3 8 7

Ranking of fuzzy numbers can be done using various approaches. One of them is Chen’s method described by Tesfamariam and Sadiq (2006).

ranked = compareFuzzyNumbers(result, "Chen")
print(ranked)
##           [,1]
## [1,] 0.3241398
## [2,] 0.1067964
## [3,] 0.8682673
## [4,] 0.2849724
## [5,] 0.6625851
## [6,] 0.3241398
## [7,]        NA
## [8,]        NA

Another possibility is the utilization of possibility theory as described by Dubois and Prade (1983). These indices work very well if there is a relatively bigger set of very good solutions. Unlike defuzzification or other methods these indices can rank them very well. However, if there is only one dominant best solution the result might not be very descriptive.

For large datasets the calculation might take a while. Because of that a graphical progressbar can be printed if it is turn on by progressBar parameter.

ranked = compareFuzzyNumbers(result, "possibilityTheory")
# ranked = compareFuzzyNumbers(result, "possibilityTheory", progressBar = TRUE)
print(ranked)
##      possiblity necessity
## [1,]          0         0
## [2,]          0         0
## [3,]          1         1
## [4,]          0         0
## [5,]          0         0
## [6,]          0         0
## [7,]         NA        NA
## [8,]         NA        NA

References

Basile, L., and L. D’Apuzzo. 1997. “Ranking and weak consistency in the A.H.P. context.” Rivista Di Matematica Per Le Scienze Economiche E Sociali 20 (1): 99–109.

Chang, Da-Yong. 1996. “Applications of the extent analysis method on fuzzy AHP.” European Journal of Operational Research 95 (3): 649–55. doi:10.1016/0377-2217(95)00300-2.

Dubois, Didier, and Henri Prade. 1983. “Ranking Fuzzy Numbers in the Setting of Possibility Theory.” Information Sciences 30 (3): 183–224.

Krejčí, Jana, Ondřej Pavlačka, and Jana Talašová. 2016. “A fuzzy extension of Analytic Hierarchy Process based on the constrained fuzzy arithmetic.” Fuzzy Optimization and Decision Making. doi:10.1007/s10700-016-9241-0.

Laarhoven, P.J.M. van, and W. Pedrycz. 1983. “A fuzzy extension of Saaty’s priority theory.” Fuzzy Sets and Systems 11 (1): Pages 229–41.

Saaty, T.L. 1980. The Analytical Hierarchy Process. New York: McGraw Hill.

Saaty, Thomas L., and Liem T. Tran. 2007. “On the invalidity of fuzzifying numerical judgments in the Analytic Hierarchy Process.” Mathematical and Computer Modelling 46 (7-8): 962–75. doi:10.1016/j.mcm.2007.03.022.

Stoklasa, Jan, Věra Jandová, and Jana Talašová. 2013. “Weak consistency in Saaty’s AHP - evaluating creative work outcomes of Czech Art Colleges.” Neural Network World 23 (1): 61–77. doi:10.14311/NNW.2013.23.005.

Tesfamariam, Solomon, and Rehan Sadiq. 2006. “Risk-based environmental decision-making using fuzzy analytic hierarchy process (F-AHP).” Stochastic Environmental Research and Risk Assessment 21 (1): 35–50. doi:10.1007/s00477-006-0042-9.