#include <math.h> #include <stdlib.h> /* 連続値ホップフィールドモデルの諸定数 */ #define TAU 1 #define DELTA_T 0.02 #define MU0 0.1 #define f(u) (1/(1+exp(-2*u/MU0))) /* 問題の定義 */ #define MAX_WEIGHT 14 int a[]={ /* 品物の重量 */ 3, 5, 4, 7, 2, 4 }; int c[]={ /* 品物の価値 */ 10, 13, 10, 16, 2, 3 }; /* 解=1 0 1 1 0 0 */ /* 品物の数 */ #define N (sizeof(a)/sizeof(a[0])) /* エネルギー関数のための係数 */ #define A 0.3 /* ニューロンの定義 */ typedef struct { double w[N]; /* 結合係数 */ double theta; /* 閾値 */ double u; /* 内部状態 */ double x; /* 出力 */ } NeuronRec; NeuronRec neuron[N]; #define rnd() ((double)rand()/RAND_MAX) /* [0, 1] の乱数 */ /* エネルギー関数 */ double Energy() { register int i, j; double E; E=0.0; for(i=0; i<N; i++) { for(j=0; j<i; j++) E+=-neuron[i].w[j]*neuron[i].x*neuron[j].x; E+=neuron[i].theta*neuron[i].x; } /* 簡単のため,積分項を無視 */ return(E); } /* Hopfield ネットワークの定義 */ Initialize() { register int i, j; for(i=0; i<N; i++) { neuron[i].w[i]=0.0; for(j=0; j<i; j++) neuron[i].w[j]=neuron[j].w[i]=-2*A*a[i]*a[j]; neuron[i].theta=-A*MAX_WEIGHT*a[i]-c[i]; } } main() { register int i, j, t; int changed; double x, du; /* 結合荷重と閾値の設定 */ Initialize(); /* ネットワークの初期状態の設定 */ for(i=0; i<N; i++) neuron[i].u=rnd(); for(t=0; ; t++) { changed=0; /* 出力の計算 */ for(i=0; i<N; i++) { x=f(neuron[i].u); if(x!=neuron[i].x) { neuron[i].x=x; changed=1; } } /* 出力の表示 */ printf("%3d: ", t); for(i=0; i<N; i++) printf("%lf ", neuron[i].x); printf(" => %lf\n", Energy()); if(!changed) break; /* 状態の計算 */ for(i=0; i<N; i++) { du=-neuron[i].u/TAU; for(j=0; j<N; j++) du+=neuron[i].w[j]*neuron[j].x; du-=neuron[i].theta; neuron[i].u+=du*DELTA_T; } } }