Skip to content

Commit

Permalink
add LMAW method
Browse files Browse the repository at this point in the history
  • Loading branch information
bahadirfyildirim committed Nov 18, 2023
1 parent b444a25 commit 0a95391
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Please check out the reference manual [here](https://jbytecode.github.io/JMcDM/)
- ELECTRE (Elimination and Choice Translating Reality)
- Entropy
- GRA (Grey Relational Analysis)
- LMAW (Logarithm Methodology of Additive Weights)
- LOPCOW (LOgarithmic Percentage Change-driven Objective Weighting)
- MABAC (Multi-Attributive Border Approximation area Comparison)
- MAIRCA (Multi Attributive Ideal-Real Comparative Analysis)
Expand Down
5 changes: 5 additions & 0 deletions src/JMcDM.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ include("moosra.jl")
include("merec.jl")
include("lopcow.jl")
include("ocra.jl")
include("lmaw.jl")

include("summary.jl")

Expand Down Expand Up @@ -157,6 +158,7 @@ import .MEREC: merec, MERECResult, MERECMethod
import .PIV: piv, PIVResult, PIVMethod
import .LOPCOW: lopcow, LOPCOWResult, LOPCOWMethod
import .OCRA: ocra, OCRAResult, OCRAMethod
import .LMAW: lmaw, LMAWResult, LMAWMethod

import .SCDM: LaplaceResult, MaximinResult, MaximaxResult, MinimaxResult, MiniminResult
import .SCDM: SavageResult, HurwiczResult, MLEResult, ExpectedRegretResult
Expand Down Expand Up @@ -199,6 +201,7 @@ export MERECMethod
export PIVMethod
export LOPCOWMethod
export OCRAMethod
export LMAWMethod


export MCDMSetting
Expand Down Expand Up @@ -235,6 +238,7 @@ export MERECResult
export PIVResult
export LOPCOWResult
export OCRAResult
export LMAWResult

#  export SCDM types
export SCDMResult
Expand Down Expand Up @@ -289,6 +293,7 @@ export merec
export piv
export lopcow
export ocra
export lmaw

#  export SCDM tools
export laplace
Expand Down
140 changes: 140 additions & 0 deletions src/lmaw.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@

module LMAW

export lmaw, LMAWResult, LMAWMethod

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

using ..Utilities

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

struct LMAWMethod <: MCDMMethod
normalization::G where {G <: Function}
end

LMAWMethod() = LMAWMethod(Normalizations.dividebycolumnmaxminnormalization)

"""
lmaw(decisionMat, weights, fns; normalization)
Apply LMAW (Logarithm Methodology of Additive Weights) 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.
- `normalization{<:Function}`: Optional normalization function.
# Description
lmaw() applies the LMAW method to rank m alternatives subject to n criteria which are supposed to be
either maximized or minimized.
# Output
- `::LMAWResult`: LMAWResult object that holds multiple outputs including scores, rankings, and best index.
# Examples
```julia-repl
julia> decMat = [
647.34 6.24 49.87 19.46 212.58 6.75;
115.64 3.24 16.26 9.69 207.59 3.00;
373.61 5.00 26.43 12.00 184.62 3.74;
37.63 2.48 2.85 9.25 142.50 3.24;
858.01 4.74 62.85 45.96 267.95 4.00;
222.92 3.00 19.24 21.46 221.38 3.49
]
6×6 Matrix{Float64}:
647.34 6.24 49.87 19.46 212.58 6.75
115.64 3.24 16.26 9.69 207.59 3.0
373.61 5.0 26.43 12.0 184.62 3.74
37.63 2.48 2.85 9.25 142.5 3.24
858.01 4.74 62.85 45.96 267.95 4.0
222.92 3.0 19.24 21.46 221.38 3.49
julia> weights = [0.215, 0.126, 0.152, 0.091, 0.19, 0.226];
julia> fns = [maximum, maximum, minimum, minimum, minimum, maximum];
julia> result = lmaw(decmat, weights, fns);
julia> result.scores
6-element Vector{Float64}:
4.839005264308832
4.679718180594332
4.797731427991642
4.732145373983716
4.73416833375772
4.702247270959649
julia> result.bestIndex
1
```
# References
- Pamučar, D., Žižović, M., Biswas, S., & Božanić, D. (2021). A new logarithm methodology of additive weights (LMAW) for multi-criteria decision-making: Application in logistics. Facta Universitatis, Series: Mechanical Engineering, 19(3), 361. https://doi.org/10.22190/FUME210214031P
"""
function lmaw(
decisionMat::Matrix,
weights::Array{Float64,1},
fns::Array{F,1};
normalization::G = Normalizations.dividebycolumnmaxminnormalization
)::LMAWResult where {F<:Function, G<:Function}

row, col = size(decisionMat)
w = unitize(weights)

colMax = colmaxs(decisionMat)
colMin = colmins(decisionMat)
A = normalization(decisionMat, fns) .+1
zerotype = eltype(A)
Q = zeros(zerotype, row, col)
N = log.(A)
a = log.(apply_columns(prod, A))
scores = zeros(zerotype, row)
for j=1:col
N[:,j] = N[:,j]./ a[j]
Q[:,j] = (2 .* N[:,j] .^ w[j]) ./ ((2 .- N[:,j]) .^ w[j] + N[:,j] .^ w[j])
end

for i = 1:row
scores[i] = sum(Q[i, :])
end

rankings = sortperm(scores)

bestIndex = rankings |> last

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

return result
end

"""
lmaw(setting)
Apply LMAW (Logarithm Methodology of Additive Weights) for a given matrix and weights.
# Arguments:
- `setting::MCDMSetting`: MCDMSetting object.
# Description
lmaw() applies the LMAW method to rank m alternatives subject to n criteria which are supposed to be
either maximized or minimized.
# Output
- `::LMAWResult`: LMAWResult object that holds multiple outputs including scores, rankings, and best index.
"""
function lmaw(setting::MCDMSetting)::LMAWResult
lmaw(setting.df, setting.weights, setting.fns)
end

end # end of module LMAW
9 changes: 6 additions & 3 deletions src/mcdm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,24 @@ julia> subtypes(MCDMMethod)
EdasMethod
ElectreMethod
GreyMethod
LMAWMethod
LOPCOWMethod
MERECMethod
MabacMethod
MaircaMethod
MarcosMethod
MERECMethod
MooraMethod
MoosraMethod
OCRAMethod
PIVMethod
PSIMethod
PrometheeMethod
PSIMethod
ROVMethod
SawMethod
TopsisMethod
VikorMethod
WPMMethod
WaspasMethod
WPMMethod
julia> # mcdm() for Topsis:
Expand Down Expand Up @@ -113,6 +114,8 @@ function mcdm(
lopcow(df, fns)
elseif method isa OCRAMethod
ocra(df, w, fns)
elseif method isa OCRAMethod
lmaw(df, w, fns)
elseif method isa PIVMethod
piv(df, w, fns)
else
Expand Down
33 changes: 33 additions & 0 deletions test/testmcdm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1515,4 +1515,37 @@
@test result2.scores == result.scores
end

@testset "LMAW" begin
tol = 0.0001
decisionMat = [
647.34 6.24 49.87 19.46 212.58 6.75;
115.64 3.24 16.26 9.69 207.59 3.00;
373.61 5.00 26.43 12.00 184.62 3.74;
37.63 2.48 2.85 9.25 142.50 3.24;
858.01 4.74 62.85 45.96 267.95 4.00;
222.92 3.00 19.24 21.46 221.38 3.49
]
weights = [0.215, 0.126, 0.152, 0.091, 0.19, 0.226]
fns = [maximum, maximum, minimum, minimum, minimum, maximum]

result = lmaw(decisionMat, weights, fns)
@test result isa LMAWResult
@test isapprox(
result.scores,
[
4.839005264308832,
4.679718180594332,
4.797731427991642,
4.732145373983716,
4.73416833375772,
4.702247270959649,
],
atol = tol,
)

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

0 comments on commit 0a95391

Please sign in to comment.