CSP202109-3 脉冲神经网络

@Pelom  July 4, 2022

题意

按照题目要求模拟脉冲神经网络
数据范围:$\begin{matrix}&T&N&S&P&D\\1&\le10^2&\le10^2&\le10^2&\le10^2&\le10^2\\2&\le10^3&\le10^3&\le10^3&\le10^3&\le10^3\\3&\le10^5&\le10^3&\le10^3&\le10^3&\le10\end{matrix}$

题解

  1. $66\%$数据
    按照题意进行模拟

    1. 枚举$[0,T]$每个时刻,这里应为一个外层循环
    2. 对脉冲源进行处理:通过$r$参数判断是否会发射脉冲
    3. 对神经元进行处理:通过$v_k$判断是否会发射脉冲;如果发射脉冲,则更新$u_k,v_k$
  2. $100\%$数据
    由于取模操作比较费时,会导致上述算法TLE
    所以提前取模以应对卡常
    同时注意存图时使用链式前向星
    代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int INF=1e9;
    const int N=1000+10;
    int n,s,p,t,cnt,mod;
    int r[N],tot[N],head[N<<1];;
    double dt;
    double v[N],u[N],a[N],b[N],c[N],d[N],I[N][N];
    struct Edge{
        int nxt,to,d;
        double w;
    }e[N<<1];
    static unsigned long Next=1;
    int myrand(void){
        Next=Next*1103515245+12345;
        return((unsigned)(Next/65536)%32768);
    }
    void add(int u,int v,double w,int d){
        e[cnt]=Edge{head[u],v,d,w};
        head[u]=cnt++;
    }
    void launch(int u,int t){
        for(int i=head[u];~i;i=e[i].nxt)
            I[(t+e[i].d)%mod][e[i].to]+=e[i].w;
    }
    int main(){
        memset(head,-1,sizeof(head));
        scanf("%d%d%d%d",&n,&s,&p,&t);
        scanf("%lf",&dt);
        int sum=0,rn;
        double vv,uu,aa,bb,cc,dd;
        for(;sum<n;){
            scanf("%d%lf%lf%lf%lf%lf%lf",&rn,&vv,&  uu,&aa,&bb,&cc,&dd);
            for(int i=sum;i<n;i++){
                v[i]=vv,u[i]=uu;
                a[i]=aa,b[i]=bb,c[i]=cc,d[i]=dd;
            }
            sum+=rn;
        }
        for(int i=0;i<p;i++)
            scanf("%d",&r[i]);
        int ss,tt,ddd;
        double ww;
        for(int i=0;i<s;i++){
            scanf("%d%d %lf %d",&ss,&tt,&ww,&ddd);
            add(ss,tt,ww,ddd);
            mod=max(mod,ddd);
        }
        mod++;
        int time=1,ct;
        double vk,uk,ik;
        for(;time<=t;){
            ct=time%mod;
            for(int i=0;i<p;i++)
                if(r[i]>myrand())
                    launch(i+n,ct);
            for(int i=0;i<n;i++){
                ik=I[ct][i];
                I[ct][i]=0;
                vk=v[i],uk=u[i];
                v[i]=vk+dt*(0.04*vk*vk+5*vk+140-uk) +ik;
                u[i]=uk+dt*a[i]*(b[i]*vk-uk);
                if(v[i]>=30){
                    launch(i,time);
                    tot[i]++;
                    v[i]=c[i],u[i]+=d[i];
                }
            }
            time++;
        }
        double vmin=INF,vmax=-INF;
        int cmin=INF,cmax=-INF;
        for(int i=0;i<n;i++){
            vmin=min(vmin,v[i]);
            vmax=max(vmax,v[i]);
            cmin=min(cmin,tot[i]);
            cmax=max(cmax,tot[i]);
        }
        printf("%.3lf %.3lf\n",vmin,vmax);
        printf("%d %d\n",cmin,cmax);
        return 0;
    }

添加新评论