Advertisement
ludaludaed

asd

Apr 4th, 2023 (edited)
951
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.00 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <set>
  4. #include <algorithm>
  5. #include <limits>
  6. #include <cmath>
  7.  
  8.  
  9. class Method {
  10. public:
  11.     virtual void Run(const std::vector<std::vector<double>> &, const std::vector<double> &) = 0;
  12.  
  13.     virtual ~Method() = default;
  14. };
  15.  
  16. class SawMethod : public Method {
  17. public:
  18.     void Run(const std::vector<std::vector<double>> &matrix, const std::vector<double> &weights) override {
  19.         double max_score = 0;
  20.         int max_score_index = 0;
  21.         std::vector<double> result;
  22.  
  23.         for (size_t i = 0; i < matrix.size(); ++i) {
  24.             double temp = 0;
  25.             for (size_t j = 0; j < matrix[i].size(); j++) {
  26.                 temp += matrix[i][j] * weights[j];
  27.             }
  28.             temp = std::floor(temp * 1000) / 1000;
  29.             if (temp > max_score) {
  30.                 max_score = temp;
  31.                 max_score_index = i;
  32.             }
  33.             result.push_back(temp);
  34.             std::cout << "Alternative #" << i + 1 << " has score - " << temp << std::endl;
  35.         }
  36.         std::cout << "Alternative #" << max_score_index + 1 << " better than others. It has score: " << max_score
  37.                   << std::endl;
  38.     }
  39. };
  40.  
  41. class ElectreMethod : public Method {
  42. private:
  43.     std::vector<std::vector<double>> getNormalize(const std::vector<std::vector<double>> &source) const {
  44.         size_t n = source.size();
  45.         size_t m = source.front().size();
  46.         std::vector<std::vector<double>> result(n, std::vector<double>(m, 0));
  47.         for (size_t j = 0; j < m; j++) {
  48.             double max = 0;
  49.             for (size_t i = 0; i < n; ++i) {
  50.                 max = std::max(source[i][j], max);
  51.             }
  52.             for (size_t i = 0; i < n; ++i) {
  53.                 result[i][j] = source[i][j] / max;
  54.             }
  55.         }
  56.         return std::move(result);
  57.     }
  58.  
  59.     std::vector<std::vector<double>>
  60.     concordanceMatrix(const std::vector<std::vector<double>> &data, const std::vector<double> &weights) const {
  61.         std::vector<std::vector<double>> result(data.size(), std::vector<double>(data.size(), 0));
  62.         for (size_t i = 0; i < result.size(); i++) {
  63.             for (size_t j = 0; j < result[i].size(); ++j) {
  64.                 double sum = 0;
  65.                 for (size_t k = 0; k < data.front().size(); ++k) {
  66.                     if (data[i][k] >= data[j][k]) {
  67.                         sum += weights[k];
  68.                     }
  69.                 }
  70.                 result[i][j] = sum;
  71.             }
  72.         }
  73.         return std::move(result);
  74.     }
  75.  
  76.     std::vector<std::vector<double>> discordanceMatrix(const std::vector<std::vector<double>> &data) const {
  77.         size_t n = data.size();
  78.         std::vector<std::vector<double>> result(n, std::vector<double>(n, 0));
  79.         for (size_t i = 0; i < n; i++) {
  80.             for (size_t j = 0; j < n; j++) {
  81.                 double max = std::numeric_limits<double>::min();
  82.                 for (int k = 0; k < data.front().size(); ++k) {
  83.                     max = std::max(data[j][k] - data[i][k], max);
  84.                 }
  85.                 result[i][j] = std::floor(max * 1000) / 1000;
  86.             }
  87.         }
  88.         return std::move(result);
  89.     }
  90.  
  91.     std::vector<std::vector<bool>> dominanceMatrix(const std::vector<std::vector<double>> &concordance,
  92.                                                    const std::vector<std::vector<double>> &discordance, double c_lim,
  93.                                                    double d_lim) {
  94.         size_t n = concordance.size();
  95.         std::vector<std::vector<bool>> result(n, std::vector<bool>(n, false));
  96.         for (int i = 0; i < n; ++i) {
  97.             for (int j = 0; j < n; ++j) {
  98.                 if (concordance[i][j] >= c_lim && discordance[i][j] <= d_lim && i != j) {
  99.                     result[i][j] = true;
  100.                 }
  101.             }
  102.         }
  103.         return std::move(result);
  104.     }
  105.  
  106. public:
  107.     void Run(const std::vector<std::vector<double>> &matrix, const std::vector<double> &weights) override {
  108.         std::vector<std::vector<double>> normalized_matrix(getNormalize(matrix));
  109.         std::vector<std::vector<double>> concordance(concordanceMatrix(normalized_matrix, weights));
  110.         std::vector<std::vector<double>> discordance(discordanceMatrix(normalized_matrix));
  111.         std::vector<std::vector<bool>> dominance(dominanceMatrix(concordance, discordance, 0.45, 0.5));
  112.         // first is sum of elements, second is index
  113.         std::multiset<std::pair<int, int>, std::greater<>> set;
  114.         for (int i = 0; i < dominance.size(); ++i) {
  115.             int sum = 0;
  116.             for (int j = 0; j < dominance[i].size(); ++j) {
  117.                 sum += dominance[i][j];
  118.             }
  119.             set.emplace(sum, i);
  120.         }
  121.         int place = 0;
  122.         for (auto it = set.begin(); it != set.end(); ++it) {
  123.             std::cout << "Place #" << ++place << " Alternative #" << it->second + 1 << " - " << it->first << std::endl;
  124.         }
  125.     }
  126. };
  127.  
  128. class TopsisMethod : public Method {
  129. private:
  130.     std::vector<std::vector<double>> getNormalize(const std::vector<std::vector<double>> &source) const {
  131.         size_t n = source.size();
  132.         size_t m = source.front().size();
  133.         std::vector<std::vector<double>> result(n, std::vector<double>(m, 0));
  134.         for (size_t j = 0; j < m; ++j) {
  135.             double sq = 0;
  136.             for (size_t i = 0; i < n; ++i) {
  137.                 sq += source[i][j] * source[i][j];
  138.             }
  139.             sq = std::sqrt(sq);
  140.             for (size_t i = 0; i < n; ++i) {
  141.                 result[i][j] = source[i][j] / sq;
  142.             }
  143.         }
  144.         return std::move(result);
  145.     }
  146.  
  147.     std::vector<double> getWorst(const std::vector<int> &signs, const std::vector<std::vector<double>> &matrix) const {
  148.         std::vector<double> result;
  149.         for (int j = 0; j < matrix.front().size(); ++j) {
  150.             if (signs[j] == 1) {
  151.                 double min = std::numeric_limits<double>::max();
  152.                 for (int i = 0; i < matrix.size(); ++i) {
  153.                     min = std::min(min, matrix[i][j]);
  154.                 }
  155.                 result.push_back(min);
  156.             } else {
  157.                 double max = std::numeric_limits<double>::min();
  158.                 for (int i = 0; i < matrix.size(); ++i) {
  159.                     max = std::max(max, matrix[i][j]);
  160.                 }
  161.                 result.push_back(max);
  162.             }
  163.         }
  164.         return std::move(result);
  165.     }
  166.  
  167.     std::vector<double> getBest(const std::vector<int> &signs, const std::vector<std::vector<double>> &matrix) const {
  168.         std::vector<double> result;
  169.         for (int j = 0; j < matrix.front().size(); ++j) {
  170.             if (signs[j] != 1) {
  171.                 double min = std::numeric_limits<double>::max();
  172.                 for (int i = 0; i < matrix.size(); ++i) {
  173.                     min = std::min(min, matrix[i][j]);
  174.                 }
  175.                 result.push_back(min);
  176.             } else {
  177.                 double max = std::numeric_limits<double>::min();
  178.                 for (int i = 0; i < matrix.size(); ++i) {
  179.                     max = std::max(max, matrix[i][j]);
  180.                 }
  181.                 result.push_back(max);
  182.             }
  183.         }
  184.         return std::move(result);
  185.     }
  186.  
  187.     std::vector<double>
  188.     getDist(const std::vector<std::vector<double>> &matrix, const std::vector<double> &alternatives) {
  189.         std::vector<std::vector<double>> temp(matrix);
  190.         for (int i = 0; i < temp.size(); ++i) {
  191.             for (int j = 0; j < temp.front().size(); ++j) {
  192.                 temp[i][j] -= alternatives[j];
  193.                 temp[i][j] *= temp[i][j];
  194.             }
  195.         }
  196.         std::vector<double> result(matrix.size());
  197.         for (int i = 0; i < result.size(); ++i) {
  198.             double sum = 0;
  199.             for (int j = 0; j < temp[i].size(); ++j) {
  200.                 sum += temp[i][j];
  201.             }
  202.             result[i] = sqrt(sum);
  203.         }
  204.         return std::move(result);
  205.     }
  206.  
  207. public:
  208.     void Run(const std::vector<std::vector<double>> &matrix, const std::vector<double> &weights) override {
  209.         auto normalized = getNormalize(matrix);
  210.         for (int i = 0; i < normalized.size(); ++i) {
  211.             for (int j = 0; j < normalized[i].size(); ++j) {
  212.                 normalized[i][j] *= weights[j];
  213.             }
  214.         }
  215.         std::vector<int> signs(weights.size(), 1);
  216.         auto worst = getWorst(signs, normalized);
  217.         auto best = getBest(signs, normalized);
  218.         auto worst_distance = getDist(normalized, worst);
  219.         auto best_distance = getDist(normalized, best);
  220.  
  221.         std::vector<double> res(worst_distance);
  222.         for (int i = 0; i < res.size(); ++i) {
  223.             res[i] /= worst_distance[i] + best_distance[i];
  224.         }
  225.         int max_index = 0;
  226.         int min_index = 0;
  227.         for (int i = 0; i < res.size(); ++i) {
  228.             if (res[max_index] < res[i]) {
  229.                 max_index = i;
  230.             }
  231.             if (res[min_index] > res[i]) {
  232.                 min_index = i;
  233.             }
  234.         }
  235.         for (int i = 0; i < res.size(); ++i) {
  236.             std::cout << "Alternative #" << i + 1 << " has score - " << res[i] << std::endl;
  237.         }
  238.         std::cout << "Alternative #" << max_index + 1 << " is the best. has score - " << res[max_index] << std::endl;
  239.         std::cout << "Alternative #" << min_index + 1 << " is the worst. has score - " << res[min_index] << std::endl;
  240.     }
  241. };
  242.  
  243. #include <fstream>
  244. #include <sstream>
  245.  
  246. int main() {
  247.     std::vector<std::vector<double>> matrix{
  248.             {3, 3, 3, 5, 3, 2, 2, 3},
  249.             {3, 3, 3, 4, 3, 2, 1, 3},
  250.             {3, 2, 3, 3, 3, 2, 2, 3},
  251.             {2, 5, 4, 2, 2, 1, 2, 3},
  252.             {2, 1, 4, 5, 3, 3, 2, 2}};
  253.  
  254.     std::vector<double> weights = {0.18, 0.13, 0.17, 0.09, 0.04, 0.13, 0.09, 0.17};
  255.  
  256.     SawMethod saw;
  257.     saw.Run(matrix, weights);
  258.     ElectreMethod electre;
  259.     electre.Run(matrix, weights);
  260.     TopsisMethod topsis;
  261.     topsis.Run(matrix, weights);
  262.     return 0;
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement