roptimizationoperations-research

How to use PROMETHEE multicriteria method in R


I used TOPSIS multicriteria method to select the best number of clusters out of the 34 options. As weights I used 0.5 for each criterion. The coverage criterion is to minimize and the production criterion is to maximize. With these same conditions, I would like to use the PROMETHEE multicriteria method. From what I saw there is a PROMETHEE package in R (https://cran.r-project.org/web/packages/PROMETHEE/index.html), but unfortunately I couldn't do it for my case.

Can you help me?

I left the TOPSIS code to give you an idea of what I want, which is to rank the best alternatives. In this case, the best option is the cluster number equal to 2, as it ranked 1st.

library(topsis)

df1<-structure(list(nclusters = c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 
28, 29, 30, 31, 32, 33, 34, 35), Coverage = c(0.0363201192049018, 
0.0315198954715543, 0.112661460735583, 0.112661460735583, 0.112661460735583, 
0.0813721071219816, 0.0862146652218061, 0.0697995564757394, 0.0599194966471805, 
0.0507632014547115, 0.052076958349629, 0.052076958349629, 0.052076958349629, 
0.052076958349629, 0.052076958349629, 0.052076958349629, 0.0410332568832433, 
0.0389940601722214, 0.0441742111970355, 0.0441742111970355, 0.0441742111970355, 
0.0438099091238968, 0.0409906284310306, 0.0409906284310306, 0.035480410134286, 
0.035480410134286, 0.035480410134286, 0.035480410134286, 0.035480410134286, 
0.035480410134286, 0.035480410134286, 0.0345381204372174, 0.0287729883480053, 
0.0287729883480053), Production = c(1635156.04305, 474707.64025, 
170773.40775, 64708.312, 64708.312, 64708.312, 949.72635, 949.72635, 
949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 
949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 
949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 
949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 949.72635, 
949.72635, 949.72635)), class = "data.frame", row.names = c(NA,-34L))
 
row.names(df1) <- df1$nclusters
df2 <- df1[c(2:3)]
df2<-data.matrix(df2)
w <- c(0.5,0.5) 
i <- c("-", "+") 
result<-topsis(df2, w, i)
result<-data.frame(nclusters = df1[,1],result[,2:3])

> result
   nclusters      score rank
1          2 0.97709831  1.0
2          3 0.35391229  2.0
3          4 0.09999171 30.0
4          5 0.03763326 33.5
5          6 0.03763326 33.5
6          7 0.09914059 31.0
7          8 0.07676999 32.0
8          9 0.11960647 29.0
9         10 0.14366970 28.0
10        11 0.16484786 21.0
11        12 0.16187453 24.5
12        13 0.16187453 24.5
13        14 0.16187453 24.5
14        15 0.16187453 24.5
15        16 0.16187453 24.5
16        17 0.16187453 24.5
17        18 0.18619947 16.0
18        19 0.19052672 13.0
19        20 0.17943485 19.0
20        21 0.17943485 19.0
21        22 0.17943485 19.0
22        23 0.18022565 17.0
23        24 0.18629045 14.5
24        25 0.18629045 14.5
25        26 0.19786466  9.0
26        27 0.19786466  9.0
27        28 0.19786466  9.0
28        29 0.19786466  9.0
29        30 0.19786466  9.0
30        31 0.19786466  9.0
31        32 0.19786466  9.0
32        33 0.19980731  5.0
33        34 0.21146288  3.5
34        35 0.21146288  3.5

Solution

  • This closely follows the vignette of the PROMETHEE package, but is hopefully helpful to clarify how to adapt it for the example shown in the question.

    setup

    For each argument to the PROMETHEE function, an (alternatives x criteria) matrix needs to be provided. This means that e.g. maximizing the production needs to be specified for each alternative (row) and not only once.

    # Preference function (options: Level, Linear, V-shape and Gaussian)
    PreferenceF <- data.frame(
      "Coverage" = rep("Linear", nrow(df2)), "Production" = rep("Linear", nrow(df2))
    )
    
    # Preference threshold - to match the topsis results, we set this 
    # so high that that it will not effect the results
    PreferenceT <- data.frame(
      "Coverage" = rep(0.2, nrow(df2)), "Production" = rep(2e6, nrow(df2))
    )
    
    # indifference threshold - not used to reproduce topsis results
    IndifferenceT <- data.frame(
      "Coverage" = rep(0, nrow(df2)), "Production" = rep(0, nrow(df2))
    )
    
    # gauss preference threshold: only relevant to preference function "Gaussian"
    S_Gauss <- data.frame(
      "Coverage" = rep(0, nrow(df2)), "Production" = rep(0, nrow(df2))
    )
    
    # weights - use 0.5 as in the question
    Weights <- data.frame(
      "Coverage" = rep(0.5, nrow(df2)), "Production" = rep(0.5, nrow(df2))
    )
    
    # specify which parameters need to be minimized or maximized
    Min_Max <- data.frame(
      "Coverage" = rep("min", nrow(df2)), "Production" = rep("max", nrow(df2))
    )
    
    

    optimization

    For ranking I've picked the PROMETHEE2 score (net preference flow), but other scores are available from the PFobject.

    library(PROMETHEE)
    library(dplyr)
    
    PF <- PROMETHEE(df2, PreferenceF, PreferenceT, IndifferenceT, Weights, Min_Max, S_Gauss)
    
    result2 <- data.frame(nclusters = df1$nclusters, score = PF$PROMETHEE2) %>%
      dplyr::arrange(desc(score)) %>%
      rownames_to_column(var = "rank")
    
    result2 %>% head()
    
      rank nclusters      score
    1    1         2 0.22044145
    2    2         3 0.07717187
    3    3        34 0.01969528
    4    4        35 0.01969528
    5    5        33 0.01227048
    6    6        26 0.01105693
    

    Comparing the top results to the TOPSIS ranking shown in the question shows good agreement (though tiebreaker seem to be handled differently).

    result %>% arrange(rank) %>% head()
    
      nclusters     score rank
    1         2 0.9770983  1.0
    2         3 0.3539123  2.0
    3        34 0.2114629  3.5
    4        35 0.2114629  3.5
    5        33 0.1998073  5.0
    6        26 0.1978647  9.0