ボルツマンマシンとはちょっと違うけど
bocchi-talks-information.hatenablog.com
をシミュレーティッドアニーリング的に(準)最適解を求める方法を少し考えたので、メモ的にソースコードだけでも。
解説はそのうちやります。
#define flp(i, n) for(int i = 0; i < n; ++i) #include <iostream> #include <bitset> #include <cmath> #include <iomanip> #include <random> using namespace std; int main() { random_device rd; mt19937 mt(rd()); uniform_real_distribution<double> score(0.0,1.0); int dist[7][7] = { { 0,124,127,125, 26, 54, 42}, {124, 0, 77,165,116,143,150}, {127, 77, 0,104,111,182,165}, {125,165,104, 0,110,164,137}, { 26,116,111,110, 0, 66, 65}, { 54,143,182,164, 66, 0, 77}, { 42,150,165,137, 65, 77, 0} }; int minn = 10000; int prm[8], mprm[8]; flp(k, 100){ prm[0] = prm[7] = 0; flp(i, 6) prm[i + 1] = i + 1; double T = 1000.0; flp(i, 200000){ int j = i % 5 + 1; double dene = dist[ prm[j - 1] ][prm[j + 1] ] - dist[ prm[j - 1] ][prm[j] ] + dist[ prm[j] ][prm[j + 2] ] - dist[ prm[j + 1] ][prm[j + 2] ]; double p = 1.0 / ( 1.0 + exp( dene/T)); double sc = score(mt); if(p > sc){int buf = prm[j]; prm[j] = prm[j + 1]; prm[j + 1] = buf;} if(i % 1000) T *= 0.9; } int sum = 0; flp(i, 7) sum += dist[ prm[i] ][prm[i + 1] ]; if( minn > sum) { flp(i, 8) mprm[i] = prm[i]; minn = sum;} } flp(i, 8) cout << mprm[i] << " "; cout << ": " << minn <<endl; return 0; }
一応これでほとんど最適解にたどり着くはず。