#include "DataEvaluator.h" #include #include #include #include "algorithm/EntropyWeights.h" #include "algorithm/PCA.h" #include "algorithm/HierarchicalAnalysis.h" #include "algorithm/MatterElementAnalysis.h" #include #include #include #include #include #include #include #include #include #include #include #include DataEvaluator::DataEvaluator(QObject *parent) : QObject(parent) { } void DataEvaluator::setProcess(SchemePlanManager::SchemeProcessInfo process) { m_process = process; } SchemePlanManager::SchemeProcessInfo DataEvaluator::process() const { return m_process; } void DataEvaluator::setGatherType(DataEvaluator::GatherType type) { m_gatherType = type; } DataEvaluator::GatherType DataEvaluator::gatherType() const { return m_gatherType; } bool DataEvaluator::evaluate() { if (m_process.type == SchemePlanManager::ImportWeightData) { if (m_process.dSource == SchemePlanManager::FromExpert) { return evaluateWeightFromExpert(); } else if (m_process.dSource == SchemePlanManager::FromMeasurement) { return evaluateWeightFromMeasure(); } } else if (m_process.type == SchemePlanManager::ImportEvalData) { if (m_process.indexType == ProjectManager::TechIndex) { return evaluateTech(); } else if (m_process.indexType == ProjectManager::OptimalIndex) { return evaluateScheme(); } else if (m_process.indexType == ProjectManager::EfficiencyIndex) { return evaluateEfficiencyMEA(); } } return false; } bool DataEvaluator::evaluateWeightFromExpert() { QMap> nodeData; bool dataRet = getNodeData(nodeData); /// 权重分析专家导入数据, 使用层次分析法 SchemePlanManager::Algorithm algorithm = SchemePlanManager::AHP; /// 获取指标体系, QList nodeList; bool mindRet = CNodeDataService().QueryAllValid(nodeList, m_process.projectId, m_process.indexType); CMind *mind = new CMind(this); mind->setNodeList(nodeList); /// 获取专家配置 QMap config; bool cfgRet = getUserConfig(config); if (!(dataRet && mindRet && cfgRet)) { return false; } QMap indexWeights; // 结果集结, 先计算各个专家的数据, 再取均值 if (m_gatherType == Result) { QMap> mWeights; for (QString expertId : nodeData.keys()) { for (int i = 1; i < mind->levels(); i++) { for (CNodeData node : mind->nodesInLevel(i)) { QList subNodes = mind->subNodes(node); QVector nxnValus; // n x n矩阵 for (int j = 0; j < subNodes.size(); j++) { QString abs = subNodes[j].name; for (int k = 0; k < subNodes.size(); k++) { QString ord = subNodes[k].name; QString key = abs + "-" + ord; double v = 1; NodeMatrixInfo *info = nodeData[expertId][key]; if (info != nullptr) { QStringList nodeValue = info->nodeValue.split("/"); if (nodeValue.size() == 1) { // v = nodeValue[0].toDouble(); v = 1.0 / nodeValue[0].toDouble(); } else { // v = nodeValue[0].toDouble() / // nodeValue[1].toDouble(); v = nodeValue[1].toDouble(); } } nxnValus.append(v); } } // 计算权重并存储 QScopedPointer ha(new HierarchicalAnalysis(subNodes.size(), nxnValus)); QVector weights = ha->getWeights(); for (int l = 0; l < weights.size(); ++l) { if (mWeights.keys().contains(expertId) == false) { mWeights[expertId] = QMap(); } CNodeData pNode = mind->node(subNodes[l].pNumber); if (mWeights[expertId].keys().contains(pNode.name)) { mWeights[expertId][subNodes[l].name] = mWeights[expertId][pNode.name] * weights[l]; } else { mWeights[expertId][subNodes[l].name] = weights[l]; } } } } } // 求平均权重 for (int i = 1; i < mind->levels(); i++) { for (CNodeData node : mind->nodesInLevel(i)) { QList subNodes = mind->subNodes(node); for (int j = 0; j < subNodes.size(); j++) { double sum = 0; for (QString expertId : nodeData.keys()) { sum += mWeights[expertId][subNodes[j].name] * config[expertId]; } indexWeights[subNodes[j].name] = sum; } } } } else { // 矩阵集结, 先计算各个专家数据的均值, 在求权重 // 求专家数据均值 QMap avgNodeValue; for (QString key : nodeData.values().first().keys()) { double sum = 0; for (QString expertId : nodeData.keys()) { double v = 1; NodeMatrixInfo *info = nodeData[expertId][key]; if (info != nullptr) { QStringList nodeValue = info->nodeValue.split("/"); if (nodeValue.size() == 1) { v = nodeValue[0].toDouble(); } else { v = nodeValue[0].toDouble() / nodeValue[1].toDouble(); } } sum += v * config[expertId]; } avgNodeValue[key] = sum / nodeData.keys().size(); } // 求权重 for (int i = 1; i < mind->levels(); i++) { for (CNodeData node : mind->nodesInLevel(i)) { QList subNodes = mind->subNodes(node); QVector nxnValus; // n x n矩阵 for (int j = 0; j < subNodes.size(); j++) { QString abs = subNodes[j].name; for (int k = 0; k < subNodes.size(); k++) { QString ord = subNodes[k].name; QString key = abs + "-" + ord; nxnValus.append(avgNodeValue[key]); } } // 计算权重并存储 QScopedPointer ha(new HierarchicalAnalysis(subNodes.size(), nxnValus)); QVector weights = ha->getWeights(); for (int l = 0; l < weights.size(); ++l) { CNodeData pNode = mind->node(subNodes[l].pNumber); if (indexWeights.keys().contains(pNode.name)) { indexWeights[subNodes[l].name] = indexWeights[pNode.name] * weights[l]; } else { indexWeights[subNodes[l].name] = weights[l]; } } } } } QStringList valueList; for (QString key : indexWeights.keys()) { valueList.append(QString("%1:%2").arg(key).arg(indexWeights[key])); } QString valueStr = valueList.join(";"); bool ret = MindWeightService().saveUniqueWeightData(m_process.projectId, m_process.indexType, m_process.dSource, algorithm, valueStr); return ret; } bool DataEvaluator::evaluateWeightFromMeasure() { QMap> nodeData; bool dataRet = getNodeData(nodeData); SchemePlanManager::Algorithm algorithm; bool algRet = getAlgorithm(algorithm); /// 获取指标体系 QList nodeList; bool mindRet = CNodeDataService().QueryAllValid(nodeList, m_process.projectId, m_process.indexType); CMind *mind = new CMind(this); mind->setNodeList(nodeList); if (!(dataRet && algRet && mindRet)) { return false; } /// 各个指标的权重值 /// 外层 QString 是 uuid, 内层 QString 是指标名称, double 是指标权重 QMap allWeights; if (algorithm == SchemePlanManager::Entropy) { // 熵值法 /// 根据指标体系层级, 构造算法需要的数据, 逐层计算权重值并保存 for (int i = 1; i < mind->levels(); i++) { for (CNodeData node : mind->nodesInLevel(i)) { QList subNodes = mind->subNodes(node); EntropyMat mat; for (int j = 0; j < subNodes.size(); j++) { QVector 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); } mat.append({ values }); } if (mat.size() <= 0) { continue; } // 计算权重 QScopedPointer ew(new EntropyWeights(mat)); QVector weights, scores; ew->compute(weights, scores); // 结合父节点指标权重计算指标最终权重 for (int k = 0; k < subNodes.size(); k++) { double w = 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; } } } } } else if (algorithm == SchemePlanManager::PrincipalComponents) { // 主成分分析法 for (int i = 1; i < mind->levels(); i++) { for (CNodeData node : mind->nodesInLevel(i)) { QList subNodes = mind->subNodes(node); QVector> mat; for (QString uuid : nodeData.keys()) { QVector 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); } mat.append({ values }); } if (mat.size() <= 0) { continue; } QScopedPointer 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; } } } } } QStringList valueList; for (QString key : allWeights.keys()) { valueList.append(QString("%1:%2").arg(key).arg(allWeights[key])); } QString valueStr = valueList.join(";"); bool ret = MindWeightService().saveUniqueWeightData(m_process.projectId, m_process.indexType, m_process.dSource, algorithm, valueStr); return ret; } bool DataEvaluator::evaluateTech() { QMap weightData; bool weightRet = getWeightData(weightData); QMap> nodeData; bool dataRet = getNodeData(nodeData); /// 获取指标体系 QList nodeList; bool mindRet = CNodeDataService().QueryAllValid(nodeList, m_process.projectId, m_process.indexType); CMind *mind = new CMind(this); mind->setNodeList(nodeList); /// 获取权重配置 QMap config; bool cfgRet = false; if (m_process.dSource == SchemePlanManager::FromExpert) { cfgRet = getUserConfig(config); } else { for (QString uuid : nodeData.keys()) { config[uuid] = 1.0 / nodeData.keys().size(); } cfgRet = nodeData.size() > 0; } if (weightRet == false || dataRet == false || mindRet == false || nodeList.size() <= 0 || cfgRet == false) { qDebug() << __FUNCTION__ << __LINE__ << endl; return false; } QMap scoreData; for (int i = 1; i < mind->levels(); i++) { for (CNodeData node : mind->nodesInLevel(i)) { QList subNodes = mind->subNodes(node); for (int j = 0; j < subNodes.size(); j++) { double score = 0; for (QString uuid : nodeData.keys()) { for (QString weightKey : weightData.keys()) { QString key = subNodes[j].name + "-" + weightKey; if (nodeData[uuid].keys().contains(key)) { score += nodeData[uuid][key]->nodeValue.toDouble() * weightData[weightKey] * config[uuid]; } } } scoreData[subNodes[j].name] = score; } } } QStringList valueList; for (QString key : scoreData.keys()) { valueList.append(QString("%1:%2").arg(key).arg(scoreData[key])); } QString valueStr = valueList.join(";"); bool ret = MindScoreService().saveUniqueScoreData(m_process.projectId, valueStr); return ret; } bool DataEvaluator::evaluateScheme() { QMap weightData; bool weightRet = getWeightData(weightData); QMap> schemeData; QMap schemeNames; bool schemeRet = getSchemeData(schemeData, schemeNames); if (weightRet == false || schemeRet == false) { return false; } for (int schemeId : schemeData.keys()) { double score = 0; for (QString key : schemeData[schemeId].keys()) { score += schemeData[schemeId][key] * weightData[key]; } SchemeInfoService().updateSchemeScore(schemeId, score); } return true; } bool DataEvaluator::evaluateEfficiencyMEA() { /// 获取指标体系 QList nodeList; bool mindRet = CNodeDataService().QueryAllValid(nodeList, m_process.projectId, m_process.indexType); CMind *mind = new CMind(this); mind->setNodeList(nodeList); /// 获取物元配置效能分级 QList processList; bool processRet = SchemeProcessService().QueryAllByProjectIdAndIndexType(processList, m_process.projectId, m_process.indexType); int domainLevel = m_process.efficiencyGrades; for (auto process : processList) { if (process.type == SchemePlanManager::RunEvaluate) { domainLevel = process.efficiencyGrades; break; } } /// 获取物元配置数据 QList rangeList; bool gradeRet = GradeIndexInfoService().QueryGradeIndexInfoByProjectId(&rangeList, m_process.projectId); /// 整理物元配置数据, int:层级 QString:指标名称 QPair:区间左右值 QMap>> rangeData; for (GradeIndexInfo *info : rangeList) { if (rangeData.keys().contains(info->gradeIndexName) == false) { rangeData[info->gradeIndexName] = QMap>(); } QString v = info->gradeIndexValue; if (v.length() > 2 && v.contains(", ")) { QStringList l = v.mid(1, v.length() - 2).split(", "); QPair range(l.first().toDouble(), l.last().toDouble()); rangeData[info->gradeIndexName][info->gradeLevel] = range; } } /// 获取样本数据 QMap> schemeData; QMap schemeNames; bool schemeRet = getSchemeData(schemeData, schemeNames); QMap weightData; bool weightRet = getWeightData(weightData); /// 获取权重数据 if (mindRet == false || processRet == false || gradeRet == false || schemeRet == false || weightRet == false) { return false; } /// 物元分析 MEAMat mat; // 样本数据 MEARangeMat ranges; // 等级数据 QVector weights; // 权重数据 QList indexList = mind->leaves(); // 最后一级指标 for (int key : schemeData.keys()) { QVector m; for (int i = 0; i < indexList.size(); ++i) { m.append(schemeData[key][indexList[i].name]); } mat.append(m); } QVector jointRanges; for (int level = 1; level < domainLevel + 1; ++level) { QVector levelRanges; for (int i = 0; i < indexList.size(); ++i) { QPair p = rangeData[indexList[i].name][level]; MEARange levRange = MEARange { i, p.first, p.second }; levelRanges.append(levRange); if (level == 1) { MEARange jointRange = MEARange { i, p.first }; jointRanges.append(jointRange); } else if (level == domainLevel) { jointRanges[i].max_value = p.second; } } ranges.append(levelRanges); } ranges.append(jointRanges); for (int i = 0; i < indexList.size(); ++i) { weights.append(weightData[indexList[i].name]); } MatterElementAnalysis me(mat, ranges); me.evaluate(weights); QVector rangeCvt = me.getRangeCVT(); MEAMat rangeWeights = me.getRangeWeights(); if (schemeData.keys().size() != rangeCvt.size() || schemeData.keys().size() != rangeWeights.size()) { return false; } QList resultData; for (int scheme = 0; scheme < schemeData.keys().size(); ++scheme) { EffectResult overall; overall.projectId = m_process.projectId; overall.schemeId = schemeData.keys()[scheme]; overall.schemeName = schemeNames[schemeData.keys()[scheme]]; overall.algType = 0; overall.indexName = "综合"; QVector values = rangeWeights[scheme]; QStringList strList; for (int v = 0; v < values.size(); ++v) { strList.append(QString("%1").arg(values[v])); } overall.value = strList.join(","); resultData.append(overall); for (int index = 0; index < indexList.size(); ++index) { EffectResult result; result.projectId = m_process.projectId; result.schemeId = schemeData.keys()[scheme]; result.schemeName = schemeNames[schemeData.keys()[scheme]]; result.algType = 0; result.indexName = indexList[index].name; QVector values = rangeCvt[scheme][index]; QStringList strList; for (int v = 0; v < values.size(); ++v) { strList.append(QString("%1").arg(values[v])); } result.value = strList.join(","); resultData.append(result); } } bool saveRet = EffectResultService().addDataList(resultData); return saveRet; } bool DataEvaluator::evaluateEfficiencyGCE() { return false; } bool DataEvaluator::getNodeData(QMap> &nodeData) const { /// 整理数据, 使用 uuid 将数据分组, 使用指标名称索引 QString indexName = ProjectManager::nameOfIndexType((ProjectManager::IndexType)m_process.indexType); QList dataList; bool ret = NodeMatrixService().QueryDataByProjectAndIndex(&dataList, indexName, m_process.projectId, m_process.dSource); if (ret == false) { return false; } if (dataList.size() <= 0) { qDebug() << __FUNCTION__ << __LINE__ << "未录入评估数据" << endl; return false; } for (NodeMatrixInfo *info : dataList) { QString key = info->strUuid; // 实测数据的 key if (m_process.dSource == SchemePlanManager::FromExpert) { key = info->expertId; // 专家数据的 key } if (nodeData.keys().contains(key) == false) { nodeData[key] = QMap(); } nodeData[key][nodeDataKey(info)] = info; } return true; } bool DataEvaluator::getAlgorithm(SchemePlanManager::Algorithm &algorithm) const { QList processList; bool ret = SchemeProcessService().QueryAllByProjectIdAndIndexType(processList, m_process.projectId, m_process.indexType); if (ret == false) { return false; } for (auto process : processList) { if (process.type == SchemePlanManager::CalculateWeight) { algorithm = process.algorithm; break; } } if (m_process.type == SchemePlanManager::ImportWeightData) { if (m_process.dSource == SchemePlanManager::FromMeasurement && algorithm == SchemePlanManager::AHP) { algorithm == SchemePlanManager::Entropy; } if (m_process.dSource == SchemePlanManager::FromExpert) { algorithm == SchemePlanManager::AHP; } } return true; } bool DataEvaluator::getUserConfig(QMap &cfg) const { QList userCfgList; bool ret = UserConfigService().QueryUserConfigListInfoByEngineerId(&userCfgList, m_process.projectId); if (ret == false) { return false; } for (UserConfig *config : userCfgList) { cfg[QString("%1").arg(config->userId)] = config->weight / 100; } return true; } bool DataEvaluator::getWeightData(QMap &weightData) const { MindWeightInfo info; int indexType = m_process.indexType; if (indexType == ProjectManager::TechIndex) { indexType = ProjectManager::AbilityIndex; } bool ret = MindWeightService().queryWeightData(&info, m_process.projectId, indexType); if (ret == false) { return false; } if (info.id < 0) { qDebug() << __FUNCTION__ << __LINE__ << "未找到指标权重数据" << endl; return false; } QStringList weightList = info.weight.split(";"); for (QString keyValueStr : weightList) { QStringList keyValue = keyValueStr.split(":"); if (keyValue.size() == 2) { weightData[keyValue.first()] = keyValue.last().toDouble(); } } return true; } bool DataEvaluator::getSchemeData(QMap> &schemeData, QMap &schemeNames) const { QList schemeList; int type = m_process.indexType == ProjectManager::OptimalIndex ? 0 : 1; bool ret = SchemeInfoService().QuerySchemeInfoByEngineerId(&schemeList, m_process.projectId, type); if (ret == false) { return false; } if (schemeList.size() <= 0) { qDebug() << __FUNCTION__ << __LINE__ << "未创建方案" << endl; return false; } for (SchemaEval *scheme : schemeList) { if (schemeData.keys().contains(scheme->id) == false) { schemeData[scheme->id] = QMap(); } QStringList keyValueStringList = scheme->valueStr.split(";"); for (QString keyValueStr : keyValueStringList) { QStringList keyValue = keyValueStr.split(":"); if (keyValue.size() == 2) { schemeData[scheme->id][keyValue.first()] = keyValue.last().toDouble(); } } schemeNames[scheme->id] = scheme->name; } return true; } QString DataEvaluator::nodeDataKey(NodeMatrixInfo *data) const { QString key = data->abscissa; if (data->ordinate.length() > 0) { key += ("-" + data->ordinate); } return key; }