Advertisement
yerseg

Untitled

Apr 20th, 2021
1,225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.88 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <random>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <limits>
  7.  
  8. inline int32_t GenerateRandomInt(int32_t lowerBound, int32_t upperBound)
  9. {
  10.     static std::random_device rd;
  11.     static std::mt19937 prng(rd());
  12.     std::uniform_int_distribution distrib(lowerBound, upperBound);
  13.     return distrib(prng);
  14. }
  15.  
  16. struct Point
  17. {
  18.     double x;
  19.     double y;
  20. };
  21.  
  22. template <auto Foo>
  23. class ImmuneSystem
  24. {
  25.     class Lymphocyte
  26.     {
  27.     public:
  28.         Lymphocyte() = default;
  29.  
  30.         void Mutate()
  31.         {
  32.             GenerateRandomInt(0, 1) ? MutateA() : MutateB();
  33.         }
  34.  
  35.         std::pair<double, double> GetCoeffs()
  36.         {
  37.             return { m_a, m_b };
  38.         }
  39.  
  40.         void RecalculateFitnessMetric(const std::vector<Point>& points)
  41.         {
  42.             double value = 0;
  43.  
  44.             for (const auto& [x, y] : points)
  45.             {
  46.                 value += std::pow(y - Foo(m_a, m_b, x), 2);
  47.             }
  48.  
  49.             m_fitness = std::sqrt(value);
  50.         }
  51.  
  52.         double FitnessMetric() const
  53.         {
  54.             return m_fitness;
  55.         }
  56.  
  57.     private:
  58.  
  59.         double Mutate(double coeff) const
  60.         {
  61.             return std::min(std::max(MinCoeffValue, coeff + GenerateRandomInt(-MutateBound, MutateBound)), MaxCoeffValue);
  62.         }
  63.  
  64.         void MutateA()
  65.         {
  66.             m_a = Mutate(m_a);
  67.         }
  68.  
  69.         void MutateB()
  70.         {
  71.             m_b = Mutate(m_b);
  72.         }
  73.  
  74.     private:
  75.         static constexpr double MutateBound = 5;
  76.         static constexpr double MaxCoeffValue = 100;
  77.         static constexpr double MinCoeffValue = -100;
  78.  
  79.         double m_a = 0.0;
  80.         double m_b = 0.0;
  81.         double m_fitness = 0;
  82.     };
  83.  
  84. public:
  85.     explicit ImmuneSystem(const std::vector<Point>& points, size_t iterationsCount, size_t lymphocytesCount)
  86.     {
  87.         std::vector<Lymphocyte> lymphocytes(lymphocytesCount);
  88.  
  89.         const auto comparator = [](const Lymphocyte& first, const Lymphocyte& second)
  90.         {
  91.             return first.FitnessMetric() < second.FitnessMetric();
  92.         };
  93.  
  94.         for (auto& lymphocyte : lymphocytes)
  95.             lymphocyte.RecalculateFitnessMetric(points);
  96.  
  97.         for (size_t i = 0; i < iterationsCount; ++i)
  98.         {
  99.             std::cout << "Iter: " << i << std::endl;
  100.             std::sort(lymphocytes.begin(), lymphocytes.end(), comparator);
  101.  
  102.             for (size_t j = 0; j < lymphocytes.size() / 2; ++j)
  103.             {
  104.                 lymphocytes[j].Mutate();
  105.             }
  106.  
  107.             for (auto& lymphocyte : lymphocytes)
  108.                 lymphocyte.RecalculateFitnessMetric(points);
  109.         }
  110.  
  111.         m_bestLymphocyte = lymphocytes.front();
  112.     }
  113.  
  114.     std::pair<double, double> GetCoefficients()
  115.     {
  116.         return m_bestLymphocyte.GetCoeffs();
  117.     }
  118.  
  119.     Lymphocyte m_bestLymphocyte;
  120. };
  121.  
  122. template <auto Foo>
  123. std::vector<Point> GeneratePoints(double a, double b, size_t count)
  124. {
  125.     std::vector<Point> points;
  126.     points.reserve(count);
  127.     for (size_t i = 0; i < count; ++i)
  128.     {
  129.         double x = static_cast<double>(GenerateRandomInt(std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max()));
  130.         points.push_back({ x, Foo(a, b, x) });
  131.     }
  132.        
  133.     return points;
  134. }
  135.  
  136. int main()
  137. {
  138.     constexpr auto func = [](double a, double b, double x)
  139.     {
  140.         return a + b / x;
  141.     };
  142.  
  143.     static constexpr size_t IterationsCount = 500;
  144.     static constexpr size_t LymphocytesCount = 100;
  145.     static constexpr size_t PointsCount = 1000;
  146.  
  147.     static constexpr double A = -12.3;
  148.     static constexpr double B = 45.3;
  149.  
  150.     ImmuneSystem<func> is(GeneratePoints<func>(A, B, PointsCount), IterationsCount, LymphocytesCount);
  151.     const auto&& [a, b] = is.GetCoefficients();
  152.  
  153.     std::cout << "Coef A: " << a << ", Coef B: " << b << std::endl;
  154.  
  155.     return 0;
  156. }
  157.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement