FEATURED · 精选文章

Python实现TOPSIS算法:多指标决策分析与技术选型实战

发布时间 / 2026/8/29 1:54:33
来源 / 创域科博编辑部
栏目 / 资讯中心
Python实现TOPSIS算法:多指标决策分析与技术选型实战 1. 从一次项目评审说起为什么TOPSIS是决策者的“公平秤”最近在帮一个朋友评审他们团队的几个备选技术方案从性能、成本、开发周期到团队适配度指标一大堆。大家吵得不可开交有人说A方案性能碾压一切成本高点也值有人说C方案成本最优性能短板可以后期优化。这种多指标、相互冲突的决策场景在技术选型、产品评估、甚至个人生活中都太常见了。单纯靠感觉或者只盯着某一两个“亮点”指标很容易做出片面的决定。这时候一个客观、量化的综合评价方法就显得尤为重要。TOPSIS这个听起来有点学术的名字就成了我们破局的关键。它就像一把“公平秤”不是简单地把所有指标分数加起来而是通过计算每个方案与“理想最优解”和“理想最劣解”的距离来给方案排序。谁离最好的那个“理想点”最近同时离最差的“理想点”最远谁就是综合最优。这个方法思路直观结果也相对公平在数学建模竞赛和实际业务分析中应用非常广泛。今天我就结合一个具体的案例手把手带你用Python从头实现一遍TOPSIS算法。我们不止是写出能跑的代码更要搞清楚每一步背后的数学意义和工程考量比如数据为什么要标准化、权重怎么确定、距离公式为什么用欧氏距离。我会把在实现过程中容易踩的坑、一些实用的变通技巧以及如何将结果更直观地呈现出来都毫无保留地分享给你。无论你是正在备战数学建模比赛的学生还是需要处理多指标决策问题的工程师或产品经理这篇内容都能给你一套可直接复用的工具箱。2. TOPSIS的核心思想寻找“理想点”的邻居在深入代码之前我们必须先吃透TOPSIS的原理。它的全称是“逼近理想解排序法”这个名字就点明了它的核心通过逼近一个理想的解来排序。想象一下我们要评选“年度最佳员工”考核指标有代码量、Bug率、文档质量、团队协作评分。显然代码量是越高越好效益型指标Bug率是越低越好成本型指标。TOPSIS的第一步就是在所有候选人的数据中虚拟出两个“极端”员工一个是“理想员工”他所有效益型指标都取最大值所有成本型指标都取最小值另一个是“负理想员工”他所有效益型指标都取最小值所有成本型指标都取最大值。现实中可能不存在这样的员工但他们构成了评价的标杆。接下来TOPSIS会计算每一位真实候选人分别与这位“理想员工”和“负理想员工”的“综合距离”。这个距离不是简单的直线距离而是考虑了各个指标重要性的加权距离。最后通过一个公式计算每个候选人相对于“理想员工”的接近程度。这个值越接近1说明该候选人综合表现越优秀。这个过程可以分解为以下几个关键步骤这也是我们代码实现的路线图数据预处理与同趋化确保所有指标方向一致通常都转化为越大越好。数据标准化归一化消除不同指标量纲单位的影响。比如代码量是几千行Bug率是百分之几直接计算距离没有意义。确定指标权重这是影响结果的关键一步权重不同排序可能完全不同。构造加权决策矩阵将标准化后的数据乘以各自权重得到加权矩阵。确定理想解与负理想解找出加权矩阵中每个指标的“最好值”和“最差值”。计算距离计算每个方案到理想解和负理想解的欧氏距离。计算相对贴近度并排序根据公式计算贴近度值越大方案越优。理解了这套逻辑我们就能明白写代码不只是实现公式更是对这套决策逻辑的精确翻译。下面我们就进入实战环节。3. 环境准备与数据构造打造我们的“实验沙盘”工欲善其事必先利其器。我们使用Python来实现主要依赖numpy进行高效的矩阵运算用pandas方便地处理表格数据用matplotlib或seaborn进行可视化。如果你使用Anaconda这些库通常已经安装。如果没有可以通过pip安装pip install numpy pandas matplotlib seaborn接下来我们需要一份数据。为了清晰地演示整个过程我构造了一个简单的例子评估4个备选的数据存储方案A, B, C, D考虑4个指标查询速度QPS越高越好效益型。单GB成本元/GB越低越好成本型。数据可靠性%越高越好效益型。社区活跃度星级1-5越高越好效益型。原始数据如下表所示方案查询速度 (QPS)单GB成本 (元)数据可靠性 (%)社区活跃度 (星)A120000.599.94B85000.399.55C150000.899.993D95000.499.74注意在实际项目中你的数据可能来自Excel、CSV或数据库。这里我们手动构造一个DataFrame来模拟这样更容易理解每一步数据的变化。import numpy as np import pandas as pd # 构造原始决策矩阵 data { ‘查询速度(QPS)‘: [12000, 8500, 15000, 9500], ‘单GB成本(元)‘: [0.5, 0.3, 0.8, 0.4], ‘数据可靠性(%)‘: [99.9, 99.5, 99.99, 99.7], ‘社区活跃度(星)‘: [4, 5, 3, 4] } df_original pd.DataFrame(data, index[‘方案A‘, ‘方案B‘, ‘方案C‘, ‘方案D‘]) print(“原始决策矩阵“) print(df_original)运行这段代码我们就有了分析的起点。你会发现指标的单位和方向都不统一这正是我们需要处理的第一步。4. 算法步骤详解与Python逐行实现现在我们按照TOPSIS的标准步骤结合上面的数据一步步用代码实现。4.1 第一步数据同趋化处理同趋化的目的是让所有指标对评价的贡献方向一致通常都转化为“越大越好”。对于成本型指标如成本、故障率我们需要将其转化为效益型。最常用的方法是取倒数或做差值转化。这里“单GB成本”是成本型我们采用“倒数法”将其转化为效益型指标即“成本效益”数值越大表示成本越低越好。但倒数法会改变数据的分布且如果有零值会出现无穷大。另一种更稳健的方法是“负向化”用该指标的最大值减去每个原始值。这里我们使用负向化。def data_direction_normalization(df, cost_indices): “““ 数据同趋化处理将成本型指标转化为效益型。 :param df: 原始数据DataFrame :param cost_indices: 成本型指标列名的列表 :return: 同趋化后的DataFrame “““ df_normalized df.copy() for col in cost_indices: if col in df.columns: # 负向化对于成本型指标用最大值减去原值使得新值越大越好 df_normalized[col] df[col].max() - df[col] # 注意负向化后原成本最低的方案其新值最大。 # 例如成本列原值为[0.5, 0.3, 0.8, 0.4]最大值为0.8。 # 转化后为[0.3, 0.5, 0.0, 0.4]。原成本0.3的方案B新值0.5最大表示其“成本效益”最高。 return df_normalized # 指定成本型指标列 cost_columns [‘单GB成本(元)‘] df_homogenized data_direction_normalization(df_original, cost_columns) print(“\n同趋化后的决策矩阵‘单GB成本‘已转化为‘成本效益‘越大越好“) print(df_homogenized)处理后的“单GB成本”列名称虽然没变但意义已变为“成本效益”值越大代表成本控制得越好。其他效益型指标保持不变。4.2 第二步数据标准化归一化标准化是为了消除量纲影响。TOPSIS常用的是“向量归一化”即每个元素除以该指标所有数据平方和的平方根。这种方法能保留原始数据间的相对关系。公式为 对于决策矩阵中的元素 \( x_{ij} \)第i个方案的第j个指标其标准化值 \( z_{ij} \) 为 \[ z_{ij} \frac{x_{ij}}{\sqrt{\sum_{i1}^{m} x_{ij}^2}} \] 其中\( m \) 是方案数量。def vector_normalization(df): “““ 向量归一化标准化 :param df: 同趋化后的DataFrame :return: 标准化后的DataFrame “““ # 使用numpy进行向量运算效率更高 matrix df.values.astype(float) # 转换为数值矩阵 # 计算每个指标列的平方和再开方 norms np.sqrt(np.sum(matrix ** 2, axis0)) # 避免除以零如果某指标全为0则归一化后仍为0 norms[norms 0] 1 normalized_matrix matrix / norms return pd.DataFrame(normalized_matrix, indexdf.index, columnsdf.columns) df_normalized vector_normalization(df_homogenized) print(“\n向量归一化后的决策矩阵“) print(df_normalized)标准化后所有指标的值都被压缩到[0, 1]区间严格来说是每个指标的平方和为1不同指标之间具备了可比性。4.3 第三步确定指标权重权重是TOPSIS的灵魂体现了决策者对各项指标的重视程度。确定权重的方法主要有主观赋权法如AHP层次分析法、专家打分和客观赋权法如熵权法、CRITIC法。这里为了演示我们采用主观赋权假设决策者给出的权重为查询速度0.3成本效益0.25数据可靠性0.3社区活跃度0.15。权重之和应为1。# 定义指标权重顺序需与DataFrame列顺序一致 weights np.array([0.3, 0.25, 0.3, 0.15]) print(“\n指标权重“, weights) print(“权重总和“, weights.sum()) # 检查权重和是否为1允许微小浮点误差 if not np.isclose(weights.sum(), 1.0): print(“警告权重之和不为1将自动归一化。“) weights weights / weights.sum()实操心得在实际项目中权重的确定往往是最耗时也最容易引发争议的环节。如果缺乏先验知识强烈建议使用熵权法进行客观赋权。熵权法根据数据本身的离散程度来确定权重数据差异越大的指标其携带的信息量越多权重也越大。这能有效减少主观偏见。我会在后面的“进阶与变体”部分简要介绍熵权法的实现思路。4.4 第四步构造加权标准化决策矩阵将标准化后的矩阵每一列每个指标乘以其对应的权重。def calculate_weighted_matrix(df_norm, weights): “““ 计算加权标准化决策矩阵 :param df_norm: 标准化后的DataFrame :param weights: 权重数组 :return: 加权标准化决策矩阵DataFrame “““ weighted_matrix df_norm.values * weights # numpy广播机制 return pd.DataFrame(weighted_matrix, indexdf_norm.index, columnsdf_norm.columns) df_weighted calculate_weighted_matrix(df_normalized, weights) print(“\n加权标准化决策矩阵“) print(df_weighted)至此我们得到了一个消除了量纲和方向影响并融入了权重信息的“纯净”决策矩阵。接下来的计算都将基于这个矩阵。4.5 第五步确定理想解与负理想解在加权标准化矩阵中理想解\( A^ \)由每个指标的最大值构成负理想解\( A^- \)由每个指标的最小值构成。因为我们已经将所有指标都转化为效益型越大越好所以直接取每列的最大/最小值即可。def determine_ideal_solutions(df_weighted): “““ 确定理想解和负理想解 :param df_weighted: 加权标准化决策矩阵 :return: 理想解向量负理想解向量 “““ ideal_best df_weighted.max().values # 理想最优解 ideal_worst df_weighted.min().values # 理想最劣解 return ideal_best, ideal_worst ideal_best, ideal_worst determine_ideal_solutions(df_weighted) print(“\n理想最优解向量 (A):“, ideal_best) print(“理想最劣解向量 (A-):“, ideal_worst)这两个向量就是我们要衡量每个方案距离的“标杆”。4.6 第六步计算各方案到理想解的距离通常使用欧几里得距离欧氏距离。计算每个方案即加权矩阵的每一行到理想解 \( A^ \) 和负理想解 \( A^- \) 的距离。公式为 \[ D_i^ \sqrt{\sum_{j1}^{n} (z_{ij}^* - A_j^)^2 } \] \[ D_i^- \sqrt{\sum_{j1}^{n} (z_{ij}^* - A_j^-)^2 } \] 其中\( z_{ij}^* \) 是加权标准化矩阵中的元素\( n \) 是指标数量。def calculate_distances(df_weighted, ideal_best, ideal_worst): “““ 计算每个方案到理想解和负理想解的欧氏距离 :param df_weighted: 加权标准化决策矩阵 :param ideal_best: 理想最优解向量 :param ideal_worst: 理想最劣解向量 :return: 到理想解的距离数组到负理想解的距离数组 “““ # 将DataFrame转换为numpy数组以便计算 matrix df_weighted.values # 利用numpy的广播机制一次性计算所有方案的距离 # np.linalg.norm用于计算范数axis1指定按行计算即对每个方案 dist_to_best np.linalg.norm(matrix - ideal_best, axis1) dist_to_worst np.linalg.norm(matrix - ideal_worst, axis1) return dist_to_best, dist_to_worst dist_best, dist_worst calculate_distances(df_weighted, ideal_best, ideal_worst) print(“\n各方案到理想最优解的距离 (D):“, dist_best) print(“各方案到理想最劣解的距离 (D-):“, dist_worst)4.7 第七步计算相对贴近度并排序相对贴近度 \( C_i \) 的计算公式为 \[ C_i \frac{D_i^-}{D_i^ D_i^-} \] \( C_i \) 的取值范围在0到1之间。\( C_i \) 越接近1说明该方案离理想解越近离负理想解越远综合表现越好。def calculate_closeness(dist_best, dist_worst): “““ 计算相对贴近度 :param dist_best: 到理想解的距离数组 :param dist_worst: 到负理想解的距离数组 :return: 相对贴近度数组 “““ # 避免除零错误 denominator dist_best dist_worst denominator[denominator 0] np.finfo(float).eps # 加一个极小值 closeness dist_worst / denominator return closeness closeness calculate_closeness(dist_best, dist_worst) print(“\n各方案的相对贴近度 (C):“, closeness) # 将结果整合到一个DataFrame中并按贴近度降序排序 result_df pd.DataFrame({ ‘方案‘: df_weighted.index, ‘D (距理想解)‘: dist_best, ‘D- (距负理想解)‘: dist_worst, ‘相对贴近度 C‘: closeness }) result_df[‘排名‘] result_df[‘相对贴近度 C‘].rank(ascendingFalse, method‘min‘).astype(int) result_df result_df.sort_values(by‘相对贴近度 C‘, ascendingFalse).reset_index(dropTrue) print(“\n TOPSIS综合评价结果 “) print(result_df.to_string(indexFalse))运行以上所有代码我们将得到最终的排序结果。根据我们预设的权重输出结果会显示哪个存储方案综合得分最高。5. 结果可视化与解读让数据自己说话纯数字的表格不够直观我们可以用图表来增强表现力。这里用条形图展示最终排名和贴近度用雷达图对比各方案在不同加权指标上的表现。import matplotlib.pyplot as plt import seaborn as sns # 设置中文字体和样式 plt.rcParams[‘font.sans-serif‘] [‘SimHei‘, ‘Arial Unicode MS‘, ‘DejaVu Sans‘] # 用来正常显示中文标签 plt.rcParams[‘axes.unicode_minus‘] False # 用来正常显示负号 sns.set_style(“whitegrid“) # 1. 绘制相对贴近度条形图 fig, axes plt.subplots(1, 2, figsize(14, 5)) # 贴近度条形图 axes[0].barh(result_df[‘方案‘], result_df[‘相对贴近度 C‘], colorsns.color_palette(“viridis“, len(result_df))) axes[0].set_xlabel(‘相对贴近度 (C)‘) axes[0].set_title(‘各方案TOPSIS相对贴近度排名‘) axes[0].axvline(x0.5, color‘gray‘, linestyle‘--‘, alpha0.5) # 添加中线参考 # 在条形末端添加数值标签 for i, v in enumerate(result_df[‘相对贴近度 C‘]): axes[0].text(v 0.01, i, f‘{v:.3f}‘, va‘center‘) # 2. 绘制加权指标雷达图对比前两名方案 from math import pi categories df_weighted.columns.tolist() N len(categories) angles [n / float(N) * 2 * pi for n in range(N)] angles angles[:1] # 闭合图形 ax axes[1] ax plt.subplot(122, polarTrue) ax.set_theta_offset(pi / 2) # 设置0度位置在顶部 ax.set_theta_direction(-1) # 设置角度增长方向为顺时针 plt.xticks(angles[:-1], categories) ax.set_rlabel_position(0) plt.yticks([0.2, 0.4, 0.6], [“0.2“, “0.4“, “0.6“], color“grey“, size7) plt.ylim(0, df_weighted.values.max()*1.1) # 绘制方案 top_two_schemes result_df[‘方案‘].head(2).tolist() colors [‘b‘, ‘r‘] for idx, scheme in enumerate(top_two_schemes): values df_weighted.loc[scheme].values.flatten().tolist() values values[:1] # 闭合图形 ax.plot(angles, values, linewidth2, linestyle‘solid‘, labelf‘{scheme} (排名{idx1})‘, colorcolors[idx]) ax.fill(angles, values, alpha0.1, colorcolors[idx]) plt.title(‘TOP2方案加权指标雷达图对比‘, size11, y1.1) plt.legend(loc‘upper right‘, bbox_to_anchor(1.3, 1.0)) plt.tight_layout() plt.show()结果解读 从条形图可以一目了然地看到方案的优劣排序。雷达图则能清晰展示排名靠前的方案在哪些指标上占优哪些是短板。例如如果排名第一的方案在“成本效益”和“社区活跃度”上突出而在“查询速度”上稍弱雷达图就能直观呈现这种均衡。这有助于决策者理解排序背后的原因而不仅仅是一个分数。6. 封装、优化与常见问题排查将上述步骤封装成一个完整的、健壮的类或函数是投入实际使用的关键。class TOPSIS: “““一个完整的TOPSIS评价模型类。“““ def __init__(self, data, weightsNone, cost_indicesNone): “““ 初始化 :param data: 原始决策数据可以是list of list或pandas DataFrame :param weights: 指标权重数组默认为等权重 :param cost_indices: 成本型指标索引或列名列表 “““ if isinstance(data, pd.DataFrame): self.original_df data.copy() self.scheme_names data.index.tolist() self.indicator_names data.columns.tolist() self.original_matrix data.values.astype(float) else: self.original_matrix np.array(data, dtypefloat) self.scheme_names [f‘方案{i1}‘ for i in range(self.original_matrix.shape[0])] self.indicator_names [f‘指标{i1}‘ for i in range(self.original_matrix.shape[1])] self.original_df pd.DataFrame(self.original_matrix, indexself.scheme_names, columnsself.indicator_names) self.num_schemes, self.num_indicators self.original_matrix.shape self.weights np.array(weights) if weights is not None else np.ones(self.num_indicators) / self.num_indicators if len(self.weights) ! self.num_indicators: raise ValueError(f“权重数量({len(self.weights)})与指标数量({self.num_indicators})不匹配“) # 归一化权重 self.weights self.weights / self.weights.sum() self.cost_indices cost_indices if cost_indices is not None else [] # 如果cost_indices是列名转换为索引 if self.cost_indices and isinstance(self.cost_indices[0], str): self.cost_indices [self.indicator_names.index(col) for col in self.cost_indices if col in self.indicator_names] # 存储中间结果 self.homogenized_matrix None self.normalized_matrix None self.weighted_matrix None self.ideal_best None self.ideal_worst None self.dist_to_best None self.dist_to_worst None self.closeness None self.result_df None def homogenize(self): “““同趋化处理。“““ matrix self.original_matrix.copy() for j in self.cost_indices: matrix[:, j] matrix[:, j].max() - matrix[:, j] self.homogenized_matrix matrix return self def normalize(self, method‘vector‘): “““标准化处理。“““ if self.homogenized_matrix is None: self.homogenize() matrix self.homogenized_matrix if method ‘vector‘: norms np.sqrt(np.sum(matrix ** 2, axis0)) norms[norms 0] 1 self.normalized_matrix matrix / norms else: raise ValueError(f“不支持的标准化方法{method}“) return self def weight_normalized_matrix(self): “““计算加权标准化矩阵。“““ if self.normalized_matrix is None: self.normalize() self.weighted_matrix self.normalized_matrix * self.weights return self def calculate_ideal_solutions(self): “““计算理想解。“““ if self.weighted_matrix is None: self.weight_normalized_matrix() self.ideal_best self.weighted_matrix.max(axis0) self.ideal_worst self.weighted_matrix.min(axis0) return self def calculate_distances(self): “““计算距离。“““ if self.ideal_best is None: self.calculate_ideal_solutions() self.dist_to_best np.linalg.norm(self.weighted_matrix - self.ideal_best, axis1) self.dist_to_worst np.linalg.norm(self.weighted_matrix - self.ideal_worst, axis1) return self def calculate_closeness(self): “““计算相对贴近度。“““ if self.dist_to_best is None: self.calculate_distances() denominator self.dist_to_best self.dist_to_worst denominator[denominator 0] np.finfo(float).eps self.closeness self.dist_to_worst / denominator return self def evaluate(self): “““执行完整评价流程并返回结果。“““ self.homogenize().normalize().weight_normalized_matrix().calculate_ideal_solutions().calculate_distances().calculate_closeness() self.result_df pd.DataFrame({ ‘方案‘: self.scheme_names, ‘D‘: self.dist_to_best, ‘D-‘: self.dist_to_worst, ‘相对贴近度C‘: self.closeness }) self.result_df[‘排名‘] self.result_df[‘相对贴近度C‘].rank(ascendingFalse, method‘min‘).astype(int) self.result_df self.result_df.sort_values(by‘相对贴近度C‘, ascendingFalse).reset_index(dropTrue) return self.result_df def get_weighted_df(self): “““获取加权标准化矩阵的DataFrame用于可视化。“““ if self.weighted_matrix is None: self.weight_normalized_matrix() return pd.DataFrame(self.weighted_matrix, indexself.scheme_names, columnsself.indicator_names) # 使用封装好的类 topsis TOPSIS( datadf_original, weights[0.3, 0.25, 0.3, 0.15], cost_indices[‘单GB成本(元)‘] ) result topsis.evaluate() print(“使用封装类计算的结果“) print(result)常见问题与排查清单结果反直觉首先检查权重。权重分配对结果影响巨大。尝试使用熵权法等客观方法计算权重与主观权重对比。其次检查成本型指标是否已正确转化。如果忘了转化成本越低得分反而越低结果会完全错误。距离计算为0或NaN检查标准化后的矩阵是否存在某一列全为0即所有方案在该指标上数值相同。在标准化步骤中我们已通过norms[norms 0] 1避免了除零错误。在计算贴近度时也处理了D D- 0的极端情况。数据量纲差异巨大这是必须进行标准化的原因。如果某个指标数值是几万另一个是零点几不标准化大数值指标将完全主导距离计算。想使用熵权法熵权法的核心是计算每个指标的信息熵熵越小数据离散程度越大权重越大。步骤简述对标准化后的矩阵需保证无负值可采用“比重法”标准化计算每个指标下各方案的比重 \( p_{ij} \)然后计算该指标的熵值 \( e_j -k \sum p_{ij} \ln(p_{ij}) \)最后根据熵值计算权重 \( w_j (1-e_j) / \sum (1-e_j) \)。可以将此逻辑集成到TOPSIS类的calculate_weights_by_entropy方法中。7. 进阶思考TOPSIS的变体与应用边界基础的TOPSIS已经能解决大部分问题但在更复杂的场景下我们可以考虑其变体权重确定方法的融合结合主观权重专家意见和客观权重熵权法例如使用乘法合成或加权平均得到综合权重。这能在尊重专家经验的同时兼顾数据本身的特性。距离公式的改进欧氏距离是默认选择但它假设各指标间相互独立。如果指标间存在相关性可以考虑使用马氏距离但它需要计算协方差矩阵的逆在指标多、数据少时可能不稳定。模糊TOPSIS当决策信息本身是模糊的、不确定的如“高”、“中”、“低”这样的语言评价可以使用三角模糊数或梯形模糊数来表示指标值然后在整个TOPSIS流程中处理这些模糊数。结合其他模型TOPSIS常与AHP层次分析法联用。AHP用于科学地确定权重TOPSIS用于对方案进行排序两者结合相得益彰。TOPSIS的应用边界与注意事项优点原理简单直观计算过程清晰对数据分布无严格要求结果易于理解和解释。局限权重依赖性强这是所有多指标决策方法的通病需要谨慎确定。“理想解”可能不现实虚拟的理想解可能过于极端导致所有方案的贴近度都不高。对指标线性变化的敏感性标准化方法如向量归一化对数据的线性变换不是不变的这意味着如果所有方案的某个指标值同时增加一个常数可能会影响排序结果尽管影响通常不大。在实际应用中需要理解所选标准化方法的这一特性。我个人在多次使用TOPSIS后最大的体会是它提供了一个系统化、可重复、可辩论的决策框架。当团队对方案选择有分歧时与其无休止地争论不如坐下来一起确定评价指标、讨论权重然后让TOPSIS给出一个量化的参考结果。这个结果未必是最终答案但它是基于共同认可规则产出的能极大提高决策效率和理性程度。最后一个小技巧在向非技术背景的同事或领导汇报TOPSIS结果时多使用类似“雷达图”这样的可视化图表比单纯展示一个排名表格要有说服力得多。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻