Quellcode durchsuchen

更新灰色聚类

Signed-off-by: codeClown <zhaomengshou@126.com>
codeClown vor 1 Jahr
Ursprung
Commit
63035dc153

+ 26 - 40
QFD/algorithm/GreyClusterEvaluation.cpp

@@ -1,45 +1,37 @@
-//
+//
 // Created by lenovo on 2023/10/16.
 //
 
 #include "GreyClusterEvaluation.h"
 
-GreyClusterEvaluation::GreyClusterEvaluation(const GCEMat& mat, const GCERangeMat& ranges)
-    : mat_(mat),
-      ranges_(ranges)
+GreyClusterEvaluation::GreyClusterEvaluation(const GCEMat &mat, const GCERangeMat &ranges) : mat_(mat), ranges_(ranges)
 {
     sample_num_ = mat_.count();
-    if (sample_num_ == 0)
-    {
+    if (sample_num_ == 0) {
         level_num_ = 0;
-    }
-    else
-    {
+    } else {
         level_num_ = ranges_.at(0).count();
     }
 
-    for (int i = 0; i < sample_num_; ++i)
-    {
+    for (int i = 0; i < sample_num_; ++i) {
         GCEMat cvtMat;
-        for (int j = 0; j < level_num_; ++j)
-        {
-            cvtMat.append(QVector<GCEmat>(level_num_, {0.0, 0.0}));
+        for (int j = 0; j < level_num_; ++j) {
+            cvtMat.append(QVector<GCEmat>(level_num_, { 0.0, 0.0 }));
         }
         ranges_cv_.append(cvtMat);
     }
-    QVector<GCEmat> cvrang_weights(level_num_, {0.0, 0.0});
+    QVector<GCEmat> cvrang_weights(level_num_, { 0.0, 0.0 });
     ranges_weight_.append(cvrang_weights);
 }
 
-void GreyClusterEvaluation::evaluate()
+void GreyClusterEvaluation::evaluate(const QVector<double> &weights)
 {
-    for (int s = 0; s < sample_num_; ++s)
-    {
+    for (int s = 0; s < sample_num_; ++s) {
         double val_front = mat_.at(s).front_val;
-        double val_back = mat_.at(s).back_val;
+        double val_back  = mat_.at(s).back_val;
         triangularwhiteningweight(s, val_front, val_back);
     }
-    QVector<double> weights = {0.2, 0.15, 0.05, 0.4, 0.2};
+    //    QVector<double> weights = {0.2, 0.15, 0.05, 0.4, 0.2};
     evaluationlevel(weights);
 }
 
@@ -53,8 +45,7 @@ void GreyClusterEvaluation::triangularwhiteningweight(int sam, double front_val,
         return (right_right - v) / (right_right - left_right);
     };
 
-    for (int i = 0; i < level_num_; ++i)
-    {
+    for (int i = 0; i < level_num_; ++i) {
         Q_ASSERT(ranges_.at(sam).at(i).level == i);
         double r1 = pFunc1(ranges_.at(sam).at(i).left_val, ranges_.at(sam).at(i).right_val);
         double r2 = pFunc2(front_val, ranges_.at(sam).at(i).left_left, r1);
@@ -77,42 +68,37 @@ void GreyClusterEvaluation::triangularwhiteningweight(int sam, double front_val,
     }
 }
 
-void GreyClusterEvaluation::evaluationlevel(const QVector<double>& weights)
+void GreyClusterEvaluation::evaluationlevel(const QVector<double> &weights)
 {
-    for (int i = 0; i < level_num_; ++i)
-    {
+    for (int i = 0; i < level_num_; ++i) {
         double front_val = 0;
-        double back_val = 0;
-        for (int j = 0; j < sample_num_; ++j)
-        {
+        double back_val  = 0;
+        for (int j = 0; j < sample_num_; ++j) {
             front_val = front_val + ranges_cv_.at(j).at(i).front_val * weights[j];
-            back_val = back_val + ranges_cv_.at(j).at(i).back_val * weights[j];
+            back_val  = back_val + ranges_cv_.at(j).at(i).back_val * weights[j];
         }
         ranges_weight_[i].front_val = front_val;
-        ranges_weight_[i].back_val = back_val;
+        ranges_weight_[i].back_val  = back_val;
     }
 }
 
 BestIndex GreyClusterEvaluation::getBestIndex() const
 {
-    BestIndex index = {0, 0};
+    BestIndex index = { 0, 0 };
     double maxf_val = ranges_weight_.at(0).front_val;
     double maxb_val = ranges_weight_.at(0).back_val;
-    for (int i = 1; i < ranges_weight_.count(); ++i)
-    {
-        if (ranges_weight_.at(i).front_val > maxf_val)
-        {
-            maxf_val = ranges_weight_.at(i).front_val;
+    for (int i = 1; i < ranges_weight_.count(); ++i) {
+        if (ranges_weight_.at(i).front_val > maxf_val) {
+            maxf_val          = ranges_weight_.at(i).front_val;
             index.front_index = i;
         }
-        if (ranges_weight_.at(i).back_val > maxb_val)
-        {
-            maxb_val = ranges_weight_.at(i).back_val;
+        if (ranges_weight_.at(i).back_val > maxb_val) {
+            maxb_val         = ranges_weight_.at(i).back_val;
             index.back_index = i;
         }
     }
     index.front_index = index.front_index + 1;
-    index.back_index = index.back_index + 1;
+    index.back_index  = index.back_index + 1;
 
     return index;
 }

+ 1 - 1
QFD/algorithm/GreyClusterEvaluation.h

@@ -42,7 +42,7 @@ public:
      */
     GreyClusterEvaluation(const GCEMat &mat, const GCERangeMat &ranges);
 
-    void evaluate();
+    void evaluate(const QVector<double> &weights);
 
     BestIndex getBestIndex() const;
 

+ 28 - 23
QFD/algorithm/MatterElementAnalysis.cpp

@@ -1,11 +1,11 @@
-//
+//
 // Created by Austin on 2023/10/11.
 //
 
 #include "MatterElementAnalysis.h"
 
-MatterElementAnalysis::MatterElementAnalysis(const MEAMat &mat, const MEARangeMat &ranges)
-        : mat_(mat), ranges_(ranges) {
+MatterElementAnalysis::MatterElementAnalysis(const MEAMat &mat, const MEARangeMat &ranges) : mat_(mat), ranges_(ranges)
+{
     sample_num_ = mat_.count();
     if (sample_num_ == 0) {
         index_num_ = 0;
@@ -25,33 +25,35 @@ MatterElementAnalysis::MatterElementAnalysis(const MEAMat &mat, const MEARangeMa
     }
 }
 
-void MatterElementAnalysis::evaluate() {
-    //根据关联函数更新转换矩阵
+void MatterElementAnalysis::evaluate(const QVector<double> &weights)
+{
+    // 根据关联函数更新转换矩阵
     for (int s = 0; s < sample_num_; ++s) {
         for (int i = 0; i < index_num_; ++i) {
             double val = mat_.at(s).at(i);
             associatedValue(s, i, val);
         }
     }
-    QVector<double> weights = {0.189, 0.203, 0.052, 0.162, 0.202, 0.151, 0.041};
+    //    QVector<double> weights_ = { 0.189, 0.203, 0.052, 0.162, 0.202, 0.151, 0.041 };
     evaluationlevel(weights);
 }
 
-void MatterElementAnalysis::associatedValue(int sam, int index, double value) {
+void MatterElementAnalysis::associatedValue(int sam, int index, double value)
+{
     auto pFunc = [](double v, double left, double right) {
         return std::abs(v - (left + right) / 2) - (right - left) / 2;
     };
 
     double r = 0;
-    for (int i = 0; i < ranges_.count() - 1; ++i) //i是等级,index是指标
+    for (int i = 0; i < ranges_.count() - 1; ++i)  // i是等级,index是指标
     {
         Q_ASSERT(ranges_.at(i).at(index).index == index);
         double minValue = ranges_.at(i).at(index).min_value;
         double maxValue = ranges_.at(i).at(index).max_value;
-        double minend = ranges_.last().at(index).min_value;
-        double maxend = ranges_.last().at(index).max_value;
-        double r1 = pFunc(value, minValue, maxValue);
-        double r2 = pFunc(value, minend, maxend);
+        double minend   = ranges_.last().at(index).min_value;
+        double maxend   = ranges_.last().at(index).max_value;
+        double r1       = pFunc(value, minValue, maxValue);
+        double r2       = pFunc(value, minend, maxend);
 
         if (abs(r1 - r2) <= 0.00000001) {
             r = -r1 - 1;
@@ -59,41 +61,44 @@ void MatterElementAnalysis::associatedValue(int sam, int index, double value) {
             r = r1 / (r2 - r1);
         }
         range_cvt_[sam][index][i] = r;
-        //结果放在range_cvt_
+        // 结果放在range_cvt_
     }
 }
 
-void MatterElementAnalysis::evaluationlevel(const QVector<double> &weights) { //输入计算出来的关联度,权值
-    //计算一个样本权值之后的总关联度
+void MatterElementAnalysis::evaluationlevel(const QVector<double> &weights)
+{  // 输入计算出来的关联度,权值
+    // 计算一个样本权值之后的总关联度
     double r;
-    for (int i = 0; i < sample_num_; ++i) //样本
-        for (int j = 0; j < ranges_.count() - 1; ++j) {                                 //等级
+    for (int i = 0; i < sample_num_; ++i)                // 样本
+        for (int j = 0; j < ranges_.count() - 1; ++j) {  // 等级
             r = 0;
-            for (int k = 0; k < index_num_; ++k) { //指标
+            for (int k = 0; k < index_num_; ++k) {  // 指标
                 r = r + range_cvt_[i][k][j] * weights[k];
             }
             range_weights_[i][j] = r;
         }
 }
 
-const MEAMat &MatterElementAnalysis::getRangeWeights() const {
+const MEAMat &MatterElementAnalysis::getRangeWeights() const
+{
     return range_weights_;
 }
 
-QVector<int> MatterElementAnalysis::getBestIndex() const {
+QVector<int> MatterElementAnalysis::getBestIndex() const
+{
     auto maxLoc = [](const QVector<double> &v) {
-        int index = 0;
+        int index       = 0;
         double maxValue = v.at(0);
         for (int i = 1; i < v.count(); ++i) {
             if (v.at(i) > maxValue) {
                 maxValue = v.at(i);
-                index = i;
+                index    = i;
             }
         }
         return index;
     };
     QVector<int> result;
-    for (const auto &s: range_weights_) {
+    for (const auto &s : range_weights_) {
         result << maxLoc(s) + 1;
     }
 

+ 1 - 1
QFD/algorithm/MatterElementAnalysis.h

@@ -30,7 +30,7 @@ public:
      */
     MatterElementAnalysis(const MEAMat &mat, const MEARangeMat &ranges);
 
-    void evaluate();
+    void evaluate(const QVector<double> &weights);
 
     const MEAMat &getRangeWeights() const;
 

+ 2 - 2
QFD/algorithm/test_main.cpp

@@ -271,7 +271,7 @@ void testSPA()
         };
 
         GreyClusterEvaluation gc(mat, ranges);
-        gc.evaluate();
+        gc.evaluate({ 0.2, 0.15, 0.05, 0.4, 0.2 });
         BestIndex index = gc.getBestIndex();
         qDebug() << index.front_index << index.back_index;
     }
@@ -318,7 +318,7 @@ void testSPA()
         };
         // 等级
         MatterElementAnalysis me(mat, ranges);
-        me.evaluate();
+        me.evaluate({ 0.189, 0.203, 0.052, 0.162, 0.202, 0.151, 0.041 });
         QVector<int> index = me.getBestIndex();
         qDebug() << index;
     }

+ 1 - 2
QFD/widgets/DataCollectionWidget.cpp

@@ -113,8 +113,7 @@ void DataCollectionWidget::setupTabWidget()
                 GreyClusteringConfigWidget *gc = new GreyClusteringConfigWidget(mind, process.efficiencyGrades);
                 m_tab->addTab(gc, indexName + " - " + "灰色聚类法效能等级配置");
 
-                QVector<GreyClusteringItem> items;
-                GreyClusteringSampleTable *gs = new GreyClusteringSampleTable(items, 2, 10);
+                GreyClusteringSampleTable *gs = new GreyClusteringSampleTable(mind, process.efficiencyGrades);
                 m_tab->addTab(gs, indexName + " - " + "收集效能评估数据");
             }
 

+ 144 - 4
QFD/widgets/GreyClusteringSampleTable.cpp

@@ -1,9 +1,13 @@
 #include "GreyClusteringItemDelegate.h"
 #include "GreyClusteringSampleTable.h"
 #include "MultiLevelHeaderView.h"
+#include "CMind.h"
+#include "dbService/GradeInfoService.h"
+#include "dbService/EffectIndexInfoService.h"
 
 #include <QHeaderView>
 #include <QDebug>
+#include <QMessageBox>
 
 /**
  * example
@@ -126,14 +130,16 @@
     gcst.show();
  */
 
-GreyClusteringSampleTable::GreyClusteringSampleTable(const QVector<GreyClusteringItem> &gcItems, int nodeDepth,
-                                                     int rowNodes, QWidget *parent)
-    : QTableView(parent), m_greyClusterings(gcItems), m_nodeDepth(nodeDepth), m_rowNodes(rowNodes)
+GreyClusteringSampleTable::GreyClusteringSampleTable(CMind *mind, int grayNumber, QWidget *parent)
+    : QTableView(parent), m_mind(mind), m_nodeDepth(2), m_grayNumber(grayNumber)
 {
     m_model = new QStandardItemModel();
     this->setModel(m_model);
 
     init();
+    initClusteringItems();
+
+    refreshTableView();
 }
 
 void GreyClusteringSampleTable::refreshTableView()
@@ -192,7 +198,7 @@ void GreyClusteringSampleTable::refreshTableView()
     }
 
     m_model->setColumnCount(colCount);
-    m_model->setRowCount(m_rowNodes);
+    m_model->setRowCount(m_rowCount);
 
     for (const auto &item : m_greyClusterings) {
         // 第一步,设置指标名
@@ -257,4 +263,138 @@ void GreyClusteringSampleTable::init()
     verticalHeader()->setStyleSheet("QHeaderView::section{background:rgb(244,244,244);color: black;}");
     verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
     setSelectionMode(QAbstractItemView::SingleSelection);
+
+    QList<GradeInfo *> gradeInfoList;
+    QMap<QString, QString> grayLevelMaps;
+    int projectId = m_mind->root().projectId;
+    if (!GradeInfoService().QueryGradeByProjectIdAndType(&gradeInfoList, projectId, 1)) {
+        QMessageBox::warning(this, "警告", "数据库访问失败");
+    } else {
+        if (gradeInfoList.size() == 0) {
+            for (int lvl = 0; lvl < m_grayNumber; ++lvl) {
+                grayLevelMaps.insert(QString("级别 %1:").arg(lvl + 1), QString("E%1").arg(lvl + 1));
+                GradeInfo ginfo;
+                ginfo.projectId  = projectId;
+                ginfo.gradeName  = QString("级别 %1").arg(lvl + 1);
+                ginfo.gradeValue = QString("灰类%1级").arg(lvl + 1);
+                ginfo.type       = 1;
+                if (!GradeInfoService().AddGradeInfo(ginfo)) {
+                    QMessageBox::warning(this, "警告", "数据库访问失败");
+                }
+            }
+        } else {
+            for (const auto &gi : gradeInfoList) {
+                grayLevelMaps.insert(gi->gradeName, gi->gradeValue);
+                if (grayLevelMaps.size() >= m_grayNumber) {
+                    break;
+                }
+            }
+            // 缺少再补
+            for (int lvl = grayLevelMaps.size(); lvl < m_grayNumber; ++lvl) {
+                grayLevelMaps.insert(QString("级别 %1:").arg(lvl + 1), QString("E%1").arg(lvl + 1));
+                GradeInfo ginfo;
+                ginfo.projectId  = projectId;
+                ginfo.gradeName  = QString("级别 %1").arg(lvl + 1);
+                ginfo.gradeValue = QString("灰类%1级").arg(lvl + 1);
+                ginfo.type       = 1;
+                if (!GradeInfoService().AddGradeInfo(ginfo)) {
+                    QMessageBox::warning(this, "警告", "数据库访问失败");
+                }
+            }
+
+            m_grayNames = grayLevelMaps.values();
+        }
+    }
+    qDeleteAll(gradeInfoList);
+}
+
+void GreyClusteringSampleTable::initClusteringItems()
+{
+    // 脑图层级 < 2 时无效
+    if (m_mind->levels() < 2) {
+        return;
+    }
+    m_greyClusterings.clear();
+
+    // 使用倒数第二层节点及其子节点
+    int row = 0;
+    for (CNodeData n : m_mind->nodesInLevel(m_mind->levels() - 1)) {
+        GreyClusteringItem parentItem = { n.name, row, 0, 1, 1, nullptr };
+        QList<CNodeData> subNodes     = m_mind->subNodes(n);
+        parentItem.colSpan            = subNodes.size() == 0 ? 2 : 1;  // 没有子节点,占两列,否则占一列
+        parentItem.rowSpan = subNodes.size() == 0 ? 1 : subNodes.size();  // 没有子节点,占一行,否则占子节点数目行
+
+        if (subNodes.size() == 0) {  // 没有子节点,需要录入值
+            GreyClusteringValue *sg = new GreyClusteringValue;
+            sg->units               = "";
+            sg->weiget              = 0;
+            for (const auto &gname : m_grayNames) {
+                sg->greyRanges << GreyRange { gname, true, 0, true, 0 };
+            }
+            sg->leftExtension  = 0;
+            sg->rightExtension = 0;
+            sg->oldValue       = 0;
+            sg->newValue       = 0;
+            parentItem.value.reset(sg);
+        }
+        m_greyClusterings.append(parentItem);
+
+        int subRow = row;
+        // 子节点
+        for (const CNodeData &sub : subNodes) {
+            // 因为已有父节点,所以在第2列
+            GreyClusteringItem childItem = { sub.name, subRow, 1, 1, 1, nullptr };
+            GreyClusteringValue *sg      = new GreyClusteringValue;
+            sg->units                    = "";
+            sg->weiget                   = 0;
+            for (const auto &gname : m_grayNames) {
+                sg->greyRanges << GreyRange { gname, true, 0, true, 0 };
+            }
+            sg->leftExtension  = 0;
+            sg->rightExtension = 0;
+            sg->oldValue       = 0;
+            sg->newValue       = 0;
+            childItem.value.reset(sg);
+            m_greyClusterings.append(childItem);
+            subRow++;
+        }
+
+        row += parentItem.rowSpan;
+    }
+
+    m_rowCount = row;
+
+    // 更新
+    QList<EffectIndexInfo *> effectIndexInfoList;
+    int projectid = m_mind->root().projectId;
+    if (!EffectIndexInfoService().QueryEffectIndexInfoByProjectId(&effectIndexInfoList, projectid)) {
+        QMessageBox::warning(this, "警告", "数据库访问失败");
+        return;
+    }
+    if (effectIndexInfoList.size() > 0) {
+        for (auto &item : m_greyClusterings) {
+            if (item.value.isNull()) {
+                continue;
+            }
+
+            for (const auto &effInfo : effectIndexInfoList) {
+                if (effInfo->effectIndexName == item.indexName) {
+                    item.value->units          = effInfo->effectIndexUnit;
+                    item.value->leftExtension  = effInfo->extendLeft.toDouble();
+                    item.value->rightExtension = effInfo->extendRight.toDouble();
+                    //[0:0],[0:0],[0:0]
+                    QStringList valueList = effInfo->effectIndexValue.split(",");
+                    int align             = qMin(valueList.size(), item.value->greyRanges.size());
+                    for (int str = 0; str < align; str++) {
+                        //[0:0]
+                        QStringList lr = valueList.at(str).mid(1, valueList.at(str).size() - 2).split(":");
+                        item.value->greyRanges[str].leftValue  = lr.at(0).toDouble();
+                        item.value->greyRanges[str].rightValue = lr.at(1).toDouble();
+                    }
+                }
+            }
+        }
+    }
+
+    qDeleteAll(effectIndexInfoList);
 }

+ 10 - 3
QFD/widgets/GreyClusteringSampleTable.h

@@ -6,6 +6,8 @@
 #include <QVector>
 #include <QSharedPointer>
 
+class CMind;
+
 struct GreyRange
 {
     QString name;
@@ -44,19 +46,24 @@ class GreyClusteringSampleTable : public QTableView
     Q_OBJECT
 
 public:
-    GreyClusteringSampleTable(const QVector<GreyClusteringItem> &gcItems, int nodeDepth, int rowNodes,
-                              QWidget *parent = nullptr);
+    GreyClusteringSampleTable(CMind *mind, int grayNumber, QWidget *parent = nullptr);
 
     void refreshTableView();
 
 private:
     void init();
+    void initClusteringItems();
 
 private:
     QVector<GreyClusteringItem> m_greyClusterings;
     QStandardItemModel *m_model;
+    CMind *m_mind;
     int m_nodeDepth;  // 节点深度
-    int m_rowNodes;   //
+    int m_rowCount;   // 行数
+    QStringList m_grayNames;
+
+    const int nodeDepth = 2;  // 节点深度
+    int m_grayNumber;
 };
 
 #endif  // GREYCLUSTERINGSAMPLETABLE_H