zoukankan      html  css  js  c++  java
  • 3076: 神经网络(bfs和拓扑排序)

    3076: 神经网络

    时间限制: 1 Sec  内存限制: 125 MB
    提交: 7  解决: 5
    [提交][状态][讨论版][命题人:外部导入][Edit] [TestData] [同步数据]

    题目描述

    人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域有广泛的应用。对神经网络的研究一直是当今的热门方向,兰兰同学在自学了一本神经网络的入门书籍后,提出了一个简化模型,他希望你能帮助他用程序检验这个神经网络模型的实用性。

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

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

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

    兰兰规定,Ci服从公式:(其中n是网络中所有神经元的数目)

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

    输入

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

    输出

    每组输出包含若干行,每行有两个整数,分别对应一个神经元的编号,及其最后的状态,两个整数间以空格分隔。仅输出最后状态非零的输出层神经元状态,并且按照编号由小到大顺序输出!
    若输出层的神经元最后状态均为 0,则输出 NULL。
     

    样例输入

    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

    提示

     
    思路:按照神经的网络传播进行模拟,一层一层,层序遍历,
    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #define  ll long long
    using namespace std;
    struct node{
        int to;
        int w;
    };
    struct point{//队列里放的东西,x代表第几个点,lay表示第几层 
        int x;
        int lay;
    };
    vector<node>vi[500];//存i点与哪些点相连 
    queue<point>fir;
    int ci[500];
    int ui[500];
    bool inq[500];//标记在不在队列里
    int in[500];//记录入度 
    int main(){
        int n,m;
        cin>>n>>m;
        while(!fir.empty()) fir.pop();
        memset(inq,0,sizeof(inq));
        memset(in,0,sizeof(in));
        for(int i=1;i<=n;i++)
        {
            cin>>ci[i]>>ui[i];
            if(ci[i]!=0)
            {
                point p;
                p.lay=1;
                p.x=i;
                fir.push(p);
                inq[i]=1;
            }
        }
        for(int i=1;i<=m;i++)
        {
            int u,v,w;
            cin>>u>>v>>w;
            node no;
            no.to=v;
            no.w=w;
            vi[u].push_back(no);
            in[v]++; 
        }
        //fir队列里存放当前这一层,一层层遍历
        //相当于来个bfs 
        while(!fir.empty())
        {
            point p = fir.front(); 
            fir.pop();
            inq[p.x]=0; //标记不在队列里 
            //cout<<"取出"<<p.x<<endl;  
            //cout<<"ci"<<ci[p.x]<<endl; 
            //拿p.x这个点更新与它相连的边
            for(int i=0;i<vi[p.x].size();i++)
            {
                //消去与它相邻的边
                node no = vi[p.x].at(i);
                int to = no.to;
                in[to]--;
                //cout<<"相邻边"<<to<<endl;
                if(in[to]==0)//如果这个点没有入度了,说明已经计算完了ci*wi,要减去ui 
                {
                    ci[to]-=ui[to];
                 } 
                if(ci[p.x]>0)
                {           
                    //先更新               
                    ci[to] += no.w*ci[p.x]; 
                    //cout<<"更新"<<to<<" "<<ci[to]<<endl;
                    //再把它放到队列里去,并更新lay 
                    if(inq[to]==0)
                    {//如果不在队列里,就把它放进去 
                        point p2;
                        p2.x = to;
                        p2.lay = p.lay+1;//层数在这个点的基础上+1 
                        inq[to]=1;//标记在队列里 
                        fir.push(p2);
                    }
                 }          
            }
     
         } 
         //找没有出度的点,输出它的值即可
         bool f = 0;//是不是没有输出 
         for(int i=1;i<=n;i++)
         {
            if(vi[i].size()==0)//找到输出层 
            {
                if(ci[i]>0)
                {
                    f=1;
                    cout<<i<<" "<<ci[i]<<endl;
                 }
             }
         }
         if(!f){
            cout<<"NULL"<<endl;
         }
        //for(int i=6;i<=7;i++){
        //  cout<<"ci[i]"<<" "<<i<<" "<<ci[i]<<endl;
        //}
        return 0;
    }
     
     
     
     
     

    来源

    [提交][状态][Edit] [TestData]
  • 相关阅读:
    CHAR和HEX互相转换
    Delphi之TComponent类
    Delphi 延迟函数 比sleep 要好的多
    Delphi中三种延时方法及其定时精度分析
    Cport 应用集合
    重命名数据库时提示无法用排他锁锁定数据库
    Bugzilla在XP下安装
    Web service 超过了最大请求长度
    调用webservice时提示对操作的回复消息正文进行反序列化时出错
    c# IL 指令解析
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/10734325.html
Copyright © 2011-2022 走看看