فهرست منبع

使用熵权法和主成分分析法计算权重

chengxr 1 سال پیش
والد
کامیت
3d6569c4d0
2فایلهای تغییر یافته به همراه76 افزوده شده و 40 حذف شده
  1. 1 0
      QFD/algorithm/EntropyWeights.cpp
  2. 75 40
      QFD/common/DataEvaluator.cpp

+ 1 - 0
QFD/algorithm/EntropyWeights.cpp

@@ -97,6 +97,7 @@ void EntropyWeights::getWeights(QVector<double> &weights, QVector<double> &score
 
     // 求权值
     double dSum = std::accumulate(d.begin(), d.end(), 0.0);
+
     for (auto v : d) {
         weights.append(v / dSum);
     }

+ 75 - 40
QFD/common/DataEvaluator.cpp

@@ -5,6 +5,7 @@
 #include <CMind.h>
 
 #include "algorithm/EntropyWeights.h"
+#include "algorithm/PCA.h"
 
 #include <dbService/ClassSet.h>
 #include <dbService/NodeMatrixService.h>
@@ -92,53 +93,89 @@ bool DataEvaluator::evaluateWeightFromMeasure()
     /// 外层 QString 是 uuid, 内层 QString 是指标名称, double 是指标权重
     QMap<QString, double> allWeights;
 
-    /// 根据指标体系层级, 构造算法需要的数据
-    for (int i = 1; i < mind->levels(); i++) {
-        for (CNodeData node : mind->nodesInLevel(i)) {
-            QList<CNodeData> subNodes = mind->subNodes(node);
-            EntropyMat mat;
-            for (int j = 0; j < subNodes.size(); j++) {
-
-                QVector<double> values;
-                for (QString uuid : nodeData.keys()) {
-                    NodeMatrixInfo *info = nodeData[uuid][subNodes[j].name];
-                    if (info == nullptr) {
-                        break;
+    if (algorithm == SchemePlanManager::Entropy) {  // 熵值法
+        /// 根据指标体系层级, 构造算法需要的数据, 逐层计算权重值并保存
+        for (int i = 1; i < mind->levels(); i++) {
+            for (CNodeData node : mind->nodesInLevel(i)) {
+                QList<CNodeData> subNodes = mind->subNodes(node);
+                EntropyMat mat;
+                for (int j = 0; j < subNodes.size(); j++) {
+
+                    QVector<double> values;
+                    for (QString uuid : nodeData.keys()) {
+                        NodeMatrixInfo *info = nodeData[uuid][subNodes[j].name];
+                        if (info == nullptr) {
+                            break;
+                        }
+                        double value = nodeData[uuid][subNodes[j].name]->nodeValue.toDouble();
+                        values.append(value);
                     }
-                    double value = nodeData[uuid][subNodes[j].name]->nodeValue.toDouble();
-                    values.append(value);
+
+                    mat.append({ values });
                 }
 
-                mat.append({ values });
-            }
+                if (mat.size() <= 0) {
+                    continue;
+                }
 
-            //                pdata = { { 4.1 }, { 0.04 }, { 0.19 }, { 0.01 }, { 0.05 } };
+                // 计算权重
+                QScopedPointer<EntropyWeights> ew(new EntropyWeights(mat));
+                QVector<double> weights, scores;
+                ew->compute(weights, scores);
 
-            //                pdata = {
-            //                    { 4.1, 3.9 }, { 0.04, 0.08 }, { 0.19, 0.38 }, { 0.01, 0.18 }, { 0.36, 0.19 }, {
-            //                    0.05, 0.04 }
-            //                };
+                // 结合父节点指标权重计算指标最终权重
+                for (int k = 0; k < subNodes.size(); k++) {
+                    double w = weights[k];
+                    if (std::_Is_nan(w)) {
+                        w = 1 / subNodes.size();
+                    }
 
-            if (mat.size() <= 0) {
-                break;
+                    CNodeData pNode = mind->node(subNodes[k].pNumber);
+                    if (allWeights.keys().contains(pNode.name)) {
+                        allWeights[subNodes[k].name] = allWeights[pNode.name] * w;
+                    } else {
+                        allWeights[subNodes[k].name] = w;
+                    }
+                }
             }
+        }
+    } else if (algorithm == SchemePlanManager::PrincipalComponents) {  // 主成分分析法
+        for (int i = 1; i < mind->levels(); i++) {
+            for (CNodeData node : mind->nodesInLevel(i)) {
+                QList<CNodeData> subNodes = mind->subNodes(node);
+                QVector<QVector<double>> mat;
+                for (QString uuid : nodeData.keys()) {
+                    QVector<double> values;
+                    for (int j = 0; j < subNodes.size(); j++) {
+                        NodeMatrixInfo *info = nodeData[uuid][subNodes[j].name];
+                        if (info == nullptr) {
+                            break;
+                        }
+                        double value = nodeData[uuid][subNodes[j].name]->nodeValue.toDouble();
+                        values.append(value);
+                    }
 
-            QScopedPointer<EntropyWeights> ew(new EntropyWeights(mat));
-            QVector<double> weights, scores;
-            ew->compute(weights, scores);
-            qDebug() << __FUNCTION__ << __LINE__ << weights << endl;
-
-            for (int j = 0; j < subNodes.size(); j++) {
-                double w = weights[j];
-                if (std::_Is_nan(w)) {
-                    w = 0;
+                    mat.append({ values });
+                }
+                if (mat.size() <= 0) {
+                    continue;
                 }
 
-                CNodeData pNode = mind->node(subNodes[j].pNumber);
-                if (allWeights.keys().contains(pNode.name)) {
-                    allWeights[subNodes[j].name] = allWeights[pNode.name] * w;
-                } else {
-                    allWeights[subNodes[j].name] = w;
+                QScopedPointer<PCA> pca(new PCA(mat));
+                pca->compute();
+                // 结合父节点指标权重计算指标最终权重
+                for (int k = 0; k < subNodes.size(); k++) {
+                    double w = pca->weights()[k];
+                    if (std::_Is_nan(w)) {
+                        w = 1 / subNodes.size();
+                    }
+
+                    CNodeData pNode = mind->node(subNodes[k].pNumber);
+                    if (allWeights.keys().contains(pNode.name)) {
+                        allWeights[subNodes[k].name] = allWeights[pNode.name] * w;
+                    } else {
+                        allWeights[subNodes[k].name] = w;
+                    }
                 }
             }
         }
@@ -203,9 +240,7 @@ bool DataEvaluator::getAlgorithm(SchemePlanManager::Algorithm &algorithm) const
     }
     for (auto process : processList) {
         if (process.type == SchemePlanManager::CalculateWeight) {
-            if (process.algorithm == SchemePlanManager::Entropy) {
-                algorithm = process.algorithm;
-            }
+            algorithm = process.algorithm;
             break;
         }
     }