题目要求实现一个脉冲神经网络的模拟器,主要由三部分:神经元,脉冲源,突触 构成,其中,神经元和脉冲源都由突触连接,可以是 脉冲源-->神经元,也可以是 神经元-->神经元,因此可以把它看成是一个有向图,脉冲源只有出度,神经元可以既有出度,又有入度,而突触就是把每个点相连的边。
每个脉冲源都有一个参数 r ,只有在 r > myrand()时脉冲源才会释放一次脉冲到神经元。
每个神经元有两个关键参数 u 和 v,只有在某时刻该神经元的 v >= 30 时该神经元才会释放一次脉冲, 释放脉冲后 v 变成 c , u 变成 u+d。
每个突触都有两个参数 w 和 d,w 表示脉冲强度,d表示传输延迟,也就是说无论是神经元还是脉冲源发射了脉冲,其脉冲值都只与相连的突触有关。
分析完毕见代码:
#include
#include
using namespace std;
static unsigned long _next = 1;
const double INF = 1e8;
//RAND_MAX assumed to be 32767
int myrand(void) {
_next = _next * 1103515245 + 12345;
return((unsigned)(_next/65536) % 32768);
}
const int N = 2010;
int n,S,P,T;
double dt;
int h[N],e[N*2],D[N*2],ne[N*2],idx;
double w[N],v[N],u[N],a[N],b[N],c[N],d[N];
int r[N],cnt[N];
double I[1024][N/2];
void Add(int a,int b,double c,int d)
{
e[idx] = b;
w[idx] = c;
D[idx] = d;
ne[idx] = h[a];
h[a] = idx++;
}//采用邻接表存储,在存储连接关系时也要额外存储突触的两个性质
int main()
{
memset(h,-1,sizeof h);
scanf("%d%d%d%d",&n,&S,&P,&T);
scanf("%lf",&dt);
for(int i = 0;i < n;)
{
int rn;
scanf("%d",&rn);
double vv,uu,aa,bb,cc,dd;
scanf("%lf%lf%lf%lf%lf%lf",&vv,&uu,&aa,&bb,&cc,&dd);
for(int j = 0;j < rn;j++,i++)
{
v[i] = vv;u[i] = uu;a[i] = aa;b[i] = bb;c[i] = cc;d[i] = dd;
}
}//读入神经元相关数据
for(int i = n;i < n+P;i++)
{
scanf("%d",&r[i]);
}//读入脉冲源相关数据
int mod = 0;//mod的目的是找到最大的时间跨度,存储空间不够,只能开成循环数组了
for(int i = 0;i < S;i++)
{
int a0,b0,d0;
double c0;
scanf("%d%d%lf%d",&a0,&b0,&c0,&d0);
mod = max(mod,d0+1);
Add(a0,b0,c0,d0);//对有向图进行初始化
}
for(int i = 0;i < T;i++)
{
int t = i % mod;
for(int j = n;j < n+P;j++)
{
if(r[j] > myrand())
{
for(int k = h[j]; k != -1;k = ne[k])
{
int x = e[k];
I[(t+D[k])%mod][x] += w[k];
}
}//发射脉冲
}
for(int j = 0;j < n;j++)
{
double vv = v[j],uu = u[j];
v[j] = vv+dt*(0.04*vv*vv+5*vv+140-uu)+I[t][j];
u[j] = uu+dt*a[j]*(b[j]*vv-uu);
if(v[j] >= 30)
{
for(int k = h[j]; k != -1;k = ne[k])
{
int x = e[k];
I[(t+D[k])%mod][x] += w[k];
}
cnt[j]++;
v[j] = c[j];
u[j] = u[j]+d[j];
}
}
memset(I[t],0,sizeof I[t]);
}
double minv = INF,maxv = -INF;
int minc = INF,maxc = -INF;
for(int i = 0;i < n;i++)
{
minv = min(minv,v[i]);
maxv = max(maxv,v[i]);
minc = min(minc,cnt[i]);
maxc = max(maxc,cnt[i]);
}
printf("%.3f %.3f\n",minv,maxv);
printf("%d %d",minc,maxc);
return 0;
}