• AcWing 477:神经网络 ← 拓扑排序+链式前向星


    【题目来源】
    https://www.acwing.com/problem/content/479/

    【题目描述】
    人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域有广泛的应用。
    对神经网络的研究一直是当今的热门方向,兰兰同学在自学了一本神经网络的入门书籍后,提出了一个简化模型,他希望你能帮助他用程序检验这个神经网络模型的实用性。
    在兰兰的模型中,神经网络就是一张有向图,图中的节点称为神经元,而且两个神经元之间至多有一条边相连,下图是一个神经元的例子:

    图中,X1—X3是信息输入渠道,Y1-Y2 是信息输出渠道,C1 表示神经元目前的状态,Ui 是阈值,可视为神经元的一个内在参数。 
    神经元按一定的顺序排列,构成整个神经网络。
    在兰兰的模型之中,神经网络中的神经元分为几层;称为输入层、输出层,和若干个中间层。
    每层神经元只向下一层的神经元输出信息,只从上一层神经元接受信息。
    下图是一个简单的三层神经网络的例子。

    兰兰规定,Ci 服从公式:Ci=WjiCjUi" role="presentation">Ci=WjiCjUi,(其中 n 是网络中所有神经元的数目)
    公式中的Wji(可能为负值)表示连接 j 号神经元和 i 号神经元的边的权值。
    当 Ci 大于 0 时,该神经元处于兴奋状态,否则就处于平静状态。
    当神经元处于兴奋状态时,下一秒它会向其他神经元传送信号,信号的强度为 Ci。
    如此.在输入层神经元被激发之后,整个网络系统就在信息传输的推动下进行运作。
    现在,给定一个神经网络,及当前输入层神经元的状态(Ci),要求你的程序运算出最后网络输出层的状态。

    【输入格式】
    输入文件第一行是两个整数 n 和 p。
    接下来 n 行,每行两个整数,第 i+1 行是神经元 i 最初状态和其阈值(Ui)。注意:输入层给定的状态即为最终值,不需要再减去 Ui,非输入层的神经元开始时状态必然为 0。
    再下面 P 行,每行有两个整数 i,j 及一个整数 Wij,表示连接神经元 i、j 的边权值为 Wij。

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

    【数据范围】
    1≤n≤100

    【输入样例】
    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

    【输出样例】
    3 1
    4 1
    5 1

    【算法分析】
    ● 拓扑序列:https://blog.csdn.net/hnjzsyjyj/article/details/129811447

    ● 链式前向星:https://blog.csdn.net/hnjzsyjyj/article/details/139369904
    val[idx]:存储编号为 idx 的边的值
    e[idx]:存储编号为 idx 的结点的值
    ne[idx]:存储编号为 idx 的结点指向的结点的编号
    h[a]:存储头结点 a 指向的结点的编号

    【算法代码】

    1. #include
    2. using namespace std;
    3. const int maxn=105;
    4. const int maxm=maxn*maxn/2;
    5. int val[maxm],e[maxn],ne[maxn],h[maxn],idx;
    6. int f[maxn],u[maxn],din[maxn],dout[maxn];
    7. int q[maxn];
    8. int n,m;
    9. void add(int a,int b,int w) {
    10. val[idx]=w,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    11. }
    12. void topsort() {
    13. int hh=0, tt=-1;
    14. for(int i=1; i<=n; i++)
    15. if(!din[i]) q[++tt]=i;
    16. while(hh<=tt) {
    17. int t=q[hh++];
    18. for(int i=h[t]; i!=-1; i=ne[i]) {
    19. int j=e[i];
    20. if(--din[j]==0) q[++tt]=j;
    21. }
    22. }
    23. }
    24. int main() {
    25. cin>>n>>m;
    26. for(int i=1; i<=n; i++) {
    27. cin>>f[i]>>u[i];
    28. if(!f[i]) f[i]-=u[i];
    29. }
    30. memset(h,-1,sizeof h);
    31. while(m--) {
    32. int a,b,c;
    33. cin>>a>>b>>c;
    34. add(a,b,c);
    35. dout[a]++;
    36. din[b]++;
    37. }
    38. topsort();
    39. for(int i=0; i
    40. int j=q[i];
    41. if(f[j]>0) {
    42. for(int k=h[j]; k!=-1; k=ne[k])
    43. f[e[k]]+=f[j]*val[k];
    44. }
    45. }
    46. bool flag=true;
    47. for(int i=1; i<=n; i++)
    48. if(!dout[i] && f[i]>0) {
    49. cout<" "<
    50. flag=false;
    51. }
    52. if(flag) cout<<"NULL"<
    53. return 0;
    54. }
    55. /*
    56. in:
    57. 5 6
    58. 1 0
    59. 1 0
    60. 0 1
    61. 0 1
    62. 0 1
    63. 1 3 1
    64. 1 4 1
    65. 1 5 1
    66. 2 3 1
    67. 2 4 1
    68. 2 5 1
    69. out:
    70. 3 1
    71. 4 1
    72. 5 1
    73. */




    【参考文献】
    https://www.acwing.com/solution/content/3706/
    https://blog.csdn.net/hnjzsyjyj/article/details/139369904
    https://blog.csdn.net/hnjzsyjyj/article/details/129811447




     

  • 相关阅读:
    计算机组成原理知识点总结——第三章存储系统
    Vue基础实例
    聚类算法评价指标——基于DBI指数的k-means算法(python代码)
    mac 安装java1.8
    基于JavaSwing开发打飞鸟游戏 课程设计 大作业 毕业设计
    让“作用域和闭包”说人话
    前端学习——初识jQuery
    flutter学习之widget的显示和隐藏
    以太坊:轻松理解EIP-4844
    【golang/问题记录】goroutine之间数据竞争问题
  • 原文地址:https://blog.csdn.net/hnjzsyjyj/article/details/139610969