| 情報学部 | 菅沼ホーム | 目次 | 索引 | 
/***********************************/
/* パーセプトロン学習              */
/* (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
*/
			
/***********************************/
/* パーセプトロン学習              */
/* (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
*/
			
<!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>
			
<?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
*/
?>
			
####################################
# パーセプトロン学習
# (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
			
# -*- 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
"""
			
/***********************************/
/* パーセプトロン学習              */
/* (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
*/
			
'*********************************'
' パーセプトロン学習              '
' (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
*/
			
| 情報学部 | 菅沼ホーム | 目次 | 索引 |