C++实现TOPSIS法(附带源码)

项目简介

TOPSIS(Technique for Order Preference by Similarity to Ideal Solution)法是一种多属性决策分析(MCDM)方法,用于在多个候选方案中选择最优方案。TOPSIS法的核心思想是通过计算每个方案与理想解和负理想解的距离,从而确定每个方案的优劣。

TOPSIS法的基本步骤:

  1. 标准化决策矩阵:将决策矩阵中的所有属性值标准化,使得所有属性的量纲一致。
  2. 构造加权标准化矩阵:通过给不同属性赋予不同的权重,来反映每个属性在决策中的重要性。
  3. 计算理想解和负理想解:理想解是每个属性的最佳值(最大化或最小化),负理想解是每个属性的最差值。
  4. 计算与理想解和负理想解的距离:分别计算每个方案与理想解和负理想解的欧几里得距离。
  5. 计算相对接近度:通过计算每个方案的相对接近度,选出最优方案。相对接近度是每个方案与理想解的距离与与负理想解的距离的比值。

目标问题

在给定多个候选方案、每个方案的多个属性值以及属性权重的情况下,使用TOPSIS法来评估并选择最佳方案。

实现方式

  1. 输入数据:决策矩阵、各属性的权重。
  2. 标准化决策矩阵:使用向量归一化方法,将所有属性值转换为标准化值。
  3. 计算加权标准化矩阵:将标准化后的决策矩阵乘以各属性的权重。
  4. 计算理想解和负理想解:找出每个属性的最大值和最小值。
  5. 计算与理想解和负理想解的距离:使用欧几里得距离公式。
  6. 计算相对接近度:根据与理想解和负理想解的距离计算每个方案的相对接近度,选择相对接近度最大者为最优方案。

代码实现

#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;
}

代码解读

  1. normalizeMatrix:标准化决策矩阵。通过将每个元素除以该列的平方和的平方根,保证每个属性的值在同一量纲下,避免量纲差异影响结果。

  2. weightedMatrix:加权标准化矩阵。每个标准化值乘以对应属性的权重,得到加权后的矩阵。

  3. calculateIdealAndNegativeIdeal:计算理想解和负理想解。理想解是每个属性的最大值,负理想解是每个属性的最小值。

  4. calculateCloseness:计算每个方案与理想解和负理想解的距离,并根据这些距离计算每个方案的相对接近度。

  5. run:执行TOPSIS法的完整过程,返回最优方案的索引。

项目总结

  1. TOPSIS法的优势

    • TOPSIS法能够综合考虑多个属性对方案的影响,适用于多属性决策问题。
    • 它通过距离的方式,能有效区分出最佳和最差的方案,从而帮助决策者作出合理选择。
  2. 性能与扩展性

    • 本实现的时间复杂度主要受决策矩阵的大小影响,在处理大规模数据时效率较高。
    • 可以扩展为处理不同类型的决策问题,例如,带有排序关系或更复杂约束条件的MCDM问题。
  3. 实际应用

    • TOPSIS法广泛应用于产品评估、供应链管理、环境决策等领域,尤其适用于需要在多个方案中综合考虑不同属性的情况。

通过本项目的实现,我们不仅掌握了TOPSIS法的理论基础,也学会了如何在C++中实现这一方法,为多属性决策问题提供一种有效的解决方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值