202109-3 CCF Pulse Neural Network 66 Problem Solutions + Problem Solving Ideas + Problem Solving Process

problem solving ideas

According to the meaning of the question, when the threshold of the pulse source is greater than the random number, it will send pulses to all its exit points.
When the neuron v>=30, it will send pulses to all its exit points, unordered_map <int, vector > ne; //store
There will be a certain delay for all the pulses of all the output points of the neuron/pulse source collection vector , so use u nordered_map <int, unordered_map <int, double>> I; // store all the pulses received by neuron i at time j and
The violent approach is to traverse every moment, update neurons and pulse sources every moment, and finally count the answers

problem solving process

  1. At the beginning, it was implemented with a structure, and did not consider the problem that one neuron/impulse source may send pulses to multiple neurons , and directly simulated purely according to the meaning of the question, and scored 16 points. .
  2. Found a one-to-many situation, added a vector to the structure to store all the exit points, burst the memory , and scored 33 points. .
    insert image description here
  3. Since each neuron does not receive pulses at every moment, it has been changed slightly, instead of using array storage, it uses unorder_map storage, which does not burst the memory, and TLE . . 66 points. .insert image description here

66 points violent version code

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>

using namespace std;

const int N = 1010;

static unsigned long nt = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    
    
    nt = nt * 1103515245 + 12345;
    return((unsigned)(nt/65536) % 32768);
}

struct node
{
    
    
    int id;
    double w;
    int D;
};

double v[N], u[N], a[N], b[N], c[N], d[N];
unordered_map <int, vector <node>> ne;
unordered_map <int, unordered_map <int, double>> I;
int sum[N];
int r[2 * N];

int main()
{
    
    
    int n, s, p, t;
    cin >> n >> s >> p >> t;
    double dt;
    cin >> dt;
    int rn;
    for (int i = 0; i < n; i += rn) //0 ~ n - 1神经元
    {
    
    
        cin >> rn;
        double vv, uu, aa, bb, cc, dd;
        cin >> vv >> uu >> aa >> bb >> cc >> dd;
        for (int j = i; j < i + rn; j ++)
        {
    
    
            v[j] = vv;
            u[j] = uu;
            a[j] = aa;
            b[j] = bb;
            c[j] = cc;
            d[j] = dd;
        }
    }

    for (int i = n; i < n + p; i ++) //n ~ n + p - 1脉冲源
    {
    
    
        cin >> r[i];
    }

    for (int i = 0; i < s; i ++) //突触
    {
    
    
        int bn, ed;
        double w;
        int D;
        cin >> bn >> ed >> w >> D;
        struct node t = {
    
    ed, w, D};
        ne[bn].push_back(t);
    }

    for (int i = 1; i <= t; i ++) //遍历每一时刻
    {
    
    
        for (int j = 0; j < n; j ++) //更新神经元
        {
    
    
            double pv = v[j], pu = u[j];
            v[j] = pv + dt * (0.04 * pv * pv + 5.0 * pv + 140.0 - pu) + I[j][i];
            u[j] = pu + dt * a[j] * (b[j] * pv - pu);
            if (v[j] >= 30.0)
            {
    
    
                v[j] = c[j];
                u[j] += d[j];
                sum[j] ++;
                for (auto x : ne[j]) //向所有出点释放脉冲
                {
    
    
                    int id = x.id;
                    double w = x.w;
                    int D = x.D;
                    I[id][i + D] += w;
                }
            }
        }
        for (int j = n; j < n + p; j ++) //脉冲源释放脉冲
        {
    
    
            int x = myrand();
            if (r[j] > x) //r大于随机值
            {
    
    
                for (auto x : ne[j]) //向所有出点释放脉冲
                {
    
    
                    int id = x.id;
                    double w = x.w;
                    int D = x.D;
                    I[id][i + D] += w;
                }
            }
        }
    }

    double r1 = v[0], r2 = v[0];
    int s1 = sum[0], s2 = sum[0];
    for (int i = 1; i < n; i ++) //得到答案
    {
    
    
        r1 = min(r1, v[i]);
        r2 = max(r2, v[i]);
        s1 = min(s1, sum[i]);
        s2 = max(s2, sum[i]);
    }
    printf("%.3lf %.3lf\n", r1, r2);
    cout << s1 << " " << s2;
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_51800570/article/details/129447422