Skip to content

Commit a15bbc5

Browse files
committed
implement LMAW
1 parent 21632c0 commit a15bbc5

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/main/scala/lmaw.scala

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.expr.mcdm
2+
3+
import scala.math.log
4+
5+
case class LmawResult (
6+
normalizedDecisionMatrix: Mat,
7+
Q: Mat,
8+
N: Mat,
9+
a: Vec,
10+
scores: Vec,
11+
orderings: VecInt,
12+
best: Int
13+
) extends MCDMResult
14+
15+
def lmaw(
16+
decmat: Mat,
17+
weights: Vec,
18+
directions: Array[Direction],
19+
normalization: NormalizationFunction =
20+
Normalization.DivideByColumnMaxMinNormalization,
21+
options: Map[String, Any] = Map.empty
22+
): LmawResult =
23+
24+
def prod(a: Vec): Double = a.product
25+
26+
val (row, col) = Matrix.size(decmat)
27+
28+
val colMax = Matrix.colmaxs(decmat)
29+
30+
val colMin = Matrix.colmins(decmat)
31+
32+
val A = normalization(decmat, weights, directions).map(row => row.map(_ + 1.0))
33+
34+
var Q = Matrix.zeros(row, col)
35+
36+
var N = A.map(row => row.map(log))
37+
38+
val a = Matrix.applyFunctionToColumns(A, prod).map(element => log(element))
39+
40+
for j <- 0 until col do
41+
N = Matrix.setcolat(N, j, Matrix.getcolat(N, j).map(_ / a(j)))
42+
Q = Matrix.setcolat(Q, j,
43+
Matrix.getcolat(N, j).map(x => (2.0 * Math.pow(x, weights(j))) /
44+
(Math.pow(2.0 - x, weights(j)) + Math.pow(x, weights(j))))
45+
)
46+
47+
48+
val scores = Q.map(row => row.sum)
49+
50+
val orderings = scores.zipWithIndex.sortBy(-_._1).map(_._2)
51+
52+
val best = orderings.head
53+
54+
LmawResult(
55+
A,
56+
Q,
57+
N,
58+
a,
59+
scores,
60+
orderings,
61+
best
62+
)

src/test/scala/testlmaw.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import munit.Assertions as A
2+
3+
import org.expr.mcdm.lmaw
4+
import org.expr.mcdm.Direction.{Maximize, Minimize}
5+
import org.expr.mcdm.Matrix
6+
7+
class TestLmaw extends munit.FunSuite {
8+
test("LMAW Example - 1") {
9+
10+
val decmat = Array(
11+
Array(647.34, 6.24, 49.87, 19.46, 212.58, 6.75),
12+
Array(115.64, 3.24, 16.26, 9.69, 207.59, 3.00),
13+
Array(373.61, 5.00, 26.43, 12.00, 184.62, 3.74),
14+
Array(37.63, 2.48, 2.85, 9.25, 142.50, 3.24),
15+
Array(858.01, 4.74, 62.85, 45.96, 267.95, 4.00),
16+
Array(222.92, 3.00, 19.24, 21.46, 221.38, 3.49)
17+
)
18+
19+
val weights = Array(0.215, 0.126, 0.152, 0.091, 0.19, 0.226)
20+
21+
val fns = Array(Maximize, Maximize, Minimize, Minimize, Minimize, Maximize)
22+
23+
val result = lmaw(decmat, weights, fns)
24+
25+
val expected_scores = Array(4.839005264308832, 4.679718180594332,
26+
4.797731427991642, 4.732145373983716, 4.73416833375772, 4.702247270959649)
27+
28+
val expected_best_index = 0
29+
30+
A.assert(Matrix.elementwise_equal(result.scores, expected_scores, 1e-6),
31+
s"Expected scores: ${Matrix.prettyPrint(expected_scores)} but got: ${Matrix.prettyPrint(result.scores)}")
32+
A.assertEquals(result.best, expected_best_index,
33+
s"Expected best index: $expected_best_index but got: ${result.best}")
34+
}
35+
}

0 commit comments

Comments
 (0)