当前位置: 首页 > article >正文

P1038 [NOIP 2003 提高组] 神经网络

题目描述

在兰兰的模型中,神经网络就是一张有向图,图中的节点称为神经元,而且两个神经元之间至多有一条边相连,下图是一个神经元的例子:

神经元(编号为 i)

图中,X1​∼X3​ 是信息输入渠道,Y1​∼Y2​ 是信息输出渠道,Ci​ 表示神经元目前的状态,Ui​ 是阈值,可视为神经元的一个内在参数。

神经元按一定的顺序排列,构成整个神经网络。在兰兰的模型之中,神经网络中的神经元分为几层;称为输入层、输出层,和若干个中间层。每层神经元只向下一层的神经元输出信息,只从上一层神经元接受信息。下图是一个简单的三层神经网络的例子。

兰兰规定,Ci​ 服从公式:C_i=(\sum_{(j,i)\in E}W_{ij}C_j-U_i)​ (其中 n 是网络中所有神经元的数目)

公式中的 Wji​(可能为负值)表示连接 j 号神经元和 i 号神经元的边的权值。当 Ci​ 大于 0 时,该神经元处于兴奋状态,否则就处于平静状态。当神经元处于兴奋状态时,下一秒它会向其他神经元传送信号,信号的强度为 Ci​。

如此.在输入层神经元被激发之后,整个网络系统就在信息传输的推动下进行运作。现在,给定一个神经网络,及当前输入层神经元的状态(Ci​),要求你的程序运算出最后网络输出层的状态。

输入格式

输入文件第一行是两个整数 n(1≤n≤100)和 p。接下来 n 行,每行 2 个整数,第 i+1 行是神经元 i 最初状态和其阈值(Ui​),非输入层的神经元开始时状态必然为 0。再下面 p 行,每行有两个整数 i,j 及一个整数 Wij​,表示连接神经元 i,j 的边权值为 Wij​。

输出格式

输出文件包含若干行,每行有 2 个整数,分别对应一个神经元的编号,及其最后的状态,2 个整数间以空格分隔。仅输出最后状态大于 0 的输出层神经元状态,并且按照编号由小到大顺序输出。

若输出层的神经元最后状态均小于等于 0,则输出 NULL

输入输出样例

输入 #1

5 6
1 0
1 0
0 1
0 1
0 1
1 3 1
1 4 1
1 5 1
2 3 1
2 4 1
2 5 1

输出 #1

3 1
4 1
5 1

可以想到通过入度和出度确定输入输出层,随后对剩下的神经元进行分层排序,最后按照层序更新神经元状态,代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

struct Edge {
    int node;// 前驱/后继神经元c
    int weight;// 边权
};

int main() {
    int n, p;
    cin >> n >> p;
    vector<int> c(n + 1);// 神经元i的初始状态
    vector<int> u(n + 1);// 神经元i的阈值
    vector<vector<Edge>> prev(n + 1);// 神经元i的前驱神经元
    vector<vector<Edge>> next(n + 1);// 神经元i的后继神经元

    for (int i = 1; i <= n; ++i) {
        int init, threshold;
        cin >> init >> threshold;
        c[i] = init;
        u[i] = threshold;
    }

    for (int i = 0; i < p; ++i) {
        int from, to, weight;
        cin >> from >> to >> weight;
        prev[to].push_back({from, weight});
        next[from].push_back({to, weight});
    }

    vector<int> layer(n + 1, 0);// 神经元i的层数
    bool changed = true;
    while (changed) {// 不断更新层数
        changed = false;
        for (int i = 1;i<=n;i++) {
            if (prev[i].empty()) {
                if (layer[i]!=0) {
                    layer[i] = 0;
                    changed = true;
                }
                continue;
            }
            int max_prev = 0;
            for (auto edge : prev[i]) {
                if (layer[edge.node]>max_prev) {
                    max_prev = layer[edge.node];
                }
            }
            int new_layer = max_prev + 1;
            if (new_layer != layer[i]) {
                layer[i] = new_layer;
                changed = true;
            }
        }
    }

    vector<pair<int, int>> nodes;// 神经元i的层数和编号
    for (int i = 1;i<=n;i++) {
        nodes.push_back({layer[i], i});
    }
    sort(nodes.begin(), nodes.end());

    for (auto node : nodes) {// 从前往后逐层更新神经元状态
        int i = node.second;
        if (layer[i] == 0) {
            continue;
        }
        int sum = 0;
        for (auto edge : prev[i]) {
            if (c[edge.node]>0) {
                sum += edge.weight * c[edge.node];
            }
        }
        c[i] = sum - u[i];
    }

    vector<int> output_nodes;// 找出输出神经元
    for (int i = 1;i<=n;i++) {
        if (next[i].empty()) {
            output_nodes.push_back(i);
        }
    }
    sort(output_nodes.begin(), output_nodes.end());

    vector<int> result;
    for (int node : output_nodes) {// 过滤状态为正的神经元
        if (c[node] > 0) {
            result.push_back(node);
        }
    }

    if (result.empty()) {
        cout << "NULL" << endl;
    } else {
        for (auto p : result) {
            cout << p << " " << c[p] << endl;
        }
    }
    return 0;
}


http://www.kler.cn/a/565147.html

相关文章:

  • docker-compose Install MinerU 0.3 GPU模式
  • 【未转变者】在 Linux 服务器上的 Unturned 联机文档
  • 音频进阶学习十六——LTI系统的差分方程与频域分析一(频率响应)
  • AI 赋能教育:智能家教与个性化学习助手的革命性设计与实践
  • 【力扣】2620. 计数器——认识闭包
  • 基于FPGA的制冷型红外成像电路设计(论文+图纸)
  • useLayoutEffect和useEffect有什么区别?
  • C#问题解决方案 --- 生成软件hash,生成文件hash
  • Spring Boot 实战:构建 RESTful API 服务
  • CD8.【C++ Dev】auto、范围for、内联函数和nullptr
  • Linux上用C++和GCC开发程序实现不同PostgreSQL实例下单个数据库的多个Schema之间的稳定高效的数据迁移
  • CSS默认样式
  • 吃一堑长一智
  • 智能生活综合平台需求规格说明书
  • 通过命令启动steam的游戏
  • vue3+naiveUI开关switch
  • PHP实现国密SM4算法,银行系统加密算法,JAVA和PHP可相互转换(附完整源码)
  • vue3.2 + vxe-table4.x 实现多层级结构的 合并、 展开、收起 功能
  • 嵌入式Qt的动平衡仪完整设计方案
  • 大模型的工作原理:分布式训练入门