// // Created by Austin on 2023/10/11. // #include "MatterElementAnalysis.h" #include MatterElementAnalysis::MatterElementAnalysis(const MEAMat &mat, const MEARangeMat &ranges) : mat_(mat), ranges_(ranges) { sample_num_ = mat_.count(); if (sample_num_ == 0) { index_num_ = 0; } else { index_num_ = mat_.at(0).count(); } for (int i = 0; i < sample_num_; ++i) { MEAMat cvtMat; for (int j = 0; j < index_num_; ++j) { cvtMat.append(QVector(ranges_.count() - 1, 0.0)); } range_cvt_.append(cvtMat); } for (int i = 0; i < sample_num_; ++i) { range_weights_.append(QVector(ranges_.count() - 1, 0.0)); } } void MatterElementAnalysis::evaluate(const QVector &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 weights_ = { 0.189, 0.203, 0.052, 0.162, 0.202, 0.151, 0.041 }; evaluationlevel(weights); } static double correlationP(double value, double left, double right) { return std::abs(value - (left + right) / 2) - (right - left) / 2; } static bool containValue(double value, bool left_close, bool right_close, double left, double right) { if (value > left && value < right) return true; if (value == left && left_close) return true; if (value == right && right_close) return true; return false; } void MatterElementAnalysis::associatedValue(int sam, int index, double value) { double r = 0; 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; bool leftValueClose = ranges_.at(i).at(index).left_close; bool rightValueClose = ranges_.at(i).at(index).right_close; double r1 = correlationP(value, minValue, maxValue); if (containValue(value, leftValueClose, rightValueClose, minValue, maxValue)) { r = -r1 / abs(maxValue - minValue); } else { double minEnd = ranges_.last().at(index).min_value; double maxEnd = ranges_.last().at(index).max_value; double r2 = correlationP(value, minEnd, maxEnd); if (abs(r1 - r2) <= 0.00000001) { r = -r1 - 1; } else { r = r1 / (r2 - r1); } } range_cvt_[sam][index][i] = r; //结果放在range_cvt_ } } void MatterElementAnalysis::evaluationlevel(const QVector &weights) { // 输入计算出来的关联度,权值 // 计算一个样本权值之后的总关联度 double r; 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) { // 指标 r = r + range_cvt_[i][k][j] * weights[k]; } range_weights_[i][j] = r; } } const MEAMat &MatterElementAnalysis::getRangeWeights() const { return range_weights_; } const QVector &MatterElementAnalysis::getRangeCVT() const { return range_cvt_; } QVector MatterElementAnalysis::getBestIndex() const { auto maxLoc = [](const QVector &v) { 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; } } return index; }; QVector result; for (const auto &s : range_weights_) { result << maxLoc(s) + 1; } for (int i = 0; i < range_cvt_.size(); i++) { qDebug() << "指标 " << i; for (int j = 0; j < range_cvt_.at(i).size(); j++) { qDebug() << range_cvt_.at(i).at(j); } } return result; }