Skip to content

Commit

Permalink
end electre 1
Browse files Browse the repository at this point in the history
  • Loading branch information
leliel12 committed Feb 21, 2016
1 parent 8b10b66 commit af96bc2
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 24 deletions.
2 changes: 1 addition & 1 deletion skcriteria/common/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def criteriarr(criteria):

def is_mtx(mtx, size=None):
try:
a, b = mtx.shapeW
a, b = mtx.shape
if size and (a, b) != size:
return False
except:
Expand Down
23 changes: 15 additions & 8 deletions skcriteria/electre.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,21 @@ def electre1(mtx, criteria, weights=1):
# This guarantee the criteria array consistency
ncriteria = util.criteriarr(criteria)

# validate the matrix is the matrix
nmtx = np.asarray(mtx)
if not util.is_mtx(nmtx):
raise ValueError("'mtx' is not a matrix")

# normalize weights
# normalize
nmtx = norm.sum(mtx)
nweights = norm.sum(weights) if weights is not None else 1

# get the concordance matrix
mtx_concordance = concordance(nmtx, nweights)
# get the concordance and discordance info
mtx_concordance, _, p = concordance(nmtx, ncriteria, nweights)
mtx_discordance, _, q = discordance(nmtx, ncriteria, nweights)

with np.errstate(invalid='ignore'):
outrank = (
(mtx_concordance >= p) & (mtx_discordance <= q))

better_than = np.sum(outrank, axis=1)

kernel = np.where(better_than==len(nmtx)-1)[0]

return kernel, outrank, mtx_concordance, mtx_discordance, p, q

3 changes: 3 additions & 0 deletions skcriteria/tests/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class SKCriteriaTestCase(unittest.TestCase):
def assertAllClose(self, a, b, **kwargs):
return npt.assert_allclose(a, b, **kwargs)

def assertArrayEqual(self, a, b, **kwargs):
return npt.assert_array_equal(a, b, **kwargs)

def assertAll(self, arr, **kwargs):
assert np.all(arr), "'{}' is not all True".format(arr)

Expand Down
68 changes: 53 additions & 15 deletions skcriteria/tests/test_electre.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,63 @@ def test_discordance(self):
[0.2000, 0.5000, 0.3333, 0.3000, np.nan, 0.4000],
[0.5000, 1.0000, 0.8333, 0.5000, 0.5000, np.nan]
]
result_mean, result_p = 0.7076, 0.70
discordance, mean, p = electre.discordance(nmtx, ncriteria, nweights)
result_mean, result_q = 0.7076, 0.70
discordance, mean, q = electre.discordance(nmtx, ncriteria, nweights)
self.assertAllClose(discordance, results, atol=1.e-3)
self.assertAllClose(mean, result_mean, atol=1.e-3)
self.assertAllClose(p, result_p, atol=1.e-3)
self.assertAllClose(q, result_q, atol=1.e-3)

def _test_electre1(self):
#~ Data from:
#~ Tzeng, G. H., & Huang, J. J. (2011). Multiple
#~ attribute decision making: methods and applications. CRC press.
VD, D, U, S, VS = 1, 2, 3, 4, 5
def test_electre1(self):
# Data From:
# Cebrián, L. I. G., & Porcar, A. M. (2009). Localización empresarial
# en Aragón: Una aplicación empírica de la ayuda a la decisión
# multicriterio tipo ELECTRE I y III. Robustez de los resultados
# obtenidos.
# Revista de Métodos Cuantitativos para la Economía y la Empresa,
# (7), 31-56.
mtx = [
[U, D, S, VS],
[D, VS, D, S],
[D, VD, S, D],
[U, VS, U, S]
[6, 5, 28, 5, 5],
[4, 2, 25, 10, 9],
[5, 7, 35, 9, 6],
[6, 1, 27, 6, 7],
[6, 8, 30, 7, 9],
[5, 6, 26, 4, 8]
]
criteria = [1, 1, -1, 1, 1]
weights = [0.25, 0.25, 0.1, 0.2, 0.2]

result_kernel, result_p, result_q = [4], 0.55, 0.70
result_outrank = [
[False, False, False, False, False, False],
[False, False, False, False, False, False],
[True, False, False, False, False, False],
[True, False, False, False, False, False],
[True, True, True, True, False, True],
[True, False, False, True, False, False],
]
result_concordance = [
[np.nan, 0.5000, 0.3500, 0.5000, 0.3500, 0.4500],
[0.5000, np.nan, 0.5000, 0.7500, 0.5000, 0.5000],
[0.6500, 0.5000, np.nan, 0.4500, 0.2000, 0.7000],
[0.7500, 0.2500, 0.5500, np.nan, 0.3500, 0.4500],
[0.9000, 0.7000, 0.8000, 0.9000, np.nan, 0.9000],
[0.5500, 0.5000, 0.5500, 0.5500, 0.1000, np.nan]
]
result_discordance = [
[np.nan, 1.0000, 0.6667, 0.5000, 1.0000, 0.7500],
[1.0000, np.nan, 0.7143, 1.0000, 1.0000, 0.5714],
[0.7000, 1.0000, np.nan, 0.8000, 0.7500, 0.9000],
[0.5714, 0.6667, 0.8571, np.nan, 1.0000, 0.7143],
[0.2000, 0.5000, 0.3333, 0.3000, np.nan, 0.4000],
[0.5000, 1.0000, 0.8333, 0.5000, 0.5000, np.nan]
]
criteria = [1, 1, 1, 1]
weights = [.35, .15, .20, .30]
electre.electre1(mtx, criteria, weights)

kernel, outrank, concordance, discordance, p, q = electre.electre1(
mtx, criteria, weights)

self.assertCountEqual(kernel, result_kernel)
self.assertArrayEqual(outrank, result_outrank)
self.assertAllClose(concordance, result_concordance, atol=1.e-3)
self.assertAllClose(discordance, result_discordance, atol=1.e-3)
self.assertAllClose(p, result_p, atol=1.e-3)
self.assertAllClose(q, result_q, atol=1.e-3)

0 comments on commit af96bc2

Please sign in to comment.