#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <local/bgi.h>
#define step 100
#define nyuron_kazu 49
#define masume 7
#define Kr 0.95
#define Ks 0.95
#define Km 0.1
#define a 2.0
#define v 2.0
#define Q 0.0
#define E 0.015
#define zikan 1800
static char tim[zikan];
FILE *data_file;
FILE *guraf_file;
double drand48();
void gaibunuryoku();
void sougoketugou();
void fuousei();
void naibu_zyoutai();
void hanbetu_gakusyu();
void input_noizu();
void graw();
void hopfild();
int in_pattan[zikan][nyuron_kazu];
int time;
int noizu_number;
int gurafikku;
int hanten;
int number;
int kaunter;
int kasan;
int kasan_zikan;
int lerne[zikan][nyuron_kazu];
int kaisi;
double gaibu_input[zikan][nyuron_kazu];
double sougo_input[zikan][nyuron_kazu];
double fuou_input[zikan][nyuron_kazu];
double wait[nyuron_kazu][nyuron_kazu];
double output[zikan+50][nyuron_kazu];
main()
{
printf("パターンごとに時間加算 YES 1 NO 0 ");
scanf("%d",&kasan);
printf("ノイズなら 1 欠落させるなら0 ");
scanf("%d",&hanten);
if(hanten==1)
printf("何個 ノイズをいれる ");
else
printf("何個 欠落させる ");
scanf("%d",&noizu_number);
while(time<zikan)
{
gaibunuryoku();
sougoketugou();
fuousei();
naibu_zyoutai();
hanbetu_gakusyu();
time=time+1;
}
hopfild();
}
}
/*外部入力*/
void gaibunuryoku()
{
int i,j;
char pattan[masume];
if(kaunter<step)
{
kaunter=kaunter+1;
kasan_zikan=0;
}
else
{
if(number==5)
number=0;
else
number=number+1;
kaunter=1;
if(kasan==1)
kasan_zikan=1;
}
if(number==0)
data_file=fopen("PATTAN/A_pattan.dat","r");
if(number==1)
data_file=fopen("PATTAN/B_pattan.dat","r");
if(number==2)
data_file=fopen("PATTAN/C_pattan.dat","r");
if(number==3)
data_file=fopen("PATTAN/a_pattan.dat","r");
if(number==4)
data_file=fopen("PATTAN/b_pattan.dat","r");
if(number==5)
data_file=fopen("PATTAN/c_pattan.dat","r");
for(j=0;j<masume;j++)
{
fscanf(data_file,"%s",pattan);
for(i=0;i<masume;i++)
{
if(pattan[i]=='#')
in_pattan[time][masume*j+i]=1;
else
in_pattan[time][masume*j+i]=-1;
}
}
input_noizu();
fclose(data_file);
for(i=0;i<nyuron_kazu;i++)
{
if(time==0||kasan_zikan==1)
gaibu_input[time][i]=v*in_pattan[time][i];
else
gaibu_input[time][i]=Ks*gaibu_input[time-1][i]+v*in_pattan[time][i];
}
}
/*ノイズ付加*/
void input_noizu()
{
int i,j,noizu_same,noizu_kazu,bango,noizu[nyuron_kazu],noi,noizu_onazi;
noizu_kazu=0;
noizu_same=1;
noizu[0]=(int)(drand48()*49);
i=1;
noizu_kazu=1;
while(noizu_kazu<noizu_number)
{
noizu_onazi=0;
while(noizu_onazi<1)
{
noizu_same=0;
noi=(int)(drand48()*49);
if(noi==49)
noi=48;
for(j=0;j<i;j++)
if(noizu[j]==noi)
noizu_same=1;
if(noizu_same==0)
noizu_onazi=1;
else
noizu_onazi=0;
}
noizu[i]=noi;
i=i+1;
noizu_kazu=noizu_kazu+1;
}
for(i=0;i<noizu_number;i++)
{
if(hanten==1)
{
if(in_pattan[time][noizu[i]]==1)
in_pattan[time][noizu[i]]=-1;
else
in_pattan[time][noizu[i]]=1;
}
else
in_pattan[time][noizu[i]]=0;
}
}
/*ニューロン間の相互結合*/
void sougoketugou()
{
int i,j;
double sougo;
for(i=0;i<nyuron_kazu;i++)
{
if(time==0||kasan_zikan==1)
sougo_input[time][i]=0;
else
{
sougo=0;
for(j=0;j<nyuron_kazu;j++)
sougo=wait[i][j]*output[time-1][j]+sougo;
sougo_input[time][i]=Km*sougo_input[time-1][i]+sougo;
}
}
}
/*ニューロン自身の不応性*/
void fuousei()
{
int i,j;
for(i=0;i<nyuron_kazu;i++)
{
if(time==0||kasan_zikan==1)
fuou_input[time][i]=0;
else
fuou_input[time][i]=Kr*fuou_input[time-1][i]-a*output[time-1][i]-Q;
}
}
/*ニューロンの内部状態*/
void naibu_zyoutai()
{
int i,j;
double naibu_input;
for(i=0;i<nyuron_kazu;i++)
{
naibu_input=gaibu_input[time][i]+sougo_input[time][i]+fuou_input[time][i];
output[time][i]=2/(1+exp(-naibu_input/E))-1;
}
}
/*未知、既知パターンの判別 と学習*/
void hanbetu_gakusyu()
{
int i,j,syuusei[nyuron_kazu];
float zyouken1,zyouken2,zyouken3;
for(i=0;i<nyuron_kazu;i++)
{
zyouken1=fabs(gaibu_input[time][i])+fabs(sougo_input[time][i]+fuou_input[time][i]);
zyouken2=fabs(gaibu_input[time][i]+sougo_input[time][i]+fuou_input[time][i]);
if(zyouken2<zyouken1)
{
lerne[time][i]=10;
for(j=0;j<nyuron_kazu;j++)
if(i!=j)
{
if(gaibu_input[time][i]*output[time-1][j]>0)
wait[i][j]=wait[i][j]+0.05;
else
wait[i][j]=wait[i][j]-0.05;
}
}
}
}
/*ホップフィールドネットによる学習の確認*/
void hopfild()
{
int i,j,pattan,timezikan,onazi,kaisu;
double hop,hopfild[nyuron_kazu],maepattan[nyuron_kazu];
timezikan=0;
for(pattan=0;pattan<6;pattan++)
{
for(i=0;i<nyuron_kazu;i++)
maepattan[i]=in_pattan[timezikan][i];
onazi=0;
kaisu=0;
while(onazi<nyuron_kazu)
{
onazi=0;
for(i=0;i<nyuron_kazu;i++)
{
for(j=0;j<nyuron_kazu;j++)
hop=wait[i][j]*maepattan[j]+hop;
if(hop<0)
hopfild[i]=-1;
else
hopfild[i]=1;
hop=0;
}
for(i=0;i<nyuron_kazu;i++)
if(maepattan[i]==hopfild[i])
onazi=onazi+1;
for(i=0;i<nyuron_kazu;i++)
maepattan[i]=hopfild[i];
kaisu=kaisu+1;
if(kaisu==50)
onazi=49;
}
for(i=0;i<nyuron_kazu;i++)
output[zikan+pattan][i]=maepattan[i];
timezikan=timezikan+step;
printf("%d\n",kaisu);
}
}