1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
| import numpy as np
class AHP: """ 使用 Python 实现层次分析法 AHP """
def __init__(self, criteria, judgment_matrix): """ 初始化 AHP 类 :param criteria: list, 评价准则的名称列表 :param judgment_matrix: np.ndarray, 判断矩阵 """ self.criteria = criteria self.matrix = np.array(judgment_matrix) self.n = self.matrix.shape[0]
self.RI = { 1: 0, 2: 0, 3: 0.58, 4: 0.90, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49, 11: 1.51, 12: 1.48, 13: 1.56, 14: 1.57, 15: 1.59 }
def _check_consistency(self, max_eigenvalue): """ 一致性检验 公式: CR = CI / RI, CI = (λ_max - n) / (n - 1) """ CI = (max_eigenvalue - self.n) / (self.n - 1)
if self.n <= 2: CR = 0 else: try: CR = CI / self.RI[self.n] except KeyError: print(f"警告: 矩阵大小 n={self.n} 超出预设的 RI 表范围,无法计算 CR。") CR = float('nan')
print("\n--- 一致性检验 ---") print(f"最大特征值 λ_max = {max_eigenvalue:.4f}") print(f"一致性指标 CI = {CI:.4f}") if self.n > 2: print(f"随机一致性指标 RI = {self.RI.get(self.n, 'N/A')}") print(f"一致性比率 CR = {CR:.4f}")
if CR < 0.10: print("结果: 判断矩阵通过一致性检验。") return True else: print(f"结果: 判断矩阵未通过一致性检验 (CR = {CR:.4f} >= 0.10),建议修正判断矩阵。") return False
def arithmetic_mean_method(self): """ 算术平均法求权重 1. 将判断矩阵按列归一化 2. 将归一化后的矩阵按行求和 3. 将行和向量归一化得到权重向量 """ col_sum = np.sum(self.matrix, axis=0) normalized_matrix = self.matrix / col_sum
row_sum = np.sum(normalized_matrix, axis=1)
weights = row_sum / self.n
print("\n--- 1. 算术平均法 (Arithmetic Mean Method) ---") for i, w in enumerate(weights): print(f" {self.criteria[i]:<10}: {w:.4f}") return weights
def geometric_mean_method(self): """ 几何平均法求权重 1. 计算判断矩阵每行元素的几何平均数 2. 将得到的向量归一化 """ row_product = np.prod(self.matrix, axis=1)
root = np.power(row_product, 1 / self.n)
weights = root / np.sum(root)
print("\n--- 2. 几何平均法 (Geometric Mean Method) ---") for i, w in enumerate(weights): print(f" {self.criteria[i]:<10}: {w:.4f}") return weights
def eigenvalue_method(self): """ 特征值法求权重 1. 求出判断矩阵的最大特征值及其对应的特征向量 2. 对特征向量进行归一化处理 """ eigenvalues, eigenvectors = np.linalg.eig(self.matrix)
max_eigenvalue_index = np.argmax(eigenvalues) max_eigenvalue = np.real(eigenvalues[max_eigenvalue_index])
eigenvector = np.real(eigenvectors[:, max_eigenvalue_index])
weights = eigenvector / np.sum(eigenvector)
print("\n--- 3. 特征值法 (Eigenvalue Method) ---") for i, w in enumerate(weights): print(f" {self.criteria[i]:<10}: {w:.4f}")
self._check_consistency(max_eigenvalue)
return weights, max_eigenvalue
if __name__ == '__main__': criteria_names = ['景色', '费用', '交通', '饮食']
judgment_matrix = [ [1, 3, 4, 2], [1 / 3, 1, 2, 1 / 2], [1 / 4, 1 / 2, 1, 1 / 3], [1 / 2, 2, 3, 1] ]
ahp_solver = AHP(criteria=criteria_names, judgment_matrix=judgment_matrix)
w_arithmetic = ahp_solver.arithmetic_mean_method() w_geometric = ahp_solver.geometric_mean_method() w_eigen, lambda_max = ahp_solver.eigenvalue_method()
print("\n--- 最终权重对比 ---") print(f"{'准则':<10} {'算术平均法':<12} {'几何平均法':<12} {'特征值法':<12}") print("-" * 50) for i in range(len(criteria_names)): print(f"{criteria_names[i]:<10} {w_arithmetic[i]:<12.4f} {w_geometric[i]:<12.4f} {w_eigen[i]:<12.4f}")
|