12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- ##################################################################
- #
- # Copyright (c) 2023 CICV, Inc. All Rights Reserved
- #
- ##################################################################
- """
- @Authors: zhanghaiwen(zhanghaiwen@china-icv.cn), yangzihao(yangzihao@china-icv.cn)
- @Data: 2024/01/12
- @Last Modified: 2024/01/12
- @Summary: Weight cal
- """
- import numpy as np
- from functools import reduce
- def cal_weight_from_80(score_list):
- # weight process
- s_list = [80.1 if x == 80 else x for x in score_list]
- weight_list = abs((np.array(s_list) - 80) / 100)
- # normalization
- weight_list = weight_list / sum(weight_list)
- return weight_list
- class AHP:
- def __init__(self, matrix):
- self.A = np.array(matrix)
- self.n = len(matrix)
- def _get_consistency_ratio(self, w_max):
- RI = [0, 0, 0.0001, 0.52, 0.89, 1.12, 1.26, 1.36,
- 1.41, 1.46, 1.49, 1.52, 1.54, 1.56, 1.58, 1.59,
- 1.5943, 1.6064, 1.6133, 1.6207, 1.6292]
- CI = (w_max - self.n) / (self.n - 1)
- CR = CI / RI[self.n]
- return CR
- def get_weights(self, method='eigenvalue'):
- # Check consistency of pairwise comparison matrix
- w, v = np.linalg.eig(self.A)
- w_index = np.argmax(w)
- w_max = np.real(w[w_index])
- cr = self._get_consistency_ratio(w_max)
- if cr > 0.1:
- raise ValueError('The pairwise comparison matrix is inconsistent.')
- # Normalize matrix
- line_sum = [sum(m) for m in zip(*self.A)]
- D = np.zeros((self.n, self.n))
- for i in range(self.n):
- for j in range(self.n):
- D[i][j] = self.A[i][j] / line_sum[j]
- # Calculate weights with selected method
- if method == 'arithmetic':
- weights = np.zeros(self.n)
- for i in range(self.n):
- weights[i] = np.average(D[i])
- elif method == 'geometric':
- weights = np.zeros(self.n)
- for i in range(self.n):
- weights[i] = reduce(lambda x, y: x * y, self.A[i])
- weights[i] = pow(weights[i], 1 / self.n)
- weights = [e / np.sum(weights) for e in weights]
- elif method == 'eigenvalue':
- weights = np.zeros(self.n)
- v_index = np.argmax(v)
- v_max = np.real(v[:, v_index])
- weights = [e / np.sum(v_max) for e in v_max]
- return weights
|