Source code for pyifdm.methods.topsis.ifs

# Copyright (c) 2022 Jakub Więckowski

import numpy as np

[docs] def ifs(matrix, weights, types, normalization, distance): """ Calculates the alternatives preferences based on Intuitionistic Fuzzy Sets Parameters ---------- matrix : ndarray Decision matrix / alternatives data. Alternatives are in rows and Criteria are in columns. weights : ndarray Vector of criteria weights in a crisp or Intuitionistic Fuzzy form types : ndarray Types of criteria, 1 profit, -1 cost normalization: callable Function used to normalize the decision matrix distance: callable Function used to calculate distance between two IFS Returns ------- ndarray Crisp preferences of alternatives """ # normalized matrix if normalization is not None: nmatrix = normalization(matrix, types) else: nmatrix = matrix.copy() # weighted matrix wmatrix = np.zeros((nmatrix.shape[0], nmatrix.shape[1], 3), dtype=object) # crisp weights if weights.ndim == 1: weights = np.repeat(weights, 2).reshape((len(weights), 2)) wmatrix[:, :, 0] = nmatrix[:, :, 0] * weights[:, 0] wmatrix[:, :, 1] = nmatrix[:, :, 1] + weights[:, 1] - nmatrix[:, :, 1] * weights[:, 1] wmatrix[:, :, 2] = 1 - nmatrix[:, :, 1] - weights[:, 1] - nmatrix[:, :, 0] * weights[:, 0] + nmatrix[:, :, 1] * weights[:, 1] # closeness to intuitionistic fuzzy positive and negative ideal solution aplus, aminus = np.zeros((matrix.shape[1], ), dtype=object), np.zeros((matrix.shape[1], ), dtype=object) for j in range(matrix.shape[1]): if types[j] == 1: aplus[j] = wmatrix[np.argmax(wmatrix[:, j, 0]), j] aminus[j] = wmatrix[np.argmin(wmatrix[:, j, 0]), j] else: aplus[j] = wmatrix[np.argmin(wmatrix[:, j, 0]), j] aminus[j] = wmatrix[np.argmax(wmatrix[:, j, 0]), j] f = 1 if 'normalized' in distance.__name__: f = 1/(2*matrix.shape[1]) # distance from ideal solution splus, sminus = np.zeros((wmatrix.shape[0], )), np.zeros((wmatrix.shape[0], )) for i in range(wmatrix.shape[0]): if distance.__name__== 'normalized_euclidean_distance': splus[i] = np.sqrt(f * np.sum([distance(wmatrix[i, idx], ap) for idx, ap in enumerate(aplus)])) sminus[i] = np.sqrt(f * np.sum([distance(wmatrix[i, idx], am) for idx, am in enumerate(aminus)])) elif distance.__name__== 'normalized_hamming_distance': splus[i] = f * np.sum([distance(wmatrix[i, idx], ap) for idx, ap in enumerate(aplus)]) sminus[i] = f * np.sum([distance(wmatrix[i, idx], am) for idx, am in enumerate(aminus)]) else: splus[i] = np.sum([distance(wmatrix[i, idx], ap) for idx, ap in enumerate(aplus)]) sminus[i] = np.sum([distance(wmatrix[i, idx], am) for idx, am in enumerate(aminus)]) # assessment score return sminus / (splus + sminus)