123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- #include "MindEvaluation.h"
- #include "CMind.h"
- #include "dbService/NodeMatrixService.h"
- #include "dbService/UserConfigService.h"
- #include "algorithm/HierarchicalAnalysis.h"
- #include "algorithm/EntropyWeights.h"
- #include "algorithm/PCA.h"
- #include <QMessageBox>
- #include <QDebug>
- MindEvaluation::MindEvaluation(CMind *mind, int expertId, const QString &tableType, int mindMatrix, QObject *parent)
- : QObject(parent),
- m_mind(mind),
- m_expertId(expertId),
- m_tableType(tableType),
- m_mindMatrix(mindMatrix),
- m_isAggregationOp(false)
- {
- init();
- }
- MindEvaluation::MindEvaluation(CMind *mind, MindEvaluation::AggregationType atype, const QString &tableType,
- int mindMatrix, QObject *parent)
- : QObject(parent),
- m_mind(mind),
- m_tableType(tableType),
- m_mindMatrix(mindMatrix),
- m_aggregationType(atype),
- m_isAggregationOp(true)
- {
- }
- MindEvaluation::~MindEvaluation() { }
- void MindEvaluation::updateSeqNodes()
- {
- m_mind->getSeqNodes(m_seqNodes);
- }
- static QList<QPair<QString, QString>> getMatrixString(const QStringList &in)
- {
- QList<QPair<QString, QString>> res;
- const int n = in.size();
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- res << QPair<QString, QString>(in.at(i), in.at(j));
- }
- }
- return res;
- }
- void MindEvaluation::computeWeights()
- {
- if (!m_isAggregationOp) {
- computeSingleWeights();
- } else {
- if (m_aggregationType == NoMerge) {
- computeNoMergeWeights();
- } else {
- computeMergeWeights();
- }
- }
- }
- void MindEvaluation::init()
- {
- updateSeqNodes();
- }
- void MindEvaluation::computeSingleWeights()
- {
- QList<NodeMatrixInfo *> nmInfos;
- if (!NodeMatrixService().QueryNodeMatrixListByExpertIdAndEngineerId(&nmInfos, m_expertId, m_mind->root().projectId,
- m_tableType)) {
- QMessageBox::warning(nullptr, "警告", "数据库访问失败");
- return;
- }
- for (int sn = 0; sn < m_seqNodes.count(); sn++) {
- qDebug() << "第" << sn << "层";
- for (auto s : m_seqNodes.at(sn)) {
- qDebug() << s.name << s.childs;
- if (m_mindMatrix == 0) { // 层次分析法
- auto matrixStr = getMatrixString(s.childs);
- QVector<qreal> nxnValus(matrixStr.size(), 0.0001); // n x n矩阵
- for (const auto &nmInfo : nmInfos) {
- if (nmInfo->mindId == m_mindMatrix) {
- int loc = matrixStr.indexOf(QPair<QString, QString>(nmInfo->abscissa, nmInfo->ordinate));
- if (loc >= 0) {
- QStringList nodeValue = nmInfo->nodeValue.split("/");
- if (nodeValue.size() == 1) {
- nxnValus[loc] = nodeValue[0].toDouble();
- } else {
- nxnValus[loc] = nodeValue[0].toDouble() / nodeValue[1].toDouble();
- }
- }
- }
- }
- QScopedPointer<HierarchicalAnalysis> ha(new HierarchicalAnalysis(s.childs.size(), nxnValus));
- QVector<qreal> weights = ha->getWeights();
- for (int c = 0; c < s.childs.size(); ++c) {
- mindNodeWeights << MindNodeItem { s.name, s.childs.at(c), weights.at(c), 0 };
- }
- } else {
- // 熵权法
- if (1) {
- QMap<QString /*指标*/, QMap<QString /*uuid*/, double>> seqMap;
- for (const auto &nmInfo : nmInfos) {
- if (nmInfo->mindId == m_mindMatrix) {
- int loc = s.childs.indexOf(nmInfo->abscissa); // 指标索引
- if (loc >= 0) {
- QStringList nodeValue = nmInfo->nodeValue.split("/");
- double v;
- if (nodeValue.size() == 1) {
- v = nodeValue[0].toDouble();
- } else {
- v = nodeValue[0].toDouble() / nodeValue[1].toDouble();
- }
- if (!seqMap.contains(nmInfo->abscissa)) {
- seqMap.insert(nmInfo->abscissa, QMap<QString /*uuid*/, double>());
- }
- seqMap[nmInfo->abscissa].insert(nmInfo->strUuid, v);
- }
- }
- }
- EntropyMat eMat; // 一个指标一行数据
- for (const auto &c : s.childs) {
- if (seqMap.contains(c)) {
- QVector<double> indexVecs;
- QMapIterator<QString, double> iter(seqMap[c]);
- while (iter.hasNext()) {
- iter.next();
- indexVecs << iter.value();
- }
- eMat << indexVecs;
- } else {
- QMessageBox::warning(nullptr, "警告", QString("指标%1数据缺失").arg(c));
- }
- }
- QScopedPointer<EntropyWeights> ew(new EntropyWeights(eMat));
- QVector<qreal> weights, score;
- ew->compute(weights, score);
- for (int c = 0; c < s.childs.size(); ++c) {
- mindNodeWeights << MindNodeItem { s.name, s.childs.at(c), weights.at(c), score.at(c) };
- }
- } else { // pca
- QMap<QString /*uuid*/, QMap<QString /*指标*/, double>> seqMap;
- for (const auto &nmInfo : nmInfos) {
- if (nmInfo->mindId == m_mindMatrix) {
- int loc = s.childs.indexOf(nmInfo->abscissa); // 指标索引
- if (loc >= 0) {
- QStringList nodeValue = nmInfo->nodeValue.split("/");
- double v;
- if (nodeValue.size() == 1) {
- v = nodeValue[0].toDouble();
- } else {
- v = nodeValue[0].toDouble() / nodeValue[1].toDouble();
- }
- if (!seqMap.contains(nmInfo->strUuid)) {
- seqMap.insert(nmInfo->strUuid, QMap<QString /*指标*/, double>());
- }
- seqMap[nmInfo->strUuid].insert(nmInfo->abscissa, v);
- }
- }
- }
- QVector<QVector<double>> pMat; // 一个指标一列数据
- QMapIterator<QString, QMap<QString /*指标*/, double>> iter(seqMap);
- while (iter.hasNext()) {
- iter.next();
- QMap<QString /*指标*/, double> indexMap = iter.value();
- QVector<double> tmp;
- QMapIterator<QString /*指标*/, double> iterIndex(indexMap);
- while (iterIndex.hasNext()) {
- iterIndex.next();
- tmp << iterIndex.value();
- }
- pMat << tmp;
- }
- QScopedPointer<PCA> pca(new PCA(pMat));
- pca->compute();
- QVector<qreal> weights = pca->weights();
- QVector<qreal> score = pca->scores();
- for (int c = 0; c < s.childs.size(); ++c) {
- mindNodeWeights << MindNodeItem { s.name, s.childs.at(c), weights.at(c), score.at(c) };
- }
- }
- }
- }
- }
- qDeleteAll(nmInfos);
- }
- /// 数据集结,先计算每个专家的权重,在求均值
- void MindEvaluation::computeNoMergeWeights()
- {
- int enjId = m_mind->root().projectId;
- QList<UserConfig *> users;
- if (!UserConfigService().QueryUserConfigListInfoByEngineerId(&users, enjId)) {
- QMessageBox::warning(nullptr, "警告", "数据库访问失败");
- return;
- }
- bool QueryUserConfigListInfoByEngineerId(QList<UserConfig *> * userCfgList, int engineerId);
- QScopedPointer<QList<QList<MindNodeItem>>> allItems(new QList<QList<MindNodeItem>>());
- for (const auto &user : users) {
- QList<NodeMatrixInfo *> nmInfos;
- if (!NodeMatrixService().QueryNodeMatrixListByExpertIdAndEngineerId(&nmInfos, user->id, enjId, m_tableType)) {
- qDeleteAll(users);
- QMessageBox::warning(nullptr, "警告", "数据库访问失败");
- return;
- }
- QList<MindNodeItem> mnItem;
- computeOneEntry(nmInfos, mnItem);
- allItems->append(mnItem);
- qDeleteAll(nmInfos);
- }
- qDeleteAll(users);
- for (int i = 0; i < allItems->size(); ++i) {
- if (i == 0) {
- mindNodeWeights = allItems->at(0);
- } else {
- for (const auto &item : allItems->at(i)) {
- int id = mindNodeWeights.indexOf(item);
- mindNodeWeights[id].value += item.value;
- mindNodeWeights[id].score += item.score;
- }
- }
- }
- for (int id = 0; id < mindNodeWeights.size(); id++) {
- mindNodeWeights[id].value /= allItems->size();
- mindNodeWeights[id].score /= allItems->size();
- }
- }
- /// 数矩阵集结,先计算出一个综合专家,在计算权重
- void MindEvaluation::computeMergeWeights()
- {
- int enjId = m_mind->root().projectId;
- QList<UserConfig *> users;
- if (!UserConfigService().QueryUserConfigListInfoByEngineerId(&users, enjId)) {
- QMessageBox::warning(nullptr, "警告", "数据库访问失败");
- return;
- }
- bool QueryUserConfigListInfoByEngineerId(QList<UserConfig *> * userCfgList, int engineerId);
- QList<NodeMatrixInfo *> megerNMInfo;
- QVector<double> nodeValues;
- for (const auto &user : users) {
- QList<NodeMatrixInfo *> nmInfos;
- if (!NodeMatrixService().QueryNodeMatrixListByExpertIdAndEngineerId(&nmInfos, user->id, enjId, m_tableType)) {
- qDeleteAll(users);
- QMessageBox::warning(nullptr, "警告", "数据库访问失败");
- return;
- }
- if (megerNMInfo.size() == 0) {
- for (int nm = 0; nm < nmInfos.size(); ++nm) {
- NodeMatrixInfo *info = nmInfos.at(nm);
- megerNMInfo.append(new NodeMatrixInfo());
- *megerNMInfo[0] = *info;
- double v;
- QStringList nds = nmInfos.at(nm)->nodeValue.split("/");
- if (nds.size() == 1) {
- v = nds.at(0).toDouble();
- } else {
- v = nds.at(0).toDouble() / nds.at(1).toDouble();
- }
- nodeValues << v;
- }
- } else {
- for (int nm = 0; nm < nmInfos.size(); ++nm) {
- double v;
- QStringList nds = nmInfos.at(nm)->nodeValue.split("/");
- if (nds.size() == 1) {
- v = nds.at(0).toDouble();
- } else {
- v = nds.at(0).toDouble() / nds.at(1).toDouble();
- }
- nodeValues[nm] += v;
- }
- }
- qDeleteAll(nmInfos);
- }
- for (int nm = 0; nm < megerNMInfo.size(); ++nm) {
- megerNMInfo[nm]->nodeValue = QString::number(nodeValues[nm] / users.size());
- }
- computeOneEntry(megerNMInfo, mindNodeWeights);
- qDeleteAll(megerNMInfo);
- qDeleteAll(users);
- }
- void MindEvaluation::computeOneEntry(const QList<NodeMatrixInfo *> &nmInfos, QList<MindNodeItem> &mindNodeItem)
- {
- for (int sn = 0; sn < m_seqNodes.count(); sn++) {
- qDebug() << "第" << sn << "层";
- for (auto s : m_seqNodes.at(sn)) {
- qDebug() << s.name << s.childs;
- if (m_mindMatrix == 0) { // 层次分析法
- auto matrixStr = getMatrixString(s.childs);
- QVector<qreal> nxnValus(matrixStr.size(), 0.0001); // n x n矩阵
- for (const auto &nmInfo : nmInfos) {
- if (nmInfo->mindId == m_mindMatrix) {
- int loc = matrixStr.indexOf(QPair<QString, QString>(nmInfo->abscissa, nmInfo->ordinate));
- if (loc >= 0) {
- QStringList nodeValue = nmInfo->nodeValue.split("/");
- if (nodeValue.size() == 1) {
- nxnValus[loc] = nodeValue[0].toDouble();
- } else {
- nxnValus[loc] = nodeValue[0].toDouble() / nodeValue[1].toDouble();
- }
- }
- }
- }
- QScopedPointer<HierarchicalAnalysis> ha(new HierarchicalAnalysis(s.childs.size(), nxnValus));
- QVector<qreal> weights = ha->getWeights();
- for (int c = 0; c < s.childs.size(); ++c) {
- mindNodeItem << MindNodeItem { s.name, s.childs.at(c), weights.at(c), 0 };
- }
- } else {
- // 熵权法
- if (1) {
- QMap<QString /*指标*/, QMap<QString /*uuid*/, double>> seqMap;
- for (const auto &nmInfo : nmInfos) {
- if (nmInfo->mindId == m_mindMatrix) {
- int loc = s.childs.indexOf(nmInfo->abscissa); // 指标索引
- if (loc >= 0) {
- QStringList nodeValue = nmInfo->nodeValue.split("/");
- double v;
- if (nodeValue.size() == 1) {
- v = nodeValue[0].toDouble();
- } else {
- v = nodeValue[0].toDouble() / nodeValue[1].toDouble();
- }
- if (!seqMap.contains(nmInfo->abscissa)) {
- seqMap.insert(nmInfo->abscissa, QMap<QString /*uuid*/, double>());
- }
- seqMap[nmInfo->abscissa].insert(nmInfo->strUuid, v);
- }
- }
- }
- EntropyMat eMat; // 一个指标一行数据
- for (const auto &c : s.childs) {
- if (seqMap.contains(c)) {
- QVector<double> indexVecs;
- QMapIterator<QString, double> iter(seqMap[c]);
- while (iter.hasNext()) {
- iter.next();
- indexVecs << iter.value();
- }
- eMat << indexVecs;
- } else {
- QMessageBox::warning(nullptr, "警告", QString("指标%1数据缺失").arg(c));
- }
- }
- QScopedPointer<EntropyWeights> ew(new EntropyWeights(eMat));
- QVector<qreal> weights, score;
- ew->compute(weights, score);
- for (int c = 0; c < s.childs.size(); ++c) {
- mindNodeItem << MindNodeItem { s.name, s.childs.at(c), weights.at(c), score.at(c) };
- }
- } else { // pca
- QMap<QString /*uuid*/, QMap<QString /*指标*/, double>> seqMap;
- for (const auto &nmInfo : nmInfos) {
- if (nmInfo->mindId == m_mindMatrix) {
- int loc = s.childs.indexOf(nmInfo->abscissa); // 指标索引
- if (loc >= 0) {
- QStringList nodeValue = nmInfo->nodeValue.split("/");
- double v;
- if (nodeValue.size() == 1) {
- v = nodeValue[0].toDouble();
- } else {
- v = nodeValue[0].toDouble() / nodeValue[1].toDouble();
- }
- if (!seqMap.contains(nmInfo->strUuid)) {
- seqMap.insert(nmInfo->strUuid, QMap<QString /*指标*/, double>());
- }
- seqMap[nmInfo->strUuid].insert(nmInfo->abscissa, v);
- }
- }
- }
- QVector<QVector<double>> pMat; // 一个指标一列数据
- QMapIterator<QString, QMap<QString /*指标*/, double>> iter(seqMap);
- while (iter.hasNext()) {
- iter.next();
- QMap<QString /*指标*/, double> indexMap = iter.value();
- QVector<double> tmp;
- QMapIterator<QString /*指标*/, double> iterIndex(indexMap);
- while (iterIndex.hasNext()) {
- iterIndex.next();
- tmp << iterIndex.value();
- }
- pMat << tmp;
- }
- QScopedPointer<PCA> pca(new PCA(pMat));
- pca->compute();
- QVector<qreal> weights = pca->weights();
- QVector<qreal> score = pca->scores();
- for (int c = 0; c < s.childs.size(); ++c) {
- mindNodeItem << MindNodeItem { s.name, s.childs.at(c), weights.at(c), score.at(c) };
- }
- }
- }
- }
- }
- }
|