Mlxa

ALGO Anneal

Feb 7th, 2018
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.49 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. namespace Mlxa {
  3.     typedef long long           ll;
  4.     typedef unsigned long long  count_t;
  5.     typedef unsigned long long  index_t;
  6.     using namespace std;
  7.  
  8.     #define read cin
  9.     #define eol '\n'
  10.     #define all(x) begin(x), end(x)
  11.  
  12.     template <class A> inline void
  13.     print   (A a)           { cout << a << ' '; }
  14.     template <class A> inline void
  15.     println (A a)           { cout << a << eol; }
  16.     template <class A> inline void
  17.     err     (A a)           { cout << a << ' '; }
  18.     template <class A> inline void
  19.     errln   (A a)           { cout << a << eol; }
  20.     template <class A, class... B> inline void
  21.     println (A a, B... b)   { cout << a << ' '; println(b...); }
  22.     template <class A, class... B> inline void
  23.     errln   (A a, B... b)   { cerr << a << ' '; errln(b...); }
  24.     template <ostream &out, class I> void
  25.     printSeq(I b, I e)      { for(I i=b;i!=e;++i)out<<*i<<' '; out<<'\n'; }
  26.     #ifdef AC
  27.         #define addLog(...) println(__VA_ARGS__)
  28.     #else
  29.         #define addLog(...) (void(0))
  30.     #endif
  31.  
  32.  
  33.     count_t s = 19191919LL;
  34.     inline count_t randomNumber ()
  35.     {
  36.         s ^= (s << 21);
  37.         s ^= (s >> 35);
  38.         s ^= (s << 4);
  39.         return s;
  40.     }
  41.  
  42. } using namespace Mlxa;
  43.  
  44. /*----------------------------------------------------------
  45. *       Метод отжига:
  46. *
  47. * float T
  48. * float F (T X)
  49. * -----------------------------------------------------------
  50. *   Иннициализация:
  51. *   а) Т = Амплитуда
  52. *   б) x0 = randomNuber()
  53. *       curX = x0
  54. *       minVal = curVal = F(curX)
  55. * -----------------------------------------------------------
  56. *   Итерация:
  57. *   Условия заверешения:
  58. *       а) T = 0.
  59. *       б) Стало ясно что достигнут глоб. мин.
  60. *       в) Выполнили N итераций.
  61. *   Действия:
  62. *       1) Случайное изменение ~ T.
  63. *       Получили:
  64. *           newX, newVal = F(newX).
  65. *       2) Переходим в новую точку если:
  66. *           Произошло событие с вероятностью ~ T
  67. *           (randomNumber() < exp((F(curX) - F(newX)) / T)
  68. *       3) T *= 0.99
  69. * -----------------------------------------------------------
  70. */
  71.  
  72. count_t N;
  73. typedef vector<index_t> per_t;
  74. per_t permutation;
  75.  
  76.  
  77. void start ()
  78. {
  79.     srand(time(nullptr) + ('2' +'4' + '8' + '1'));
  80.     read >> N;
  81.     for (index_t i = 0; i < N; ++ i)
  82.         permutation.push_back(i);
  83. }
  84.  
  85. count_t diag[2][10000];
  86.  
  87. count_t F (const per_t &X)
  88. {
  89.     for (index_t i = 0; i <= 2*N; ++ i)
  90.         diag[0][i] = diag[1][i] = 0;
  91.  
  92.     for(index_t i = 0; i < N; ++ i)
  93.         ++ diag[0][i + X[i]],
  94.         ++ diag[1][N + i - X[i]];
  95.  
  96.     count_t result = 0;
  97.     for (index_t i = 0; i <= 2*N; ++ i)
  98.         result += diag[0][i] * (diag[0][i] - 1) / 2,
  99.         result += diag[1][i] * (diag[1][i] - 1) / 2;
  100.  
  101.     return result;
  102. }
  103.  
  104. count_t burn ()
  105. {
  106.     per_t   curX    = permutation;
  107.     count_t curVal  = F(curX),
  108.             minVal  = curVal;
  109.     index_t i, j;
  110.  
  111.     const count_t repeat = max(20000ull, N * N / 2);
  112.  
  113.     index_t tmp;
  114.  
  115.     for (double t = -100; t < repeat && curVal; ++ t)
  116.     {
  117.         i   = randomNumber() % N;
  118.         j   = randomNumber() % N;
  119.  
  120.         tmp = curX[i];
  121.         curX[i] = curX[j];
  122.         curX[j] = tmp;
  123.  
  124.         curVal = F(curX);
  125.  
  126.         count_t d = (count_t)(2.71 * exp( -t * 0.019));
  127.         if ( curVal < minVal + d )
  128.             minVal = curVal;
  129.         else
  130.             tmp = curX[i],
  131.             curX[i] = curX[j],
  132.             curX[j] = tmp;
  133.     }
  134.  
  135.     permutation = curX;
  136.     return minVal;
  137. }
  138.  
  139. int main ()
  140. {
  141.     start();
  142.  
  143.     ll cnt = 1;
  144.  
  145.     while (burn() > 0)
  146.         random_shuffle(all(permutation)), ++ cnt;
  147.  
  148.     addLog("Burn count  =", cnt);
  149.  
  150.     for (auto i : permutation)
  151.         print(i + 1);
  152.     println("");
  153.  
  154.     return 0;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment