项目简介
TOPSIS(Technique for Order Preference by Similarity to Ideal Solution)法是一种多属性决策分析(MCDM)方法,用于在多个候选方案中选择最优方案。TOPSIS法的核心思想是通过计算每个方案与理想解和负理想解的距离,从而确定每个方案的优劣。
TOPSIS法的基本步骤:
- 标准化决策矩阵:将决策矩阵中的所有属性值标准化,使得所有属性的量纲一致。
- 构造加权标准化矩阵:通过给不同属性赋予不同的权重,来反映每个属性在决策中的重要性。
- 计算理想解和负理想解:理想解是每个属性的最佳值(最大化或最小化),负理想解是每个属性的最差值。
- 计算与理想解和负理想解的距离:分别计算每个方案与理想解和负理想解的欧几里得距离。
- 计算相对接近度:通过计算每个方案的相对接近度,选出最优方案。相对接近度是每个方案与理想解的距离与与负理想解的距离的比值。
目标问题
在给定多个候选方案、每个方案的多个属性值以及属性权重的情况下,使用TOPSIS法来评估并选择最佳方案。
实现方式
- 输入数据:决策矩阵、各属性的权重。
- 标准化决策矩阵:使用向量归一化方法,将所有属性值转换为标准化值。
- 计算加权标准化矩阵:将标准化后的决策矩阵乘以各属性的权重。
- 计算理想解和负理想解:找出每个属性的最大值和最小值。
- 计算与理想解和负理想解的距离:使用欧几里得距离公式。
- 计算相对接近度:根据与理想解和负理想解的距离计算每个方案的相对接近度,选择相对接近度最大者为最优方案。
代码实现
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
// 计算欧几里得距离
double euclideanDistance(const vector<double>& vec1, const vector<double>& vec2) {
double sum = 0.0;
for (size_t i = 0; i < vec1.size(); ++i) {
sum += pow(vec1[i] - vec2[i], 2);
}
return sqrt(sum);
}
// TOPSIS算法
class TOPSIS {
public:
// 决策矩阵和权重
vector<vector<double>> decisionMatrix; // 决策矩阵 (m x n)
vector<double> weights; // 属性权重 (n)
// 标准化决策矩阵
vector<vector<double>> normalizeMatrix() {
size_t m = decisionMatrix.size(); // 方案数
size_t n = decisionMatrix[0].size(); // 属性数
vector<vector<double>> normalizedMatrix(m, vector<double>(n));
for (size_t j = 0; j < n; ++j) {
double sumOfSquares = 0.0;
// 计算该属性的平方和
for (size_t i = 0; i < m; ++i) {
sumOfSquares += pow(decisionMatrix[i][j], 2);
}
double normFactor = sqrt(sumOfSquares);
// 标准化
for (size_t i = 0; i < m; ++i) {
normalizedMatrix[i][j] = decisionMatrix[i][j] / normFactor;
}
}
return normalizedMatrix;
}
// 计算加权标准化矩阵
vector<vector<double>> weightedMatrix(const vector<vector<double>>& normalizedMatrix) {
size_t m = normalizedMatrix.size(); // 方案数
size_t n = normalizedMatrix[0].size(); // 属性数
vector<vector<double>> weightedMatrix(m, vector<double>(n));
for (size_t i = 0; i < m; ++i) {
for (size_t j = 0; j < n; ++j) {
weightedMatrix[i][j] = normalizedMatrix[i][j] * weights[j];
}
}
return weightedMatrix;
}
// 计算理想解和负理想解
pair<vector<double>, vector<double>> calculateIdealAndNegativeIdeal(const vector<vector<double>>& weightedMatrix) {
size_t m = weightedMatrix.size(); // 方案数
size_t n = weightedMatrix[0].size(); // 属性数
vector<double> idealSolution(n, -1e9); // 理想解
vector<double> negativeIdealSolution(n, 1e9); // 负理想解
for (size_t j = 0; j < n; ++j) {
for (size_t i = 0; i < m; ++i) {
if (weightedMatrix[i][j] > idealSolution[j]) {
idealSolution[j] = weightedMatrix[i][j];
}
if (weightedMatrix[i][j] < negativeIdealSolution[j]) {
negativeIdealSolution[j] = weightedMatrix[i][j];
}
}
}
return {idealSolution, negativeIdealSolution};
}
// 计算相对接近度
vector<double> calculateCloseness(const vector<vector<double>>& weightedMatrix, const vector<double>& idealSolution, const vector<double>& negativeIdealSolution) {
size_t m = weightedMatrix.size(); // 方案数
vector<double> closeness(m);
for (size_t i = 0; i < m; ++i) {
double distanceToIdeal = euclideanDistance(weightedMatrix[i], idealSolution);
double distanceToNegativeIdeal = euclideanDistance(weightedMatrix[i], negativeIdealSolution);
closeness[i] = distanceToNegativeIdeal / (distanceToIdeal + distanceToNegativeIdeal);
}
return closeness;
}
// 主函数:执行TOPSIS法
int run() {
// 1. 标准化决策矩阵
vector<vector<double>> normalizedMatrix = normalizeMatrix();
// 2. 计算加权标准化矩阵
vector<vector<double>> weightedMatrix = weightedMatrix(normalizedMatrix);
// 3. 计算理想解和负理想解
auto [idealSolution, negativeIdealSolution] = calculateIdealAndNegativeIdeal(weightedMatrix);
// 4. 计算每个方案的相对接近度
vector<double> closeness = calculateCloseness(weightedMatrix, idealSolution, negativeIdealSolution);
// 5. 返回相对接近度最大的方案的索引
int bestIndex = max_element(closeness.begin(), closeness.end()) - closeness.begin();
return bestIndex;
}
};
int main() {
// 示例数据(决策矩阵)
vector<vector<double>> decisionMatrix = {
{7, 9, 6}, // 方案1
{6, 7, 8}, // 方案2
{8, 6, 7}, // 方案3
};
// 权重(每个属性的权重)
vector<double> weights = {0.5, 0.3, 0.2};
// 创建TOPSIS对象并设置决策矩阵和权重
TOPSIS topsis;
topsis.decisionMatrix = decisionMatrix;
topsis.weights = weights;
// 执行TOPSIS法
int bestIndex = topsis.run();
// 输出最优方案
cout << "The best solution is option " << bestIndex + 1 << endl;
return 0;
}
代码解读
-
normalizeMatrix
:标准化决策矩阵。通过将每个元素除以该列的平方和的平方根,保证每个属性的值在同一量纲下,避免量纲差异影响结果。 -
weightedMatrix
:加权标准化矩阵。每个标准化值乘以对应属性的权重,得到加权后的矩阵。 -
calculateIdealAndNegativeIdeal
:计算理想解和负理想解。理想解是每个属性的最大值,负理想解是每个属性的最小值。 -
calculateCloseness
:计算每个方案与理想解和负理想解的距离,并根据这些距离计算每个方案的相对接近度。 -
run
:执行TOPSIS法的完整过程,返回最优方案的索引。
项目总结
-
TOPSIS法的优势:
- TOPSIS法能够综合考虑多个属性对方案的影响,适用于多属性决策问题。
- 它通过距离的方式,能有效区分出最佳和最差的方案,从而帮助决策者作出合理选择。
-
性能与扩展性:
- 本实现的时间复杂度主要受决策矩阵的大小影响,在处理大规模数据时效率较高。
- 可以扩展为处理不同类型的决策问题,例如,带有排序关系或更复杂约束条件的MCDM问题。
-
实际应用:
- TOPSIS法广泛应用于产品评估、供应链管理、环境决策等领域,尤其适用于需要在多个方案中综合考虑不同属性的情况。
通过本项目的实现,我们不仅掌握了TOPSIS法的理论基础,也学会了如何在C++中实现这一方法,为多属性决策问题提供一种有效的解决方案。