#include "DataEvaluator.h" #include #include #include #include "algorithm/EntropyWeights.h" #include "algorithm/PCA.h" #include "algorithm/HierarchicalAnalysis.h" #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; QStringList nodeValue = nodeData[expertId][key]->nodeValue.split("/"); if (nodeValue.size() == 1) { v = nodeValue[0].toDouble(); } else { v = nodeValue[0].toDouble() / 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; QStringList nodeValue = nodeData[expertId][key]->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; bool schemeRet = getSchemeData(schemeData); 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() { return false; } 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) 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(); } } } return true; } QString DataEvaluator::nodeDataKey(NodeMatrixInfo *data) const { QString key = data->abscissa; if (data->ordinate.length() > 0) { key += ("-" + data->ordinate); } return key; }