Skip to content

Commit

Permalink
Merge pull request jbytecode#54 from bahadirfyildirim/main
Browse files Browse the repository at this point in the history
add OCRA method
  • Loading branch information
jbytecode authored Nov 17, 2023
2 parents 12c1c40 + 1619adb commit b444a25
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 31 deletions.
63 changes: 32 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,39 +94,40 @@ Please check out the reference manual [here](https://jbytecode.github.io/JMcDM/)

### MCDM Tools

- TOPSIS (Technique for Order Preference by Similarity to Ideal Solutions)
- ELECTRE (Elimination and Choice Translating Reality)
- DEMATEL (The Decision Making Trial and Evaluation Laboratory)
- MOORA Reference (Multi-Objective Optimization By Ratio Analysis)
- MOORA Ratio
- VIKOR (VlseKriterijumska Optimizcija I Kaompromisno Resenje in Serbian)
- AHP (Analytic Hierarchy Process)
- DEA (Data Envelopment Analysis)
- GRA (Grey Relational Analysis)
- Non-dominated Sorting
- SAW (Simple Additive Weighting) (aka WSM)
- ARAS (Additive Ratio Assessment)
- WPM (Weighted Product Model)
- WASPAS (Weighted Aggregated Sum Product ASsessment)
- EDAS (Evaluation based on Distance from Average Solution)
- MARCOS (Measurement Alternatives and Ranking according to COmpromise Solution)
- MABAC (Multi-Attributive Border Approximation area Comparison)
- MAIRCA (Multi Attributive Ideal-Real Comparative Analysis)
- COPRAS (COmplex PRoportional ASsessment)
- PROMETHEE (Preference Ranking Organization METHod for Enrichment of Evaluations)
- CoCoSo (Combined Compromise Solution)
- CRITIC (CRiteria Importance Through Intercriteria Correlation)
- Entropy
- CODAS (COmbinative Distance-based ASsessment)
- Copeland (For combining multiple ordering results)
- SD Method for determining weights of criteria
- ROV (Range of Value) Method
- PSI (Preference Selection Index) Method
- MOOSRA (Multi-Objective Optimization on the basis of Simple Ratio Analysis) Method
- COPRAS (COmplex PRoportional ASsessment)
- CRITIC (CRiteria Importance Through Intercriteria Correlation)
- DEA (Data Envelopment Analysis)
- DEMATEL (The Decision Making Trial and Evaluation Laboratory)
- EDAS (Evaluation based on Distance from Average Solution)
- ELECTRE (Elimination and Choice Translating Reality)
- Entropy
- GRA (Grey Relational Analysis)
- LOPCOW (LOgarithmic Percentage Change-driven Objective Weighting)
- MABAC (Multi-Attributive Border Approximation area Comparison)
- MAIRCA (Multi Attributive Ideal-Real Comparative Analysis)
- MARCOS (Measurement Alternatives and Ranking according to COmpromise Solution)
- MEREC (MEthod based on the Removal Effects of Criteria) for determining weights
- MOORA Ratio
- MOORA Reference (Multi-Objective Optimization By Ratio Analysis)
- MOOSRA (Multi-Objective Optimization on the basis of Simple Ratio Analysis) Method
- Non-dominated Sorting
- OCRA (Operational Competitiveness RAting)
- PIV (Proximity Indexed Value) method
- PROMETHEE (Preference Ranking Organization METHod for Enrichment of Evaluations)
- PSI (Preference Selection Index) Method
- ROV (Range of Value) Method
- SAW (Simple Additive Weighting) (aka WSM)
- SD Method for determining weights of criteria
- SECA (Simultaneous Evaluation of Criteria and Alternatives)
- LOPCOW (LOgarithmic Percentage Change-driven Objective Weighting)
- TOPSIS (Technique for Order Preference by Similarity to Ideal Solutions)
- VIKOR (VlseKriterijumska Optimizcija I Kaompromisno Resenje in Serbian)
- WASPAS (Weighted Aggregated Sum Product ASsessment)
- WPM (Weighted Product Model)

### SCDM Tools

Expand All @@ -145,18 +146,18 @@ Please check out the reference manual [here](https://jbytecode.github.io/JMcDM/)
- Game solver for zero sum games

## Unimplemented methods
- UTA
- MAUT
- STEM
- PAPRIKA
- ANP (Analytical Network Process)
- COMET
- Goal Programming
- MACBETH
- COMET
- SWARA
- MAUT
- ORESTE
- PAPRIKA
- SMAA
- STEM
- SWARA
- TODIM
- UTA

- will be updated soon.

Expand Down
6 changes: 6 additions & 0 deletions src/JMcDM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ include("psi.jl")
include("moosra.jl")
include("merec.jl")
include("lopcow.jl")
include("ocra.jl")

include("summary.jl")

Expand Down Expand Up @@ -155,6 +156,7 @@ import .AHP: ahp, ahp_consistency, ahp_RI, AHPResult, AHPConsistencyResult
import .MEREC: merec, MERECResult, MERECMethod
import .PIV: piv, PIVResult, PIVMethod
import .LOPCOW: lopcow, LOPCOWResult, LOPCOWMethod
import .OCRA: ocra, OCRAResult, OCRAMethod

import .SCDM: LaplaceResult, MaximinResult, MaximaxResult, MinimaxResult, MiniminResult
import .SCDM: SavageResult, HurwiczResult, MLEResult, ExpectedRegretResult
Expand Down Expand Up @@ -196,6 +198,8 @@ export ROVMethod
export MERECMethod
export PIVMethod
export LOPCOWMethod
export OCRAMethod


export MCDMSetting

Expand Down Expand Up @@ -230,6 +234,7 @@ export MoosraResult
export MERECResult
export PIVResult
export LOPCOWResult
export OCRAResult

#  export SCDM types
export SCDMResult
Expand Down Expand Up @@ -283,6 +288,7 @@ export moosra
export merec
export piv
export lopcow
export ocra

#  export SCDM tools
export laplace
Expand Down
3 changes: 3 additions & 0 deletions src/mcdm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ julia> subtypes(MCDMMethod)
MarcosMethod
MooraMethod
MoosraMethod
OCRAMethod
PIVMethod
PSIMethod
PrometheeMethod
Expand Down Expand Up @@ -110,6 +111,8 @@ function mcdm(
merec(df, fns)
elseif method isa LOPCOWMethod
lopcow(df, fns)
elseif method isa OCRAMethod
ocra(df, w, fns)
elseif method isa PIVMethod
piv(df, w, fns)
else
Expand Down
152 changes: 152 additions & 0 deletions src/ocra.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
module OCRA

export ocra, OCRAResult, OCRAMethod

import ..MCDMMethod, ..MCDMResult, ..MCDMSetting

using ..Utilities

struct OCRAResult <: MCDMResult
decisionMatrix::Matrix
weights::Array{Float64,1}
scores::Vector
ranking::Array{Int64,1}
bestIndex::Int64
end

"""
ocra(decisionMat, weights, fns)
Apply ORCA (Operational Competitiveness RAting) for a given matrix and weights.
# Arguments:
- `decisionMat::Matrix`: m × n matrix of objective values for n alternatives and m criteria
- `weights::Array{Float64, 1}`: n-vector of weights that sum up to 1.0. If the sum of weights is not 1.0, it is automatically normalized.
- `fns::Array{<:Function, 1}`: n-vector of functions to be applied on the columns.
# Description
ocra() applies the OCRA method to rank m alternatives subject to n criteria which are supposed to be
either maximized or minimized.
# Output
- `::OCRAResult`: OCRAResult object that holds multiple outputs including scores, rankings, and best index.
# Examples
```julia-repl
julia> decMat = [
8.0 16.0 1.5 1.2 4200.0 5.0 5.0 314.0 185.0;
8.0 16.0 1.0 1.3 4200.0 5.0 4.0 360.0 156.0;
10.1 16.0 2.0 1.3 4060.0 5.0 3.0 503.0 160.0;
10.1 8.0 1.0 1.5 5070.0 2.0 4.0 525.0 200.0;
10.0 16.0 2.0 1.2 6350.0 5.0 3.0 560.0 190.0;
10.1 16.0 1.0 1.2 5500.0 2.0 2.0 521.0 159.0;
10.1 64.0 2.0 1.7 5240.0 5.0 3.0 770.0 199.0;
7.0 32.0 1.0 1.8 3000.0 3.0 4.0 364.0 157.0;
10.1 16.0 1.0 1.3 3540.0 5.0 3.0 510.0 171.0;
9.7 16.0 2.0 1.83 7500.0 6.0 2.0 550.0 170.0
]
10×9 Matrix{Float64}:
8.0 16.0 1.5 1.2 4200.0 5.0 5.0 314.0 185.0
8.0 16.0 1.0 1.3 4200.0 5.0 4.0 360.0 156.0
10.1 16.0 2.0 1.3 4060.0 5.0 3.0 503.0 160.0
10.1 8.0 1.0 1.5 5070.0 2.0 4.0 525.0 200.0
10.0 16.0 2.0 1.2 6350.0 5.0 3.0 560.0 190.0
10.1 16.0 1.0 1.2 5500.0 2.0 2.0 521.0 159.0
10.1 64.0 2.0 1.7 5240.0 5.0 3.0 770.0 199.0
7.0 32.0 1.0 1.8 3000.0 3.0 4.0 364.0 157.0
10.1 16.0 1.0 1.3 3540.0 5.0 3.0 510.0 171.0
9.7 16.0 2.0 1.83 7500.0 6.0 2.0 550.0 170.0
julia> weights =[0.167, 0.039, 0.247, 0.247, 0.116, 0.02, 0.056, 0.027, 0.081];
julia> fns = [maximum,maximum,maximum,maximum,maximum,maximum,maximum,minimum,minimum];
julia> result = ocra(decmat, weights, fns);
julia> result.scores
10-element Vector{Float64}:
0.14392093908214929
0.024106550710436096
0.27342011595623067
0.04297916544177691
0.31851953804157623
0.0024882426914910674
0.5921715172301161
0.11390289470614312
0.0
0.47874854984718046
julia> result.bestIndex
7
```
# References
- Parkan, C. (1994). Operational competitiveness ratings of production units. Managerial and Decision Economics, 15(3), 201–221. doi:10.1002/mde.4090150303 
- Parkan, C. (2003). Measuring the effect of a new point of sale system on the performance of drugstore operations. Computers & Operations Research, 30(5), 729–744. doi:10.1016/s0305-0548(02)00047-3 
- Kundakcı, N. (2017). An Integrated Multi-Criteria Decision Making Approach for Tablet Computer Selection. European Journal of Multidisciplinary Studies, 2(5), 31-43.
"""
function ocra(
decisionMat::Matrix,
weights::Array{Float64,1},
fns::Array{F,1};
)::OCRAResult where {F<:Function}

row, col = size(decisionMat)
w = unitize(weights)
zerotype = eltype(decisionMat)
I1 = zeros(zerotype, row)
I2 = zeros(zerotype, row)
O1 = zeros(zerotype, row)
O2 = zeros(zerotype, row)
scores = zeros(zerotype, row)

colMax = colmaxs(decisionMat)
colMin = colmins(decisionMat)

for i = 1:row
for j = 1:col
if fns[j] == minimum
I1[i] += w[j]*(colMax[j] - decisionMat[i,j])/colMin[j]
else
O1[i] += w[j]*(decisionMat[i,j] - colMin[j])/colMin[j]
end
end
end

I2 = I1 .- minimum(I1)
O2 = O1 .- minimum(O1)
scores = I2 .+ O2
scores = scores .- minimum(scores)

rankings = sortperm(scores)

bestIndex = rankings |> last

result = OCRAResult(decisionMat, w, scores, rankings, bestIndex)

return result
end

"""
ocra(setting)
Apply OCRA (Operational Competitiveness RAting) for a given matrix and weights.
# Arguments:
- `setting::MCDMSetting`: MCDMSetting object.
# Description
ocra() applies the OCRA method to rank m alternatives subject to n criteria which are supposed to be
either maximized or minimized.
# Output
- `::OCRAResult`: OCRAResult object that holds multiple outputs including scores, rankings, and best index.
"""
function ocra(setting::MCDMSetting)::OCRAResult
ocra(setting.df, setting.weights, setting.fns)
end

end # end of module OCRA
43 changes: 43 additions & 0 deletions test/testmcdm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1472,4 +1472,47 @@
@test result2 isa LOPCOWResult
@test result2.w == result.w
end

@testset "OCRA" begin
tol = 0.0001
decisionMat = [
8.0 16.0 1.5 1.2 4200.0 5.0 5.0 314.0 185.0;
8.0 16.0 1.0 1.3 4200.0 5.0 4.0 360.0 156.0;
10.1 16.0 2.0 1.3 4060.0 5.0 3.0 503.0 160.0;
10.1 8.0 1.0 1.5 5070.0 2.0 4.0 525.0 200.0;
10.0 16.0 2.0 1.2 6350.0 5.0 3.0 560.0 190.0;
10.1 16.0 1.0 1.2 5500.0 2.0 2.0 521.0 159.0;
10.1 64.0 2.0 1.7 5240.0 5.0 3.0 770.0 199.0;
7.0 32.0 1.0 1.8 3000.0 3.0 4.0 364.0 157.0;
10.1 16.0 1.0 1.3 3540.0 5.0 3.0 510.0 171.0;
9.7 16.0 2.0 1.83 7500.0 6.0 2.0 550.0 170.0
]
fns = [maximum,maximum,maximum,maximum,maximum,maximum,maximum,minimum,minimum]
weights =[0.167, 0.039, 0.247, 0.247, 0.116, 0.02, 0.056, 0.027, 0.081]

result = ocra(decisionMat, weights, fns)
@test result isa OCRAResult
@test isapprox(
result.scores,
[
0.1439209390821490,
0.0241065507104361,
0.2734201159562310,
0.0429791654417769,
0.3185195380415760,
0.0024882426914911,
0.5921715172301160,
0.1139028947061430,
0.0000000000000000,
0.4787485498471800,
],
atol = tol,
)

setting = MCDMSetting(decisionMat, weights, fns)
result2 = ocra(setting)
@test result2 isa OCRAResult
@test result2.scores == result.scores
end

end

0 comments on commit b444a25

Please sign in to comment.