情報理論関連をぐだぐだと

情報理論関係を勉強中の筆者がそれっぽいことを書くブログ

ボルツマンマシンとはちょっと違うけど

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;
}

一応これでほとんど最適解にたどり着くはず。