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

パーセプトロン

    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 個の入力ユニットと 1 個の出力ユニットからなるニューラルネットワークに対してパーセプトロン学習を行います.なお,このプログラムでは,クラスを使用しています.

  1. C++

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

    /***********************************/
    /* パーセプトロン学習              */
    /* (Pocket Algorith with Ratcet) */
    /*      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, 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();
    			n = Integer.parseInt(str.nextToken());
    
    			str = new StringTokenizer(in.readLine(), " ");
    			str.nextToken();
    			name = str.nextToken();
    
    			in.close();
    					// ネットワークの定義
    			Perceptron net = new Perceptron (max, n, 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);
    		}
    	}
    }
    
    /**************************/
    /* Perceptronクラスの定義 */
    /**************************/
    class Perceptron {
    
    	private int max;   // 最大学習回数
    	private int n;   // 訓練例の数
    	private int p;   // 入力セルの数
    	private int W_p[];   // 重み(ポケット)
    	private int W[];   // 重み
    	private int E[][];   // 訓練例
    	private int C[];   // 各訓練例に対する正しい出力
    	private Random rn;   // 乱数
    
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	Perceptron(int max_i, int n_i, int p_i)
    	{
    	/*
    	     設定
    	*/
    		max = max_i;
    		n   = n_i;
    		p   = p_i;
    
    		rn  = new Random();   // 乱数の初期設定
    	/*
    	     領域の確保
    	*/
    		E   = new int [n][p+1];
    		W_p = new int [p+1];
    		W   = new int [p+1];
    		C   = new int [n];
    	}
    
    	/******************************************/
    	/* 訓練例の分類                           */
    	/*      return : 正しく分類した訓練例の数 */
    	/******************************************/
    	int bunrui()
    	{
    		int i1, i2, num = 0, s;
    
    		for (i1 = 0; i1 < n; i1++) {
    			s = 0;
    			for (i2 = 0; i2 <= p; i2++)
    				s += W[i2] * E[i1][i2];
    			if ((s > 0 && C[i1] > 0) || (s < 0 && C[i1] < 0))
    				num++;
    		}
    
    		return num;
    	}
    
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      name : ファイル名 */
    	/**************************/
    	void input (String name) throws IOException, FileNotFoundException
    	{
    		int i1, i2;
    		StringTokenizer str;
    
    		BufferedReader st = new BufferedReader(new FileReader(name));
    
    		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());
    			C[i1] = Integer.parseInt(str.nextToken());
    		}
    
    		st.close();
    	}
    
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	void learn(int pr, String name) throws FileNotFoundException
    	{
    		int i1, i2, n_tri, s;
    		int num[] = new int [1];
    					// 学習
    		n_tri = pocket(num);
    					// 結果の出力
    		if (pr == 0) {
    
    			System.out.print("重み\n");
    			for (i1 = 0; i1 <= p; i1++)
    				System.out.print("  " + W_p[i1]);
    			System.out.println();
    
    			System.out.print("分類結果\n");
    			for (i1 = 0; i1 < n; i1++) {
    				s  = 0;
    				for (i2 = 0; i2 <= p; i2++)
    					s += E[i1][i2] * W_p[i2];
    				if (s > 0)
    					s = 1;
    				else
    					s = (s < 0) ? -1 : 0;
    				for (i2 = 1; i2 <= p; i2++)
    					System.out.print(" " + E[i1][i2]);
    				System.out.println(" Cor " + C[i1] + " Res " + s);
    			}
    		}
    
    		else {
    
    			PrintStream out = new PrintStream(new FileOutputStream(name));
    
    			out.print("重み\n");
    			for (i1 = 0; i1 <= p; i1++)
    				out.print("  " + W_p[i1]);
    			out.println();
    
    			out.print("分類結果\n");
    			for (i1 = 0; i1 < n; i1++) {
    				s  = 0;
    				for (i2 = 0; i2 <= p; i2++)
    					s += E[i1][i2] * W_p[i2];
    				if (s > 0)
    					s = 1;
    				else
    					s = (s < 0) ? -1 : 0;
    				for (i2 = 1; i2 <= p; i2++)
    					out.print(" " + E[i1][i2]);
    				out.println(" Cor " + C[i1] + " Res " + s);
    			}
    
    			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 count = 0, i1, k, num, run = 0, run_p = 0, s, sw = -1;
    	/*
    	     初期設定
    	*/
    		num_p[0] = 0;
    
    		for (i1 = 0; i1 <= p; i1++)
    			W[i1] = 0;
    	/*
    	     実行
    	*/
    		while (sw < 0) {
    
    			count++;
    			if (count > max)
    				sw = 0;
    
    			else {
    					// 訓練例の選択
    				k = (int)(rn.nextDouble() * n);
    				if (k >= n)
    					k = n - 1;
    					// 出力の計算
    				s = 0;
    				for (i1 = 0; i1 <= p; i1++)
    					s += W[i1] * E[k][i1];
    					// 正しい分類
    				if ((s > 0 && C[k] > 0) || (s < 0 && C[k] < 0)) {
    					run++;
    					if (run > run_p) {
    						num = bunrui();
    						if (num > num_p[0]) {
    							num_p[0] = num;
    							run_p  = run;
    							for (i1 = 0; i1 <= p; i1++)
    								W_p[i1] = W[i1];
    							if (num == n)
    								sw = count;
    						}
    					}
    				}
    					// 誤った分類
    				else {
    					run = 0;
    					for (i1 = 0; i1 <= p; i1++)
    						W[i1] += C[k] * E[k][i1];
    				}
    			}
    		}
    
    		return sw;
    	}
    }
    
    /*
    ---------------------入力ファイル------------
    最大試行回数 100 入力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ---------------------or.dat--------------
    OR演算の訓練例.最後のデータが目標出力値
    -1 -1 -1
    -1  1  1
     1 -1  1
     1  1  1
    */
    			

  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 n   = parseInt(document.getElementById("n").value);
    					// ネットワークの定義
    			net = new Perceptron (max, n, p);
    			net.input();
    					// 学習と結果の出力
    			net.learn();
    			document.getElementById("result").value = res;
    		}
    
    		/***************************/
    		/* Perceptron オブジェクト */
    		/***************************/
    		function Perceptron(max_i, n_i, p_i)
    		{
    				//
    				// 設定
    				//
    			this.max = max_i;   // 最大学習回数
    			this.n   = n_i;   // 訓練例の数
    			this.p   = p_i;   // 入力セルの数
    				//
    				// 領域の確保
    				//
    			this.E = new Array(this.n);   // 訓練例
    			for (let i1 = 0; i1 < this.n; i1++)
    				this.E[i1] = new Array(this.p+1);
    			this.W_p = new Array(this.p+1);   // 重み(ポケット)
    			this.W   = new Array(this.p+1);   // 重み
    			this.C   = new Array(this.n);   // 各訓練例に対する正しい出力
    		}
    
    		/******************************************/
    		/* 訓練例の分類                           */
    		/*      return : 正しく分類した訓練例の数 */
    		/******************************************/
    		Perceptron.prototype.bunrui = function()
    		{
    			let num = 0;
    
    			for (let i1 = 0; i1 < net.n; i1++) {
    				let s = 0;
    				for (let i2 = 0; i2 <= net.p; i2++)
    					s += net.W[i2] * net.E[i1][i2];
    				if ((s > 0 && net.C[i1] > 0) || (s < 0 && net.C[i1] < 0))
    					num++;
    			}
    
    			return num;
    		}
    
    		/************************/
    		/* 学習データの読み込み */
    		/************************/
    		Perceptron.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]);
    				net.C[i1] = parseInt(str[net.p]);
    			}
    		}
    
    		/********************/
    		/* 学習と結果の出力 */
    		/********************/
    		Perceptron.prototype.learn = function()
    		{
    					// 学習
    			let num   = new Array(1);
    			let n_tri = net.pocket(num);
    					// 結果の出力
    			res += "重み\n";
    			for (let i1 = 0; i1 <= net.p; i1++)
    				res += ("  " + net.W_p[i1]);
    			res += "\n";
    
    			res += "分類結果\n";
    			for (let i1 = 0; i1 < net.n; i1++) {
    				let s = 0;
    				for (let i2 = 0; i2 <= net.p; i2++)
    					s += net.E[i1][i2] * net.W_p[i2];
    				if (s > 0)
    					s = 1;
    				else
    					s = (s < 0) ? -1 : 0;
    				for (let i2 = 1; i2 <= net.p; i2++)
    					res += (" " + net.E[i1][i2]);
    				res += (" Cor " + net.C[i1] + " Res " + s + "\n");
    			}
    
    			if (net.n == num[0])
    				res += ("  !!すべてを分類(試行回数:" + n_tri + ")\n");
    			else
    				res += ("  !!" + num[0] + " 個を分類\n");
    		}
    
    		/********************************************/
    		/* Pocket Algorith with Ratcet              */
    		/*      num_p : 正しく分類した訓練例の数    */
    		/*      return : =0 : 最大学習回数          */
    		/*               >0  : すべてを分類(回数) */
    		/********************************************/
    		Perceptron.prototype.pocket = function(num_p)
    		{
    					//
    					// 初期設定
    					//
    			num_p[0] = 0;
    		
    			for (let i1 = 0; i1 <= net.p; i1++)
    				net.W[i1] = 0;
    					//
    					// 実行
    					//
    			let count = 0, k, run = 0, run_p = 0, sw = -1;
    		
    			while (sw < 0) {
    		
    				count++;
    				if (count > net.max)
    					sw = 0;
    		
    				else {
    						// 訓練例の選択
    					k = Math.floor(Math.random() * net.n);
    					if (k >= net.n)
    						k = net.n - 1;
    						// 出力の計算
    					let s = 0;
    					for (let i1 = 0; i1 <= net.p; i1++)
    						s += net.W[i1] * net.E[k][i1];
    						// 正しい分類
    					if ((s > 0 && net.C[k] > 0) || (s < 0 && net.C[k] < 0)) {
    						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.p; i1++)
    									net.W_p[i1] = net.W[i1];
    								if (num == net.n)
    									sw = count;
    							}
    						}
    					}
    						// 誤った分類
    					else {
    						run = 0;
    						for (let i1 = 0; i1 <= net.p; i1++)
    							net.W[i1] += net.C[k] * net.E[k][i1];
    					}
    				}
    			}
    		
    			return sw;
    		}
    	</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="100"> 
    	入力セル数:<INPUT ID="p" 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演算の訓練例.各行の最後のデータが目標出力値
    -1 -1 -1
    -1  1  1
     1 -1  1
     1  1  1
    			</TEXTAREA>
    		</DIV>
    	</DIV>
    </BODY>
    
    </HTML>
    			

  4. PHP

    <?php
    
    /***********************************/
    /* パーセプトロン学習              */
    /* (Pocket Algorith with Ratcet) */
    /*      coded by Y.Suganuma        */
    /***********************************/
    
    /**************************/
    /* Perceptronクラスの定義 */
    /**************************/
    class Perceptron {
    	private $max;   // 最大学習回数
    	private $n;   // 訓練例の数
    	private $p;   // 入力セルの数
    	private $W_p;   // 重み(ポケット)
    	private $W;   // 重み
    	private $E;   // 訓練例
    	private $C;   // 各訓練例に対する正しい出力
    	
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	function Perceptron($max_i, $n_i, $p_i)
    	{
    	/*
    	     設定
    	*/
    		$this->max = $max_i;
    		$this->n   = $n_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+1);
    	
    		$this->W_p = array($this->p+1);
    		$this->W   = array($this->p+1);
    		$this->C   = array($this->n);
    	}
    	
    	/******************************************/
    	/* 訓練例の分類                           */
    	/*      return : 正しく分類した訓練例の数 */
    	/******************************************/
    	function Bunrui()
    	{
    		$num = 0;
    	
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$s = 0;
    			for ($i2 = 0; $i2 <= $this->p; $i2++)
    				$s += $this->W[$i2] * $this->E[$i1][$i2];
    			if (($s > 0 && $this->C[$i1] > 0) || ($s < 0 && $this->C[$i1] < 0))
    				$num++;
    		}
    	
    		return $num;
    	}
    	
    	/**************************/
    	/* 学習データの読み込み   */
    	/*      name : ファイル名 */
    	/**************************/
    	function Input($name)
    	{
    		$st = fopen($name, "r");
    	
    		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(" "));
    			$this->C[$i1] = intval(strtok(" "));
    		}
    	
    		fclose($st);
    	}
    	
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      pr : =0 : 画面に出力     */
    	/*           =1 : ファイルに出力 */
    	/*      name : 出力ファイル名    */
    	/*********************************/
    	function Learn($pr, $name = "STDOUT")
    	{
    		$n_tri = $this->Pocket($num);
    	
    		if ($pr == 0)
    			$out = STDOUT;
    		else
    			$out = fopen($name, "wb");
    	
    		fwrite($out, "重み\n");
    		$str = "";
    		for ($i1 = 0; $i1 <= $this->p; $i1++)
    			$str = $str.$this->W_p[$i1]." ";
    		fwrite($out, $str."\n");
    	
    		fwrite($out,"分類結果\n");
    		for ($i1 = 0; $i1 < $this->n; $i1++) {
    			$s  = 0;
    			for ($i2 = 0; $i2 <= $this->p; $i2++)
    				$s += $this->E[$i1][$i2] * $this->W_p[$i2];
    			if ($s > 0)
    				$s = 1;
    			else
    				$s = ($s < 0) ? -1 : 0;
    			$str = "";
    			for ($i2 = 1; $i2 <= $this->p; $i2++)
    				$str = $str.$this->E[$i1][$i2]." ";
    			$str = $str."Cor ".$this->C[$i1]." Res ".$s;
    			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;
    		$run   = 0;
    		$run_p = 0;
    		$sw    = -1;
    		$num_p = 0;
    	
    		for ($i1 = 0; $i1 <= $this->p; $i1++)
    			$this->W[$i1] = 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;
    						// 出力の計算
    				$s = 0;
    				for ($i1 = 0; $i1 <= $this->p; $i1++)
    					$s += $this->W[$i1] * $this->E[$k][$i1];
    						// 正しい分類
    				if (($s > 0 && $this->C[$k] > 0) || ($s < 0 && $this->C[$k] < 0)) {
    					$run++;
    					if ($run > $run_p) {
    						$num = $this->Bunrui();
    						if ($num > $num_p) {
    							$num_p = $num;
    							$run_p = $run;
    							for ($i1 = 0; $i1 <= $this->p; $i1++)
    								$this->W_p[$i1] = $this->W[$i1];
    							if ($num == $this->n)
    								$sw = $count;
    						}
    					}
    				}
    						// 誤った分類
    				else {
    					$run = 0;
    					for ($i1 = 0; $i1 <= $this->p; $i1++)
    						$this->W[$i1] += $this->C[$k] * $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", $max, $p, $n);
    		fscanf($st, "%*s %s", $name);
    		fclose($st);
    					// ネットワークの定義
    		$net = new Perceptron($max, $n, $p);
    		$net->Input($name);
    					// 学習と結果の出力
    		if (count($argv) == 2)
    			$net->Learn(0);
    		else
    			$net->Learn(1, $argv[2]);
    	}
    
    	else
    		exit("***error   入力データファイル名を指定して下さい\n");
    
    /*
    ---------------------入力ファイル------------
    最大試行回数 100 入力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ---------------------or.dat--------------
    OR演算の訓練例.最後のデータが目標出力値
    -1 -1 -1
    -1  1  1
     1 -1  1
     1  1  1
    */
    
    ?>
    			

  5. Ruby

    ####################################
    # パーセプトロン学習
    # (Pocket Algorith with Ratcet)
    #      coded by Y.Suganuma
    ####################################
    
    ###########################
    # Perceptronクラスの定義
    #      coded by Y.Suganuma
    ###########################
    
    class Perceptron
    
    	#########################
    	# コンストラクタ
    	#      max : 最大学習回数
    	#      n : 訓練例の数
    	#      p : 入力セルの数
    	#########################
    	def initialize(max_i, n_i, p_i)
    			# 設定
    		@_max = max_i
    		@_n   = n_i
    		@_p   = p_i
    			# 領域の確保
    		@_E   = Array.new(@_n)   # 訓練例
    		for i1 in 0 ... @_n
    			@_E[i1] = Array.new(@_p+1)
    		end
    		@_W_p = Array.new(@_p+1)   # 重み(ポケット)
    		@_W   = Array.new(@_p+1)   # 重み
    		@_C   = Array.new(@_n)   # 各訓練例に対する正しい出力
    	end
    
    	#########################################
    	# 訓練例の分類
    	#      return : 正しく分類した訓練例の数
    	#########################################
    	def Bunrui()
    
    		num = 0
    		for i1 in 0 ... @_n
    			s = 0
    			for i2 in 0 ... @_p+1
    				s += @_W[i2] * @_E[i1][i2]
    			end
    			if (s > 0 and @_C[i1] > 0) or (s < 0 and @_C[i1] < 0)
    				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
    			@_C[i1] = Integer(s[@_p])
    		end
    	
    		f.close()
    	end
    
    	#################################
    	# 学習と結果の出力
    	#      pr : =0 : 画面に出力
    	#           =1 : ファイルに出力
    	#      name : 出力ファイル名
    	#################################
    	def Learn(pr, name="")
    	
    		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 ... @_p+1
    			out.print(" " + String(@_W_p[i1]))
    		end
    		out.print("\n")
    	
    		out.print("分類結果\n")
    		for i1 in 0 ... @_n
    			s  = 0
    			for i2 in 0 ... @_p+1
    				s += @_E[i1][i2] * @_W_p[i2]
    			end
    			if s > 0
    				s = 1
    			else
    				if s < 0
    					s = -1
    				else
    					s = 0
    				end
    			end
    			for i2 in 1 ... @_p+1
    				out.print(" " + String(@_E[i1][i2]))
    			end
    			out.print(" Cor " + String(@_C[i1]) + " Res " + String(s) + "\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
    		run      = 0
    		run_p    = 0
    		sw       = -1
    		num_p[0] = 0
    		for i1 in 0 ... @_p+1
    			@_W[i1] = 0
    		end
    			# 実行
    		while sw < 0
    	
    			count += 1
    			if count > @_max
    				sw = 0
    	
    			else
    					# 訓練例の選択
    				k = Integer(rand(0) * @_n)
    				if k >= @_n
    					k = @_n - 1
    				end
    					# 出力の計算
    				s = 0
    				for i1 in 0 ... @_p+1
    					s += @_W[i1] * @_E[k][i1]
    				end
    					# 正しい分類
    				if (s > 0 and @_C[k] > 0) or (s < 0 and @_C[k] < 0)
    					run += 1
    					if run > run_p 
    						num = Bunrui()
    						if num > num_p[0]
    							num_p[0] = num
    							run_p    = run
    							for i1 in 0 ... @_p+1
    								@_W_p[i1] = @_W[i1]
    							end
    							if num == @_n
    								sw = count
    							end
    						end
    					end
    					# 誤った分類
    				else
    					run = 0
    					for i1 in 0 ... @_p+1
    						@_W[i1] += @_C[k] * @_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])
    	n    = Integer(s[5])
    	s    = gets().split(" ")
    	name = s[1]
    				# ネットワークの定義
    	srand()
    	net = Perceptron.new(max, n, 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 訓練例の数 4
    入力データファイル or.dat
    
    ---------------------or.dat--------------
    OR演算の訓練例.最後のデータが目標出力値
    -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 *
    
    ###########################
    # Perceptronクラスの定義
    #      coded by Y.Suganuma
    ###########################
    
    class Perceptron :
    
    	#########################
    	# コンストラクタ
    	#      max : 最大学習回数
    	#      n : 訓練例の数
    	#      p : 入力セルの数
    	#########################
    	def __init__(self, max_i, n_i, p_i) :
    			# 設定
    		self.max = max_i
    		self.n   = n_i
    		self.p   = p_i
    			# 領域の確保
    		self.E   = np.empty((self.n, self.p+1), np.int)   # 訓練例
    		self.W_p = np.empty(self.p+1, np.int)   # 重み(ポケット)
    		self.W   = np.empty(self.p+1, np.int)   # 重み
    		self.C   = np.empty(self.n, np.int)   # 各訓練例に対する正しい出力
    
    	#########################################
    	# 訓練例の分類
    	#      return : 正しく分類した訓練例の数
    	#########################################
    	def Bunrui(self) :
    
    		num = 0
    		for i1 in range(0, self.n) :
    			s = 0
    			for i2 in range(0, self.p+1) :
    				s += self.W[i2] * self.E[i1][i2]
    			if (s > 0 and self.C[i1] > 0) or (s < 0 and self.C[i1] < 0) :
    				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])
    			self.C[i1] = int(s[self.p])
    	
    		f.close()
    
    	#################################
    	# 学習と結果の出力
    	#      pr : =0 : 画面に出力
    	#           =1 : ファイルに出力
    	#      name : 出力ファイル名
    	#################################
    	def Learn(self, pr, name="") :
    	
    		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.p+1) :
    			out.write(" " + str(self.W_p[i1]))
    		out.write("\n")
    	
    		out.write("分類結果\n")
    		for i1 in range(0, self.n) :
    			s  = 0
    			for i2 in range(0, self.p+1) :
    				s += self.E[i1][i2] * self.W_p[i2]
    			if s > 0 :
    				s = 1
    			else :
    				if s < 0 :
    					s = -1
    				else :
    					s = 0
    			for i2 in range(1, self.p+1) :
    				out.write(" " + str(self.E[i1][i2]))
    			out.write(" Cor " + str(self.C[i1]) + " Res " + str(s) + "\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
    		run      = 0
    		run_p    = 0
    		sw       = -1
    		num_p[0] = 0
    		for i1 in range(0, self.p+1) :
    			self.W[i1] = 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
    					# 出力の計算
    				s = 0
    				for i1 in range(0, self.p+1) :
    					s += self.W[i1] * self.E[k][i1]
    					# 正しい分類
    				if (s > 0 and self.C[k] > 0) or (s < 0 and self.C[k] < 0) :
    					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.p+1) :
    								self.W_p[i1] = self.W[i1]
    							if num == self.n :
    								sw = count
    					# 誤った分類
    				else :
    					run = 0
    					for i1 in range(0, self.p+1) :
    						self.W[i1] += self.C[k] * self.E[k][i1]
    	
    		return sw
    
    ####################################
    # パーセプトロン学習
    # (Pocket Algorith with Ratcet)
    #      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])
    	n    = int(s[5])
    	s    = f.readline().split()
    	name = s[1]
    	f.close()
    				# ネットワークの定義
    	seed()
    	net = Perceptron(max, n, p)
    	net.Input(name)
    				# 学習と結果の出力
    	if len(sys.argv) == 2 :
    		net.Learn(0)
    	else :
    		net.Learn(1, sys.argv[2])
    
    else :
    	print("***error   入力ファイル名を指定して下さい")
    
    """
    ---------------------入力ファイル------------
    最大試行回数 100 入力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ---------------------or.dat--------------
    OR演算の訓練例.最後のデータが目標出力値
    -1 -1 -1
    -1  1  1
     1 -1  1
     1  1  1
    """
    			

  7. C#

    /***********************************/
    /* パーセプトロン学習              */
    /* (Pocket Algorith with Ratcet) */
    /*      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 n          = int.Parse(str[5]);
    
    			str            = lines[1].Split(charSep, StringSplitOptions.RemoveEmptyEntries);
    			String name    = str[1];
    					// ネットワークの定義
    			Perceptron net = new Perceptron (max, n, p);
    			net.input(name);
    					// 学習と結果の出力
    			if (args.Length == 1)
    				net.learn(0, "");
    			else
    				net.learn(1, args[1]);
    		}
    					// エラー
    		else {
    			Console.WriteLine("***error   入力データファイル名を指定して下さい");
    			Environment.Exit(1);
    		}
    	}
    }
    
    /**************************/
    /* Perceptronクラスの定義 */
    /**************************/
    class Perceptron {
    
    	int max;   // 最大学習回数
    	int n;   // 訓練例の数
    	int p;   // 入力セルの数
    	int[] W_p;   // 重み(ポケット)
    	int[] W;   // 重み
    	int[][] E;   // 訓練例
    	int[] C;   // 各訓練例に対する正しい出力
    	Random rn;   // 乱数
    
    	/******************/
    	/* コンストラクタ */
    	/******************/
    	public Perceptron(int max_i, int n_i, int p_i)
    	{
    				//
    				// 設定
    				//
    		max = max_i;
    		n   = n_i;
    		p   = p_i;
    
    		rn  = new Random();   // 乱数の初期設定
    				//
    				// 領域の確保
    				//
    		E   = new int [n][];
    		for (int i1 = 0; i1 < n; i1++)
    			E[i1] = new int [p+1];
    		W_p = new int [p+1];
    		W   = new int [p+1];
    		C   = new int [n];
    	}
    
    	/******************************************/
    	/* 訓練例の分類                           */
    	/*      return : 正しく分類した訓練例の数 */
    	/******************************************/
    	int bunrui()
    	{
    		int num = 0;
    
    		for (int i1 = 0; i1 < n; i1++) {
    			int s = 0;
    			for (int i2 = 0; i2 <= p; i2++)
    				s += W[i2] * E[i1][i2];
    			if ((s > 0 && C[i1] > 0) || (s < 0 && C[i1] < 0))
    				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]);
    			C[i1] = int.Parse(str[p]);
    		}
    	}
    
    	/*********************************/
    	/* 学習と結果の出力              */
    	/*      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 <= p; i1++)
    				Console.Write("  " + W_p[i1]);
    			Console.WriteLine();
    
    			Console.WriteLine("分類結果");
    			for (int i1 = 0; i1 < n; i1++) {
    				int s  = 0;
    				for (int i2 = 0; i2 <= p; i2++)
    					s += E[i1][i2] * W_p[i2];
    				if (s > 0)
    					s = 1;
    				else
    					s = (s < 0) ? -1 : 0;
    				for (int i2 = 1; i2 <= p; i2++)
    					Console.Write(" " + E[i1][i2]);
    				Console.WriteLine(" Cor " + C[i1] + " Res " + s);
    			}
    		}
    
    		else {
    
    			StreamWriter OUT = new StreamWriter(name, true);
    
    			OUT.WriteLine("重み");
    			for (int i1 = 0; i1 <= p; i1++)
    				OUT.Write("  " + W_p[i1]);
    			OUT.WriteLine();
    
    			OUT.WriteLine("分類結果");
    			for (int i1 = 0; i1 < n; i1++) {
    				int s  = 0;
    				for (int i2 = 0; i2 <= p; i2++)
    					s += E[i1][i2] * W_p[i2];
    				if (s > 0)
    					s = 1;
    				else
    					s = (s < 0) ? -1 : 0;
    				for (int i2 = 1; i2 <= p; i2++)
    					OUT.Write(" " + E[i1][i2]);
    				OUT.WriteLine(" Cor " + C[i1] + " Res " + s);
    			}
    
    			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;
    
    		for (int i1 = 0; i1 <= p; i1++)
    			W[i1] = 0;
    				//
    				// 実行
    				//
    		int count = 0, k, run = 0, run_p = 0, sw = -1;
    
    		while (sw < 0) {
    
    			count++;
    			if (count > max)
    				sw = 0;
    
    			else {
    					// 訓練例の選択
    				k = (int)(rn.NextDouble() * n);
    				if (k >= n)
    					k = n - 1;
    					// 出力の計算
    				int s = 0;
    				for (int i1 = 0; i1 <= p; i1++)
    					s += W[i1] * E[k][i1];
    					// 正しい分類
    				if ((s > 0 && C[k] > 0) || (s < 0 && C[k] < 0)) {
    					run++;
    					if (run > run_p) {
    						int num = bunrui();
    						if (num > num_p) {
    							num_p = num;
    							run_p = run;
    							for (int i1 = 0; i1 <= p; i1++)
    								W_p[i1] = W[i1];
    							if (num == n)
    								sw = count;
    						}
    					}
    				}
    					// 誤った分類
    				else {
    					run = 0;
    					for (int i1 = 0; i1 <= p; i1++)
    						W[i1] += C[k] * E[k][i1];
    				}
    			}
    		}
    
    		return sw;
    	}
    }
    
    /*
    ---------------------入力ファイル------------
    最大試行回数 100 入力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ---------------------or.dat--------------
    OR演算の訓練例.最後のデータが目標出力値
    -1 -1 -1
    -1  1  1
     1 -1  1
     1  1  1
    */
    			

  8. VB

    '*********************************'
    ' パーセプトロン学習              '
    ' (Pocket Algorith with Ratcet) '
    '      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 n As Integer        = Integer.Parse(str(5))
    
    			str                = MS.Split(inp.ReadLine().Trim())
    			Dim name As String = str(1)
    			inp.Close()
    					' ネットワークの定義
    			Dim net As Perceptron = new Perceptron (max, n, 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
    
    	'************************'
    	' Perceptronクラスの定義 '
    	'************************'
    	Class Perceptron
    
    		Private max As Integer   ' 最大学習回数
    		Private n As Integer   ' 訓練例の数
    		Private p As Integer   ' 入力セルの数
    		Private W_p() As Integer   ' 重み(ポケット)
    		Private W() As Integer   ' 重み
    		Private E(,) As Integer   ' 訓練例
    		Private C() As Integer   ' 各訓練例に対する正しい出力
    		Private rn As Random   ' 乱数
    
    		'****************'
    		' コンストラクタ '
    		'****************'
    		Public Sub New(max_i As Integer, n_i As Integer, p_i As Integer)
    				'
    				' 設定
    				'
    			max = max_i
    			n   = n_i
    			p   = p_i
    
    			rn  = new Random()   ' 乱数の初期設定
    				'
    				' 領域の確保
    				'
    			ReDim E(n,p+1)
    			ReDim W_p(p+1)
    			ReDim W(p+1)
    			ReDim C(n)
    
    		End Sub
    
    		'****************************************'
    		' 訓練例の分類                           '
    		'      return : 正しく分類した訓練例の数 '
    		'****************************************'
    		Function bunrui()
    
    			Dim num As Integer = 0
    
    			For i1 As Integer = 0 To n-1
    				Dim s As Integer = 0
    				For i2 As Integer = 0 To p
    					s += W(i2) * E(i1,i2)
    				Next
    				If (s > 0 and C(i1) > 0) or (s < 0 and C(i1) < 0)
    					num += 1
    				End If
    			Next
    
    			Return num
    
    		End Function
    
    		'************************'
    		' 学習データの読み込み   '
    		'      name : ファイル名 '
    		'************************'
    		Public Sub input (name As String)
    
    			Dim MS As Regex = New Regex("\s+") 
    			Dim inp As StreamReader = New StreamReader(name)
    			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
    				C(i1) = Integer.Parse(str(p))
    			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 p
    					Console.Write("  " & W_p(i1))
    				Next
    				Console.WriteLine()
    
    				Console.WriteLine("分類結果")
    				For i1 As Integer = 0 To n-1
    					Dim s As Integer = 0
    					For i2 As Integer = 0 To p
    						s += E(i1,i2) * W_p(i2)
    					Next
    					If s > 0
    						s = 1
    					Else
    						If s < 0
    							s = -1
    						Else
    							s = 0
    						End If
    					End If
    					For i2 As Integer = 1 To p
    						Console.Write(" " & E(i1,i2))
    					Next
    					Console.WriteLine(" Cor " & C(i1) & " Res " & s)
    				Next
    
    			Else
    
    				Dim OUT As StreamWriter = new StreamWriter(name)
    
    				OUT.WriteLine("重み")
    				For i1 As Integer = 0 To p
    					OUT.Write("  " & W_p(i1))
    				Next
    				OUT.WriteLine()
    
    				OUT.WriteLine("分類結果")
    				For i1 As Integer = 0 To n-1
    					Dim s As Integer = 0
    					For i2 As Integer = 0 To p
    						s += E(i1,i2) * W_p(i2)
    					Next
    					If s > 0
    						s = 1
    					Else
    						If s < 0
    							s = -1
    						Else
    							s = 0
    						End If
    					End If
    					For i2 As Integer = 1 To p
    						OUT.Write(" " & E(i1,i2))
    					Next
    					OUT.WriteLine(" Cor " & C(i1) & " Res " & s)
    				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
    
    			For i1 As Integer = 0 To p
    				W(i1) = 0
    			Next
    					'
    					' 実行
    					'
    			Dim k As Integer
    			Dim count As Integer = 0
    			Dim run As Integer   = 0
    			Dim run_p As Integer = 0
    			Dim sw As Integer    = -1
    
    			Do While sw < 0
    
    				count += 1
    				If count > max
    					sw = 0
    
    				Else
    						' 訓練例の選択
    					k = Math.Floor(rn.NextDouble() * n)
    					If k >= n
    						k = n - 1
    					End If
    						' 出力の計算
    					Dim s As Integer = 0
    					For i1 As Integer = 0 To p
    						s += W(i1) * E(k,i1)
    					Next
    						' 正しい分類
    					If (s > 0 and C(k) > 0) or (s < 0 and C(k) < 0)
    						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 p
    									W_p(i1) = W(i1)
    								Next
    								If num = n
    									sw = count
    								End If
    							End If
    						End If
    						' 誤った分類
    					Else
    						run = 0
    						For i1 As Integer = 0 To p
    							W(i1) += C(k) * E(k,i1)
    						Next
    					End If
    				End If
    			Loop
    	
    			Return sw
    
    		End Function
    
    	End Class
    
    End Module
    
    /*
    ---------------------入力ファイル------------
    最大試行回数 100 入力セルの数 2 訓練例の数 4
    入力データファイル or.dat
    
    ---------------------or.dat--------------
    OR演算の訓練例.最後のデータが目標出力値
    -1 -1 -1
    -1  1  1
     1 -1  1
     1  1  1
    */
    			

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