静岡理工科大学 菅沼ホーム 目次 索引

Winner-Take-All

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

  プログラム(使用方法)は,p 個の入力ユニットと o 個の出力ユニットからなる Winner-Take-All ニューラルネットワークに対する学習を行います.Winner-Take-All ニューラルネットワークとは,出力ユニットの内,最大の出力を持つユニットだけが発火することによって,与えられたデータを分類しようとするものです.なお,このプログラムでは,クラスを使用しています.

  1. C++

      C++11 においては,「メルセンヌ・ツイスター法による擬似乱数生成エンジン」を使用することができます.
    /****************************/
    /* Winner-Take-All Groups   */
    /*      coded by Y.Suganuma */
    /****************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include "MT.h"
    
    /**********************/
    /* Winnerクラスの定義 */
    /**********************/
    class Winner {
    		long max;   // 最大学習回数
    		long n;   // 訓練例の数
    		long o;   // 出力セルの数
    		long p;   // 入力セルの数
    		long **W_p;   // 重み(ポケット)
    		long **W;   // 重み
    		long **E;   // 訓練例
    		long **C;   // 各訓練例に対する正しい出力
    		long *Ct;   // 作業領域
    	public:
    		Winner(long, long, long, long, long);
    		~Winner();
    		long Bunrui();
    		void Input(char *);
    		void Learn(int, char *name = "");
    		long Pocket(long *);
    };
    
    /******************/
    /* コンストラクタ */
    /******************/
    Winner::Winner(long max_i, long n_i, long o_i, long p_i, long seed)
    {
    	long i1;
    /*
         設定
    */
    	max = max_i;
    	n   = n_i;
    	o   = o_i;
    	p   = p_i;
    
    	init_genrand(seed);
    /*
         領域の確保
    */
    	E = new long * [n];
    	C = new long * [n];
    	for (i1 = 0; i1 < n; i1++) {
    		E[i1] = new long [p+1];
    		C[i1] = new long [o];
    	}
    
    	W_p = new long * [o];
    	W   = new long * [o];
    	for (i1 = 0; i1 < o; i1++) {
    		W_p[i1] = new long [p+1];
    		W[i1]   = new long [p+1];
    	}
    
    	Ct = new long [o];
    }
    
    /****************/
    /* デストラクタ */
    /****************/
    Winner::~Winner()
    {
    	int i1;
    
    	for (i1 = 0; i1 < n; i1++) {
    		delete [] E[i1];
    		delete [] C[i1];
    	}
    	delete [] E;
    	delete [] C;
    
    	for (i1 = 0; i1 < o; i1++) {
    		delete [] W_p[i1];
    		delete [] W[i1];
    	}
    	delete [] W_p;
    	delete [] W;
    
    	delete [] Ct;
    }
    
    /******************************************/
    /* 訓練例の分類                           */
    /*      return : 正しく分類した訓練例の数 */
    /******************************************/
    long Winner::Bunrui()
    {
    	long cor, i1, i2, i3, mx = 0, mx_v = 0, num = 0, s;
    	int sw = 0;
    
    	for (i1 = 0; i1 < n; i1++) {
    		cor = 0;
    		for (i2 = 0; i2 < o; i2++) {
    			if (C[i1][i2] == 1)
    				cor = i2;
    			s = 0;
    			for (i3 = 0; i3 <= p; i3++)
    				s += W[i2][i3] * E[i1][i3];
    			if (i2 == 0) {
    				mx   = 0;
    				mx_v = s;
    			}
    			else {
    				if (s > mx_v) {
    					mx   = i2;
    					mx_v = s;
    					sw   = 0;
    				}
    				else {
    					if (s == mx_v)
    						sw = 1;
    				}
    			}
    		}
    
    		if (sw == 0 && cor == mx)
    			num++;
    	}
    
    	return num;
    }
    
    /**************************/
    /* 学習データの読み込み   */
    /*      name : ファイル名 */
    /**************************/
    void Winner::Input(char *name)
    {
    	long i1, i2;
    	FILE *st;
    
    	st = fopen(name, "r");
    
    	fscanf(st, "%*s");
    
    	for (i1 = 0; i1 < n; i1++) {
    		E[i1][0] = 1;
    		for (i2 = 1; i2 <= p; i2++)
    			fscanf(st, "%ld", &E[i1][i2]);
    		for (i2 = 0; i2 < o; i2++)
    			fscanf(st, "%ld", &C[i1][i2]);
    	}
    
    	fclose(st);
    }
    
    /*********************************/
    /* 学習と結果の出力              */
    /*      seed : 乱数の初期値      */
    /*      pr : =0 : 画面に出力     */
    /*           =1 : ファイルに出力 */
    /*      name : 出力ファイル名    */
    /*********************************/
    void Winner::Learn(int pr, char *name)
    {
    	long i1, i2, i3, mx = 0, mx_v = 0, n_tri, num, s;
    	int sw;
    	FILE *out;
    
    	n_tri = Pocket(&num);
    
    	if (pr == 0)
    		out = stdout;
    	else
    		out = fopen(name, "w");
    
    	fprintf(out, "重み\n");
    	for (i1 = 0; i1 < o; i1++) {
    		for (i2 = 0; i2 <= p; i2++)
    			fprintf(out, "%5ld", W_p[i1][i2]);
    		fprintf(out, "\n");
    	}
    
    	fprintf(out, "分類結果\n");
    	for (i1 = 0; i1 < n; i1++) {
    		sw = 0;
    		for (i2 = 0; i2 < o; i2++) {
    			s = 0;
    			for (i3 = 0; i3 <= p; i3++)
    				s += W_p[i2][i3] * E[i1][i3];
    			if (i2 == 0) {
    				mx_v = s;
    				mx   = 0;
    			}
    			else {
    				if (s > mx_v) {
    					sw   = 0;
    					mx_v = s;
    					mx   = i2;
    				}
    				else {
    					if (s == mx_v)
    						sw = 1;
    				}
    			}
    		}
    		for (i2 = 1; i2 <= p; i2++)
    			fprintf(out, "%2ld", E[i1][i2]);
    		fprintf(out, " Cor ");
    		for (i2 = 0; i2 < o; i2++)
    			fprintf(out,"%2ld", C[i1][i2]);
    		if (sw > 0)
    			mx = -1;
    		fprintf(out, " Res %2ld\n", mx+1);
    	}
    
    	if (n == num)
    		printf("  !!すべてを分類(試行回数:%ld)\n", n_tri);
    	else
    		printf("  !!%ld 個を分類\n", num);
    }
    
    /********************************************/
    /* Pocket Algorith with Ratcet              */
    /*      num_p : 正しく分類した訓練例の数    */
    /*      return : =0 : 最大学習回数          */
    /*               >0  : すべてを分類(回数) */
    /********************************************/
    long Winner::Pocket(long *num_p)
    {
    	long cor, count = 0, i1, i2, k, mx = 0, num, run = 0, run_p = 0, s, sw = -1;
    	int sw1;
    /*
         初期設定
    */
    	*num_p = 0;
    
    	for (i1 = 0; i1 < o; i1++) {
    		for (i2 = 0; i2 <= p; i2++)
    			W[i1][i2] = 0;
    	}
    /*
         実行
    */
    	while (sw < 0) {
    					// 終了チェック
    		count++;;
    		if (count > max)
    			sw = 0;
    
    		else {
    					// 訓練例の選択
    			k = (long)(genrand_real3() * n);
    			if (k >= n)
    				k = n - 1;
    					// 出力の計算
    			sw1 = 0;
    			cor = -1;
    
    			for (i1 = 0; i1 < o; i1++) {
    
    				if (C[k][i1] == 1)
    					cor = i1;
    
    				s = 0;
    				for (i2 = 0; i2 <= p; i2++)
    					s += W[i1][i2] * E[k][i2];
    				Ct[i1] = s;
    
    				if (i1 == 0)
    					mx = 0;
    				else {
    					if (s > Ct[mx]) {
    						mx = i1;
    						sw1 = 0;
    					}
    					else {
    						if (s == Ct[mx]) {
    							sw1 = 1;
    							if (cor >= 0 && mx == cor)
    								mx = i1;
    						}
    					}
    				}
    			}
    					// 正しい分類
    			if (sw1 == 0 && cor == mx) {
    				run++;
    				if (run > run_p) {
    					num = Bunrui();
    					if (num > *num_p) {
    						*num_p = num;
    						run_p  = run;
    						for (i1 = 0; i1 < o; i1++) {
    							for (i2 = 0; i2 <= p; i2++)
    								W_p[i1][i2] = W[i1][i2];
    						}
    						if (num == n)
    							sw = count;
    					}
    				}
    			}
    					// 誤った分類
    			else {
    				run  = 0;
    				for (i1 = 0; i1 <= p; i1++) {
    					W[cor][i1] += E[k][i1];
    					W[mx][i1]  -= E[k][i1];
    				}
    			}
    		}
    	}
    
    	return sw;
    }
    
    /****************/
    /* main program */
    /****************/
    int main(int argc, char *argv[])
    {
    	long max, n, o, p;
    	unsigned long seed = (unsigned)time(NULL);
    	char name[100];
    	FILE *st;
    
    	if (argc > 1) {
    					// 基本データの入力
    		st = fopen(argv[1], "r");
    		fscanf(st, "%*s %ld %*s %ld %*s %ld %*s %ld",
                   &max, &p, &o, &n);
    		fscanf(st, "%*s %s", name);
    		fclose(st);
    					// ネットワークの定義と学習データ等の設定
    		Winner net(max, n, o, p, seed);
    		net.Input(name);
    					// 学習と結果の出力
    		if (argc == 2)
    			net.Learn(0);
    		else
    			net.Learn(1, argv[2]);
    	}
    
    	else {
    		printf("***error   入力データファイル名を指定して下さい\n");
    		exit(1);
    	}
    
    	return 0;
    }
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ------------------------or.dat--------------------
    OR演算の訓練例.最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    
    //---------------------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

    /****************************/
    /* Winner-Take-All Groups   */
    /*      coded by Y.Suganuma */
    /****************************/
    import java.io.*;
    import java.util.Random;
    import java.util.StringTokenizer;
    
    public class Test {
    	/****************/
    	/* main program */
    	/****************/
    	public static void main(String args[]) throws IOException, FileNotFoundException
    	{
    		int max, n, o, p;
    		StringTokenizer str;
    		String name;
    
    		if (args.length > 0) {
    					// 基本データの入力
    			BufferedReader in = new BufferedReader(new FileReader(args[0]));
    
    			str = new StringTokenizer(in.readLine(), " ");
    			str.nextToken();
    			max = Integer.parseInt(str.nextToken());
    			str.nextToken();
    			p = Integer.parseInt(str.nextToken());
    			str.nextToken();
    			o = Integer.parseInt(str.nextToken());
    			str.nextToken();
    			n = Integer.parseInt(str.nextToken());
    
    			str = new StringTokenizer(in.readLine(), " ");
    			str.nextToken();
    			name = str.nextToken();
    
    			in.close();
    					// ネットワークの定義
    			Winner net = new Winner (max, n, o, p);
    			net.input(name);
    					// 学習と結果の出力
    			if (args.length == 1)
    				net.learn(0, "");
    			else
    				net.learn(1, args[1]);
    		}
    					// エラー
    		else {
    			System.out.print("***error   入力データファイル名を指定して下さい\n");
    			System.exit(1);
    		}
    	}
    }
    
    /**********************/
    /* Winnerクラスの定義 */
    /**********************/
    class Winner {
    
    	private int max;   // 最大学習回数
    	private int n;   // 訓練例の数
    	private int o;   // 出力セルの数
    	private int p;   // 入力セルの数
    	private int W_p[][];   // 重み(ポケット)
    	private int W[][];   // 重み
    	private int E[][];   // 訓練例
    	private int C[][];   // 各訓練例に対する正しい出力
    	private int Ct[];   // 作業領域
    	private Random rn;   // 乱数
    
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	Winner (int max_i, int n_i, int o_i, int p_i)
    	{
    	/*
    	     設定
    	*/
    		max = max_i;
    		n   = n_i;
    		o   = o_i;
    		p   = p_i;
    
    		rn  = new Random();   // 乱数の初期設定
    	/*
    	     領域の確保
    	*/
    		E   = new int [n][p+1];
    		W_p = new int [o][p+1];
    		W   = new int [o][p+1];
    		C   = new int [n][o];
    		Ct  = new int [o];
    	}
    
    	/******************************************/
    	/* 訓練例の分類                           */
    	/*      return : 正しく分類した訓練例の数 */
    	/******************************************/
    	int bunrui()
    	{
    		int cor, i1, i2, i3, mx = 0, mx_v = 0, num = 0, s, sw = 0;
    
    		for (i1 = 0; i1 < n; i1++) {
    			cor = 0;
    			for (i2 = 0; i2 < o; i2++) {
    				if (C[i1][i2] == 1)
    					cor = i2;
    				s = 0;
    				for (i3 = 0; i3 <= p; i3++)
    					s += W[i2][i3] * E[i1][i3];
    				if (i2 == 0) {
    					mx   = 0;
    					mx_v = s;
    				}
    				else {
    					if (s > mx_v) {
    						mx   = i2;
    						mx_v = s;
    						sw   = 0;
    					}
    					else {
    						if (s == mx_v)
    							sw = 1;
    					}
    				}
    			}
    
    			if (sw == 0 && cor == mx)
    				num++;
    		}
    
    		return num;
    	}
    
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      name : ファイル名 */
    	/**************************/
    	void input (String name) throws IOException, FileNotFoundException
    	{
    		int i1, i2;
    		StringTokenizer str;
    
    		BufferedReader st = new BufferedReader(new FileReader(name));
    
    		str = new StringTokenizer(st.readLine(), " ");
    
    		for (i1 = 0; i1 < n; i1++) {
    			E[i1][0] = 1;
    			str = new StringTokenizer(st.readLine(), " ");
    			for (i2 = 1; i2 <= p; i2++)
    				E[i1][i2] = Integer.parseInt(str.nextToken());
    			for (i2 = 0; i2 < o; i2++)
    				C[i1][i2] = Integer.parseInt(str.nextToken());
    		}
    
    		st.close();
    	}
    
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	void learn(int pr, String name) throws FileNotFoundException
    	{
    		int i1, i2, i3, mx = 0, mx_v = 0, n_tri, s, sw;
    		int num[] = new int [1];
    					// 学習
    		n_tri = pocket(num);
    					// 結果の出力
    		if (pr == 0) {
    
    			System.out.print("重み\n");
    			for (i1 = 0; i1 < o; i1++) {
    				for (i2 = 0; i2 <= p; i2++)
    					System.out.print("  " + W_p[i1][i2]);
    				System.out.println();
    			}
    
    			System.out.print("分類結果\n");
    			for (i1 = 0; i1 < n; i1++) {
    				sw = 0;
    				for (i2 = 0; i2 < o; i2++) {
    					s = 0;
    					for (i3 = 0; i3 <= p; i3++)
    						s += W_p[i2][i3] * E[i1][i3];
    					if (i2 == 0) {
    						mx_v = s;
    						mx   = 0;
    					}
    					else {
    						if (s > mx_v) {
    							sw   = 0;
    							mx_v = s;
    							mx   = i2;
    						}
    						else {
    							if (s == mx_v)
    								sw = 1;
    						}
    					}
    				}
    				for (i2 = 1; i2 <= p; i2++)
    					System.out.print(" " + E[i1][i2]);
    				System.out.print(" Cor ");
    				for (i2 = 0; i2 < o; i2++)
    					System.out.print(" " + C[i1][i2]);
    				if (sw > 0)
    					mx = -1;
    				System.out.println(" Res " + (mx+1));
    			}
    		}
    
    		else {
    
    			PrintStream out = new PrintStream(new FileOutputStream(name));
    
    			out.print("重み\n");
    			for (i1 = 0; i1 < o; i1++) {
    				for (i2 = 0; i2 <= p; i2++)
    					out.print("  " + W_p[i1][i2]);
    				out.println();
    			}
    
    			out.print("分類結果\n");
    			for (i1 = 0; i1 < n; i1++) {
    				sw = 0;
    				for (i2 = 0; i2 < o; i2++) {
    					s = 0;
    					for (i3 = 0; i3 <= p; i3++)
    						s += W_p[i2][i3] * E[i1][i3];
    					if (i2 == 0) {
    						mx_v = s;
    						mx   = 0;
    					}
    					else {
    						if (s > mx_v) {
    							sw   = 0;
    							mx_v = s;
    							mx   = i2;
    						}
    						else {
    							if (s == mx_v)
    								sw = 1;
    						}
    					}
    				}
    				for (i2 = 1; i2 <= p; i2++)
    					out.print(" " + E[i1][i2]);
    				out.print(" Cor ");
    				for (i2 = 0; i2 < o; i2++)
    					out.print(" " + C[i1][i2]);
    				if (sw > 0)
    					mx = -1;
    				out.println(" Res " + (mx+1));
    			}
    
    			out.close();
    		}
    
    		if (n == num[0])
    			System.out.print("  !!すべてを分類(試行回数:" + n_tri + ")\n");
    		else
    			System.out.print("  !!" + num[0] + " 個を分類\n");
    	}
    
    	/********************************************/
    	/* Pocket Algorith with Ratcet              */
    	/*      num_p : 正しく分類した訓練例の数    */
    	/*      return : =0 : 最大学習回数          */
    	/*               >0  : すべてを分類(回数) */
    	/********************************************/
    	int pocket(int num_p[])
    	{
    		int cor, count = 0, i1, i2, k, mx = 0, num, run = 0, run_p = 0, s, sw = -1, sw1;
    	/*
    	     初期設定
    	*/
    		num_p[0] = 0;
    
    		for (i1 = 0; i1 < o; i1++) {
    			for (i2 = 0; i2 <= p; i2++)
    				W[i1][i2] = 0;
    		}
    	/*
    	     実行
    	*/
    		while (sw < 0) {
    					// 終了チェック
    			count++;;
    			if (count > max)
    				sw = 0;
    
    			else {
    					// 訓練例の選択
    				k = (int)(rn.nextDouble() * n);
    				if (k >= n)
    					k = n - 1;
    					// 出力の計算
    				sw1 = 0;
    				cor = -1;
    
    				for (i1 = 0; i1 < o; i1++) {
    
    					if (C[k][i1] == 1)
    						cor = i1;
    
    					s = 0;
    					for (i2 = 0; i2 <= p; i2++)
    						s += W[i1][i2] * E[k][i2];
    					Ct[i1] = s;
    
    					if (i1 == 0)
    						mx = 0;
    					else {
    						if (s > Ct[mx]) {
    							mx = i1;
    							sw1 = 0;
    						}
    						else {
    							if (s == Ct[mx]) {
    								sw1 = 1;
    								if (cor >= 0 && mx == cor)
    									mx = i1;
    							}
    						}
    					}
    				}
    					// 正しい分類
    				if (sw1 == 0 && cor == mx) {
    					run++;
    					if (run > run_p) {
    						num = bunrui();
    						if (num > num_p[0]) {
    							num_p[0] = num;
    							run_p    = run;
    							for (i1 = 0; i1 < o; i1++) {
    								for (i2 = 0; i2 <= p; i2++)
    									W_p[i1][i2] = W[i1][i2];
    							}
    							if (num == n)
    								sw = count;
    						}
    					}
    				}
    					// 誤った分類
    				else {
    					run  = 0;
    					for (i1 = 0; i1 <= p; i1++) {
    						W[cor][i1] += E[k][i1];
    						W[mx][i1]  -= E[k][i1];
    					}
    				}
    			}
    		}
    
    		return sw;
    	}
    }
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ------------------------or.dat--------------------
    OR演算の訓練例.最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    */
    			

  3. JavaScript

      ここをクリックして表示された画面においてデータを設定し,「実行」ボタンをクリックすれば画面上で実行可能です.

    <!DOCTYPE HTML>
    
    <HTML>
    
    <HEAD>
    
    	<TITLE>Winner-Take-All Groups</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<SCRIPT TYPE="text/javascript">
    		res = "";
    		net = null;
    		/****************/
    		/* main program */
    		/****************/
    		function main()
    		{
    					// 基本データの入力
    			let max = parseInt(document.getElementById("max").value);
    			let p   = parseInt(document.getElementById("p").value);
    			let o   = parseInt(document.getElementById("o").value);
    			let n   = parseInt(document.getElementById("n").value);
    					// ネットワークの定義
    			net = new Winner (max, n, o, p);
    			net.input();
    					// 学習と結果の出力
    			net.learn();
    			document.getElementById("result").value = res;
    		}
    
    		/**********************/
    		/* Winnerオブジェクト */
    		/**********************/
    		function Winner(max_i, n_i, o_i, p_i)
    		{
    				//
    				// 設定
    				//
    			this.max = max_i;
    			this.n   = n_i;
    			this.o   = o_i;
    			this.p   = p_i;
    				//
    				// 領域の確保
    				//
    			this.E   = new Array(this.n);
    			this.W_p = new Array(this.o);
    			this.W   = new Array(this.o);
    			this.C   = new Array(this.n);
    			for (let i1 = 0; i1 < this.n; i1++) {
    				this.E[i1] = new Array(this.p+1);
    				this.C[i1] = new Array(this.o);
    			}
    			for (let i1 = 0; i1 < this.o; i1++) {
    				this.W_p[i1] = new Array(this.p+1);
    				this.W[i1]   = new Array(this.p+1);
    			}
    			this.Ct  = new Array(this.o);
    		}
    
    		/******************************************/
    		/* 訓練例の分類                           */
    		/*      return : 正しく分類した訓練例の数 */
    		/******************************************/
    		Winner.prototype.bunrui = function()
    		{
    			let mx = 0, mx_v = 0, num = 0, sw = 0;
    		
    			for (let i1 = 0; i1 < net.n; i1++) {
    				let cor = 0;
    				for (let i2 = 0; i2 < net.o; i2++) {
    					if (net.C[i1][i2] == 1)
    						cor = i2;
    					let s = 0;
    					for (let i3 = 0; i3 <= net.p; i3++)
    						s += net.W[i2][i3] * net.E[i1][i3];
    					if (i2 == 0) {
    						mx   = 0;
    						mx_v = s;
    					}
    					else {
    						if (s > mx_v) {
    							mx   = i2;
    							mx_v = s;
    							sw   = 0;
    						}
    						else {
    							if (s == mx_v)
    								sw = 1;
    						}
    					}
    				}
    		
    				if (sw == 0 && cor == mx)
    					num++;
    			}
    		
    			return num;
    		}
    
    		/************************/
    		/* 学習データの読み込み */
    		/************************/
    		Winner.prototype.input = function()
    		{
    			let lines = (document.getElementById("data").value).split('\n');
    
    			for (let i1 = 0; i1 < net.n; i1++) {
    				let str      = lines[1+i1].split(' ').filter(function(e){return e.length > 0;});
    				net.E[i1][0] = 1;
    				for (let i2 = 1; i2 <= net.p; i2++)
    					net.E[i1][i2] = parseInt(str[i2-1]);
    				for (let i2 = 0; i2 < net.o; i2++)
    					net.C[i1][i2] = parseInt(str[net.p+i2]);
    			}
    		}
    
    		/*********************************/
    		/* 学習と結果の出力              */
    		/*********************************/
    		Winner.prototype.learn = function()
    		{
    						// 学習
    			let num   = new Array(1);
    			let n_tri = net.pocket(num);
    						// 結果の出力
    			res += ("重み\n");
    			for (let i1 = 0; i1 < net.o; i1++) {
    				for (let i2 = 0; i2 <= net.p; i2++)
    					res += ("  " + net.W_p[i1][i2]);
    				res += "\n";
    			}
    		
    			res += ("分類結果\n");
    			let mx   = 0;
    			let mx_v = 0;
    			for (let i1 = 0; i1 < net.n; i1++) {
    				let sw = 0;
    				for (let i2 = 0; i2 < net.o; i2++) {
    					let s = 0;
    					for (let i3 = 0; i3 <= net.p; i3++)
    						s += net.W_p[i2][i3] * net.E[i1][i3];
    					if (i2 == 0) {
    						mx_v = s;
    						mx   = 0;
    					}
    					else {
    						if (s > mx_v) {
    							sw   = 0;
    							mx_v = s;
    							mx   = i2;
    						}
    						else {
    							if (s == mx_v)
    								sw = 1;
    						}
    					}
    				}
    				for (let i2 = 1; i2 <= net.p; i2++)
    					res += (" " + net.E[i1][i2]);
    				res += " Cor ";
    				for (let i2 = 0; i2 < net.o; i2++)
    					res += (" " + net.C[i1][i2]);
    				if (sw > 0)
    					mx = -1;
    				res += (" Res " + (mx+1) + "\n");
    			}
    		
    			if (net.n == num[0])
    				res += ("  !!すべてを分類(試行回数:" + n_tri + ")\n");
    			else
    				res += ("  !!" + num[0] + " 個を分類\n");
    		}
    		
    		/********************************************/
    		/* Pocket Algorith with Ratcet              */
    		/*      num_p : 正しく分類した訓練例の数    */
    		/*      return : =0 : 最大学習回数          */
    		/*               >0  : すべてを分類(回数) */
    		/********************************************/
    		Winner.prototype.pocket = function(num_p)
    		{
    					//
    					// 初期設定
    					//
    			num_p[0]  = 0;
    			let count = 0, mx = 0, run = 0, run_p = 0, sw = -1;
    		
    			for (let i1 = 0; i1 < net.o; i1++) {
    				for (let i2 = 0; i2 <= net.p; i2++)
    					net.W[i1][i2] = 0;
    			}
    					//
    					// 実行
    					//
    			while (sw < 0) {
    						// 終了チェック
    				count++;;
    				if (count > net.max)
    					sw = 0;
    		
    				else {
    						// 訓練例の選択
    					let k = Math.floor(Math.random() * net.n);
    					if (k >= net.n)
    						k = net.n - 1;
    						// 出力の計算
    					let sw1 = 0;
    					let cor = -1;
    		
    					for (let i1 = 0; i1 < net.o; i1++) {
    		
    						if (net.C[k][i1] == 1)
    							cor = i1;
    		
    						let s = 0;
    						for (let i2 = 0; i2 <= net.p; i2++)
    							s += net.W[i1][i2] * net.E[k][i2];
    						net.Ct[i1] = s;
    		
    						if (i1 == 0)
    							mx = 0;
    						else {
    							if (s > net.Ct[mx]) {
    								mx = i1;
    								sw1 = 0;
    							}
    							else {
    								if (s == net.Ct[mx]) {
    									sw1 = 1;
    									if (cor >= 0 && mx == cor)
    										mx = i1;
    								}
    							}
    						}
    					}
    						// 正しい分類
    					if (sw1 == 0 && cor == mx) {
    						run++;
    						if (run > run_p) {
    							let num = net.bunrui();
    							if (num > num_p[0]) {
    								num_p[0] = num;
    								run_p    = run;
    								for (let i1 = 0; i1 < net.o; i1++) {
    									for (let i2 = 0; i2 <= net.p; i2++)
    										net.W_p[i1][i2] = net.W[i1][i2];
    								}
    								if (num == net.n)
    									sw = count;
    							}
    						}
    					}
    						// 誤った分類
    					else {
    						run  = 0;
    						for (let i1 = 0; i1 <= net.p; i1++) {
    							net.W[cor][i1] += net.E[k][i1];
    							net.W[mx][i1]  -= net.E[k][i1];
    						}
    					}
    				}
    			}
    		
    			return sw;
    		}
    	</SCRIPT>
    
    </HEAD>
    
    <BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;">
    
    	<H2><B>Winner-Take-All Groups</B></H2>
    
    	最大試行回数:<INPUT ID="max" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="100"> 
    	入力セル数:<INPUT ID="p" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="2"> 
    	出力セル数:<INPUT ID="o" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="2"> 
    	訓練例数:<INPUT ID="n" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="4"> 
    	<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="data" COLS="35" ROWS="10" STYLE="font-size: 100%; width: 380px">
    OR演算の訓練例.各行の最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    			</TEXTAREA>
    		</DIV>
    	</DIV>
    </BODY>
    
    </HTML>
    			

  4. PHP

    <?php
    
    /****************************/
    /* Winner-Take-All Groups   */
    /*      coded by Y.Suganuma */
    /****************************/
    
    /**********************/
    /* Winnerクラスの定義 */
    /**********************/
    class Winner {
    	private $max;   // 最大学習回数
    	private $n;   // 訓練例の数
    	private $o;   // 出力セルの数
    	private $p;   // 入力セルの数
    	private $W_p;   // 重み(ポケット)
    	private $W;   // 重み
    	private $E;   // 訓練例
    	private $C;   // 各訓練例に対する正しい出力
    	private $Ct;   // 作業領域
    	
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	function Winner($max_i, $n_i, $o_i, $p_i)
    	{
    	/*
    	     設定
    	*/
    		$this->max = $max_i;
    		$this->n   = $n_i;
    		$this->o   = $o_i;
    		$this->p   = $p_i;
    	
    		mt_srand();
    	/*
    	     領域の確保
    	*/
    		$this->E = array($this->n);
    		$this->C = array($this->n);
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$this->E[$i1] = array($this->p+1);
    			$this->C[$i1] = array($this->o);
    		}
    	
    		$this->W_p = array($this->o);
    		$this->W   = array($this->o);
    		for ($i1 = 0; $i1 < $this->o; $i1++) {
    			$this->W_p[$i1] = array($this->p+1);
    			$this->W[$i1]   = array($this->p+1);
    		}
    	
    		$this->Ct = array($this->o);
    	}
    	
    	/******************************************/
    	/* 訓練例の分類                           */
    	/*      return : 正しく分類した訓練例の数 */
    	/******************************************/
    	function Bunrui()
    	{
    		$mx   = 0;
    		$mx_v = 0;
    		$num  = 0;
    		$sw   = 0;
    	
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$cor = 0;
    			for ($i2 = 0; $i2 < $this->o; $i2++) {
    				if ($this->C[$i1][$i2] == 1)
    					$cor = $i2;
    				$s = 0;
    				for ($i3 = 0; $i3 <= $this->p; $i3++)
    					$s += $this->W[$i2][$i3] * $this->E[$i1][$i3];
    				if ($i2 == 0) {
    					$mx   = 0;
    					$mx_v = $s;
    				}
    				else {
    					if ($s > $mx_v) {
    						$mx   = $i2;
    						$mx_v = $s;
    						$sw   = 0;
    					}
    					else {
    						if ($s == $mx_v)
    							$sw = 1;
    					}
    				}
    			}
    	
    			if ($sw == 0 && $cor == $mx)
    				$num++;
    		}
    	
    		return $num;
    	}
    	
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      name : ファイル名 */
    	/**************************/
    	function Input($name)
    	{
    		$st = fopen($name, "rb");
    	
    		fgets($st);
    	
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$this->E[$i1][0] = 1;
    			$str             = trim(fgets($st));
    			$this->E[$i1][1] = intval(strtok($str, " "));
    			for ($i2 = 2; $i2 <= $this->p; $i2++)
    				$this->E[$i1][$i2] = intval(strtok(" "));
    			for ($i2 = 0; $i2 < $this->o; $i2++)
    				$this->C[$i1][$i2] = intval(strtok(" "));
    		}
    	
    		fclose($st);
    	}
    	
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	function Learn($pr, $name = "STDOUT")
    	{
    		$mx   = 0;
    		$mx_v = 0;
    	
    		$n_tri = $this->Pocket($num);
    	
    		if ($pr == 0)
    			$out = STDOUT;
    		else
    			$out = fopen($name, "w");
    	
    		fwrite($out, "重み\n");
    		for ($i1 = 0; $i1 < $this->o; $i1++) {
    			$str = "";
    			for ($i2 = 0; $i2 <= $this->p; $i2++)
    				$str = $str." ".$this->W_p[$i1][$i2];
    			fwrite($out, $str."\n");
    		}
    	
    		fwrite($out, "分類結果\n");
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$sw = 0;
    			for ($i2 = 0; $i2 < $this->o; $i2++) {
    				$s = 0;
    				for ($i3 = 0; $i3 <= $this->p; $i3++)
    					$s += $this->W_p[$i2][$i3] * $this->E[$i1][$i3];
    				if ($i2 == 0) {
    					$mx_v = $s;
    					$mx   = 0;
    				}
    				else {
    					if ($s > $mx_v) {
    						$sw   = 0;
    						$mx_v = $s;
    						$mx   = $i2;
    					}
    					else {
    						if ($s == $mx_v)
    							$sw = 1;
    					}
    				}
    			}
    			$str = "";
    			for ($i2 = 1; $i2 <= $this->p; $i2++)
    				$str = $str." ".$this->E[$i1][$i2];
    			$str = $str." Cor ";
    			for ($i2 = 0; $i2 < $this->o; $i2++)
    				$str = $str." ".$this->C[$i1][$i2];
    			if ($sw > 0)
    				$mx = -1;
    			$str = $str." Res ".($mx+1);
    			fwrite($out, $str."\n");
    		}
    	
    		if ($this->n == $num)
    			printf("  !!すべてを分類(試行回数:%ld)\n", $n_tri);
    		else
    			printf("  !!%ld 個を分類\n", $num);
    	}
    	
    	/********************************************/
    	/* Pocket Algorith with Ratcet              */
    	/*      num_p : 正しく分類した訓練例の数    */
    	/*      return : =0 : 最大学習回数          */
    	/*               >0  : すべてを分類(回数) */
    	/********************************************/
    	function Pocket(&$num_p)
    	{
    	/*
    	     初期設定
    	*/
    		$count = 0;
    		$mx    = 0;
    		$run   = 0;
    		$run_p = 0;
    		$sw    = -1;
    		$num_p = 0;
    	
    		for ($i1 = 0; $i1 < $this->o; $i1++) {
    			for ($i2 = 0; $i2 <= $this->p; $i2++)
    				$this->W[$i1][$i2] = 0;
    		}
    	/*
    	     実行
    	*/
    		while ($sw < 0) {
    						// 終了チェック
    			$count++;;
    			if ($count > $this->max)
    				$sw = 0;
    	
    			else {
    						// 訓練例の選択
    				$k = intval(mt_rand() / mt_getrandmax() * $this->n);
    				if ($k >= $this->n)
    					$k = $this->n - 1;
    						// 出力の計算
    				$sw1 = 0;
    				$cor = -1;
    	
    				for ($i1 = 0; $i1 < $this->o; $i1++) {
    	
    					if ($this->C[$k][$i1] == 1)
    						$cor = $i1;
    	
    					$s = 0;
    					for ($i2 = 0; $i2 <= $this->p; $i2++)
    						$s += $this->W[$i1][$i2] * $this->E[$k][$i2];
    					$this->Ct[$i1] = $s;
    	
    					if ($i1 == 0)
    						$mx = 0;
    					else {
    						if ($s > $this->Ct[$mx]) {
    							$mx = $i1;
    							$sw1 = 0;
    						}
    						else {
    							if ($s == $this->Ct[$mx]) {
    								$sw1 = 1;
    								if ($cor >= 0 && $mx == $cor)
    									$mx = $i1;
    							}
    						}
    					}
    				}
    						// 正しい分類
    				if ($sw1 == 0 && $cor == $mx) {
    					$run++;
    					if ($run > $run_p) {
    						$num = $this->Bunrui();
    						if ($num > $num_p) {
    							$num_p = $num;
    							$run_p = $run;
    							for ($i1 = 0; $i1 < $this->o; $i1++) {
    								for ($i2 = 0; $i2 <= $this->p; $i2++)
    									$this->W_p[$i1][$i2] = $this->W[$i1][$i2];
    							}
    							if ($num == $this->n)
    								$sw = $count;
    						}
    					}
    				}
    						// 誤った分類
    				else {
    					$run  = 0;
    					for ($i1 = 0; $i1 <= $this->p; $i1++) {
    						$this->W[$cor][$i1] += $this->E[$k][$i1];
    						$this->W[$mx][$i1]  -= $this->E[$k][$i1];
    					}
    				}
    			}
    		}
    	
    		return $sw;
    	}
    }
    
    /****************/
    /* main program */
    /****************/
    
    	if (count($argv) > 1) {
    					// 基本データの入力
    		$st = fopen($argv[1], "rb");
    		fscanf($st, "%*s %ld %*s %ld %*s %ld %*s %ld",$max, $p, $o, $n);
    		fscanf($st, "%*s %s", $name);
    		fclose($st);
    					// ネットワークの定義と学習データ等の設定
    		$net = new Winner($max, $n, $o, $p);
    		$net->Input($name);
    					// 学習と結果の出力
    		if (count($argv) == 2)
    			$net->Learn(0);
    		else
    			$net->Learn(1, $argv[2]);
    	}
    
    	else
    		exit("***error   入力データファイル名を指定して下さい\n");
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ------------------------or.dat--------------------
    OR演算の訓練例.最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    */
    
    ?>
    			

  5. Ruby

    ####################################
    # Winner-Take-All Groups
    #      coded by Y.Suganuma
    ####################################
    
    #############################
    # Winnerクラスの定義
    #      coded by Y.Suganuma
    #############################
    
    class Winner
    
    	#########################
    	# コンストラクタ
    	#      max : 最大学習回数
    	#      n : 訓練例の数
    	#      o : 出力セルの数
    	#      p : 入力セルの数
    	#########################
    	def initialize(max_i, n_i, o_i, p_i)
    			# 設定
    		@_max = max_i
    		@_n   = n_i
    		@_o   = o_i
    		@_p   = p_i
    			# 領域の確保
    		@_e = Array.new(@_n)   # 訓練例
    		@_c = Array.new(@_n)   # 各訓練例に対する正しい出力
    		for i1 in 0 ... @_n
    			@_e[i1] = Array.new(@_p+1)
    			@_c[i1] = Array.new(@_o)
    		end
    		@_w_p = Array.new(@_o)   # 重み(ポケット)
    		@_w   = Array.new(@_o)   # 重み
    		for i1 in 0 ... @_o
    			@_w_p[i1] = Array.new(@_p+1)
    			@_w[i1]   = Array.new(@_p+1)
    		end
    		@_ct  = Array.new(@_o)   # 作業領域
    	end
    	
    	#########################################
    	# 訓練例の分類
    	#      return : 正しく分類した訓練例の数
    	#########################################
    	def Bunrui()
    	
    		mx   = 0
    		mx_v = 0
    		num  = 0
    		sw   = 0
    	
    		for i1 in 0 ... @_n
    			cor = 0
    			for i2 in 0 ... @_o
    				if @_c[i1][i2] == 1
    					cor = i2
    				end
    				s = 0
    				for i3 in 0 ... @_p+1
    					s += @_w[i2][i3] * @_e[i1][i3]
    				end
    				if i2 == 0
    					mx   = 0
    					mx_v = s
    				else
    					if s > mx_v
    						mx   = i2
    						mx_v = s
    						sw   = 0
    					else
    						if s == mx_v
    							sw = 1
    						end
    					end
    				end
    			end
    	
    			if sw == 0 and cor == mx
    				num += 1
    			end
    		end
    	
    		return num
    	end
    	
    	#*************************/
    	# 学習データの読み込み   */
    	#      name : ファイル名 */
    	#*************************/
    	
    	def Input(name)
    	
    		f = open(name, "r")
    		f.gets()
    	
    		for i1 in 0 ... @_n
    			@_e[i1][0] = 1
    			s          = f.gets().split(" ")
    			for i2 in 1 ... @_p+1
    				@_e[i1][i2] = Integer(s[i2-1])
    			end
    			for i2 in 0 ... @_o
    				@_c[i1][i2] = Integer(s[@_p+i2])
    			end
    		end
    	
    		f.close()
    	end
    	
    	#################################
    	# 学習と結果の出力
    	#      pr : =0 : 画面に出力
    	#           =1 : ファイルに出力
    	#      name : 出力ファイル名
    	#################################
    
    	def Learn(pr, name="")
    
    		mx    = 0
    		mx_v  = 0
    	
    		num   = Array.new(1)
    		n_tri = Pocket(num)
    	
    		if pr == 0
    			out = $stdout
    		else
    			out = open(name, "w")
    		end
    	
    		out.print("重み\n")
    		for i1 in 0 ... @_o
    			for i2 in 0 ... @_p+1
    				out.print(" " + String(@_w_p[i1][i2]))
    			end
    			out.print("\n")
    		end
    	
    		out.print("分類結果\n")
    		for i1 in 0 ... @_n
    			sw = 0
    			for i2 in 0 ... @_o
    				s = 0
    				for i3 in 0 ... @_p+1
    					s += @_w_p[i2][i3] * @_e[i1][i3]
    				end
    				if i2 == 0
    					mx_v = s
    					mx   = 0
    				else
    					if s > mx_v
    						sw   = 0
    						mx_v = s
    						mx   = i2
    					else
    						if s == mx_v
    							sw = 1
    						end
    					end
    				end
    			end
    			for i2 in 1 ... @_p+1
    				out.print(" " + String(@_e[i1][i2]))
    			end
    			out.print(" Cor ")
    			for i2 in 0 ... @_o
    				out.print(" " + String(@_c[i1][i2]))
    			end
    			if sw > 0
    				mx = -1
    			end
    			out.print(" Res " + String(mx+1) + "\n")
    		end
    	
    		if @_n == num[0]
    			print("  !!すべてを分類(試行回数:" + String(n_tri) + ")\n")
    		else
    			print("  !!" + String(num[0]) + " 個を分類\n")
    		end
    	end
    	
    	############################################
    	# Pocket Algorith with Ratcet
    	#      num_p : 正しく分類した訓練例の数
    	#      return : =0 : 最大学習回数
    	#               >0  : すべてを分類(回数)
    	############################################
    	def Pocket(num_p)
    			# 初期設定
    		count    = 0
    		mx       = 0
    		run      = 0
    		run_p    = 0
    		sw       = -1
    		num_p[0] = 0
    	
    		for i1 in 0 ... @_o
    			for i2 in 0 ... @_p+1
    				@_w[i1][i2] = 0
    			end
    		end
    			# 実行
    		while sw < 0
    					# 終了チェック
    			count += 1
    			if count > @_max
    				sw = 0
    	
    			else
    					# 訓練例の選択
    				k = Integer(rand(0) * @_n)
    				if k >= @_n
    					k = @_n - 1
    				end
    					# 出力の計算
    				sw1 = 0
    				cor = -1
    	
    				for i1 in 0 ... @_o
    	
    					if @_c[k][i1] == 1
    						cor = i1
    					end
    	
    					s = 0
    					for i2 in 0 ... @_p+1
    						s += @_w[i1][i2] * @_e[k][i2]
    					end
    					@_ct[i1] = s
    	
    					if i1 == 0
    						mx = 0
    					else
    						if s > @_ct[mx]
    							mx = i1
    							sw1 = 0
    						else
    							if s == @_ct[mx]
    								sw1 = 1
    								if cor >= 0 and mx == cor
    									mx = i1
    								end
    							end
    						end
    					end
    				end
    					# 正しい分類
    				if sw1 == 0 and cor == mx
    					run += 1
    					if run > run_p
    						num = Bunrui()
    						if num > num_p[0]
    							num_p[0] = num
    							run_p    = run
    							for i1 in 0 ... @_o
    								for i2 in 0 ... @_p+1
    									@_w_p[i1][i2] = @_w[i1][i2]
    								end
    							end
    							if num == @_n
    								sw = count
    							end
    						end
    					end
    					# 誤った分類
    				else
    					run  = 0
    					for i1 in 0 ... @_p+1
    						@_w[cor][i1] += @_e[k][i1]
    						@_w[mx][i1]  -= @_e[k][i1]
    					end
    				end
    			end
    		end
    	
    		return sw
    	end
    end
    
    if ARGV[0] != nil
    				# 基本データの入力
    	s    = gets().split(" ")
    	max  = Integer(s[1])
    	p    = Integer(s[3])
    	o    = Integer(s[5])
    	n    = Integer(s[7])
    	s    = gets().split(" ")
    	name = s[1]
    				# ネットワークの定義
    	srand()
    	net = Winner.new(max, n, o, p)
    	net.Input(name)
    				# 学習と結果の出力
    	if ARGV[0] == nil
    		net.Learn(0)
    	else
    		net.Learn(1, ARGV[0])
    	end
    
    else
    	print("***error   入力ファイル名を指定して下さい\n")
    end
    
    =begin
    ------------------------入力ファイル--------------
    最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ------------------------or.dat--------------------
    OR演算の訓練例.最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    =end
    			

  6. Python

    # -*- coding: UTF-8 -*-
    import numpy as np
    import sys
    from math import *
    from random import *
    
    #############################
    # Winnerクラスの定義
    #      coded by Y.Suganuma
    #############################
    
    class Winner :
    
    	#########################
    	# コンストラクタ
    	#      max : 最大学習回数
    	#      n : 訓練例の数
    	#      o : 出力セルの数
    	#      p : 入力セルの数
    	#########################
    	def __init__(self, max_i, n_i, o_i, p_i) :
    			# 設定
    		self.max = max_i
    		self.n   = n_i
    		self.o   = o_i
    		self.p   = p_i
    			# 領域の確保
    		self.E   = np.empty((self.n, self.p+1), np.int)   # 訓練例
    		self.C   = np.empty((self.n, self.o), np.int)   # 各訓練例に対する正しい出力
    		self.W_p = np.empty((self.o, self.p+1), np.int)   # 重み(ポケット)
    		self.W   = np.empty((self.o, self.p+1), np.int)   # 重み
    		self.Ct  = np.empty(self.o, np.int)   # 作業領域
    	
    	#########################################
    	# 訓練例の分類
    	#      return : 正しく分類した訓練例の数
    	#########################################
    	def Bunrui(self) :
    	
    		mx   = 0
    		mx_v = 0
    		num  = 0
    		sw   = 0
    	
    		for i1 in range(0, self.n) :
    			cor = 0
    			for i2 in range(0, self.o) :
    				if self.C[i1][i2] == 1 :
    					cor = i2
    				s = 0
    				for i3 in range(0, self.p+1) :
    					s += self.W[i2][i3] * self.E[i1][i3]
    				if i2 == 0 :
    					mx   = 0
    					mx_v = s
    				else :
    					if s > mx_v :
    						mx   = i2
    						mx_v = s
    						sw   = 0
    					else :
    						if s == mx_v :
    							sw = 1
    	
    			if sw == 0 and cor == mx :
    				num += 1
    	
    		return num
    	
    	#*************************/
    	# 学習データの読み込み   */
    	#      name : ファイル名 */
    	#*************************/
    	
    	def Input(self, name) :
    	
    		f = open(name, "r")
    		f.readline()
    	
    		for i1 in range(0, self.n) :
    			self.E[i1][0] = 1
    			s = f.readline().split()
    			for i2 in range(1, self.p+1) :
    				self.E[i1][i2] = int(s[i2-1])
    			for i2 in range(0, self.o) :
    				self.C[i1][i2] = int(s[self.p+i2])
    	
    		f.close()
    	
    	#################################
    	# 学習と結果の出力
    	#      pr : =0 : 画面に出力
    	#           =1 : ファイルに出力
    	#      name : 出力ファイル名
    	#################################
    
    	def Learn(self, pr, name="") :
    
    		mx   = 0
    		mx_v = 0
    	
    		num   = np.empty(1, np.int)
    		n_tri = self.Pocket(num)
    	
    		if pr == 0 :
    			out = sys.stdout
    		else :
    			out = open(name, "w")
    	
    		out.write("重み\n")
    		for i1 in range(0, self.o) :
    			for i2 in range(0, self.p+1) :
    				out.write(" " + str(self.W_p[i1][i2]))
    			out.write("\n")
    	
    		out.write("分類結果\n")
    		for i1 in range(0, self.n) :
    			sw = 0
    			for i2 in range(0, self.o) :
    				s = 0
    				for i3 in range(0, self.p+1) :
    					s += self.W_p[i2][i3] * self.E[i1][i3]
    				if i2 == 0 :
    					mx_v = s
    					mx   = 0
    				else :
    					if s > mx_v :
    						sw   = 0
    						mx_v = s
    						mx   = i2
    					else :
    						if s == mx_v :
    							sw = 1
    			for i2 in range(1, self.p+1) :
    				out.write(" " + str(self.E[i1][i2]))
    			out.write(" Cor ")
    			for i2 in range(0, self.o) :
    				out.write(" " + str(self.C[i1][i2]))
    			if sw > 0 :
    				mx = -1
    			out.write(" Res " + str(mx+1) + "\n")
    	
    		if self.n == num[0] :
    			print("  !!すべてを分類(試行回数:" + str(n_tri) + ")")
    		else :
    			print("  !!" + str(num[0]) + " 個を分類")
    	
    	############################################
    	# Pocket Algorith with Ratcet
    	#      num_p : 正しく分類した訓練例の数
    	#      return : =0 : 最大学習回数
    	#               >0  : すべてを分類(回数)
    	############################################
    	def Pocket(self, num_p) :
    			# 初期設定
    		count    = 0
    		mx       = 0
    		run      = 0
    		run_p    = 0
    		sw       = -1
    		num_p[0] = 0
    	
    		for i1 in range(0, self.o) :
    			for i2 in range(0, self.p+1) :
    				self.W[i1][i2] = 0
    			# 実行
    		while sw < 0 :
    					# 終了チェック
    			count += 1
    			if count > self.max :
    				sw = 0
    	
    			else :
    					# 訓練例の選択
    				k = int(random() * self.n)
    				if k >= self.n :
    					k = self.n - 1
    					# 出力の計算
    				sw1 = 0
    				cor = -1
    	
    				for i1 in range(0, self.o) :
    	
    					if self.C[k][i1] == 1 :
    						cor = i1
    	
    					s = 0
    					for i2 in range(0, self.p+1) :
    						s += self.W[i1][i2] * self.E[k][i2]
    					self.Ct[i1] = s
    	
    					if i1 == 0 :
    						mx = 0
    					else :
    						if s > self.Ct[mx] :
    							mx = i1
    							sw1 = 0
    						else :
    							if s == self.Ct[mx] :
    								sw1 = 1
    								if cor >= 0 and mx == cor :
    									mx = i1
    					# 正しい分類
    				if sw1 == 0 and cor == mx :
    					run += 1
    					if run > run_p :
    						num = self.Bunrui()
    						if num > num_p[0] :
    							num_p[0] = num
    							run_p    = run
    							for i1 in range(0, self.o) :
    								for i2 in range(0, self.p+1) :
    									self.W_p[i1][i2] = self.W[i1][i2]
    							if num == self.n :
    								sw = count
    					# 誤った分類
    				else :
    					run  = 0
    					for i1 in range(0, self.p+1) :
    						self.W[cor][i1] += self.E[k][i1]
    						self.W[mx][i1]  -= self.E[k][i1]
    	
    		return sw
    
    ####################################
    # Winner-Take-All Groups
    #      coded by Y.Suganuma
    ####################################
    
    if len(sys.argv) > 1 :
    				# 基本データの入力
    	f    = open(sys.argv[1], "r")
    	s    = f.readline().split()
    	max  = int(s[1])
    	p    = int(s[3])
    	o    = int(s[5])
    	n    = int(s[7])
    	s    = f.readline().split()
    	name = s[1]
    	f.close()
    				# ネットワークの定義
    	seed()
    	net = Winner(max, n, o, p)
    	net.Input(name)
    				# 学習と結果の出力
    	if len(sys.argv) == 2 :
    		net.Learn(0)
    	else :
    		net.Learn(1, sys.argv[2])
    
    else :
    	print("***error   入力ファイル名を指定して下さい")
    
    """
    ------------------------入力ファイル--------------
    最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ------------------------or.dat--------------------
    OR演算の訓練例.最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    """
    			

  7. C#

    /****************************/
    /* Winner-Take-All Groups   */
    /*      coded by Y.Suganuma */
    /****************************/
    using System;
    using System.IO;
    
    class Program
    {
    	/****************/
    	/* main program */
    	/****************/
    	static void Main(String[] args)
    	{
    		if (args.Length > 0) {
    			char[] charSep = new char[] {' '};
    					// 基本データの入力
    			String[] lines = File.ReadAllLines(args[0]);
    			String[] str   = lines[0].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			int max        = int.Parse(str[1]);
    			int p          = int.Parse(str[3]);
    			int o          = int.Parse(str[5]);
    			int n          = int.Parse(str[7]);
    
    			str            = lines[1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			String name    = str[1];
    					// ネットワークの定義
    			Winner net = new Winner (max, n, o, p);
    			net.input(name);
    					// 学習と結果の出力
    			if (args.Length == 1)
    				net.learn(0, "");
    			else
    				net.learn(1, args[1]);
    		}
    					// エラー
    		else {
    			Console.WriteLine("***error   入力データファイル名を指定して下さい");
    			Environment.Exit(1);
    		}
    	}
    }
    
    /**********************/
    /* Winnerクラスの定義 */
    /**********************/
    class Winner {
    
    	int max;   // 最大学習回数
    	int n;   // 訓練例の数
    	int o;   // 出力セルの数
    	int p;   // 入力セルの数
    	int[][] W_p;   // 重み(ポケット)
    	int[][] W;   // 重み
    	int[][] E;   // 訓練例
    	int[][] C;   // 各訓練例に対する正しい出力
    	int[] Ct;   // 作業領域
    	Random rn;   // 乱数
    
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	public Winner (int max_i, int n_i, int o_i, int p_i)
    	{
    				//
    				// 設定
    				//
    		max = max_i;
    		n   = n_i;
    		o   = o_i;
    		p   = p_i;
    
    		rn  = new Random();   // 乱数の初期設定
    				//
    				// 領域の確保
    				//
    		E   = new int [n][];
    		W_p = new int [o][];
    		W   = new int [o][];
    		C   = new int [n][];
    		for (int i1 = 0; i1 < n; i1++) {
    			E[i1] = new int [p+1];
    			C[i1] = new int [o];
    		}
    		for (int i1 = 0; i1 < o; i1++) {
    			W_p[i1] = new int [p+1];
    			W[i1]   = new int [p+1];
    		}
    		Ct  = new int [o];
    	}
    
    	/******************************************/
    	/* 訓練例の分類                           */
    	/*      return : 正しく分類した訓練例の数 */
    	/******************************************/
    	int bunrui()
    	{
    		int mx = 0, mx_v = 0, num = 0, sw = 0;
    
    		for (int i1 = 0; i1 < n; i1++) {
    			int cor = 0;
    			for (int i2 = 0; i2 < o; i2++) {
    				if (C[i1][i2] == 1)
    					cor = i2;
    				int s = 0;
    				for (int i3 = 0; i3 <= p; i3++)
    					s += W[i2][i3] * E[i1][i3];
    				if (i2 == 0) {
    					mx   = 0;
    					mx_v = s;
    				}
    				else {
    					if (s > mx_v) {
    						mx   = i2;
    						mx_v = s;
    						sw   = 0;
    					}
    					else {
    						if (s == mx_v)
    							sw = 1;
    					}
    				}
    			}
    
    			if (sw == 0 && cor == mx)
    				num++;
    		}
    
    		return num;
    	}
    
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      name : ファイル名 */
    	/**************************/
    	public void input (String name)
    	{
    		char[] charSep = new char[] {' '};
    		String[] lines = File.ReadAllLines(name);
    
    		for (int i1 = 0; i1 < n; i1++) {
    			String[] str = lines[1+i1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			E[i1][0]     = 1;
    			for (int i2 = 1; i2 <= p; i2++)
    				E[i1][i2] = int.Parse(str[i2-1]);
    			for (int i2 = 0; i2 < o; i2++)
    				C[i1][i2] = int.Parse(str[p+i2]);
    		}
    	}
    
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	public void learn(int pr, String name)
    	{
    					// 学習
    		int num   = 0;
    		int n_tri = pocket(ref num);
    					// 結果の出力
    		if (pr == 0) {
    
    			Console.WriteLine("重み");
    			for (int i1 = 0; i1 < o; i1++) {
    				for (int i2 = 0; i2 <= p; i2++)
    					Console.Write("  " + W_p[i1][i2]);
    				Console.WriteLine();
    			}
    
    			Console.WriteLine("分類結果");
    			int mx   = 0;
    			int mx_v = 0;
    			for (int i1 = 0; i1 < n; i1++) {
    				int sw = 0;
    				for (int i2 = 0; i2 < o; i2++) {
    					int s = 0;
    					for (int i3 = 0; i3 <= p; i3++)
    						s += W_p[i2][i3] * E[i1][i3];
    					if (i2 == 0) {
    						mx_v = s;
    						mx   = 0;
    					}
    					else {
    						if (s > mx_v) {
    							sw   = 0;
    							mx_v = s;
    							mx   = i2;
    						}
    						else {
    							if (s == mx_v)
    								sw = 1;
    						}
    					}
    				}
    				for (int i2 = 1; i2 <= p; i2++)
    					Console.Write(" " + E[i1][i2]);
    				Console.Write(" Cor ");
    				for (int i2 = 0; i2 < o; i2++)
    					Console.Write(" " + C[i1][i2]);
    				if (sw > 0)
    					mx = -1;
    				Console.WriteLine(" Res " + (mx+1));
    			}
    		}
    
    		else {
    
    			StreamWriter OUT = new StreamWriter(name, true);
    
    			OUT.WriteLine("重み");
    			for (int i1 = 0; i1 < o; i1++) {
    				for (int i2 = 0; i2 <= p; i2++)
    					OUT.Write("  " + W_p[i1][i2]);
    				OUT.WriteLine();
    			}
    
    			OUT.WriteLine("分類結果");
    			int mx   = 0;
    			int mx_v = 0;
    			for (int i1 = 0; i1 < n; i1++) {
    				int sw = 0;
    				for (int i2 = 0; i2 < o; i2++) {
    					int s = 0;
    					for (int i3 = 0; i3 <= p; i3++)
    						s += W_p[i2][i3] * E[i1][i3];
    					if (i2 == 0) {
    						mx_v = s;
    						mx   = 0;
    					}
    					else {
    						if (s > mx_v) {
    							sw   = 0;
    							mx_v = s;
    							mx   = i2;
    						}
    						else {
    							if (s == mx_v)
    								sw = 1;
    						}
    					}
    				}
    				for (int i2 = 1; i2 <= p; i2++)
    					OUT.Write(" " + E[i1][i2]);
    				OUT.Write(" Cor ");
    				for (int i2 = 0; i2 < o; i2++)
    					OUT.Write(" " + C[i1][i2]);
    				if (sw > 0)
    					mx = -1;
    				OUT.WriteLine(" Res " + (mx+1));
    			}
    
    			OUT.Close();
    		}
    
    		if (n == num)
    			Console.WriteLine("  !!すべてを分類(試行回数:" + n_tri + ")");
    		else
    			Console.WriteLine("  !!" + num + " 個を分類");
    	}
    
    	/********************************************/
    	/* Pocket Algorith with Ratcet              */
    	/*      num_p : 正しく分類した訓練例の数    */
    	/*      return : =0 : 最大学習回数          */
    	/*               >0  : すべてを分類(回数) */
    	/********************************************/
    	int pocket(ref int num_p)
    	{
    				//
    				// 初期設定
    				//
    		num_p = 0;
    		int count = 0, mx = 0, run = 0, run_p = 0, sw = -1;
    
    		for (int i1 = 0; i1 < o; i1++) {
    			for (int i2 = 0; i2 <= p; i2++)
    				W[i1][i2] = 0;
    		}
    				//
    				// 実行
    				//
    		while (sw < 0) {
    					// 終了チェック
    			count++;;
    			if (count > max)
    				sw = 0;
    
    			else {
    					// 訓練例の選択
    				int k = (int)(rn.NextDouble() * n);
    				if (k >= n)
    					k = n - 1;
    					// 出力の計算
    				int sw1 = 0;
    				int cor = -1;
    
    				for (int i1 = 0; i1 < o; i1++) {
    
    					if (C[k][i1] == 1)
    						cor = i1;
    
    					int s = 0;
    					for (int i2 = 0; i2 <= p; i2++)
    						s += W[i1][i2] * E[k][i2];
    					Ct[i1] = s;
    
    					if (i1 == 0)
    						mx = 0;
    					else {
    						if (s > Ct[mx]) {
    							mx = i1;
    							sw1 = 0;
    						}
    						else {
    							if (s == Ct[mx]) {
    								sw1 = 1;
    								if (cor >= 0 && mx == cor)
    									mx = i1;
    							}
    						}
    					}
    				}
    					// 正しい分類
    				if (sw1 == 0 && cor == mx) {
    					run++;
    					if (run > run_p) {
    						int num = bunrui();
    						if (num > num_p) {
    							num_p = num;
    							run_p = run;
    							for (int i1 = 0; i1 < o; i1++) {
    								for (int i2 = 0; i2 <= p; i2++)
    									W_p[i1][i2] = W[i1][i2];
    							}
    							if (num == n)
    								sw = count;
    						}
    					}
    				}
    					// 誤った分類
    				else {
    					run  = 0;
    					for (int i1 = 0; i1 <= p; i1++) {
    						W[cor][i1] += E[k][i1];
    						W[mx][i1]  -= E[k][i1];
    					}
    				}
    			}
    		}
    
    		return sw;
    	}
    }
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ------------------------or.dat--------------------
    OR演算の訓練例.最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    */
    			

  8. VB

    '**************************'
    ' Winner-Take-All Groups   '
    '      coded by Y.Suganuma '
    '**************************'
    Imports System.IO
    Imports System.Text.RegularExpressions
    
    Module Test
    
    	Sub Main(args() As String)
    
    		If args.Length > 0
    					' 基本データの入力
    			Dim inp As StreamReader = New StreamReader(args(0))
    			Dim MS As Regex         = New Regex("\s+") 
    			Dim str() As String     = MS.Split(inp.ReadLine().Trim())
    			Dim max As Integer      = Integer.Parse(str(1))
    			Dim p As Integer        = Integer.Parse(str(3))
    			Dim o As Integer        = Integer.Parse(str(5))
    			Dim n As Integer        = Integer.Parse(str(7))
    
    			str                = MS.Split(inp.ReadLine().Trim())
    			Dim name As String = str(1)
    			inp.Close()
    					' ネットワークの定義
    			Dim net As Winner = new Winner (max, n, o, p)
    			net.input(name)
    					' 学習と結果の出力
    			If args.Length = 1
    				net.learn(0, "")
    			Else
    				net.learn(1, args(1))
    			End If
    					' エラー
    		Else
    			Console.WriteLine("***error   入力データファイル名を指定して下さい")
    			Environment.Exit(1)
    		End If
    
    	End Sub
    
    	'********************'
    	' Winnerクラスの定義 '
    	'********************'
    	Class Winner
    	
    		Private max As Integer   ' 最大学習回数
    		Private n As Integer   ' 訓練例の数
    		Private o As Integer   ' 出力セルの数
    		Private p As Integer   ' 入力セルの数
    		Private W_p(,) As Integer   ' 重み(ポケット)
    		Private W(,) As Integer   ' 重み
    		Private E(,) As Integer   ' 訓練例
    		Private C(,) As Integer   ' 各訓練例に対する正しい出力
    		Private Ct() As Integer   ' 作業領域
    		Private rn As Random   ' 乱数
    	
    		'****************'
    		' コンストラクタ '
    		'****************'
    		Public Sub New (max_i As Integer, n_i As Integer, o_i As Integer, p_i As Integer)
    					'
    					' 設定
    					'
    			max = max_i
    			n   = n_i
    			o   = o_i
    			p   = p_i
    	
    			rn  = new Random()   ' 乱数の初期設定
    					'
    					' 領域の確保
    					'
    			ReDim E(n,p+1)
    			ReDim W_p(o,p+1)
    			ReDim W(o,p+1)
    			ReDim C(n,o)
    			ReDim Ct(o)
    
    		End Sub
    	
    		'****************************************'
    		' 訓練例の分類                           '
    		'      return : 正しく分類した訓練例の数 '
    		'****************************************'
    		Function bunrui()
    
    			Dim mx As Integer   = 0
    			Dim mx_v As Integer = 0
    			Dim num As Integer  = 0
    			Dim sw As Integer   = 0
    	
    			For i1 As Integer = 0 To n-1
    				Dim cor As Integer = 0
    				For i2 As Integer = 0 To o-1
    					If C(i1,i2) = 1
    						cor = i2
    					End If
    					Dim s As Integer = 0
    					For i3 As Integer = 0 To p
    						s += W(i2,i3) * E(i1,i3)
    					Next
    					If i2 = 0
    						mx   = 0
    						mx_v = s
    					Else
    						If s > mx_v
    							mx   = i2
    							mx_v = s
    							sw   = 0
    						Else
    							If s = mx_v
    								sw = 1
    							End If
    						End If
    					End If
    				Next
    	
    				If sw = 0 and cor = mx
    					num += 1
    				End If
    			Next
    	
    			Return num
    
    		End Function
    	
    		'************************'
    		' 学習データの読み込み   '
    		'      name : ファイル名 '
    		'************************'
    		Public Sub input (name As String)
    
    			Dim inp As StreamReader = New StreamReader(name)
    			Dim MS As Regex         = New Regex("\s+") 
    			inp.ReadLine()
    	
    			For i1 As Integer = 0 To n-1
    				Dim str() As String = MS.Split(inp.ReadLine().Trim())
    				E(i1,0)             = 1
    				For i2 As Integer = 1 To p
    					E(i1,i2) = Integer.Parse(str(i2-1))
    				Next
    				For i2 As Integer = 0 To o-1
    					C(i1,i2) = Integer.Parse(str(p+i2))
    				Next
    			Next
    			inp.Close()
    
    		End Sub
    	
    		'*******************************'
    		' 学習と結果の出力              '
    		'      pr : =0 : 画面に出力     '
    		'           =1 : ファイルに出力 '
    		'      name : 出力ファイル名    '
    		'*******************************'
    		Public Sub learn(pr As Integer, name As String)
    
    						' 学習
    			Dim num As Integer   = 0
    			Dim n_tri As Integer = pocket(num)
    						' 結果の出力
    			If pr = 0
    	
    				Console.WriteLine("重み")
    				For i1 As Integer = 0 To o-1
    					For i2 As Integer = 0 To p
    						Console.Write("  " & W_p(i1,i2))
    					Next
    					Console.WriteLine()
    				Next
    	
    				Console.WriteLine("分類結果")
    				Dim mx As Integer   = 0
    				Dim mx_v As Integer = 0
    				For i1 As Integer = 0 To n-1
    					Dim sw As Integer = 0
    					For i2 As Integer = 0 To o-1
    						Dim s As Integer = 0
    						For i3 As Integer = 0 To p
    							s += W_p(i2,i3) * E(i1,i3)
    						Next
    						If i2 = 0
    							mx_v = s
    							mx   = 0
    						Else
    							If s > mx_v
    								sw   = 0
    								mx_v = s
    								mx   = i2
    							Else
    								If s = mx_v
    									sw = 1
    								End If
    							End If
    						End If
    					Next
    					For i2 As Integer = 1 To p
    						Console.Write(" " & E(i1,i2))
    					Next
    					Console.Write(" Cor ")
    					For i2 As Integer = 0 To o-1
    						Console.Write(" " & C(i1,i2))
    					Next
    					If sw > 0
    						mx = -1
    					End If
    					Console.WriteLine(" Res " & (mx+1))
    				Next
    	
    			Else
    	
    				Dim OUT As StreamWriter = new StreamWriter(name)
    	
    				OUT.WriteLine("重み")
    				For i1 As Integer = 0 To o-1
    					For i2 As Integer = 0 To p
    						OUT.Write("  " & W_p(i1,i2))
    					Next
    					OUT.WriteLine()
    				Next
    	
    				OUT.WriteLine("分類結果")
    				Dim mx As Integer   = 0
    				Dim mx_v As Integer = 0
    				For i1 As Integer = 0 To n-1
    					Dim sw As Integer = 0
    					For i2 As Integer = 0 To o-1
    						Dim s As Integer = 0
    						For i3 As Integer = 0 To p
    							s += W_p(i2,i3) * E(i1,i3)
    						Next
    						If i2 = 0
    							mx_v = s
    							mx   = 0
    						Else
    							If s > mx_v
    								sw   = 0
    								mx_v = s
    								mx   = i2
    							Else
    								If s = mx_v
    									sw = 1
    								End If
    							End If
    						End If
    					Next
    					For i2 As Integer = 1 To p
    						OUT.Write(" " & E(i1,i2))
    					Next
    					OUT.Write(" Cor ")
    					For i2 As Integer = 0 To o-1
    						OUT.Write(" " & C(i1,i2))
    					Next
    					If sw > 0
    						mx = -1
    					End If
    					OUT.WriteLine(" Res " & (mx+1))
    				Next
    	
    				OUT.Close()
    
    			End If
    	
    			If n = num
    				Console.WriteLine("  !!すべてを分類(試行回数:" & n_tri & ")")
    			Else
    				Console.WriteLine("  !!" & num & " 個を分類")
    			End If
    
    		End Sub
    	
    		'******************************************'
    		' Pocket Algorith with Ratcet              '
    		'      num_p : 正しく分類した訓練例の数    '
    		'      return : =0 : 最大学習回数          '
    		'               >0  : すべてを分類(回数) '
    		'******************************************'
    		Function pocket(ByRef num_p As Integer)
    					'
    					' 初期設定
    					'
    			num_p                = 0
    			Dim count As Integer = 0
    			Dim mx As Integer    = 0
    			Dim run As Integer   = 0
    			Dim run_p As Integer = 0
    			Dim sw As Integer    = -1
    	
    			For i1 As Integer = 0 To o-1
    				For i2 As Integer = 0 To p
    					W(i1,i2) = 0
    				Next
    			Next
    					'
    					' 実行
    					'
    			Do While sw < 0
    						' 終了チェック
    				count += 1
    				If count > max
    					sw = 0
    	
    				Else
    						' 訓練例の選択
    					Dim k As Integer = Math.Floor(rn.NextDouble() * n)
    					If k >= n
    						k = n - 1
    					End If
    						' 出力の計算
    					Dim sw1 As Integer = 0
    					Dim cor As Integer = -1
    	
    					For i1 As Integer = 0 To o-1
    	
    						If C(k,i1) = 1
    							cor = i1
    						End If
    	
    						Dim s As Integer = 0
    						For i2 As Integer = 0 To p
    							s += W(i1,i2) * E(k,i2)
    						Next
    						Ct(i1) = s
    	
    						If i1 = 0
    							mx = 0
    						Else
    							If s > Ct(mx)
    								mx = i1
    								sw1 = 0
    							Else
    								If s = Ct(mx)
    									sw1 = 1
    									If cor >= 0 and mx = cor
    										mx = i1
    									End If
    								End If
    							End If
    						End If
    					Next
    						' 正しい分類
    					If sw1 = 0 and cor = mx
    						run += 1
    						If run > run_p
    							Dim num As Integer = bunrui()
    							If num > num_p
    								num_p = num
    								run_p = run
    								For i1 As Integer = 0 To o-1
    									For i2 As Integer = 0 To p
    										W_p(i1,i2) = W(i1,i2)
    									Next
    								Next
    								If num = n
    									sw = count
    								End If
    							End If
    						End If
    						' 誤った分類
    					Else
    						run = 0
    						For i1 As Integer = 0 To p
    							W(cor,i1) += E(k,i1)
    							W(mx,i1)  -= E(k,i1)
    						Next
    					End If
    				End If
    			Loop
    	
    			Return sw
    
    		End Function
    
    	End Class
    
    End Module
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 100 入力セルの数 2 出力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ------------------------or.dat--------------------
    OR演算の訓練例.最後の2つのデータが目標出力値
    -1 -1 -1 1
    -1  1  1 -1
     1 -1  1 -1
     1  1  1 -1
    */
    			

静岡理工科大学 菅沼ホーム 目次 索引