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

競合学習

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

  プログラム(使用方法)は,与えられた n 個のパターンを競合学習という教師無しの方法で分類するためのものです(入力ユニット数: p,出力ユニット数: o ).なお,このプログラムでは,クラスを使用しています.

  1. C++

      C++11 においては,「メルセンヌ・ツイスター法による擬似乱数生成エンジン」を使用することができます.
    /****************************/
    /* 競合学習                 */
    /*      coded by Y.Suganuma */
    /****************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctime>
    #include "MT.h"
    
    /***************************/
    /* Competitionクラスの定義 */
    /***************************/
    class Competition {
    		long max;   // 最大学習回数
    		long n;   // 訓練例の数
    		long o;   // 出力セルの数
    		long p;   // 入力セルの数
    		long **E;   // 訓練例
    		double **W;   // 重み
    		double sig;   // 重み修正係数
    	public:
    		Competition(long, long, long, long, long, double);
    		~Competition();
    		void Input(char *);
    		void Learn(int, char *name = "");
    };
    
    /******************/
    /* コンストラクタ */
    /******************/
    Competition::Competition(long max_i, long n_i, long o_i, long p_i, long seed, double sig_i)
    {
    	long i1;
    /*
         設定
    */
    	sig = sig_i;
    	max = max_i;
    	n   = n_i;
    	o   = o_i;
    	p   = p_i;
    
    	init_genrand(seed);
    /*
         領域の確保
    */
    	E = new long * [n];
    	for (i1 = 0; i1 < n; i1++)
    		E[i1] = new long [p];
    
    	W = new double * [o];
    	for (i1 = 0; i1 < o; i1++)
    		W[i1]   = new double [p];
    }
    
    /****************/
    /* デストラクタ */
    /****************/
    Competition::~Competition()
    {
    	int i1;
    
    	for (i1 = 0; i1 < n; i1++)
    		delete [] E[i1];
    	delete [] E;
    
    	for (i1 = 0; i1 < o; i1++)
    		delete [] W[i1];
    	delete [] W;
    }
    
    /**************************/
    /* 学習データの読み込み   */
    /*      name : ファイル名 */
    /**************************/
    void Competition::Input(char *name)
    {
    	long i1, i2;
    	FILE *st;
    
    	st = fopen(name, "r");
    
    	for (i1 = 0; i1 < n; i1++) {
    		for (i2 = 0; i2 < p; i2++)
    			fscanf(st, "%ld", &E[i1][i2]);
    	}
    
    	fclose(st);
    }
    
    /*********************************/
    /* 学習と結果の出力              */
    /*      pr : =0 : 画面に出力     */
    /*           =1 : ファイルに出力 */
    /*      name : 出力ファイル名    */
    /*********************************/
    void Competition::Learn(int pr, char *name)
    {
    	double mx_v = 0.0, s, sum;
    	long count, i1, i2, i3, k, mx = 0;
    	FILE *out;
    
    /*
         初期設定
    */
    	for (i1 = 0; i1 < o; i1++) {
    		sum = 0.0;
    		for (i2 = 0; i2 < p; i2++) {
    			W[i1][i2]  = genrand_real3();
    			sum       += W[i1][i2];
    		}
    		sum = 1.0 / sum;
    		for (i2 = 0; i2 < p; i2++)
    			W[i1][i2] *= sum;
    	}
    /*
         学習
    */
    	for (count = 0; count < max; count++) {
    					// 訓練例の選択
    		k = (long)(genrand_real3() * n);
    		if (k >= n)
    			k = n - 1;
    					// 出力の計算
    		for (i1 = 0; i1 < o; i1++) {
    			s = 0.0;
    			for (i2 = 0; i2 < p; i2++)
    				s += W[i1][i2] * E[k][i2];
    			if (i1 == 0 || s > mx_v) {
    				mx   = i1;
    				mx_v = s;
    			}
    		}
    					// 重みの修正
    		sum = 0.0;
    		for (i1 = 0; i1 < p; i1++)
    			sum += E[k][i1];
    		for (i1 = 0; i1 < p; i1++)
    			W[mx][i1] += sig * (E[k][i1] / sum - W[mx][i1]);
    	}
    /*
         出力
    */
    	if (pr == 0)
    		out = stdout;
    	else
    		out = fopen(name, "w");
    
    	fprintf(out, "分類結果\n");
    	for (i1 = 0; i1 < n; i1++) {
    		for (i2 = 0; i2 < p; i2++)
    			fprintf(out, "%2ld", E[i1][i2]);
    		fprintf(out, " Res ");
    		for (i2 = 0; i2 < o; i2++) {
    			s = 0.0;
    			for (i3 = 0; i3 < p; i3++)
    	            s += W[i2][i3] * E[i1][i3];
    			if (i2 == 0 || s > mx_v) {
    				mx   = i2;
    				mx_v = s;
    			}
    		}
    		fprintf(out, "%3ld\n", mx+1);
    	}
    }
    
    /****************/
    /* main program */
    /****************/
    int main(int argc, char *argv[])
    {
    	double sig;
    	long max, n, p, o;
    	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 %*s %lf",
                   &max, &p, &o, &n, &sig);
    		fscanf(st, "%*s %s", name);
    		fclose(st);
    					// ネットワークの定義
    		Competition net(max, n, o, p, seed, sig);
    		net.Input(name);
    					// 学習と結果の出力
    		if (argc == 2)
    			net.Learn(0);
    		else
    			net.Learn(1, argv[2]);
    	}
    
    	else {
    		printf("***error   入力データファイル名を指定して下さい\n");
    		exit(1);
    	}
    
    	return 0;
    }
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
    入力データファイル pat.dat
    
    ------------------------pat.dat-------------------
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 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
    */
    			

  2. Java

    /****************************/
    /* 競合学習                 */
    /*      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
    	{
    		double sig;
    		int max, n, o, p;
    		String name;
    		StringTokenizer str;
    
    		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.nextToken();
    			sig = Double.parseDouble(str.nextToken());
    
    			str = new StringTokenizer(in.readLine(), " ");
    			str.nextToken();
    			name = str.nextToken();
    
    			in.close();
    					// ネットワークの定義
    			Competition net = new Competition (max, n, o, p, sig);
    			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);
    		}
    	}
    }
    
    /***************************/
    /* Competitionクラスの定義 */
    /***************************/
    class Competition {
    
    	private int max;   // 最大学習回数
    	private int n;   // 訓練例の数
    	private int o;   // 出力セルの数
    	private int p;   // 入力セルの数
    	private int E[][];   // 訓練例
    	private double W[][];   // 重み
    	private double sig;   // 重み修正係数
    	private Random rn;   // 乱数
    
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	Competition (int max_i, int n_i, int o_i, int p_i, double sig_i)
    	{
    	/*
    	     設定
    	*/
    		max = max_i;
    		n   = n_i;
    		o   = o_i;
    		p   = p_i;
    		sig = sig_i;
    
    		rn  = new Random();   // 乱数の初期設定
    	/*
    	     領域の確保
    	*/
    		E   = new int [n][p];
    		W   = new double [o][p];
    	}
    
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      name : ファイル名 */
    	/**************************/
    	void input (String name) throws IOException, FileNotFoundException
    	{
    		int i1, i2;
    		StringTokenizer str;
    
    		BufferedReader st = new BufferedReader(new FileReader(name));
    
    		for (i1 = 0; i1 < n; i1++) {
    			str = new StringTokenizer(st.readLine(), " ");
    			for (i2 = 0; i2 < p; i2++)
    				E[i1][i2] = Integer.parseInt(str.nextToken());
    		}
    
    		st.close();
    	}
    
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	void learn(int pr, String name) throws FileNotFoundException
    	{
    		double mx_v = 0.0, s, sum;
    		int count, i1, i2, i3, k, mx = 0;
    	/*
    	     初期設定
    	*/
    		for (i1 = 0; i1 < o; i1++) {
    			sum = 0.0;
    			for (i2 = 0; i2 < p; i2++) {
    				W[i1][i2]  = rn.nextDouble();
    				sum       += W[i1][i2];
    			}
    			sum = 1.0 / sum;
    			for (i2 = 0; i2 < p; i2++)
    				W[i1][i2] *= sum;
    		}
    	/*
    	     学習
    	*/
    		for (count = 0; count < max; count++) {
    					// 訓練例の選択
    			k = (int)(rn.nextDouble() * n);
    			if (k >= n)
    				k = n - 1;
    					// 出力の計算
    			for (i1 = 0; i1 < o; i1++) {
    				s = 0.0;
    				for (i2 = 0; i2 < p; i2++)
    					s += W[i1][i2] * E[k][i2];
    				if (i1 == 0 || s > mx_v) {
    					mx   = i1;
    					mx_v = s;
    				}
    			}
    					// 重みの修正
    			sum = 0.0;
    			for (i1 = 0; i1 < p; i1++)
    				sum += E[k][i1];
    			for (i1 = 0; i1 < p; i1++)
    				W[mx][i1] += sig * (E[k][i1] / sum - W[mx][i1]);
    		}
    	/*
    	     出力
    	*/
    		if (pr == 0) {
    
    			System.out.print("分類結果\n");
    			for (i1 = 0; i1 < n; i1++) {
    				for (i2 = 0; i2 < p; i2++)
    					System.out.print(" " + E[i1][i2]);
    				System.out.print(" Res ");
    				for (i2 = 0; i2 < o; i2++) {
    					s = 0.0;
    					for (i3 = 0; i3 < p; i3++)
    	    		        s += W[i2][i3] * E[i1][i3];
    					if (i2 == 0 || s > mx_v) {
    						mx   = i2;
    						mx_v = s;
    					}
    				}
    				System.out.println((mx+1));
    			}
    		}
    
    		else {
    
    			PrintStream out = new PrintStream(new FileOutputStream(name));
    
    			out.print("分類結果\n");
    			for (i1 = 0; i1 < n; i1++) {
    				for (i2 = 0; i2 < p; i2++)
    					out.print(" " + E[i1][i2]);
    				out.print(" Res ");
    				for (i2 = 0; i2 < o; i2++) {
    					s = 0.0;
    					for (i3 = 0; i3 < p; i3++)
    	    		        s += W[i2][i3] * E[i1][i3];
    					if (i2 == 0 || s > mx_v) {
    						mx   = i2;
    						mx_v = s;
    					}
    				}
    				out.println((mx+1));
    			}
    
    			out.close();
    		}
    	}
    }
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
    入力データファイル pat.dat
    
    ------------------------pat.dat-------------------
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0
    */
    			

  3. JavaScript

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

    <!DOCTYPE HTML>
    
    <HTML>
    
    <HEAD>
    
    	<TITLE>競合学習</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);
    			let sig = parseFloat(document.getElementById("sig").value);
    					// ネットワークの定義
    			net = new Competition (max, n, o, p, sig);
    			net.input(name);
    					// 学習と結果の出力
    			net.learn(0, "");
    			document.getElementById("result").value = res;
    		}
    
    		/***************************/
    		/* Competitionオブジェクト */
    		/***************************/
    		function Competition (max_i, n_i, o_i, p_i, sig_i)
    		{
    					//
    					// 設定
    					//
    			this.max = max_i;
    			this.n   = n_i;
    			this.o   = o_i;
    			this.p   = p_i;
    			this.sig = sig_i;
    					//
    					// 領域の確保
    					//
    			this.E = new Array(this.n);
    			for (let i1 = 0; i1 < this.n; i1++)
    				this.E[i1] = new Array(this.p);
    			this.W = new Array(this.o);
    			for (let i1 = 0; i1 < this.o; i1++)
    				this.W[i1] = new Array(this.p);
    		}
    
    		/************************/
    		/* 学習データの読み込み */
    		/************************/
    		Competition.prototype.input = function()
    		{
    			let lines = (document.getElementById("data").value).split('\n');
    
    			for (let i1 = 0; i1 < net.n; i1++) {
    				let str = lines[i1].split(' ').filter(function(e){return e.length > 0;});
    				for (let i2 = 0; i2 < net.p; i2++)
    					net.E[i1][i2] = parseInt(str[i2]);
    			}
    		}
    
    		/********************/
    		/* 学習と結果の出力 */
    		/********************/
    		Competition.prototype.learn = function()
    		{
    			let mx_v = 0.0;
    			let count, mx = 0;
    					//
    					// 初期設定
    					//
    			for (let i1 = 0; i1 < net.o; i1++) {
    				let sum = 0.0;
    				for (let i2 = 0; i2 < net.p; i2++) {
    					net.W[i1][i2]  = Math.random();
    					sum           += net.W[i1][i2];
    				}
    				sum = 1.0 / sum;
    				for (let i2 = 0; i2 < net.p; i2++)
    					net.W[i1][i2] *= sum;
    			}
    					//
    					// 学習
    					//
    			for (count = 0; count < max; count++) {
    						// 訓練例の選択
    				let k = Math.floor(Math.random() * net.n);
    				if (k >= net.n)
    					k = net.n - 1;
    						// 出力の計算
    				for (let i1 = 0; i1 < net.o; i1++) {
    					let s = 0.0;
    					for (let i2 = 0; i2 < net.p; i2++)
    						s += net.W[i1][i2] * net.E[k][i2];
    					if (i1 == 0 || s > mx_v) {
    						mx   = i1;
    						mx_v = s;
    					}
    				}
    						// 重みの修正
    				let sum = 0.0;
    				for (let i1 = 0; i1 < net.p; i1++)
    					sum += net.E[k][i1];
    				for (let i1 = 0; i1 < net.p; i1++)
    					net.W[mx][i1] += net.sig * (net.E[k][i1] / sum - net.W[mx][i1]);
    			}
    				//
    				// 出力
    				//
    			res += "分類結果\n";
    			for (let i1 = 0; i1 < net.n; i1++) {
    				for (let i2 = 0; i2 < net.p; i2++)
    					res += (" " + net.E[i1][i2]);
    				res += (" Res ");
    				for (let i2 = 0; i2 < net.o; i2++) {
    					let s = 0.0;
    					for (let i3 = 0; i3 < net.p; i3++)
    	    		        s += net.W[i2][i3] * net.E[i1][i3];
    					if (i2 == 0 || s > mx_v) {
    						mx   = i2;
    						mx_v = s;
    					}
    				}
    				res += ((mx+1) + "\n");
    			}
    		}
    	</SCRIPT>
    
    </HEAD>
    
    <BODY STYLE="font-size: 130%; text-align:center; background-color: #eeffee;">
    
    	<H2><B>競合学習</B></H2>
    
    	最大試行回数:<INPUT ID="max" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="1000"> 
    	入力セル数:<INPUT ID="p" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="9"> 
    	出力セル数:<INPUT ID="o" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="3"> 
    	訓練例数:<INPUT ID="n" STYLE="font-size: 100%" TYPE="text" SIZE="1" VALUE="9"> 
    	係数(0~1):<INPUT ID="sig" STYLE="font-size: 100%" TYPE="text" SIZE="2" VALUE="0.1"> 
    	<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">
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0
    			</TEXTAREA>
    		</DIV>
    	</DIV>
    </BODY>
    
    </HTML>
    			

  4. PHP

    <?php
    
    /****************************/
    /* 競合学習                 */
    /*      coded by Y.Suganuma */
    /****************************/
    
    /***************************/
    /* Competitionクラスの定義 */
    /***************************/
    class Competition {
    	private $max;   // 最大学習回数
    	private $n;   // 訓練例の数
    	private $o;   // 出力セルの数
    	private $p;   // 入力セルの数
    	private $E;   // 訓練例
    	private $W;   // 重み
    	private $sig;   // 重み修正係数
    
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	function Competition($max_i, $n_i, $o_i, $p_i, $sig_i)
    	{
    	/*
    	     設定
    	*/
    		$this->sig = $sig_i;
    		$this->max = $max_i;
    		$this->n   = $n_i;
    		$this->o   = $o_i;
    		$this->p   = $p_i;
    	
    		mt_srand();
    	/*
    	     領域の確保
    	*/
    		$this->E = array($this->n);
    		for ($i1 = 0; $i1 < $this->n; $i1++)
    			$this->E[$i1] = array($this->p);
    	
    		$this->W = array($this->o);
    		for ($i1 = 0; $i1 < $this->o; $i1++)
    			$this->W[$i1]   = array($this->p);
    	}
    	
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      name : ファイル名 */
    	/**************************/
    	function Input($name)
    	{
    		$st = fopen($name, "rb");
    	
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$str             = trim(fgets($st));
    			$this->E[$i1][0] = intval(strtok($str, " "));
    			for ($i2 = 1; $i2 < $this->p; $i2++)
    				$this->E[$i1][$i2] = intval(strtok(" "));
    		}
    	
    		fclose($st);
    	}
    	
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	function Learn($pr, $name = "STDOUT")
    	{
    		$mx   = 0;
    		$mx_v = 0.0;
    	/*
    	     初期設定
    	*/
    		for ($i1 = 0; $i1 < $this->o; $i1++) {
    			$sum = 0.0;
    			for ($i2 = 0; $i2 < $this->p; $i2++) {
    				$this->W[$i1][$i2]  = mt_rand() / mt_getrandmax();
    				$sum               += $this->W[$i1][$i2];
    			}
    			$sum = 1.0 / $sum;
    			for ($i2 = 0; $i2 < $this->p; $i2++)
    				$this->W[$i1][$i2] *= $sum;
    		}
    	/*
    	     学習
    	*/
    		for ($count = 0; $count < $this->max; $count++) {
    						// 訓練例の選択
    			$k = intval(mt_rand() / mt_getrandmax() * $this->n);
    			if ($k >= $this->n)
    				$k = $this->n - 1;
    						// 出力の計算
    			for ($i1 = 0; $i1 < $this->o; $i1++) {
    				$s = 0.0;
    				for ($i2 = 0; $i2 < $this->p; $i2++)
    					$s += $this->W[$i1][$i2] * $this->E[$k][$i2];
    				if ($i1 == 0 || $s > $mx_v) {
    					$mx   = $i1;
    					$mx_v = $s;
    				}
    			}
    						// 重みの修正
    			$sum = 0.0;
    			for ($i1 = 0; $i1 < $this->p; $i1++)
    				$sum += $this->E[$k][$i1];
    			for ($i1 = 0; $i1 < $this->p; $i1++)
    				$this->W[$mx][$i1] += $this->sig * ($this->E[$k][$i1] / $sum - $this->W[$mx][$i1]);
    		}
    	/*
    	     出力
    	*/
    		if ($pr == 0)
    			$out = STDOUT;
    		else
    			$out = fopen($name, "w");
    	
    		fwrite($out, "分類結果\n");
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$str = "";
    			for ($i2 = 0; $i2 < $this->p; $i2++)
    				$str = $str." ".$this->E[$i1][$i2];
    			$str = $str." Res ";
    			for ($i2 = 0; $i2 < $this->o; $i2++) {
    				$s = 0.0;
    				for ($i3 = 0; $i3 < $this->p; $i3++)
    		            $s += $this->W[$i2][$i3] * $this->E[$i1][$i3];
    				if ($i2 == 0 || $s > $mx_v) {
    					$mx   = $i2;
    					$mx_v = $s;
    				}
    			}
    			fwrite($out, $str.($mx+1)."\n");
    		}
    	}
    }
    	
    /****************/
    /* main program */
    /****************/
    	
    	if (count($argv) > 1) {
    					// 基本データの入力
    		$st = fopen($argv[1], "r");
    		fscanf($st, "%*s %ld %*s %ld %*s %ld %*s %ld %*s %lf", $max, $p, $o, $n, $sig);
    		fscanf($st, "%*s %s", $name);
    		fclose($st);
    					// ネットワークの定義
    		$net = new Competition($max, $n, $o, $p, $sig);
    		$net->Input($name);
    					// 学習と結果の出力
    		if (count($argv) == 2)
    			$net->Learn(0);
    		else
    			$net->Learn(1, $argv[2]);
    	}
    
    	else
    		exit("***error   入力データファイル名を指定して下さい\n");
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
    入力データファイル pat.dat
    
    ------------------------pat.dat-------------------
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0
    */
    
    ?>
    			

  5. Ruby

    ##########################
    # 競合学習
    #      coded by Y.Suganuma
    ##########################
    
    #############################
    # Competitionクラスの定義
    #      coded by Y.Suganuma
    #############################
    
    class Competition
    
    	#########################
    	# コンストラクタ
    	#      max : 最大学習回数
    	#      n : 訓練例の数
    	#      o : 出力セルの数
    	#      p : 入力セルの数
    	#      sig : 重み修正係数
    	#########################
    
    	def initialize(max_i, n_i, o_i, p_i, sig_i)
    			# 設定
    		@_max = max_i
    		@_n   = n_i
    		@_o   = o_i
    		@_p   = p_i
    		@_sig = sig_i
    			# 領域の確保
    		@_e = Array.new(@_n)   # 訓練例
    		for i1 in 0 ...@_n
    			@_e[i1] = Array.new(@_p)
    		end
    		@_w = Array.new(@_o)   # 重み
    		for i1 in 0 ...@_o
    			@_w[i1] = Array.new(@_p)
    		end
    	end
    	
    	#*************************/
    	# 学習データの読み込み   */
    	#      name : ファイル名 */
    	#*************************/
    	
    	def Input(name)
    	
    		f = open(name, "r")
    	
    		for i1 in 0 ... @_n
    			s = f.gets().split(" ")
    			for i2 in 0 ... @_p
    				@_e[i1][i2] = Integer(s[i2])
    			end
    		end
    	
    		f.close()
    	end
    	
    	#################################
    	# 学習と結果の出力
    	#      pr : =0 : 画面に出力
    	#           =1 : ファイルに出力
    	#      name : 出力ファイル名
    	#################################
    	
    	def Learn(pr, name="")
    			# 初期設定
    		mx_v = 0.0
    		mx   = 0
    		for i1 in 0 ... @_o
    			sum = 0.0
    			for i2 in 0 ... @_p
    				@_w[i1][i2]  = rand(0)
    				sum         += @_w[i1][i2]
    			end
    			sum = 1.0 / sum
    			for i2 in 0 ... @_p
    				@_w[i1][i2] *= sum
    			end
    		end
    			# 学習
    		for count in 0 ... @_max
    					# 訓練例の選択
    			k = Integer(rand(0) * @_n)
    			if k >= @_n
    				k = @_n - 1
    			end
    					# 出力の計算
    			for i1 in 0 ... @_o
    				s = 0.0
    				for i2 in 0 ... @_p
    					s += @_w[i1][i2] * @_e[k][i2]
    				end
    				if i1 == 0 or s > mx_v
    					mx   = i1
    					mx_v = s
    				end
    			end
    					# 重みの修正
    			sum = 0.0
    			for i1 in 0 ... @_p
    				sum += @_e[k][i1]
    			end
    			for i1 in 0 ... @_p
    				@_w[mx][i1] += @_sig * (@_e[k][i1] / sum - @_w[mx][i1])
    			end
    		end
    			# 出力
    		if pr == 0
    			out = $stdout
    		else
    			out = open(name, "w")
    		end
    	
    		out.print("分類結果\n")
    		for i1 in 0 ... @_n
    			for i2 in 0 ... @_p
    				out.print(" " + String(@_e[i1][i2]))
    			end
    			out.print(" Res ")
    			for i2 in 0 ... @_o
    				s = 0.0
    				for i3 in 0 ... @_p
    					s += @_w[i2][i3] * @_e[i1][i3]
    				end
    				if i2 == 0 or s > mx_v
    					mx   = i2
    					mx_v = s
    				end
    			end
    			out.print(" " + String(mx+1) + "\n")
    		end
    	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])
    	sig  = Float(s[9])
    	s    = gets().split(" ")
    	name = s[1]
    				# ネットワークの定義
    	srand()
    	net = Competition.new(max, n, o, p, sig)
    	net.Input(name)
    				# 学習と結果の出力
    	if ARGV[0] == nil
    		net.Learn(0)
    	else
    		net.Learn(1, ARGV[0])
    	end
    
    else
    	print("***error   入力ファイル名を指定して下さい\n")
    end
    
    =begin
    ------------------------入力ファイル--------------
    最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
    入力データファイル pat.dat
    
    ------------------------pat.dat-------------------
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0
    =end
    			

  6. Python

    # -*- coding: UTF-8 -*-
    import numpy as np
    import sys
    from math import *
    from random import *
    
    #############################
    # Competitionクラスの定義
    #      coded by Y.Suganuma
    #############################
    
    class Competition :
    
    	#########################
    	# コンストラクタ
    	#      max : 最大学習回数
    	#      n : 訓練例の数
    	#      o : 出力セルの数
    	#      p : 入力セルの数
    	#      sig : 重み修正係数
    	#########################
    
    	def __init__(self, max_i, n_i, o_i, p_i, sig_i) :
    			# 設定
    		self.max = max_i
    		self.n   = n_i
    		self.o   = o_i
    		self.p   = p_i
    		self.sig = sig_i
    			# 領域の確保
    		self.E = np.empty((self.n, self.p), np.int)   # 訓練例
    		self.W = np.empty((self.o, self.p), np.float)   # 重み
    	
    	#*************************/
    	# 学習データの読み込み   */
    	#      name : ファイル名 */
    	#*************************/
    	
    	def Input(self, name) :
    	
    		f = open(name, "r")
    	
    		for i1 in range(0, self.n) :
    			s = f.readline().split()
    			for i2 in range(0, self.p) :
    				self.E[i1][i2] = int(s[i2])
    	
    		f.close()
    	
    	#################################
    	# 学習と結果の出力
    	#      pr : =0 : 画面に出力
    	#           =1 : ファイルに出力
    	#      name : 出力ファイル名
    	#################################
    	
    	def Learn(self, pr, name="") :
    			# 初期設定
    		mx_v = 0.0
    		mx   = 0
    		for i1 in range(0, self.o) :
    			sum = 0.0
    			for i2 in range(0, self.p) :
    				self.W[i1][i2]  = random()
    				sum            += self.W[i1][i2]
    			sum = 1.0 / sum
    			for i2 in range(0, self.p) :
    				self.W[i1][i2] *= sum
    			# 学習
    		for count in range(0, self.max) :
    					# 訓練例の選択
    			k = int(random() * self.n)
    			if k >= self.n :
    				k = self.n - 1
    					# 出力の計算
    			for i1 in range(0, self.o) :
    				s = 0.0
    				for i2 in range(0, self.p) :
    					s += self.W[i1][i2] * self.E[k][i2]
    				if i1 == 0 or s > mx_v :
    					mx   = i1
    					mx_v = s
    					# 重みの修正
    			sum = 0.0
    			for i1 in range(0, self.p) :
    				sum += self.E[k][i1]
    			for i1 in range(0, self.p) :
    				self.W[mx][i1] += self.sig * (self.E[k][i1] / sum - self.W[mx][i1])
    			# 出力
    		if pr == 0 :
    			out = sys.stdout
    		else :
    			out = open(name, "w")
    	
    		out.write("分類結果\n")
    		for i1 in range(0, self.n) :
    			for i2 in range(0, self.p) :
    				out.write(" " + str(self.E[i1][i2]))
    			out.write(" Res ")
    			for i2 in range(0, self.o) :
    				s = 0.0
    				for i3 in range(0, self.p) :
    					s += self.W[i2][i3] * self.E[i1][i3]
    				if i2 == 0 or s > mx_v :
    					mx   = i2
    					mx_v = s
    			out.write(" " + str(mx+1) + "\n")
    
    ##########################
    # 競合学習
    #      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])
    	sig  = float(s[9])
    	s    = f.readline().split()
    	name = s[1]
    	f.close()
    				# ネットワークの定義
    	seed()
    	net = Competition(max, n, o, p, sig)
    	net.Input(name)
    				# 学習と結果の出力
    	if len(sys.argv) == 2 :
    		net.Learn(0)
    	else :
    		net.Learn(1, sys.argv[2])
    
    else :
    	print("***error   入力ファイル名を指定して下さい")
    
    """
    ------------------------入力ファイル--------------
    最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
    入力データファイル pat.dat
    
    ------------------------pat.dat-------------------
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0
    """
    			

  7. C#

    /****************************/
    /* 競合学習                 */
    /*      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]);
    			double sig     = double.Parse(str[9]);
    
    			str            = lines[1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			String name    = str[1];
    					// ネットワークの定義
    			Competition net = new Competition (max, n, o, p, sig);
    			net.input(name);
    					// 学習と結果の出力
    			if (args.Length == 1)
    				net.learn(0, "");
    			else
    				net.learn(1, args[1]);
    		}
    					// エラー
    		else {
    			Console.WriteLine("***error   入力データファイル名を指定して下さい");
    			Environment.Exit(1);
    		}
    	}
    }
    
    /***************************/
    /* Competitionクラスの定義 */
    /***************************/
    class Competition {
    
    	int max;   // 最大学習回数
    	int n;   // 訓練例の数
    	int o;   // 出力セルの数
    	int p;   // 入力セルの数
    	int[][] E;   // 訓練例
    	double[][] W;   // 重み
    	double sig;   // 重み修正係数
    	Random rn;   // 乱数
    
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	public Competition (int max_i, int n_i, int o_i, int p_i, double sig_i)
    	{
    				//
    				// 設定
    				//
    		max = max_i;
    		n   = n_i;
    		o   = o_i;
    		p   = p_i;
    		sig = sig_i;
    
    		rn  = new Random();   // 乱数の初期設定
    				//
    				// 領域の確保
    				//
    		E = new int [n][];
    		for (int i1 = 0; i1 < n; i1++)
    			E[i1] = new int [p];
    		W = new double [o][];
    		for (int i1 = 0; i1 < o; i1++)
    			W[i1] = new double [p];
    	}
    
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      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[i1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			for (int i2 = 0; i2 < p; i2++)
    				E[i1][i2] = int.Parse(str[i2]);
    		}
    	}
    
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	public void learn(int pr, String name)
    	{
    		double mx_v = 0.0;
    		int count, mx = 0;
    				//
    				// 初期設定
    				//
    		for (int i1 = 0; i1 < o; i1++) {
    			double sum = 0.0;
    			for (int i2 = 0; i2 < p; i2++) {
    				W[i1][i2]  = rn.NextDouble();
    				sum       += W[i1][i2];
    			}
    			sum = 1.0 / sum;
    			for (int i2 = 0; i2 < p; i2++)
    				W[i1][i2] *= sum;
    		}
    				//
    				// 学習
    				//
    		for (count = 0; count < max; count++) {
    					// 訓練例の選択
    			int k = (int)(rn.NextDouble() * n);
    			if (k >= n)
    				k = n - 1;
    					// 出力の計算
    			for (int i1 = 0; i1 < o; i1++) {
    				double s = 0.0;
    				for (int i2 = 0; i2 < p; i2++)
    					s += W[i1][i2] * E[k][i2];
    				if (i1 == 0 || s > mx_v) {
    					mx   = i1;
    					mx_v = s;
    				}
    			}
    					// 重みの修正
    			double sum = 0.0;
    			for (int i1 = 0; i1 < p; i1++)
    				sum += E[k][i1];
    			for (int i1 = 0; i1 < p; i1++)
    				W[mx][i1] += sig * (E[k][i1] / sum - W[mx][i1]);
    		}
    				//
    				// 出力
    				//
    		if (pr == 0) {
    
    			Console.WriteLine("分類結果");
    			for (int i1 = 0; i1 < n; i1++) {
    				for (int i2 = 0; i2 < p; i2++)
    					Console.Write(" " + E[i1][i2]);
    				Console.Write(" Res ");
    				for (int i2 = 0; i2 < o; i2++) {
    					double s = 0.0;
    					for (int i3 = 0; i3 < p; i3++)
    	    		        s += W[i2][i3] * E[i1][i3];
    					if (i2 == 0 || s > mx_v) {
    						mx   = i2;
    						mx_v = s;
    					}
    				}
    				Console.WriteLine((mx+1));
    			}
    		}
    
    		else {
    
    			StreamWriter OUT = new StreamWriter(name, true);
    
    			OUT.WriteLine("分類結果");
    			for (int i1 = 0; i1 < n; i1++) {
    				for (int i2 = 0; i2 < p; i2++)
    					OUT.Write(" " + E[i1][i2]);
    				OUT.Write(" Res ");
    				for (int i2 = 0; i2 < o; i2++) {
    					double s = 0.0;
    					for (int i3 = 0; i3 < p; i3++)
    	    		        s += W[i2][i3] * E[i1][i3];
    					if (i2 == 0 || s > mx_v) {
    						mx   = i2;
    						mx_v = s;
    					}
    				}
    				OUT.WriteLine((mx+1));
    			}
    
    			OUT.Close();
    		}
    	}
    }
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
    入力データファイル pat.dat
    
    ------------------------pat.dat-------------------
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0
    */
    			

  8. VB

    '**************************'
    ' 競合学習                 '
    '      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))
    			Dim sig As Double       = Double.Parse(str(9))
    
    			str                = MS.Split(inp.ReadLine().Trim())
    			Dim name As String = str(1)
    			inp.Close()
    					' ネットワークの定義
    			Dim net As Competition = new Competition (max, n, o, p, sig)
    			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
    
    	'*************************'
    	' Competitionクラスの定義 '
    	'*************************'
    	Class Competition
    	
    		Private max As Integer   ' 最大学習回数
    		Private n As Integer   ' 訓練例の数
    		Private o As Integer   ' 出力セルの数
    		Private p As Integer   ' 入力セルの数
    		Private E(,) As Integer   ' 訓練例
    		Private W(,) As Double   ' 重み
    		Private sig As Double   ' 重み修正係数
    		Private rn As Random   ' 乱数
    	
    		'****************'
    		' コンストラクタ '
    		'****************'
    		Public Sub New(max_i As Integer, n_i As Integer, o_i As Integer, p_i As Integer, sig_i As Double)
    					'
    					' 設定
    					'
    			max = max_i
    			n   = n_i
    			o   = o_i
    			p   = p_i
    			sig = sig_i
    	
    			rn  = new Random()   ' 乱数の初期設定
    					'
    					' 領域の確保
    					'
    			ReDim E(n,p)
    			ReDim W(o,p)
    
    		End Sub
    	
    		'************************'
    		' 学習データの読み込み   '
    		'      name : ファイル名 '
    		'************************'
    		Public Sub input (name As String)
    
    			Dim inp As StreamReader = New StreamReader(name)
    			Dim MS As Regex         = New Regex("\s+") 
    	
    			For i1 As Integer = 0 To n-1
    				Dim str() As String = MS.Split(inp.ReadLine().Trim())
    				For i2 As Integer = 0 To p-1
    					E(i1,i2) = Integer.Parse(str(i2))
    				Next
    			Next
    			inp.Close()
    
    		End Sub
    	
    		'*******************************'
    		' 学習と結果の出力              '
    		'      pr : =0 : 画面に出力     '
    		'           =1 : ファイルに出力 '
    		'      name : 出力ファイル名    '
    		'*******************************'
    		Public Sub learn(pr As Integer, name As String)
    
    			Dim count As Integer
    			Dim mx As Integer  = 0
    			Dim mx_v As Double = 0.0
    					'
    					' 初期設定
    					'
    			For i1 As Integer = 0 To o-1
    				Dim sum As Double = 0.0
    				For i2 As Integer = 0 To p-1
    					W(i1,i2) = rn.NextDouble()
    					sum      += W(i1,i2)
    				Next
    				sum = 1.0 / sum
    				For i2 As Integer = 0 To p-1
    					W(i1,i2) *= sum
    				Next
    			Next
    					'
    					' 学習
    					'
    			For count = 0 To max-1
    						' 訓練例の選択
    				Dim k As Integer = Math.Floor(rn.NextDouble() * n)
    				If k >= n
    					k = n - 1
    				End If
    						' 出力の計算
    				For i1 As Integer = 0 To o-1
    					Dim s As Double = 0.0
    					For i2 As Integer = 0 To p-1
    						s += W(i1,i2) * E(k,i2)
    					Next
    					If i1 = 0 or s > mx_v
    						mx   = i1
    						mx_v = s
    					End If
    				Next
    						' 重みの修正
    				Dim sum As Double = 0.0
    				For i1 As Integer = 0 To p-1
    					sum += E(k,i1)
    				Next
    				For i1 As Integer = 0 To p-1
    					W(mx,i1) += sig * (E(k,i1) / sum - W(mx,i1))
    				Next
    			Next
    					'
    					' 出力
    					'
    			If pr = 0
    	
    				Console.WriteLine("分類結果")
    				For i1 As Integer = 0 To n-1
    					For i2 As Integer = 0 To p-1
    						Console.Write(" " & E(i1,i2))
    					Next
    					Console.Write(" Res ")
    					For i2 As Integer = 0 To o-1
    						Dim s As Double = 0.0
    						For i3 As Integer = 0 To p-1
    		    		        s += W(i2,i3) * E(i1,i3)
    						Next
    						If i2 = 0 or s > mx_v
    							mx   = i2
    							mx_v = s
    						End If
    					Next
    					Console.WriteLine((mx+1))
    				Next
    	
    			Else
    	
    				Dim OUT As StreamWriter = new StreamWriter(name)
    	
    				OUT.WriteLine("分類結果")
    				For i1 As Integer = 0 To n-1
    					For i2 As Integer = 0 To p-1
    						OUT.Write(" " & E(i1,i2))
    					Next
    					OUT.Write(" Res ")
    					For i2 As Integer = 0 To o-1
    						Dim s As Double = 0.0
    						For i3 As Integer = 0 To p-1
    		    		        s += W(i2,i3) * E(i1,i3)
    						Next
    						If i2 = 0 or s > mx_v
    							mx   = i2
    							mx_v = s
    						End If
    					Next
    					OUT.WriteLine((mx+1))
    				Next
    	
    				OUT.Close()
    
    			End If
    
    		End Sub
    
    	End Class
    
    End Module
    
    /*
    ------------------------入力ファイル--------------
    最大試行回数 1000 入力セルの数 9 出力セルの数 3 訓練例の数 9 係数(0~1) 0.1
    入力データファイル pat.dat
    
    ------------------------pat.dat-------------------
    0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 1 0 1
    0 0 0 0 0 0 1 1 0
    0 0 0 0 1 1 0 0 0
    0 0 0 1 0 1 0 0 0
    0 0 0 1 1 0 0 0 0
    0 1 1 0 0 0 0 0 0
    1 0 1 0 0 0 0 0 0
    1 1 0 0 0 0 0 0 0
    */
    			

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