“计算图”(computational graph)是现代深度学习系统的基础执行引擎,提供了一种表示任意数学表达式的方法,例如用有向无环图表示的神经网络。 图中的节点表示基本操作或输入变量,边表示节点之间的中间值的依赖性。 例如,下图就是一个函数 ( 的计算图。

现在给定一个计算图,请你根据所有输入变量计算函数值及其偏导数(即梯度)。 例如,给定输入,,上述计算图获得函数值 (;并且根据微分链式法则,上图得到的梯度 ∇。

知道你已经把微积分忘了,所以这里只要求你处理几个简单的算子:加法、减法、乘法、指数(e​x​​,即编程语言中的 exp(x) 函数)、对数(ln,即编程语言中的 log(x) 函数)和正弦函数(sin,即编程语言中的 sin(x) 函数)。

友情提醒:

  • 常数的导数是 0;x 的导数是 1;e​x​​ 的导数还是 e​x​​;ln 的导数是 1;sin 的导数是 cos。
  • 回顾一下什么是偏导数:在数学中,一个多变量的函数的偏导数,就是它关于其中一个变量的导数而保持其他变量恒定。在上面的例子中,当我们对 x​1​​ 求偏导数 / 时,就将 x​2​​ 当成常数,所以得到 ln 的导数是 1,x​1​​x​2​​ 的导数是 x​2​​,sin 的导数是 0。
  • 回顾一下链式法则:复合函数的导数是构成复合这有限个函数在相应点的导数的乘积,即若有 (,(,则 /。例如对 sin 求导,就得到 cos。

如果你注意观察,可以发现在计算图中,计算函数值是一个从左向右进行的计算,而计算偏导数则正好相反。

输入格式:

输入在第一行给出正整数 N(≤),为计算图中的顶点数。

以下 N 行,第 i 行给出第 i 个顶点的信息,其中 ,。第一个值是顶点的类型编号,分别为:

  • 0 代表输入变量
  • 1 代表加法,对应 x​1​​+x​2​​
  • 2 代表减法,对应 x​1​​−x​2​​
  • 3 代表乘法,对应 x​1​​×x​2​​
  • 4 代表指数,对应 e​x​​
  • 5 代表对数,对应 ln
  • 6 代表正弦函数,对应 sin

对于输入变量,后面会跟它的双精度浮点数值;对于单目算子,后面会跟它对应的单个变量的顶点编号(编号从 0 开始);对于双目算子,后面会跟它对应两个变量的顶点编号。

题目保证只有一个输出顶点(即没有出边的顶点,例如上图最右边的 -),且计算过程不会超过双精度浮点数的计算精度范围。

输出格式:

首先在第一行输出给定计算图的函数值。在第二行顺序输出函数对于每个变量的偏导数的值,其间以一个空格分隔,行首尾不得有多余空格。偏导数的输出顺序与输入变量的出现顺序相同。输出小数点后 3 位。

输入样例:

7
0 2.0
0 5.0
5 0
3 0 1
6 1
1 2 3
2 5 4

输出样例:

11.652
5.500 1.716

天梯赛L3的第二题,反向建图之后利用各种求导公式对每个变量分别跑一遍dfs求偏导就行了。场下30分钟过掉,场上的我真是宛如一个智障,~QAQ~

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=5e4+;
int n,f[N],dg[N],s,nxt[N][],vis[N],x;
db a[N],f1[N],f2[N];
vector<int> vec;
vector<db> ans;
void dfs(int u) {
if(vis[u])return;
vis[u]=;
if(f[u]==)f1[u]=a[u],f2[u]=u==x?:;
else if(f[u]==) {
int v1=nxt[u][],v2=nxt[u][];
dfs(v1),dfs(v2);
f1[u]=f1[v1]+f1[v2],f2[u]=f2[v1]+f2[v2];
} else if(f[u]==) {
int v1=nxt[u][],v2=nxt[u][];
dfs(v1),dfs(v2);
f1[u]=f1[v1]-f1[v2],f2[u]=f2[v1]-f2[v2];
} else if(f[u]==) {
int v1=nxt[u][],v2=nxt[u][];
dfs(v1),dfs(v2);
f1[u]=f1[v1]*f1[v2],f2[u]=f2[v1]*f1[v2]+f1[v1]*f2[v2];
} else if(f[u]==) {
int v=nxt[u][];
dfs(v),f1[u]=exp(f1[v]),f2[u]=exp(f1[v])*f2[v];
} else if(f[u]==) {
int v=nxt[u][];
dfs(v),f1[u]=log(f1[v]),f2[u]=f2[v]/f1[v];
} else if(f[u]==) {
int v=nxt[u][];
dfs(v),f1[u]=sin(f1[v]),f2[u]=cos(f1[v])*f2[v];
}
}
int main() {
scanf("%d",&n);
for(int i=; i<n; ++i) {
scanf("%d",&f[i]);
if(f[i]==) {
scanf("%lf",&a[i]);
vec.push_back(i);
} else if(f[i]>=&&f[i]<=) {
int u,v;
scanf("%d%d",&u,&v);
nxt[i][]=u,nxt[i][]=v,dg[u]++,dg[v]++;
} else if(f[i]>=&&f[i]<=) {
int u;
scanf("%d",&u);
nxt[i][]=u,dg[u]++;
}
}
for(int i=; i<n; ++i)if(!dg[i])s=i;
for(int i:vec)x=i,memset(vis,,sizeof vis),dfs(s),ans.push_back(f2[s]);
printf("%.3f\n",f1[s]);
for(int i=; i<ans.size(); ++i)printf("%.3f%c",ans[i]," \n"[i==ans.size()-]);
return ;
}

PTA L3-023 计算图 (dfs+数学推导)的更多相关文章

  1. 借One-Class-SVM回顾SMO在SVM中的数学推导--记录毕业论文5

    上篇记录了一些决策树算法,这篇是借OC-SVM填回SMO在SVM中的数学推导这个坑. 参考文献: http://research.microsoft.com/pubs/69644/tr-98-14.p ...

  2. 关于不同进制数之间转换的数学推导【Written By KillerLegend】

    关于不同进制数之间转换的数学推导 涉及范围:正整数范围内二进制(Binary),八进制(Octonary),十进制(Decimal),十六进制(hexadecimal)之间的转换 数的进制有多种,比如 ...

  3. UVA - 10014 - Simple calculations (经典的数学推导题!!)

    UVA - 10014 Simple calculations Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

  4. 『sumdiv 数学推导 分治』

    sumdiv(POJ 1845) Description 给定两个自然数A和B,S为A^B的所有正整数约数和,编程输出S mod 9901的结果. Input Format 只有一行,两个用空格隔开的 ...

  5. LDA-线性判别分析(二)Two-classes 情形的数学推导

    本来是要调研 Latent Dirichlet Allocation 的那个 LDA 的, 没想到查到很多关于 Linear Discriminant Analysis 这个 LDA 的资料.初步看了 ...

  6. leetcode 343. Integer Break(dp或数学推导)

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  7. [hdu5307] He is Flying [FFT+数学推导]

    题面 传送门 思路 看到这道题,我的第一想法是前缀和瞎搞,说不定能$O\left(n\right)$? 事实证明我的确是瞎扯...... 题目中的提示 这道题的数据中告诉了我们: $sum\left( ...

  8. ZOJ3329(数学推导+期望递推)

    要点: 1.期望的套路,要求n以上的期望,则设dp[i]为i分距离终点的期望步数,则终点dp值为0,答案是dp[0]. 2.此题主要在于数学推导,一方面是要写出dp[i] = 什么,虽然一大串但是思维 ...

  9. [国家集训队]整数的lqp拆分 数学推导 打表找规律

    题解: 考场上靠打表找规律切的题,不过严谨的数学推导才是本题精妙所在:求:$\sum\prod_{i=1}^{m}F_{a{i}}$ 设 $f(i)$ 为 $N=i$ 时的答案,$F_{i}$ 为斐波 ...

随机推荐

  1. ruby安装神器rvm,你造吗?

    以前的一篇文章介绍过如何安装ruby,叫做:如何安装/更新ruby,安装cocoapods,为开发做好准备!(2016年12月07日更新内容) 文章中讲到的方法依然可行,但是该方法繁琐并且可能会出现各 ...

  2. 完美修改iOS项目名

    注意:重命名项目时,记得先备份好一份 1.选中旧项目名,改为新项目名: 选择rename: 2.修改相关文件夹名称: 3.全局搜索旧项目名称,然后替换为新项目名称: 4.经过步骤3的替换,再次全局搜索 ...

  3. 介绍Web项目中用到的几款表单验证插件

    第一个插件 jqueryvalidation 官网地址:http://jqueryvalidation.org/ 第二个插件 nice Validator 官网地址: http://niceue.co ...

  4. 20145229吴姗珊逆向BOF实践

    20145229吴姗珊逆向BOF实践 实践 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. ...

  5. 20145217《网络对抗》 MSF基础应用

    20145217<网络对抗> MSF基础应用 MSF基础应用 1.实践任务 任务一:ms08_067渗透攻击 任务二:IE浏览器渗透攻击--MS12063安全漏洞 任务三:adobe渗透攻 ...

  6. unidbnavigator提示汉化

  7. 初入Spring-boot(三)

    Spring boot 的运行原理 Spring boot关于自动配置的源码在spring-boot-autoconfigure-xxxx.jar内. 一.可以通过下面三种方式查看当前项目中已启用和未 ...

  8. Java集合Collection&Map

    Map<K,V>是键值对,K - 此映射所维护的键的类型,V - 映射值的类型.键值是一一对应的关系: Collection是只有键,底层也是由键值对,但是值的类型被隐藏起来. Colle ...

  9. 常见linux系统中RPM包的通用命名规则

    本文重点说一下在常见的linux系统中,RPM包通用的命名规则. RPM包的一般格式为:name-version-arch.rpmname-version-arch.src.rpm 例:httpd-2 ...

  10. POST方式跨域上传文件

    JSONP请求有限制: 第一,不能跳出两层, 第二,不支持POST. 往往解决跨域POST请求的方案是个"古老"方法, 请求同域下的iframe. 服务器端:  需要附加头信息: ...