MatterElementAnalysis.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //
  2. // Created by Austin on 2023/10/11.
  3. //
  4. #include "MatterElementAnalysis.h"
  5. #include <QDebug>
  6. MatterElementAnalysis::MatterElementAnalysis(const MEAMat &mat, const MEARangeMat &ranges) : mat_(mat), ranges_(ranges)
  7. {
  8. sample_num_ = mat_.count();
  9. if (sample_num_ == 0) {
  10. index_num_ = 0;
  11. } else {
  12. index_num_ = mat_.at(0).count();
  13. }
  14. for (int i = 0; i < sample_num_; ++i) {
  15. MEAMat cvtMat;
  16. for (int j = 0; j < index_num_; ++j) {
  17. cvtMat.append(QVector<double>(ranges_.count() - 1, 0.0));
  18. }
  19. range_cvt_.append(cvtMat);
  20. }
  21. for (int i = 0; i < sample_num_; ++i) {
  22. range_weights_.append(QVector<double>(ranges_.count() - 1, 0.0));
  23. }
  24. }
  25. void MatterElementAnalysis::evaluate(const QVector<double> &weights)
  26. {
  27. // 根据关联函数更新转换矩阵
  28. for (int s = 0; s < sample_num_; ++s) {
  29. for (int i = 0; i < index_num_; ++i) {
  30. double val = mat_.at(s).at(i);
  31. associatedValue(s, i, val);
  32. }
  33. }
  34. // QVector<double> weights_ = { 0.189, 0.203, 0.052, 0.162, 0.202, 0.151, 0.041 };
  35. evaluationlevel(weights);
  36. }
  37. static double correlationP(double value, double left, double right)
  38. {
  39. return std::abs(value - (left + right) / 2) - (right - left) / 2;
  40. }
  41. static bool containValue(double value, bool left_close, bool right_close, double left, double right)
  42. {
  43. if (value > left && value < right)
  44. return true;
  45. if (value == left && left_close)
  46. return true;
  47. if (value == right && right_close)
  48. return true;
  49. return false;
  50. }
  51. void MatterElementAnalysis::associatedValue(int sam, int index, double value)
  52. {
  53. double r = 0;
  54. for (int i = 0; i < ranges_.count() - 1; ++i) //i是等级,index是指标
  55. {
  56. Q_ASSERT(ranges_.at(i).at(index).index == index);
  57. double minValue = ranges_.at(i).at(index).min_value;
  58. double maxValue = ranges_.at(i).at(index).max_value;
  59. bool leftValueClose = ranges_.at(i).at(index).left_close;
  60. bool rightValueClose = ranges_.at(i).at(index).right_close;
  61. double r1 = correlationP(value, minValue, maxValue);
  62. if (containValue(value, leftValueClose, rightValueClose, minValue, maxValue))
  63. {
  64. r = -r1 / abs(maxValue - minValue);
  65. }
  66. else
  67. {
  68. double minEnd = ranges_.last().at(index).min_value;
  69. double maxEnd = ranges_.last().at(index).max_value;
  70. double r2 = correlationP(value, minEnd, maxEnd);
  71. if (abs(r1 - r2) <= 0.00000001)
  72. {
  73. r = -r1 - 1;
  74. }
  75. else
  76. {
  77. r = r1 / (r2 - r1);
  78. }
  79. }
  80. range_cvt_[sam][index][i] = r;
  81. //结果放在range_cvt_
  82. }
  83. }
  84. void MatterElementAnalysis::evaluationlevel(const QVector<double> &weights)
  85. { // 输入计算出来的关联度,权值
  86. // 计算一个样本权值之后的总关联度
  87. double r;
  88. for (int i = 0; i < sample_num_; ++i) // 样本
  89. for (int j = 0; j < ranges_.count() - 1; ++j) { // 等级
  90. r = 0;
  91. for (int k = 0; k < index_num_; ++k) { // 指标
  92. r = r + range_cvt_[i][k][j] * weights[k];
  93. }
  94. range_weights_[i][j] = r;
  95. }
  96. }
  97. const MEAMat &MatterElementAnalysis::getRangeWeights() const
  98. {
  99. return range_weights_;
  100. }
  101. const QVector<MEAMat> &MatterElementAnalysis::getRangeCVT() const
  102. {
  103. return range_cvt_;
  104. }
  105. QVector<int> MatterElementAnalysis::getBestIndex() const
  106. {
  107. auto maxLoc = [](const QVector<double> &v) {
  108. int index = 0;
  109. double maxValue = v.at(0);
  110. for (int i = 1; i < v.count(); ++i) {
  111. if (v.at(i) > maxValue) {
  112. maxValue = v.at(i);
  113. index = i;
  114. }
  115. }
  116. return index;
  117. };
  118. QVector<int> result;
  119. for (const auto &s : range_weights_) {
  120. result << maxLoc(s) + 1;
  121. }
  122. for (int i = 0; i < range_cvt_.size(); i++) {
  123. qDebug() << "指标 " << i;
  124. for (int j = 0; j < range_cvt_.at(i).size(); j++) {
  125. qDebug() << range_cvt_.at(i).at(j);
  126. }
  127. }
  128. return result;
  129. }