情報学部 菅沼ホーム 目次 索引

Hopfield ネットワーク

    1. A. C++
    2. B. Java
    3. C. JavaScript
    4. D. PHP
    5. E. Ruby
    6. F. Python
    7. G. C#
    8. H. VB

  プログラムは,Hopfield ネットワーク(入力データの意味に関してはここを読んでください)を使用して,連想記憶,及び,4 都市に対する巡回セールスマン問題( TSP )を扱った例です.

  1. C++

      C++11 においては,「メルセンヌ・ツイスター法による擬似乱数生成エンジン」を使用することができます.

    連想記憶
    /************************************/
    /* Hopfieldネットワーク(連想記憶) */
    /*      Coded by Y.Suganuma)        */
    /************************************/
    #include <stdio.h>
    #include <time.h>
    #include "MT.h"
    
    int main()
    {
    	int a[3][36] = {{0, 0, 1, 1, 0, 0,
    	                 0, 0, 1, 1, 0, 0,
    	                 0, 0, 1, 1, 0, 0,
    	                 0, 0, 1, 1, 0, 0,
    	                 0, 0, 1, 1, 0, 0,
    	                 0, 0, 1, 1, 0, 0},
    	                {0, 0, 0, 0, 0, 0,
    	                 0, 0, 0, 0, 0, 0,
    	                 1, 1, 1, 1, 1, 1,
    	                 1, 1, 1, 1, 1, 1,
    	                 0, 0, 0, 0, 0, 0,
    	                 0, 0, 0, 0, 0, 0},
    	                {1, 1, 0, 0, 0, 0,
    	                 1, 1, 1, 0, 0, 0,
    	                 0, 1, 1, 1, 0, 0,
    	                 0, 0, 1, 1, 1, 0,
    	                 0, 0, 0, 1, 1, 1,
    	                 0, 0, 0, 0, 1, 1}};
    	int W[36][36], n = 36, p = 3;
    					// 重みの設定(学習)
    	for (int i1 = 0; i1 < n-1; i1++) {
    		for (int i2 = i1+1; i2 < n; i2++) {
    			W[i1][i2] = 0;
    			for (int i3 = 0; i3 < p; i3++)
    				W[i1][i2] += (2 * a[i3][i1] - 1) * (2 * a[i3][i2] - 1);
    			W[i2][i1] = W[i1][i2];
    		}
    	}
    	for (int i1 = 0; i1 < n; i1++)
    		W[i1][i1] = 0;
    					// 初期状態
    	init_genrand((unsigned)time(NULL));
    	int u[36], m, pn;
    	printf("パターン番号と修正ユニット数 ");
    	scanf ("%d %d", &pn, &m);
    	for (int i1 = 0; i1 < n; i1++)
    		u[i1] = a[pn][i1];
    	for (int i1 = 0; i1 < m; i1++) {
    		int k = (int)(genrand_real3() * n);
    		if (k >= n)
    			k = n - 1;
    		if (u[k] > 0)
    			u[k] = 0;
    		else
    			u[k] = 1;
    	}
    
    	printf("初期状態:\n");
    	int k = 0;
    	for (int i1 = 0; i1 < 6; i1++) {
    		for (int i2 = 0; i2 < 6; i2++) {
    			printf("%2d", u[k]);
    			k++;
    		}
    		printf("\n");
    	}
    					// 更新
    	int count1 = 0, count2 = 0, count3 = 0;
    	while (count1 < 100) {
    		count2++;
    		bool sw = false;
    		k = (int)(genrand_real3() * n);
    		if (k >= n)
    			k = n - 1;
    		int s = 0;
    		for (int i1 = 0; i1 < n; i1++)
    			s += W[k][i1] * u[i1];
    		if (s >= 0) {
    			if (u[k] == 0) {
    				sw = true;
    				u[k] = 1;
    			}
    		}
    		else {
    			if (u[k] > 0) {
    				sw = true;
    				u[k] = 0;
    			}
    		}
    		if (sw) {
    			count1 = 0;
    			count3++;
    		}
    		else
    			count1++;
    	}
    					// 結果
    	printf("試行回数 = %d,更新回数 = %d\n", count2, count3);
    	k = 0;
    	for (int i1 = 0; i1 < 6; i1++) {
    		for (int i2 = 0; i2 < 6; i2++) {
    			printf("%2d", u[k]);
    			k++;
    		}
    		printf("\n");
    	}
    
    	return 0;
    }
    
    //---------------------MT.h---------------------------
    //   A C-program for MT19937, with initialization improved 2002/1/26.
    //   Coded by Takuji Nishimura and Makoto Matsumoto.
    //
    //   Before using, initialize the state by using init_genrand(seed)  
    //   or init_by_array(init_key, key_length).
    //
    //   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
    //   All rights reserved.                          
    //
    //   Redistribution and use in source and binary forms, with or without
    //   modification, are permitted provided that the following conditions
    //   are met:
    //
    //     1. Redistributions of source code must retain the above copyright
    //        notice, this list of conditions and the following disclaimer.
    //
    //     2. Redistributions in binary form must reproduce the above copyright
    //        notice, this list of conditions and the following disclaimer in the
    //        documentation and/or other materials provided with the distribution.
    //
    //     3. The names of its contributors may not be used to endorse or promote 
    //        products derived from this software without specific prior written 
    //        permission.
    //
    //   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    //   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    //   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    //   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    //   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    //   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    //   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    //   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    //   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    //   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    //   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    //
    //
    //   Any feedback is very welcome.
    //   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
    //   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
    
    
    //   The original version of http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c was modified by Takahiro Omi as
    //   - delete line 47 "#include<stdio.h>"
    //   - delete line 174 int main(void){...}
    //   - change N -> MT_N
    //   - change N -> MT_N
    //   - change the file name "mt19937ar.c" -> "MT.h"
    
    
    /*
    // Period parameters
    #define MT_N 624
    #define MT_M 397
    #define MATRIX_A 0x9908b0dfUL   // constant vector a
    #define UPPER_MASK 0x80000000UL // most significant w-r bits
    #define LOWER_MASK 0x7fffffffUL // least significant r bits
    
    static unsigned long mt[MT_N]; // the array for the state vector
    static int mti=MT_N+1; // mti==MT_N+1 means mt[MT_N] is not initialized
    
    // initializes mt[MT_N] with a seed
    void init_genrand(unsigned long s)
    {
        mt[0]= s & 0xffffffffUL;
        for (mti=1; mti<MT_N; mti++) {
            mt[mti] = 
    	    (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 
            // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier.
            // In the previous versions, MSBs of the seed affect
            // only MSBs of the array mt[].
            // 2002/01/09 modified by Makoto Matsumoto
            mt[mti] &= 0xffffffffUL;
            // for >32 bit machines
        }
    }
    
    // initialize by an array with array-length
    // init_key is the array for initializing keys
    // key_length is its length
    // slight change for C++, 2004/2/26
    void init_by_array(unsigned long init_key[], int key_length)
    {
        int i, j, k;
        init_genrand(19650218UL);
        i=1; j=0;
        k = (MT_N>key_length ? MT_N : key_length);
        for (; k; k--) {
            mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
              + init_key[j] + j; // non linear
            mt[i] &= 0xffffffffUL; // for WORDSIZE > 32 machines
            i++; j++;
            if (i>=MT_N) { mt[0] = mt[MT_N-1]; i=1; }
            if (j>=key_length) j=0;
        }
        for (k=MT_N-1; k; k--) {
            mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
              - i; // non linear
            mt[i] &= 0xffffffffUL; // for WORDSIZE > 32 machines
            i++;
            if (i>=MT_N) { mt[0] = mt[MT_N-1]; i=1; }
        }
    
        mt[0] = 0x80000000UL; // MSB is 1; assuring non-zero initial array
    }
    
    // generates a random number on [0,0xffffffff]-interval
    unsigned long genrand_int32(void)
    {
        unsigned long y;
        static unsigned long mag01[2]={0x0UL, MATRIX_A};
        // mag01[x] = x * MATRIX_A  for x=0,1
    
        if (mti >= MT_N) { // generate N words at one time
            int kk;
    
            if (mti == MT_N+1)   // if init_genrand() has not been called,
                init_genrand(5489UL); // a default initial seed is used
    
            for (kk=0;kk<MT_N-MT_M;kk++) {
                y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
                mt[kk] = mt[kk+MT_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
            }
            for (;kk<MT_N-1;kk++) {
                y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
                mt[kk] = mt[kk+(MT_M-MT_N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
            }
            y = (mt[MT_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
            mt[MT_N-1] = mt[MT_M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
    
            mti = 0;
        }
      
        y = mt[mti++];
    
        // Tempering
        y ^= (y >> 11);
        y ^= (y << 7) & 0x9d2c5680UL;
        y ^= (y << 15) & 0xefc60000UL;
        y ^= (y >> 18);
    
        return y;
    }
    
    // generates a random number on [0,0x7fffffff]-interval
    long genrand_int31(void)
    {
        return (long)(genrand_int32()>>1);
    }
    
    // generates a random number on [0,1]-real-interval
    double genrand_real1(void)
    {
        return genrand_int32()*(1.0/4294967295.0); 
        // divided by 2^32-1
    }
    
    // generates a random number on [0,1)-real-interval
    double genrand_real2(void)
    {
        return genrand_int32()*(1.0/4294967296.0); 
        // divided by 2^32
    }
    
    // generates a random number on (0,1)-real-interval
    double genrand_real3(void)
    {
        return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); 
        // divided by 2^32
    }
    
    // generates a random number on [0,1) with 53-bit resolution
    double genrand_res53(void) 
    { 
        unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
        return(a*67108864.0+b)*(1.0/9007199254740992.0); 
    } 
    // These real versions are due to Isaku Wada, 2002/01/09 added
    */
    			
    TSP
    /*********************************/
    /* Hopfieldネットワーク( TSP ) */
    /*      Coded by Y.Suganuma)     */
    /*********************************/
    #include <stdio.h>
    #include <time.h>
    #include <math.h>
    #include "MT.h"
    
    double out(double);
    void snx(double, double *, double *);
    double rkg(double, double, double *, double *, double **, int, void (*)(double, double *, double *));
    
    int n = 4;
    double A = 10.0, B = 10.0, C = 10.0, D = 2.0, d[4][4];
    
    int main()
    {
    					// 距離
    	double r = sqrt(2.0);
    	for (int i1 = 0; i1 < n; i1++) {
    		for (int i2 = 0; i2 < n; i2++) {
    			if (i1 == i2)
    				d[i1][i2] = 0.0;
    			else
    				d[i1][i2] = 1.0;
    		}
    	}
    	d[0][2] = r;
    	d[1][3] = r;
    	d[2][0] = r;
    	d[3][1] = r;
    					// 初期状態
    	double u[4][4];
    	init_genrand((unsigned)time(NULL));
    	for (int i1 = 0; i1 < n; i1++) {
    		for (int i2 = 0; i2 < n; i2++)
    			u[i1][i2] = 0.1 * genrand_real3() - 0.05;
    	}
    
    	printf("初期状態(出力):\n");
    	for (int i1 = 0; i1 < n; i1++) {
    		for (int i2 = 0; i2 < n; i2++)
    			printf("%6.3f", out(u[i1][i2]));
    		printf("\n");
    	}
    					// 更新
    	double time = 0.0, dx[16], **g = new double * [4];
    	for (int i1 = 0; i1 < 4; i1++)
    		g[i1] = new double [16];
    	for (int i1 = 0; i1 < 100; i1++)
    		time = rkg(time, 1, &u[0][0], dx, g, n*n, snx);
    
    	printf("最終状態(出力):\n");
    	for (int i1 = 0; i1 < n; i1++) {
    		for (int i2 = 0; i2 < n; i2++)
    			printf("%6.3f", out(u[i1][i2]));
    		printf("\n");
    	}
    
    	return 0;
    }
    
    /******************/
    /* ユニットの出力 */
    /******************/
    double out(double x)
    {
    	return 0.5 * (1.0 + tanh(x));
    //	return 1.0 / (1.0 + exp(-x));
    }
    
    /****************/
    /* 微係数の計算 */
    /****************/
    void snx(double time, double *u, double *du)
    {
    	for (int x = 0; x < n; x++) {
    		for (int i = 0; i < n; i++) {
    			int k = n * x + i;
    			du[k] = 0.0;
    			for (int j = 0; j < n; j++) {
    				if (j != i)
    					du[k] -= A * out(u[n*x+j]);
    			}
    			for (int y = 0; y < n; y++) {
    				if (y != x)
    					du[k] -= B * out(u[n*y+i]);
    			}
    			double N = 0.0;
    			for (int xx = 0; xx < n; xx++) {
    				for (int ii = 0; ii < n; ii++)
    					N += out(u[n*xx+ii]);
    			}
    			du[k] -= C * (N - n);
    			for (int y = 0; y < n; y++) {
    				int m1 = (i + 1) % n;
    				int m2 = i - 1;
    				if (m2 < 0)
    					m2 = n - 1;
    				du[k] -= D * d[x][y] * (out(u[n*y+m1]) + out(u[n*y+m2]));
    			}
    		}
    	}
    }
    
    /*******************************************/
    /* ルンゲ・クッタ法  dx/dt=f(t,x)          */
    /*      time : 現在の時間                  */
    /*      h : 時間刻み幅                     */
    /*      x : 現在の状態                     */
    /*      dx : 微係数(f(t,x):snxで計算する)*/
    /*      g : 作業域(g[4][n])              */
    /*      n : 微分方程式の次数               */
    /*      sub : 微係数を計算する関数の名前   */
    /*      return : time+h                    */
    /*******************************************/
    double rkg(double time, double h, double *x, double *dx, double **g,
               int n, void (*sub)(double, double *, double *))
    {
    	int i1;
    	double h2;
    
    	h2 = 0.5 * h;
    
    	(*sub)(time, x, dx);
    	for (i1 = 0; i1 < n; i1++)
    		g[0][i1] = h * dx[i1];
    
    	time += h2;
    	for (i1 = 0; i1 < n; i1++)
    		g[1][i1] = x[i1] + 0.5 * g[0][i1];
    	(*sub)(time, g[1], dx);
    	for (i1 = 0; i1 < n; i1++)
    		g[1][i1] = h * dx[i1];
    
    	for (i1 = 0; i1 < n; i1++)
    		g[2][i1] = x[i1] + 0.5 * g[1][i1];
    	(*sub)(time, g[2], dx);
    	for (i1 = 0; i1 < n; i1++)
    		g[2][i1] = h * dx[i1];
    
    	time += h2;
    	for (i1 = 0; i1 < n; i1++)
    		g[3][i1] = x[i1] + g[2][i1];
    	(*sub)(time, g[3], dx);
    	for (i1 = 0; i1 < n; i1++)
    		g[3][i1] = h * dx[i1];
    
    	for (i1 = 0; i1 < n; i1++)
    		x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0;
    
    	return time;
    }
    
    //---------------------MT.h---------------------------
    //   A C-program for MT19937, with initialization improved 2002/1/26.
    //   Coded by Takuji Nishimura and Makoto Matsumoto.
    //
    //   Before using, initialize the state by using init_genrand(seed)  
    //   or init_by_array(init_key, key_length).
    //
    //   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
    //   All rights reserved.                          
    //
    //   Redistribution and use in source and binary forms, with or without
    //   modification, are permitted provided that the following conditions
    //   are met:
    //
    //     1. Redistributions of source code must retain the above copyright
    //        notice, this list of conditions and the following disclaimer.
    //
    //     2. Redistributions in binary form must reproduce the above copyright
    //        notice, this list of conditions and the following disclaimer in the
    //        documentation and/or other materials provided with the distribution.
    //
    //     3. The names of its contributors may not be used to endorse or promote 
    //        products derived from this software without specific prior written 
    //        permission.
    //
    //   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    //   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    //   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    //   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    //   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    //   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    //   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    //   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    //   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    //   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    //   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    //
    //
    //   Any feedback is very welcome.
    //   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
    //   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
    
    
    //   The original version of http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c was modified by Takahiro Omi as
    //   - delete line 47 "#include<stdio.h>"
    //   - delete line 174 int main(void){...}
    //   - change N -> MT_N
    //   - change N -> MT_N
    //   - change the file name "mt19937ar.c" -> "MT.h"
    
    
    /*
    // Period parameters
    #define MT_N 624
    #define MT_M 397
    #define MATRIX_A 0x9908b0dfUL   // constant vector a
    #define UPPER_MASK 0x80000000UL // most significant w-r bits
    #define LOWER_MASK 0x7fffffffUL // least significant r bits
    
    static unsigned long mt[MT_N]; // the array for the state vector
    static int mti=MT_N+1; // mti==MT_N+1 means mt[MT_N] is not initialized
    
    // initializes mt[MT_N] with a seed
    void init_genrand(unsigned long s)
    {
        mt[0]= s & 0xffffffffUL;
        for (mti=1; mti<MT_N; mti++) {
            mt[mti] = 
    	    (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 
            // See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier.
            // In the previous versions, MSBs of the seed affect
            // only MSBs of the array mt[].
            // 2002/01/09 modified by Makoto Matsumoto
            mt[mti] &= 0xffffffffUL;
            // for >32 bit machines
        }
    }
    
    // initialize by an array with array-length
    // init_key is the array for initializing keys
    // key_length is its length
    // slight change for C++, 2004/2/26
    void init_by_array(unsigned long init_key[], int key_length)
    {
        int i, j, k;
        init_genrand(19650218UL);
        i=1; j=0;
        k = (MT_N>key_length ? MT_N : key_length);
        for (; k; k--) {
            mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
              + init_key[j] + j; // non linear
            mt[i] &= 0xffffffffUL; // for WORDSIZE > 32 machines
            i++; j++;
            if (i>=MT_N) { mt[0] = mt[MT_N-1]; i=1; }
            if (j>=key_length) j=0;
        }
        for (k=MT_N-1; k; k--) {
            mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
              - i; // non linear
            mt[i] &= 0xffffffffUL; // for WORDSIZE > 32 machines
            i++;
            if (i>=MT_N) { mt[0] = mt[MT_N-1]; i=1; }
        }
    
        mt[0] = 0x80000000UL; // MSB is 1; assuring non-zero initial array
    }
    
    // generates a random number on [0,0xffffffff]-interval
    unsigned long genrand_int32(void)
    {
        unsigned long y;
        static unsigned long mag01[2]={0x0UL, MATRIX_A};
        // mag01[x] = x * MATRIX_A  for x=0,1
    
        if (mti >= MT_N) { // generate N words at one time
            int kk;
    
            if (mti == MT_N+1)   // if init_genrand() has not been called,
                init_genrand(5489UL); // a default initial seed is used
    
            for (kk=0;kk<MT_N-MT_M;kk++) {
                y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
                mt[kk] = mt[kk+MT_M] ^ (y >> 1) ^ mag01[y & 0x1UL];
            }
            for (;kk<MT_N-1;kk++) {
                y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
                mt[kk] = mt[kk+(MT_M-MT_N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
            }
            y = (mt[MT_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
            mt[MT_N-1] = mt[MT_M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
    
            mti = 0;
        }
      
        y = mt[mti++];
    
        // Tempering
        y ^= (y >> 11);
        y ^= (y << 7) & 0x9d2c5680UL;
        y ^= (y << 15) & 0xefc60000UL;
        y ^= (y >> 18);
    
        return y;
    }
    
    // generates a random number on [0,0x7fffffff]-interval
    long genrand_int31(void)
    {
        return (long)(genrand_int32()>>1);
    }
    
    // generates a random number on [0,1]-real-interval
    double genrand_real1(void)
    {
        return genrand_int32()*(1.0/4294967295.0); 
        // divided by 2^32-1
    }
    
    // generates a random number on [0,1)-real-interval
    double genrand_real2(void)
    {
        return genrand_int32()*(1.0/4294967296.0); 
        // divided by 2^32
    }
    
    // generates a random number on (0,1)-real-interval
    double genrand_real3(void)
    {
        return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); 
        // divided by 2^32
    }
    
    // generates a random number on [0,1) with 53-bit resolution
    double genrand_res53(void) 
    { 
        unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
        return(a*67108864.0+b)*(1.0/9007199254740992.0); 
    } 
    // These real versions are due to Isaku Wada, 2002/01/09 added
    */
    			

  2. Java

    連想記憶
    /************************************/
    /* Hopfieldネットワーク(連想記憶) */
    /*      Coded by Y.Suganuma)        */
    /************************************/
    import java.io.*;
    import java.util.StringTokenizer;
    import java.util.Random;
    
    public class Test1 {
    	public static void main(String args[])
    	{
    		int a[][] = {{0, 0, 1, 1, 0, 0,
    		              0, 0, 1, 1, 0, 0,
    		              0, 0, 1, 1, 0, 0,
    		              0, 0, 1, 1, 0, 0,
    		              0, 0, 1, 1, 0, 0,
    		              0, 0, 1, 1, 0, 0},
    		             {0, 0, 0, 0, 0, 0,
    		              0, 0, 0, 0, 0, 0,
    		              1, 1, 1, 1, 1, 1,
    		              1, 1, 1, 1, 1, 1,
    		              0, 0, 0, 0, 0, 0,
    		              0, 0, 0, 0, 0, 0},
    		             {1, 1, 0, 0, 0, 0,
    		              1, 1, 1, 0, 0, 0,
    		              0, 1, 1, 1, 0, 0,
    		              0, 0, 1, 1, 1, 0,
    		              0, 0, 0, 1, 1, 1,
    		              0, 0, 0, 0, 1, 1}};
    		int W[][] = new int [36][36], n = 36, p = 3;
    					// 重みの設定(学習)
    		for (int i1 = 0; i1 < n-1; i1++) {
    			for (int i2 = i1+1; i2 < n; i2++) {
    				W[i1][i2] = 0;
    				for (int i3 = 0; i3 < p; i3++)
    					W[i1][i2] += (2 * a[i3][i1] - 1) * (2 * a[i3][i2] - 1);
    				W[i2][i1] = W[i1][i2];
    			}
    		}
    		for (int i1 = 0; i1 < n; i1++)
    			W[i1][i1] = 0;
    					// 初期状態
    		Random rn = new Random();
    		Console con = System.console();
    		String line = con.readLine("パターン番号と修正ユニット数 ");
    		StringTokenizer str = new StringTokenizer(line, " ");
    		int pn = Integer.parseInt(str.nextToken());
    		int m = Integer.parseInt(str.nextToken());
    		int u[] = new int [36];
    		for (int i1 = 0; i1 < n; i1++)
    			u[i1] = a[pn][i1];
    		for (int i1 = 0; i1 < m; i1++) {
    			int k = (int)(rn.nextDouble() * n);
    			if (k >= n)
    				k = n - 1;
    			if (u[k] > 0)
    				u[k] = 0;
    			else
    				u[k] = 1;
    		}
    
    		con.printf("初期状態:\n");
    		int k = 0;
    		for (int i1 = 0; i1 < 6; i1++) {
    			for (int i2 = 0; i2 < 6; i2++) {
    				con.printf("%2d", u[k]);
    				k++;
    			}
    			con.printf("\n");
    		}
    					// 更新
    		int count1 = 0, count2 = 0, count3 = 0;
    		while (count1 < 100) {
    			count2++;
    			boolean sw = false;
    			k = (int)(rn.nextDouble() * n);
    			if (k >= n)
    				k = n - 1;
    			int s = 0;
    			for (int i1 = 0; i1 < n; i1++)
    				s += W[k][i1] * u[i1];
    			if (s >= 0) {
    				if (u[k] == 0) {
    					sw = true;
    					u[k] = 1;
    				}
    			}
    			else {
    				if (u[k] > 0) {
    					sw = true;
    					u[k] = 0;
    				}
    			}
    			if (sw) {
    				count1 = 0;
    				count3++;
    			}
    			else
    				count1++;
    		}
    					// 結果
    		con.printf("試行回数 = %d,更新回数 = %d\n", count2, count3);
    		k = 0;
    		for (int i1 = 0; i1 < 6; i1++) {
    			for (int i2 = 0; i2 < 6; i2++) {
    				con.printf("%2d", u[k]);
    				k++;
    			}
    			con.printf("\n");
    		}
    	}
    }
    			
    TSP
    /*********************************/
    /* Hopfieldネットワーク( TSP ) */
    /*      Coded by Y.Suganuma)     */
    /*********************************/
    import java.io.*;
    import java.util.StringTokenizer;
    import java.util.Random;
    
    public class Test2 {
    
    	static int n = 4;
    	static double A = 10.0, B = 10.0, C = 10.0, D = 2.0, d[][] = new double [n][n];
    
    	public static void main(String args[])
    	{
    					// 距離
    		double r = Math.sqrt(2.0);
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++) {
    				if (i1 == i2)
    					d[i1][i2] = 0.0;
    				else
    					d[i1][i2] = 1.0;
    			}
    		}
    		d[0][2] = r;
    		d[1][3] = r;
    		d[2][0] = r;
    		d[3][1] = r;
    					// 初期状態
    		double u[][] = new double [n][n];
    		Random rn = new Random();
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++)
    				u[i1][i2] = 0.1 * rn.nextDouble() - 0.05;
    		}
    
    		Console con = System.console();
    		con.printf("初期状態(出力):\n");
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++)
    				con.printf("%6.3f", out(u[i1][i2]));
    			con.printf("\n");
    		}
    					// 更新
    		double time = 0.0;
    		double dx[] = new double[n*n];
    		double uu[] = new double[n*n];
    		double g[][] = new double [4][n*n];
    		int k = 0;
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++) {
    				uu[k] = u[i1][i2];
    				k++;
    			}
    		}
    		for (int i1 = 0; i1 < 100; i1++)
    			time = rkg(time, 1, uu, dx, g, n*n);
    
    		con.printf("最終状態(出力):\n");
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++)
    				con.printf("%6.3f", out(uu[i1*n+i2]));
    			con.printf("\n");
    		}
    	}
    
    	/******************/
    	/* ユニットの出力 */
    	/******************/
    	static double out(double x)
    	{
    		return 0.5 * (1.0 + Math.tanh(x));
    //		return 1.0 / (1.0 + Math.exp(-x));
    	}
    
    	/****************/
    	/* 微係数の計算 */
    	/****************/
    	static void snx(double time, double u[], double du[])
    	{
    		for (int x = 0; x < n; x++) {
    			for (int i = 0; i < n; i++) {
    				int k = n * x + i;
    				du[k] = 0.0;
    				for (int j = 0; j < n; j++) {
    					if (j != i)
    						du[k] -= A * out(u[n*x+j]);
    				}
    				for (int y = 0; y < n; y++) {
    					if (y != x)
    						du[k] -= B * out(u[n*y+i]);
    				}
    				double N = 0.0;
    				for (int xx = 0; xx < n; xx++) {
    					for (int ii = 0; ii < n; ii++)
    						N += out(u[n*xx+ii]);
    				}
    				du[k] -= C * (N - n);
    				for (int y = 0; y < n; y++) {
    					int m1 = (i + 1) % n;
    					int m2 = i - 1;
    					if (m2 < 0)
    						m2 = n - 1;
    					du[k] -= D * d[x][y] * (out(u[n*y+m1]) + out(u[n*y+m2]));
    				}
    			}
    		}
    	}
    
    	/*************************************************/
    	/* ルンゲ・クッタ法  dx/dt=f(t,x)                */
    	/*      time : 現在の時間                        */
    	/*      h : 時間刻み幅                           */
    	/*      x : 現在の状態                           */
    	/*      dx : 微係数(f(t,x):snxで計算する)      */
    	/*      g : 作業域(g[4][n])                    */
    	/*      n : 微分方程式の次数                     */
    	/*      return : time+h                          */
    	/*************************************************/
    	static double rkg(double time, double h, double x[], double dx[], double g[][], int n)
    	{
    		int i1;
    		double h2;
    
    		h2 = 0.5 * h;
    
    		snx(time, x, dx);
    		for (i1 = 0; i1 < n; i1++)
    			g[0][i1] = h * dx[i1];
    
    		time += h2;
    		for (i1 = 0; i1 < n; i1++)
    			g[1][i1] = x[i1] + 0.5 * g[0][i1];
    		snx(time, g[1], dx);
    		for (i1 = 0; i1 < n; i1++)
    			g[1][i1] = h * dx[i1];
    
    		for (i1 = 0; i1 < n; i1++)
    			g[2][i1] = x[i1] + 0.5 * g[1][i1];
    		snx(time, g[2], dx);
    		for (i1 = 0; i1 < n; i1++)
    			g[2][i1] = h * dx[i1];
    
    		time += h2;
    		for (i1 = 0; i1 < n; i1++)
    			g[3][i1] = x[i1] + g[2][i1];
    		snx(time, g[3], dx);
    		for (i1 = 0; i1 < n; i1++)
    			g[3][i1] = h * dx[i1];
    
    		for (i1 = 0; i1 < n; i1++)
    			x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0;
    
    		return time;
    	}
    }
    			

  3. JavaScript

      いずれか(連想記憶TST )をクリックして表示された画面においてデータを設定し,「実行」ボタンをクリックすれば画面上で実行可能です.

    連想記憶
    <!DOCTYPE HTML>
    
    <HTML>
    
    <HEAD>
    
    	<TITLE>Hopfieldネットワーク(連想記憶)</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<SCRIPT TYPE="text/javascript">
    		function main()
    		{
    			res = "";
    			let n = 36, p = 3;
    			let a = new Array(3);
    			a[0] = new Array(0, 0, 1, 1, 0, 0,
    			                 0, 0, 1, 1, 0, 0,
    			                 0, 0, 1, 1, 0, 0,
    			                 0, 0, 1, 1, 0, 0,
    			                 0, 0, 1, 1, 0, 0,
    			                 0, 0, 1, 1, 0, 0);
    			a[1] = new Array(0, 0, 0, 0, 0, 0,
    			                 0, 0, 0, 0, 0, 0,
    			                 1, 1, 1, 1, 1, 1,
    			                 1, 1, 1, 1, 1, 1,
    			                 0, 0, 0, 0, 0, 0,
    			                 0, 0, 0, 0, 0, 0);
    			a[2] = new Array(1, 1, 0, 0, 0, 0,
    			                 1, 1, 1, 0, 0, 0,
    			                 0, 1, 1, 1, 0, 0,
    			                 0, 0, 1, 1, 1, 0,
    			                 0, 0, 0, 1, 1, 1,
    			                 0, 0, 0, 0, 1, 1);
    			let W = new Array(n);
    			for (let i1 = 0; i1 < n; i1++)
    				W[i1] = new Array(n);
    						// 重みの設定(学習)
    			for (let i1 = 0; i1 < n-1; i1++) {
    				for (let i2 = i1+1; i2 < n; i2++) {
    					W[i1][i2] = 0;
    					for (let i3 = 0; i3 < p; i3++)
    						W[i1][i2] += (2 * a[i3][i1] - 1) * (2 * a[i3][i2] - 1);
    					W[i2][i1] = W[i1][i2];
    				}
    			}
    			for (let i1 = 0; i1 < n; i1++)
    				W[i1][i1] = 0;
    						// 初期状態
    			let pn       = parseInt(document.getElementById("pn").value);
    			let m        = parseInt(document.getElementById("m").value);
    			let u      = new Array(n);
    			for (let i1 = 0; i1 < n; i1++)
    				u[i1] = a[pn][i1];
    			let k;
    			for (let i1 = 0; i1 < m; i1++) {
    				k = Math.floor(Math.random() * n);
    				if (k >= n)
    					k = n - 1;
    				if (u[k] > 0)
    					u[k] = 0;
    				else
    					u[k] = 1;
    			}
    		
    			res += "初期状態:\n";
    			k    = 0;
    			for (let i1 = 0; i1 < 6; i1++) {
    				for (let i2 = 0; i2 < 6; i2++) {
    					res += (" " + u[k]);
    					k++;
    				}
    				res += "\n";
    			}
    						// 更新
    			let count1 = 0, count2 = 0, count3 = 0;
    			while (count1 < 100) {
    				count2++;
    				let sw = 0;
    				k      = Math.floor(Math.random() * n);
    				if (k >= n)
    					k = n - 1;
    				let s = 0;
    				for (let i1 = 0; i1 < n; i1++)
    					s += W[k][i1] * u[i1];
    				if (s >= 0) {
    					if (u[k] == 0) {
    						sw   = 1;
    						u[k] = 1;
    					}
    				}
    				else {
    					if (u[k] > 0) {
    						sw   = 1;
    						u[k] = 0;
    					}
    				}
    				if (sw > 0) {
    					count1 = 0;
    					count3++;
    				}
    				else
    					count1++;
    			}
    						// 結果
    			res += ("試行回数 = " + count2 + ",更新回数 = " + count3 + "\n");
    			k    = 0;
    			for (let i1 = 0; i1 < 6; i1++) {
    				for (let i2 = 0; i2 < 6; i2++) {
    					res += (" " + u[k]);
    					k++;
    				}
    				res += "\n";
    			}
    			document.getElementById("result").value = res;
    		}
    	</SCRIPT>
    
    </HEAD>
    
    <BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;">
    
    	<H2><B>Hopfieldネットワーク(連想記憶)</B></H2>
    
    	パターン番号(0~2):<INPUT ID="pn" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="0"> 
    	修正ユニット数:<INPUT ID="m" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="5"> 
    	<BUTTON STYLE="font-size: 100%; background-color: pink" onClick="return main()">実行</BUTTON><BR>
    	<DIV STYLE="text-align:center">結果</DIV>
    	<TEXTAREA ID="result" COLS="50" ROWS="10" STYLE="font-size: 100%;"></TEXTAREA>
    </BODY>
    
    </HTML>
    			
    TSP
    <!DOCTYPE HTML>
    
    <HTML>
    
    <HEAD>
    
    	<TITLE>Hopfieldネットワーク( TSP )</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<SCRIPT TYPE="text/javascript">
    		res = "";
    		n   = 4;
    		A   = 10.0;
    		B   = 10.0;
    		C   = 10.0;
    		D   = 2.0;
    		d   = null;
    		/****************/
    		/* main program */
    		/****************/
    		function main()
    		{
    			d = new Array(n);
    			for (let i1 = 0; i1 < n; i1++)
    				d[i1] = new Array(n);
    						// 距離
    			let r = Math.sqrt(2.0);
    			for (let i1 = 0; i1 < n; i1++) {
    				for (let i2 = 0; i2 < n; i2++) {
    					if (i1 == i2)
    						d[i1][i2] = 0.0;
    					else
    						d[i1][i2] = 1.0;
    				}
    			}
    			d[0][2] = r;
    			d[1][3] = r;
    			d[2][0] = r;
    			d[3][1] = r;
    						// 初期状態
    			let u = new Array(n);
    			for (let i1 = 0; i1 < n; i1++) {
    				u[i1] = new Array(n);
    				for (let i2 = 0; i2 < n; i2++)
    					u[i1][i2] = 0.1 * Math.random() - 0.05;
    			}
    
    			res = "初期状態(出力):\n";
    			for (let i1 = 0; i1 < n; i1++) {
    				for (let i2 = 0; i2 < n; i2++)
    					res += (" " + out_u(u[i1][i2]));
    				res += "\n";
    			}
    			document.getElementById("init").value = res;
    						// 更新
    			let time = 0.0;
    			let nn   = n * n;
    			let dx   = new Array(nn);
    			let uu   = new Array(nn);
    			let g    = new Array(4);
    			for (let i1 = 0; i1 < 4; i1++)
    				g[i1] = new Array(nn);
    			let k = 0;
    			for (let i1 = 0; i1 < n; i1++) {
    				for (let i2 = 0; i2 < n; i2++) {
    					uu[k] = u[i1][i2];
    					k++;
    				}
    			}
    			for (let i1 = 0; i1 < 100; i1++)
    				time = rkg(time, 1, uu, dx, g, (nn), snx);
    
    			res = "最終状態(出力):\n";
    			for (let i1 = 0; i1 < n; i1++) {
    				for (let i2 = 0; i2 < n; i2++)
    					res += (" " + out_u(uu[i1*n+i2]));
    				res += "\n";
    			}
    			document.getElementById("result").value = res;
    		}
    
    		/******************/
    		/* ユニットの出力 */
    		/******************/
    		function out_u(x)
    		{
    			return 0.5 * (1.0 + Math.tanh(x));
    //			return 1.0 / (1.0 + Math.exp(-x));   // tanh が使用できない場合(IE など)
    		}
    
    		/****************/
    		/* 関数値の計算 */
    		/****************/
    		function snx(time, u, du)
    		{
    			for (let x = 0; x < n; x++) {
    				for (let i = 0; i < n; i++) {
    					let k = n * x + i;
    					du[k] = 0.0;
    					for (let j = 0; j < n; j++) {
    						if (j != i)
    							du[k] -= A * out_u(u[n*x+j]);
    					}
    					for (let y = 0; y < n; y++) {
    						if (y != x)
    							du[k] -= B * out_u(u[n*y+i]);
    					}
    					let N = 0.0;
    					for (let xx = 0; xx < n; xx++) {
    						for (let ii = 0; ii < n; ii++)
    							N += out_u(u[n*xx+ii]);
    					}
    					du[k] -= C * (N - n);
    					for (let y = 0; y < n; y++) {
    						let m1 = (i + 1) % n;
    						let m2 = i - 1;
    						if (m2 < 0)
    							m2 = n - 1;
    						du[k] -= D * d[x][y] * (out_u(u[n*y+m1]) + out_u(u[n*y+m2]));
    					}
    				}
    			}
    		}
    
    		/********************************************/
    		/* ルンゲ・クッタ法  dx/dt=f(t,x)           */
    		/*      time : 現在の時間                   */
    		/*      h : 時間刻み幅                      */
    		/*      x : 現在の状態                      */
    		/*      dx : 微係数(f(t,x):snxで計算する) */
    		/*      g : 作業域(g[4][n])               */
    		/*      n : 微分方程式の次数                */
    		/*      fn : 関数値を計算する関数           */
    		/*      return : time+h                     */
    		/********************************************/
    		function rkg(time, h, x, dx, g, n, fn)
    		{
    			let h2 = 0.5 * h;
    
    			fn(n, x, dx);
    			for (let i1 = 0; i1 < n; i1++)
    				g[0][i1] = h * dx[i1];
    
    			time += h2;
    			for (let i1 = 0; i1 < n; i1++)
    				g[1][i1] = x[i1] + 0.5 * g[0][i1];
    			fn(n, g[1], dx);
    			for (let i1 = 0; i1 < n; i1++)
    				g[1][i1] = h * dx[i1];
    
    			for (let i1 = 0; i1 < n; i1++)
    				g[2][i1] = x[i1] + 0.5 * g[1][i1];
    			fn(n, g[2], dx);
    			for (let i1 = 0; i1 < n; i1++)
    				g[2][i1] = h * dx[i1];
    
    			time += h2;
    			for (let i1 = 0; i1 < n; i1++)
    				g[3][i1] = x[i1] + g[2][i1];
    			fn(n, g[3], dx);
    			for (let i1 = 0; i1 < n; i1++)
    				g[3][i1] = h * dx[i1];
    
    			for (let i1 = 0; i1 < n; i1++)
    				x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0;
    
    			return time;
    		}
    	</SCRIPT>
    
    </HEAD>
    
    <BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;">
    
    	<H2><B>Hopfieldネットワーク( TSP )</B></H2>
    
    	<BUTTON STYLE="font-size: 100%; background-color: pink" onClick="return main()">実行</BUTTON><BR>
    	<DIV STYLE="width: 800px; margin-right: auto; margin-left: auto">
    		<DIV STYLE="text-align:center; float: right; width: 400px">
    			<DIV STYLE="text-align:center">最終状態</DIV>
    			<TEXTAREA ID="result" COLS="35" ROWS="10" STYLE="font-size: 100%; width: 380px">
    			</TEXTAREA>
    		</DIV>
    		<DIV STYLE="text-align:center; width: 400px">
    			<DIV STYLE="text-align:center">初期状態</DIV>
    			<TEXTAREA ID="init" COLS="35" ROWS="10" STYLE="font-size: 100%; width: 380px">
    			</TEXTAREA>
    		</DIV>
    	</DIV>
    </BODY>
    
    </HTML>
    			

  4. PHP

    連想記憶
    <?php
    
    /************************************/
    /* Hopfieldネットワーク(連想記憶) */
    /*      Coded by Y.Suganuma)        */
    /************************************/
    
    $a    = array(3);
    $a[0] = array(0, 0, 1, 1, 0, 0,
                  0, 0, 1, 1, 0, 0,
                  0, 0, 1, 1, 0, 0,
                  0, 0, 1, 1, 0, 0,
                  0, 0, 1, 1, 0, 0,
                  0, 0, 1, 1, 0, 0);
    $a[1] = array(0, 0, 0, 0, 0, 0,
                  0, 0, 0, 0, 0, 0,
                  1, 1, 1, 1, 1, 1,
                  1, 1, 1, 1, 1, 1,
                  0, 0, 0, 0, 0, 0,
                  0, 0, 0, 0, 0, 0);
    $a[2] = array(1, 1, 0, 0, 0, 0,
                  1, 1, 1, 0, 0, 0,
                  0, 1, 1, 1, 0, 0,
                  0, 0, 1, 1, 1, 0,
                  0, 0, 0, 1, 1, 1,
                  0, 0, 0, 0, 1, 1);
    $n = 36;
    $p = 3;
    				// 重みの設定(学習)
    $W = array($n);
    for ($i1 = 0; $i1 < $n; $i1++)
    	$W[$i1] = array($n);
    for ($i1 = 0; $i1 < $n-1; $i1++) {
    	for ($i2 = $i1+1; $i2 < $n; $i2++) {
    		$W[$i1][$i2] = 0;
    		for ($i3 = 0; $i3 < $p; $i3++)
    			$W[$i1][$i2] += (2 * $a[$i3][$i1] - 1) * (2 * $a[$i3][$i2] - 1);
    		$W[$i2][$i1] = $W[$i1][$i2];
    	}
    }
    for ($i1 = 0; $i1 < $n; $i1++)
    	$W[$i1][$i1] = 0;
    				// 初期状態
    mt_srand();
    
    $u = array(36);
    
    printf("パターン番号(0~1)と修正ユニット数 ");
    fscanf(STDIN, "%d %d", $pn, $m);
    for ($i1 = 0; $i1 < $n; $i1++)
    	$u[$i1] = $a[$pn][$i1];
    for ($i1 = 0; $i1 < $m; $i1++) {
    	$k = intval(mt_rand() / mt_getrandmax() * $n);
    	if ($k >= $n)
    		$k = $n - 1;
    	if ($u[$k] > 0)
    		$u[$k] = 0;
    	else
    		$u[$k] = 1;
    }
    
    printf("初期状態:\n");
    $k = 0;
    for ($i1 = 0; $i1 < 6; $i1++) {
    	for ($i2 = 0; $i2 < 6; $i2++) {
    		printf("%2d", $u[$k]);
    		$k++;
    	}
    	printf("\n");
    }
    				// 更新
    $count1 = 0;
    $count2 = 0;
    $count3 = 0;
    while ($count1 < 100) {
    	$count2++;
    	$sw = false;
    	$k  = intval(mt_rand() / mt_getrandmax() * $n);
    	if ($k >= $n)
    		$k = $n - 1;
    	$s = 0;
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$s += $W[$k][$i1] * $u[$i1];
    	if ($s >= 0) {
    		if ($u[$k] == 0) {
    			$sw    = true;
    			$u[$k] = 1;
    		}
    	}
    	else {
    		if ($u[$k] > 0) {
    			$sw    = true;
    			$u[$k] = 0;
    		}
    	}
    	if ($sw) {
    		$count1 = 0;
    		$count3++;
    	}
    	else
    		$count1++;
    }
    				// 結果
    printf("試行回数 = %d,更新回数 = %d\n", $count2, $count3);
    $k = 0;
    for ($i1 = 0; $i1 < 6; $i1++) {
    	for ($i2 = 0; $i2 < 6; $i2++) {
    		printf("%2d", $u[$k]);
    		$k++;
    	}
    	printf("\n");
    }
    
    ?>
    			
    TSP
    <?php
    
    /*********************************/
    /* Hopfieldネットワーク( TSP ) */
    /*      Coded by Y.Suganuma)     */
    /*********************************/
    
    $n = 4;
    $A = 10.0;
    $B = 10.0;
    $C = 10.0;
    $D = 2.0;
    $d = array(4);
    for ($i1 = 0; $i1 < 4; $i1++)
    	$d[$i1] = array(4);
    					// 距離
    $r = sqrt(2.0);
    for ($i1 = 0; $i1 < $n; $i1++) {
    	for ($i2 = 0; $i2 < $n; $i2++) {
    		if ($i1 == $i2)
    			$d[$i1][$i2] = 0.0;
    		else
    			$d[$i1][$i2] = 1.0;
    	}
    }
    $d[0][2] = $r;
    $d[1][3] = $r;
    $d[2][0] = $r;
    $d[3][1] = $r;
    				// 初期状態
    mt_srand();
    
    $u = array(16);
    for ($i1 = 0; $i1 < $n; $i1++) {
    	for ($i2 = 0; $i2 < $n; $i2++)
    		$u[$i1*$n+$i2] = 0.1 * (mt_rand() / mt_getrandmax()) - 0.05;
    }
    
    printf("初期状態(出力):\n");
    for ($i1 = 0; $i1 < $n; $i1++) {
    	for ($i2 = 0; $i2 < $n; $i2++)
    		printf("%6.3f", out($u[$i1*$n+$i2]));
    	printf("\n");
    }
    				// 更新
    $time = 0.0;
    $dx   = array(16);
    $g    = array(4);
    for ($i1 = 0; $i1 < 4; $i1++)
    	$g[$i1] = array(16);
    for ($i1 = 0; $i1 < 100; $i1++)
    	$time = rkg($time, 1, $u, $dx, $g, $n*$n, "snx");
    
    printf("最終状態(出力):\n");
    for ($i1 = 0; $i1 < $n; $i1++) {
    	for ($i2 = 0; $i2 < $n; $i2++)
    		printf("%6.3f", out($u[$i1*$n+$i2]));
    	printf("\n");
    }
    
    /******************/
    /* ユニットの出力 */
    /******************/
    function out($x)
    {
    	return 0.5 * (1.0 + tanh($x));
    //	return 1.0 / (1.0 + exp(-$x));
    }
    
    /****************/
    /* 微係数の計算 */
    /****************/
    function snx($time, $u, &$du)
    {
    	global $n, $A, $B, $C, $D, $d;
    
    	for ($x = 0; $x < $n; $x++) {
    		for ($i = 0; $i < $n; $i++) {
    			$k      = $n * $x + $i;
    			$du[$k] = 0.0;
    			for ($j = 0; $j < $n; $j++) {
    				if ($j != $i)
    					$du[$k] -= $A * out($u[$n*$x+$j]);
    			}
    			for ($y = 0; $y < $n; $y++) {
    				if ($y != $x)
    					$du[$k] -= $B * out($u[$n*$y+$i]);
    			}
    			$N = 0.0;
    			for ($xx = 0; $xx < $n; $xx++) {
    				for ($ii = 0; $ii < $n; $ii++)
    					$N += out($u[$n*$xx+$ii]);
    			}
    			$du[$k] -= $C * ($N - $n);
    			for ($y = 0; $y < $n; $y++) {
    				$m1 = ($i + 1) % $n;
    				$m2 = $i - 1;
    				if ($m2 < 0)
    					$m2 = $n - 1;
    				$du[$k] -= $D * $d[$x][$y] * (out($u[$n*$y+$m1]) + out($u[$n*$y+$m2]));
    			}
    		}
    	}
    }
    
    /*******************************************/
    /* ルンゲ・クッタ法  dx/dt=f(t,x)          */
    /*      time : 現在の時間                  */
    /*      h : 時間刻み幅                     */
    /*      x : 現在の状態                     */
    /*      dx : 微係数(f(t,x):snxで計算する)*/
    /*      g : 作業域(g[4][n])              */
    /*      n : 微分方程式の次数               */
    /*      sub : 微係数を計算する関数の名前   */
    /*      return : time+h                    */
    /*******************************************/
    function rkg($time, $h, &$x, $dx, $g, $n, $sub)
    {
    	$h2 = 0.5 * $h;
    
    	$sub($time, $x, $dx);
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$g[0][$i1] = $h * $dx[$i1];
    
    	$time += $h2;
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$g[1][$i1] = $x[$i1] + 0.5 * $g[0][$i1];
    	$sub($time, $g[1], $dx);
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$g[1][$i1] = $h * $dx[$i1];
    
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$g[2][$i1] = $x[$i1] + 0.5 * $g[1][$i1];
    	$sub($time, $g[2], $dx);
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$g[2][$i1] = $h * $dx[$i1];
    
    	$time += $h2;
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$g[3][$i1] = $x[$i1] + $g[2][$i1];
    	$sub($time, $g[3], $dx);
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$g[3][$i1] = $h * $dx[$i1];
    
    	for ($i1 = 0; $i1 < $n; $i1++)
    		$x[$i1] = $x[$i1] + ($g[0][$i1] + 2.0 * $g[1][$i1] + 2.0 * $g[2][$i1] + $g[3][$i1]) / 6.0;
    
    	return $time;
    }
    
    ?>
    			

  5. Ruby

    連想記憶
    #####################################
    # Hopfieldネットワーク(連想記憶)
    #      Coded by Y.Suganuma
    #####################################
    
    a = [[0, 0, 1, 1, 0, 0,
          0, 0, 1, 1, 0, 0,
          0, 0, 1, 1, 0, 0,
          0, 0, 1, 1, 0, 0,
          0, 0, 1, 1, 0, 0,
          0, 0, 1, 1, 0, 0],
         [0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0,
          1, 1, 1, 1, 1, 1,
          1, 1, 1, 1, 1, 1,
          0, 0, 0, 0, 0, 0,
          0, 0, 0, 0, 0, 0],
         [1, 1, 0, 0, 0, 0,
          1, 1, 1, 0, 0, 0,
          0, 1, 1, 1, 0, 0,
          0, 0, 1, 1, 1, 0,
          0, 0, 0, 1, 1, 1,
          0, 0, 0, 0, 1, 1]]
    w = Array.new(36)
    for i1 in 0 ... 36
    	w[i1] = Array.new(36)
    end
    n = 36
    p = 3
    		# 重みの設定(学習)
    for i1 in 0 ... n-1
    	for i2 in i1+1 ... n
    		w[i1][i2] = 0
    		for i3 in 0 ... p
    			w[i1][i2] += (2 * a[i3][i1] - 1) * (2 * a[i3][i2] - 1)
    		end
    		w[i2][i1] = w[i1][i2]
    	end
    end
    for i1 in 0 ... n
    	w[i1][i1] = 0
    end
    		# 初期状態
    srand();
    u = Array.new(36)
    print("パターン番号と修正ユニット数 ")
    s  = gets().split(" ")
    pn = Integer(s[0]);
    m  = Integer(s[1])
    for i1 in 0 ... n
    	u[i1] = a[pn][i1]
    end
    for i1 in 0 ... m
    	k = Integer(rand(0) * n)
    	if k >= n
    		k = n - 1
    	end
    	if u[k] > 0
    		u[k] = 0
    	else
    		u[k] = 1
    	end
    end
    
    print("初期状態:\n")
    k = 0
    for i1 in 0 ... 6
    	for i2 in 0 ... 6
    		print(" " + String(u[k]))
    		k += 1
    	end
    	print("\n")
    end
    		# 更新
    count1 = 0
    count2 = 0
    count3 = 0
    while count1 < 100
    	count2 += 1
    	sw = 0
    	k  = Integer(rand(0) * n)
    	if k >= n
    		k = n - 1
    	end
    	s = 0
    	for i1 in 0 ... n
    		s += (w[k][i1] * u[i1])
    	end
    	if s >= 0
    		if u[k] == 0
    			sw   = 1
    			u[k] = 1
    		end
    	else
    		if u[k] > 0
    			sw   = 1
    			u[k] = 0
    		end
    	end
    	if sw > 0
    		count1  = 0
    		count3 += 1
    	else
    		count1 += 1
    	end
    end
    		# 結果
    print("試行回数 = " + String(count2) + ",更新回数 = " + String(count3) + "\n")
    k = 0
    for i1 in 0 ... 6
    	for i2 in 0 ... 6
    		print(" " + String(u[k]))
    		k += 1
    	end
    	print("\n")
    end
    			
    TSP
    ##################################
    # Hopfieldネットワーク( TSP )
    #      Coded by Y.Suganuma
    ##################################
    
    ##################
    # ユニットの出力
    ##################
    def out(x)
    	return 0.5 * (1.0 + Math.tanh(x))
    #	return 1.0 / (1.0 + Math.exp(-x))
    end
    
    #***************/
    # 微係数の計算 */
    #***************/
    snx = Proc.new { |time, u, du|
    	for x in 0 ... $n
    		for i in 0 ... $n
    			k     = $n * x + i
    			du[k] = 0.0
    			for j in 0 ... $n
    				if j != i
    					du[k] -= $aa * out(u[$n*x+j])
    				end
    			end
    			for y in 0 ... $n
    				if y != x
    					du[k] -= $bb * out(u[$n*y+i])
    				end
    			end
    			nn = 0.0
    			for xx in 0 ... $n
    				for ii in 0 ... $n
    					nn += out(u[$n*xx+ii])
    				end
    			end
    			du[k] -= $cc * (nn - $n)
    			for y in 0 ... $n
    				m1 = (i + 1) % $n
    				m2 = i - 1
    				if m2 < 0
    					m2 = $n - 1
    				end
    				du[k] -= $dd * $d[x][y] * (out(u[$n*y+m1]) + out(u[$n*y+m2]))
    			end
    		end
    	end
    }
    
    #******************************************/
    # ルンゲ・クッタ法  dx/dt=f(t,x)          */
    #      time : 現在の時間                  */
    #      h : 時間刻み幅                     */
    #      x : 現在の状態                     */
    #      dx : 微係数(f(t,x):snxで計算する)*/
    #      g : 作業域(g[4][n])              */
    #      n : 微分方程式の次数               */
    #      snx : 微係数を計算する関数の名前   */
    #      return : time+h                    */
    #******************************************/
    def rkg(time, h, x, dx, g, n, &sub)
    
    	h2 = 0.5 * h
    
    	sub.call(time, x, dx)
    	for i1 in 0 ... n
    		g[0][i1] = h * dx[i1]
    	end
    
    	time += h2
    	for i1 in 0 ... n
    		g[1][i1] = x[i1] + 0.5 * g[0][i1]
    	end
    	sub.call(time, g[1], dx)
    	for i1 in 0 ... n
    		g[1][i1] = h * dx[i1]
    	end
    
    	for i1 in 0 ... n
    		g[2][i1] = x[i1] + 0.5 * g[1][i1]
    	end
    	sub.call(time, g[2], dx)
    	for i1 in 0 ... n
    		g[2][i1] = h * dx[i1]
    	end
    
    	time += h2
    	for i1 in 0 ... n
    		g[3][i1] = x[i1] + g[2][i1]
    	end
    	sub.call(time, g[3], dx)
    	for i1 in 0 ... n
    		g[3][i1] = h * dx[i1]
    	end
    
    	for i1 in 0 ... n
    		x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0
    	end
    
    	return time
    end
    
    $n  = 4
    $nn = $n * $n
    $aa = 10.0
    $bb = 10.0
    $cc = 10.0
    $dd = 2.0
    $d  = Array.new($n)
    for i1 in 0 ... $n
    	$d[i1] = Array.new($n)
    end
    					# 距離
    r = Math.sqrt(2.0)
    for i1 in 0 ... $n
    	for i2 in 0 ... $n
    		if i1 == i2
    			$d[i1][i2] = 0.0
    		else
    			$d[i1][i2] = 1.0
    		end
    	end
    end
    $d[0][2] = r
    $d[1][3] = r
    $d[2][0] = r
    $d[3][1] = r
    					# 初期状態
    srand()
    u = Array.new($n)
    for i1 in 0 ... $n
    	u[i1] = Array.new($n)
    	for i2 in 0 ... $n
    		u[i1][i2] = 0.1 * rand(0) - 0.05
    	end
    end
    
    print("初期状態(出力):\n")
    for i1 in 0 ... $n
    	for i2 in 0 ... $n
    		print(" " + String(out(u[i1][i2])))
    	end
    	print("\n")
    end
    					# 更新
    time = 0.0
    dx   = Array.new(16)
    g    = Array.new(4)
    for i1 in 0 ... 4
    	g[i1] = Array.new(16)
    end
    k  = 0
    uu = Array.new(16)
    for i1 in 0 ... 4
    	for i2 in 0 ... 4
    		uu[k] = u[i1][i2]
    		k    += 1
    	end
    end
    for i1 in 0 ... 100
    	time = rkg(time, 1, uu, dx, g, $n*$n, &snx)
    end
    
    print("最終状態(出力):\n")
    k = 0
    for i1 in 0 ... $n
    	for i2 in 0 ... $n
    		print(" " + String(out(uu[k])))
    		k += 1
    	end
    	print("\n")
    end
    			

  6. Python

    連想記憶
    # -*- coding: UTF-8 -*-
    import numpy as np
    import sys
    from math import *
    from random import *
    
    #####################################
    # Hopfieldネットワーク(連想記憶)
    #      Coded by Y.Suganuma
    #####################################
    
    a = np.array([[0, 0, 1, 1, 0, 0,
                   0, 0, 1, 1, 0, 0,
                   0, 0, 1, 1, 0, 0,
                   0, 0, 1, 1, 0, 0,
                   0, 0, 1, 1, 0, 0,
                   0, 0, 1, 1, 0, 0],
                  [0, 0, 0, 0, 0, 0,
                   0, 0, 0, 0, 0, 0,
                   1, 1, 1, 1, 1, 1,
                   1, 1, 1, 1, 1, 1,
                   0, 0, 0, 0, 0, 0,
                   0, 0, 0, 0, 0, 0],
                  [1, 1, 0, 0, 0, 0,
                   1, 1, 1, 0, 0, 0,
                   0, 1, 1, 1, 0, 0,
                   0, 0, 1, 1, 1, 0,
                   0, 0, 0, 1, 1, 1,
                   0, 0, 0, 0, 1, 1]], np.int)
    W = np.empty((36, 36), np.int)
    n = 36
    p = 3
    		# 重みの設定(学習)
    for i1 in range(0, n-1) :
    	for i2 in range(i1+1, n) :
    		W[i1][i2] = 0
    		for i3 in range(0, p) :
    			W[i1][i2] += (2 * a[i3][i1] - 1) * (2 * a[i3][i2] - 1)
    		W[i2][i1] = W[i1][i2]
    for i1 in range(0, n) :
    	W[i1][i1] = 0
    		# 初期状態
    seed();
    u  = np.empty(36, np.int)
    s  = input("パターン番号と修正ユニット数 ").split()
    pn = int(s[0]);
    m  = int(s[1])
    for i1 in range(0, n) :
    	u[i1] = a[pn][i1]
    for i1 in range(0, m) :
    	k = int(random() * n)
    	if k >= n :
    		k = n - 1
    	if u[k] > 0 :
    		u[k] = 0
    	else :
    		u[k] = 1
    
    print("初期状態:")
    k = 0
    for i1 in range(0, 6) :
    	for i2 in range(0, 6) :
    		print(" " + str(u[k]), end="")
    		k += 1
    	print()
    		# 更新
    count1 = 0
    count2 = 0
    count3 = 0
    while count1 < 100 :
    	count2 += 1
    	sw = 0
    	k  = int(random() * n)
    	if k >= n :
    		k = n - 1
    	s = 0
    	for i1 in range(0, n) :
    		s += (W[k][i1] * u[i1])
    	if s >= 0 :
    		if u[k] == 0 :
    			sw   = 1
    			u[k] = 1
    	else :
    		if u[k] > 0 :
    			sw   = 1
    			u[k] = 0
    	if sw > 0 :
    		count1  = 0
    		count3 += 1
    	else :
    		count1 += 1
    		# 結果
    print("試行回数 = " + str(count2) + ",更新回数 = " + str(count3))
    k = 0
    for i1 in range(0, 6) :
    	for i2 in range(0, 6) :
    		print(" " + str(u[k]), end="")
    		k += 1
    	print("")
    			
    TSP
    # -*- coding: UTF-8 -*-
    import numpy as np
    import sys
    from math import *
    from random import *
    
    ############################################
    # ルンゲ・クッタ法  dx/dt=f(t,x)
    #      time : 現在の時間
    #      h : 時間刻み幅
    #      x : 現在の状態
    #      dx : 微係数(f(t,x):subで計算する)
    #      g : 作業域(g[4][n])
    #      n : 微分方程式の次数
    #      sub : 微係数を計算する関数の名前
    #      return : time+h
    #      coded by Y.Suganuma
    ############################################
    
    def rkg(time, h, x, dx, g, n, sub) :
    
    	h2 = 0.5 * h
    	sub(time, x, dx)
    	for i1 in range(0, n) :
    		g[0][i1] = h * dx[i1]
    
    	time += h2
    	for i1 in range(0, n) :
    		g[1][i1] = x[i1] + 0.5 * g[0][i1]
    	sub(time, g[1], dx)
    	for i1 in range(0, n) :
    		g[1][i1] = h * dx[i1]
    
    	for i1 in range(0, n) :
    		g[2][i1] = x[i1] + 0.5 * g[1][i1]
    	sub(time, g[2], dx)
    	for i1 in range(0, n) :
    		g[2][i1] = h * dx[i1]
    
    	time += h2
    	for i1 in range(0, n) :
    		g[3][i1] = x[i1] + g[2][i1]
    	sub(time, g[3], dx)
    	for i1 in range(0, n) :
    		g[3][i1] = h * dx[i1]
    
    	for i1 in range(0, n) :
    		x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0
    
    	return time
    
    ##################################
    # Hopfieldネットワーク( TSP )
    #      Coded by Y.Suganuma
    ##################################
    
    ##################
    # ユニットの出力
    ##################
    def out(x) :
    	return 0.5 * (1.0 + tanh(x))
    #	return 1.0 / (1.0 + exp(-x))
    
    ################
    # 微係数の計算
    ################
    def snx(time, u, du) :
    
    	for x in range(0, n) :
    		for i in range(0, n) :
    			k     = n * x + i
    			du[k] = 0.0
    			for j in range(0, n) :
    				if j != i :
    					du[k] -= A * out(u[n*x+j])
    			for y in range(0, n) :
    				if y != x :
    					du[k] -= B * out(u[n*y+i])
    			N = 0.0
    			for xx in range(0, n) :
    				for ii in range(0, n) :
    					N += out(u[n*xx+ii])
    			du[k] -= C * (N - n)
    			for y in range(0, n) :
    				m1 = (i + 1) % n
    				m2 = i - 1
    				if m2 < 0 :
    					m2 = n - 1
    				du[k] -= D * d[x][y] * (out(u[n*y+m1]) + out(u[n*y+m2]))
    
    n = 4
    A = 10.0
    B = 10.0
    C = 10.0
    D = 2.0
    d = np.empty((4, 4), np.float)
    					# 距離
    r = sqrt(2.0)
    for i1 in range(0, n) :
    	for i2 in range(0, n) :
    		if i1 == i2 :
    			d[i1][i2] = 0.0
    		else :
    			d[i1][i2] = 1.0
    d[0][2] = r
    d[1][3] = r
    d[2][0] = r
    d[3][1] = r
    					# 初期状態
    seed()
    u = np.empty((4, 4), np.float)
    for i1 in range(0, n) :
    	for i2 in range(0, n) :
    		u[i1][i2] = 0.1 * random() - 0.05
    
    print("初期状態(出力):")
    for i1 in range(0, n) :
    	for i2 in range(0, n) :
    		print(" " + str(out(u[i1][i2])), end="")
    	print("")
    					# 更新
    time = 0.0
    dx   = np.empty(16, np.float)
    g    = np.empty((4, 16), np.float)
    uu   = np.reshape(u, 16)
    for i1 in range(0, 100) :
    	time = rkg(time, 1, uu, dx, g, n*n, snx)
    
    print("最終状態(出力):")
    for i1 in range(0, n) :
    	for i2 in range(0, n) :
    		print(" " + str(out(u[i1][i2])), end="")
    	print("")
    			

  7. C#

    連想記憶
    /************************************/
    /* Hopfieldネットワーク(連想記憶) */
    /*      Coded by Y.Suganuma)        */
    /************************************/
    using System;
    
    class Program
    {
    	static void Main()
    	{
    		int n = 36, p = 3;
    		int[][] a = new int [3][];
    		a[0] = new int[] {0, 0, 1, 1, 0, 0,
    		                  0, 0, 1, 1, 0, 0,
    		                  0, 0, 1, 1, 0, 0,
    		                  0, 0, 1, 1, 0, 0,
    		                  0, 0, 1, 1, 0, 0,
    		                  0, 0, 1, 1, 0, 0};
    		a[1] = new int[] {0, 0, 0, 0, 0, 0,
    		                  0, 0, 0, 0, 0, 0,
    		                  1, 1, 1, 1, 1, 1,
    		                  1, 1, 1, 1, 1, 1,
    		                  0, 0, 0, 0, 0, 0,
    		                  0, 0, 0, 0, 0, 0};
    		a[2] = new int[] {1, 1, 0, 0, 0, 0,
    		                  1, 1, 1, 0, 0, 0,
    		                  0, 1, 1, 1, 0, 0,
    		                  0, 0, 1, 1, 1, 0,
    		                  0, 0, 0, 1, 1, 1,
    		                  0, 0, 0, 0, 1, 1};
    		int[][] W = new int [n][];
    		for (int i1 = 0; i1 < n; i1++)
    			W[i1] = new int [n];
    					// 重みの設定(学習)
    		for (int i1 = 0; i1 < n-1; i1++) {
    			for (int i2 = i1+1; i2 < n; i2++) {
    				W[i1][i2] = 0;
    				for (int i3 = 0; i3 < p; i3++)
    					W[i1][i2] += (2 * a[i3][i1] - 1) * (2 * a[i3][i2] - 1);
    				W[i2][i1] = W[i1][i2];
    			}
    		}
    		for (int i1 = 0; i1 < n; i1++)
    			W[i1][i1] = 0;
    					// 初期状態
    		Random rn = new Random();
    		Console.Write("パターン番号と修正ユニット数 ");
    		string[] str = Console.ReadLine().Split(' ');
    		int pn       = int.Parse(str[0]);
    		int m        = int.Parse(str[1]);
    		int[] u      = new int [n];
    		for (int i1 = 0; i1 < n; i1++)
    			u[i1] = a[pn][i1];
    		int k;
    		for (int i1 = 0; i1 < m; i1++) {
    			k = (int)(rn.NextDouble() * n);
    			if (k >= n)
    				k = n - 1;
    			if (u[k] > 0)
    				u[k] = 0;
    			else
    				u[k] = 1;
    		}
    
    		Console.WriteLine("初期状態:");
    		k = 0;
    		for (int i1 = 0; i1 < 6; i1++) {
    			for (int i2 = 0; i2 < 6; i2++) {
    				Console.Write(" " + u[k]);
    				k++;
    			}
    			Console.WriteLine();
    		}
    					// 更新
    		int count1 = 0, count2 = 0, count3 = 0;
    		while (count1 < 100) {
    			count2++;
    			bool sw = false;
    			k = (int)(rn.NextDouble() * n);
    			if (k >= n)
    				k = n - 1;
    			int s = 0;
    			for (int i1 = 0; i1 < n; i1++)
    				s += W[k][i1] * u[i1];
    			if (s >= 0) {
    				if (u[k] == 0) {
    					sw   = true;
    					u[k] = 1;
    				}
    			}
    			else {
    				if (u[k] > 0) {
    					sw   = true;
    					u[k] = 0;
    				}
    			}
    			if (sw) {
    				count1 = 0;
    				count3++;
    			}
    			else
    				count1++;
    		}
    					// 結果
    		Console.WriteLine("試行回数 = " + count2 + ",更新回数 = " + count3);
    		k = 0;
    		for (int i1 = 0; i1 < 6; i1++) {
    			for (int i2 = 0; i2 < 6; i2++) {
    				Console.Write(" " + u[k]);
    				k++;
    			}
    			Console.WriteLine();
    		}
    	}
    }
    			
    TSP
    /*********************************/
    /* Hopfieldネットワーク( TSP ) */
    /*      Coded by Y.Suganuma)     */
    /*********************************/
    using System;
    
    class Program
    {
    	static void Main()
    	{
    		Test1 ts = new Test1();
    	}
    }
    
    class Test1
    {
    
    	int n = 4;
    	double A = 10.0, B = 10.0, C = 10.0, D = 2.0;
    	double[][] d;
    
    	public Test1()
    	{
    		d = new double [n][];
    		for (int i1 = 0; i1 < n; i1++)
    			d[i1] = new double [n];
    					// 距離
    		double r = Math.Sqrt(2.0);
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++) {
    				if (i1 == i2)
    					d[i1][i2] = 0.0;
    				else
    					d[i1][i2] = 1.0;
    			}
    		}
    		d[0][2] = r;
    		d[1][3] = r;
    		d[2][0] = r;
    		d[3][1] = r;
    					// 初期状態
    		double[][] u = new double [n][];
    		Random rn = new Random();
    		for (int i1 = 0; i1 < n; i1++) {
    			u[i1] = new double [n];
    			for (int i2 = 0; i2 < n; i2++)
    				u[i1][i2] = 0.1 * rn.NextDouble() - 0.05;
    		}
    
    		Console.WriteLine("初期状態(出力):");
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++)
    				Console.Write(" " + out_u(u[i1][i2]));
    			Console.WriteLine();
    		}
    					// 更新
    		double time  = 0.0;
    		double[] dx  = new double[n*n];
    		double[] uu  = new double[n*n];
    		double[][] g = new double [4][];
    		for (int i1 = 0; i1 < 4; i1++)
    			g[i1] = new double [n*n];
    		int k = 0;
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++) {
    				uu[k] = u[i1][i2];
    				k++;
    			}
    		}
    		for (int i1 = 0; i1 < 100; i1++)
    			time = rkg(time, 1, uu, dx, g, n*n, snx);
    
    		Console.WriteLine("最終状態(出力):");
    		for (int i1 = 0; i1 < n; i1++) {
    			for (int i2 = 0; i2 < n; i2++)
    				Console.Write(" " + out_u(uu[i1*n+i2]));
    			Console.WriteLine();
    		}
    	}
    
    	/******************/
    	/* ユニットの出力 */
    	/******************/
    	double out_u(double x)
    	{
    		return 0.5 * (1.0 + Math.Tanh(x));
    //		return 1.0 / (1.0 + Math.Exp(-x));
    	}
    
    	/****************/
    	/* 微係数の計算 */
    	/****************/
    	int snx(double time, double[] u, double[] du)
    	{
    		for (int x = 0; x < n; x++) {
    			for (int i = 0; i < n; i++) {
    				int k = n * x + i;
    				du[k] = 0.0;
    				for (int j = 0; j < n; j++) {
    					if (j != i)
    						du[k] -= A * out_u(u[n*x+j]);
    				}
    				for (int y = 0; y < n; y++) {
    					if (y != x)
    						du[k] -= B * out_u(u[n*y+i]);
    				}
    				double N = 0.0;
    				for (int xx = 0; xx < n; xx++) {
    					for (int ii = 0; ii < n; ii++)
    						N += out_u(u[n*xx+ii]);
    				}
    				du[k] -= C * (N - n);
    				for (int y = 0; y < n; y++) {
    					int m1 = (i + 1) % n;
    					int m2 = i - 1;
    					if (m2 < 0)
    						m2 = n - 1;
    					du[k] -= D * d[x][y] * (out_u(u[n*y+m1]) + out_u(u[n*y+m2]));
    				}
    			}
    		}
    		return 0;
    	}
    
    	/********************************************/
    	/* ルンゲ・クッタ法  dx/dt=f(t,x)           */
    	/*      time : 現在の時間                   */
    	/*      h : 時間刻み幅                      */
    	/*      x : 現在の状態                      */
    	/*      dx : 微係数(f(t,x):snxで計算する) */
    	/*      g : 作業域(g[4][n])               */
    	/*      n : 微分方程式の次数                */
    	/*      fn : 関数値を計算する関数           */
    	/*      return : time+h                     */
    	/********************************************/
    	double rkg(double time, double h, double[] x, double[] dx, double[][] g,
    	           int n, Func fn)
    	{
    		double h2 = 0.5 * h;
    
    		fn(time, x, dx);
    		for (int i1 = 0; i1 < n; i1++)
    			g[0][i1] = h * dx[i1];
    
    		time += h2;
    		for (int i1 = 0; i1 < n; i1++)
    			g[1][i1] = x[i1] + 0.5 * g[0][i1];
    		fn(time, g[1], dx);
    		for (int i1 = 0; i1 < n; i1++)
    			g[1][i1] = h * dx[i1];
    
    		for (int i1 = 0; i1 < n; i1++)
    			g[2][i1] = x[i1] + 0.5 * g[1][i1];
    		fn(time, g[2], dx);
    		for (int i1 = 0; i1 < n; i1++)
    			g[2][i1] = h * dx[i1];
    
    		time += h2;
    		for (int i1 = 0; i1 < n; i1++)
    			g[3][i1] = x[i1] + g[2][i1];
    		fn(time, g[3], dx);
    		for (int i1 = 0; i1 < n; i1++)
    			g[3][i1] = h * dx[i1];
    
    		for (int i1 = 0; i1 < n; i1++)
    			x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0;
    
    		return time;
    	}
    }
    			

  8. VB

    連想記憶
    '**********************************'
    ' Hopfieldネットワーク(連想記憶) '
    '      Coded by Y.Suganuma)        '
    '**********************************'
    Imports System.Text.RegularExpressions
    
    Module Test
    
    	Sub Main()
    
    		Dim n As Integer = 36
    		Dim p As Integer = 3
    		Dim a(,) As Integer = 
    		                 {{0, 0, 1, 1, 0, 0,
    		                   0, 0, 1, 1, 0, 0,
    		                   0, 0, 1, 1, 0, 0,
    		                   0, 0, 1, 1, 0, 0,
    		                   0, 0, 1, 1, 0, 0,
    		                   0, 0, 1, 1, 0, 0},
    		                  {0, 0, 0, 0, 0, 0,
    		                   0, 0, 0, 0, 0, 0,
    		                   1, 1, 1, 1, 1, 1,
    		                   1, 1, 1, 1, 1, 1,
    		                   0, 0, 0, 0, 0, 0,
    		                   0, 0, 0, 0, 0, 0},
    		                  {1, 1, 0, 0, 0, 0,
    		                   1, 1, 1, 0, 0, 0,
    		                   0, 1, 1, 1, 0, 0,
    		                   0, 0, 1, 1, 1, 0,
    		                   0, 0, 0, 1, 1, 1,
    		                   0, 0, 0, 0, 1, 1}}
    		Dim W(n,n) As Integer
    					' 重みの設定(学習)
    		For i1 As Integer = 0 To n-2
    			For i2 As Integer = i1+1 To n-1
    				W(i1,i2) = 0
    				For i3 As Integer = 0 To p-1
    					W(i1,i2) += (2 * a(i3,i1) - 1) * (2 * a(i3,i2) - 1)
    				Next
    				W(i2,i1) = W(i1,i2)
    			Next
    		Next
    		For i1 As Integer = 0 To n-1
    			W(i1,i1) = 0
    		Next
    					' 初期状態
    		Dim MS As Regex  = New Regex("\s+") 
    		Dim rn As Random = new Random()
    		Console.Write("パターン番号と修正ユニット数 ")
    		Dim str() As String = MS.Split(Console.ReadLine().Trim())
    		Dim pn As Integer   = Integer.Parse(str(0))
    		Dim m As Integer    = Integer.Parse(str(1))
    		Dim u(n) As Integer
    		For i1 As Integer = 0 To n-1
    			u(i1) = a(pn,i1)
    		Next
    		Dim k As Integer
    		For i1 As Integer = 0 To m-1
    			k = Math.Floor(rn.NextDouble() * n)
    			If k >= n
    				k = n - 1
    			End If
    			If u(k) > 0
    				u(k) = 0
    			Else
    				u(k) = 1
    			End If
    		Next
    
    		Console.WriteLine("初期状態:")
    		k = 0
    		For i1 As Integer = 0 To 5
    			For i2 As Integer = 0 To 5
    				Console.Write(" " & u(k))
    				k += 1
    			Next
    			Console.WriteLine()
    		Next
    					' 更新
    		Dim count1 As Integer = 0
    		Dim count2 As Integer = 0
    		Dim count3 As Integer = 0
    		Do While count1 < 100
    			count2           += 1
    			Dim sw As Boolean = False
    			k = Math.Floor(rn.NextDouble() * n)
    			If k >= n
    				k = n - 1
    			End If
    			Dim s As Integer = 0
    			For i1 As Integer = 0 To n-1
    				s += W(k,i1) * u(i1)
    			Next
    			If s >= 0
    				If u(k) = 0
    					sw   = True
    					u(k) = 1
    				End If
    			Else
    				If u(k) > 0
    					sw   = True
    					u(k) = 0
    				End If
    			End If
    			If sw
    				count1  = 0
    				count3 += 1
    			Else
    				count1 += 1
    			End If
    		Loop
    					' 結果
    		Console.WriteLine("試行回数 = " & count2 & ",更新回数 = " & count3)
    		k = 0
    		For i1 As Integer = 0 To 5
    			For i2 As Integer = 0 To 5
    				Console.Write(" " & u(k))
    				k += 1
    			Next
    			Console.WriteLine()
    		Next
    
    	End Sub
    
    End Module
    			
    TSP
    '*******************************'
    ' Hopfieldネットワーク( TSP ) '
    '      Coded by Y.Suganuma)     '
    '*******************************'
    Module Test
    
    	Dim n As Integer = 4
    	Dim A As Double = 10.0
    	Dim B As Double = 10.0
    	Dim C As Double = 10.0
    	Dim D As Double = 2.0
    	Dim dd(n,n) As Double
    
    	Sub Main()
    				' 微係数の計算
    		Dim snx = Function(tm, v, dv)
    			For x As Integer = 0 To n-1
    				For i As Integer = 0 To n-1
    					Dim kk As Integer = n * x + i
    					dv(kk)            = 0.0
    					For j As Integer = 0 To n-1
    						If j <> i
    							dv(kk) -= A * out_u(v(n*x+j))
    						End If
    					Next
    					For y As Integer = 0 To n-1
    						If y <> x
    							dv(kk) -= B * out_u(v(n*y+i))
    						End If
    					Next
    					Dim NN As Double = 0.0
    					For xx As Integer = 0 To n-1
    						For ii As Integer = 0 To n-1
    							NN += out_u(v(n*xx+ii))
    						Next
    					Next
    					dv(kk) -= C * (NN - n)
    					For y As Integer = 0 To n-1
    						Dim m1 As Integer = (i + 1) Mod n
    						Dim m2 As Integer = i - 1
    						If m2 < 0
    							m2 = n - 1
    						End If
    						dv(kk) -= D * dd(x,y) * (out_u(v(n*y+m1)) + out_u(v(n*y+m2)))
    					Next
    				Next
    			Next
    			Return 0
    		End Function
    					' 距離
    		Dim r As Double = Math.Sqrt(2.0)
    		For i1 As Integer = 0 To n-1
    			For i2 As Integer = 0 To n-1
    				If i1 = i2
    					dd(i1,i2) = 0.0
    				Else
    					dd(i1,i2) = 1.0
    				End If
    			Next
    		Next
    		dd(0,2) = r
    		dd(1,3) = r
    		dd(2,0) = r
    		dd(3,1) = r
    					' 初期状態
    		Dim u(n,n) As Double
    		Dim rn As Random = new Random()
    		For i1 As Integer = 0 To n-1
    			For i2 As Integer = 0 To n-1
    				u(i1,i2) = 0.1 * rn.NextDouble() - 0.05
    			Next
    		Next
    
    		Console.WriteLine("初期状態(出力):")
    		For i1 As Integer = 0 To n-1
    			For i2 As Integer = 0 To n-1
    				Console.Write(" " & out_u(u(i1,i2)))
    			Next
    			Console.WriteLine()
    		Next
    					' 更新
    		Dim time As Double  = 0.0
    		Dim dx(n*n) As Double
    		Dim uu(n*n) As Double
    		Dim g0(n*n) As Double
    		Dim g1(n*n) As Double
    		Dim g2(n*n) As Double
    		Dim g3(n*n) As Double
    		Dim k As Integer = 0
    		For i1 As Integer = 0 To n-1
    			For i2 As Integer = 0 To n-1
    				uu(k) = u(i1,i2)
    				k    += 1
    			Next
    		Next
    		For i1 As Integer = 0 To 99
    			time = rkg(time, 1, uu, dx, g0, g1, g2, g3, n*n, snx)
    		Next
    
    		Console.WriteLine("最終状態(出力):")
    		For i1 As Integer = 0 To n-1
    			For i2 As Integer = 0 To n-1
    				Console.Write(" " & out_u(uu(i1*n+i2)))
    			Next
    			Console.WriteLine()
    		Next
    
    	End Sub
    
    	'****************'
    	' ユニットの出力 '
    	'****************'
    	Function out_u(x As Double)
    		Return 0.5 * (1.0 + Math.Tanh(x))
    '		Return 1.0 / (1.0 + Math.Exp(-x))
    	End Function
    
    	''''''''''''''''''''''''''''''''''''''''''''
    	' ルンゲ・クッタ法  dx/dt=f(t,x)           '
    	'      time : 現在の時間                   '
    	'      h : 時間刻み幅                      '
    	'      x : 現在の状態                      '
    	'      dx : 微係数(f(t,x):snxで計算する) '
    	'      g0,g1,g2,g3 : 作業域(gi(n))       '
    	'      n : 微分方程式の次数                '
    	'      fn : 関数値を計算する関数           '
    	'      return : time+h                     '
    	''''''''''''''''''''''''''''''''''''''''''''
    	Function rkg(time As Double, h As Double, x() As Double, dx() As Double,
    	             g0() As Double, g1() As Double, g2() As Double, g3() As Double,
    	             n As Integer, fn As Func(Of Double, Double(), Double(), Integer))
    
    		Dim h2 As Double = 0.5 * h
    
    		fn(time, x, dx)
    		For i1 As Integer = 0 To n-1
    			g0(i1) = h * dx(i1)
    		Next
    
    		time += h2
    		For i1 As Integer = 0 To n-1
    			g1(i1) = x(i1) + 0.5 * g0(i1)
    		Next
    		fn(time, g1, dx)
    		For i1 As Integer = 0 To n-1
    			g1(i1) = h * dx(i1)
    		Next
    
    		For i1 As Integer = 0 To n-1
    			g2(i1) = x(i1) + 0.5 * g1(i1)
    		Next
    		fn(time, g2, dx)
    		For i1 As Integer = 0 To n-1
    			g2(i1) = h * dx(i1)
    		Next
    
    		time += h2
    		For i1 As Integer = 0 To n-1
    			g3(i1) = x(i1) + g2(i1)
    		Next
    		fn(time, g3, dx)
    		For i1 As Integer = 0 To n-1
    			g3(i1) = h * dx(i1)
    		Next
    
    		For i1 As Integer = 0 To n-1
    			x(i1) = x(i1) + (g0(i1) + 2.0 * g1(i1) + 2.0 * g2(i1) + g3(i1)) / 6.0
    		Next
    
    		Return time
    
    	End Function
    
    End Module
    			

情報学部 菅沼ホーム 目次 索引