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

现在给定一个计算图,请你根据所有输入变量计算函数值及其偏导数(即梯度)。 例如,给定输入x1​=2,x2​=5,上述计算图获得函数值 f(2,5)=ln(2)+2×5−sin(5)=11.652;并且根据微分链式法则,上图得到的梯度 ∇f=[∂f/∂x1​,∂f/∂x2​]=[1/x1​+x2​,x1​−cosx2​]=[5.500,1.716]。

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

友情提醒:

  • 常数的导数是 0;x 的导数是 1;ex 的导数还是 ex;lnx 的导数是 1/x;sinx 的导数是 cosx
  • 回顾一下什么是偏导数:在数学中,一个多变量的函数的偏导数,就是它关于其中一个变量的导数而保持其他变量恒定。在上面的例子中,当我们对 x1​ 求偏导数 ∂f/∂x1​ 时,就将 x2​ 当成常数,所以得到 lnx1​ 的导数是 1/x1​,x1​x2​ 的导数是 x2​,sinx2​ 的导数是 0。
  • 回顾一下链式法则:复合函数的导数是构成复合这有限个函数在相应点的导数的乘积,即若有 u=f(y),y=g(x),则 du/dx=du/dydy/dx。例如对 sin(lnx) 求导,就得到 cos(lnx)⋅(1/x)。

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

输入格式:

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

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

  • 0 代表输入变量
  • 1 代表加法,对应 x1​+x2​
  • 2 代表减法,对应 x1​−x2​
  • 3 代表乘法,对应 x1​×x2​
  • 4 代表指数,对应 ex
  • 5 代表对数,对应 lnx
  • 6 代表正弦函数,对应 sinx

对于输入变量,后面会跟它的双精度浮点数值;对于单目算子,后面会跟它对应的单个变量的顶点编号(编号从 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

分析:结构体A中存储相关节点信息,de[i]表示第i个点是否被其他节点调用操作到,使用deal做dfs操作来根据题意进行题目的模拟运行,其中,c为1表示求导,c为0表示正常晕眩,index表示当前节点信息,to为求偏导数得目标,Record则是一个dfs下的记忆优化,start为一个可以作为出发点的节点。依题意输入数据后,遍历找出一个出发点节点,然后直接丢到deal函数中即可得到答案~注意导数运算的相关规则~

#include <bits/stdc++.h>
using namespace std;
struct node {int which, op1, op2;double value;
}A[50001];
int N, start = -1, cnt, de[50001];
map<bool, map<int, map<int, double>>> Record;
double deal(int c, int index, int to) {if (Record[c][index][to]) return Record[c][index][to];if (A[index].which == 0) return Record[c][index][to] = c ? (index == to ? 1.0 : 0.0) : A[index].value;else if (A[index].which == 1) return Record[c][index][to] = deal(c, A[index].op1, to) + deal(c, A[index].op2, to);else if (A[index].which == 2) return Record[c][index][to] = deal(c, A[index].op1, to) - deal(c, A[index].op2, to);else if (A[index].which == 3) return Record[c][index][to] = c ? (deal(1, A[index].op1, to) * deal(0, A[index].op2, to) + deal(0, A[index].op1, to) * deal(1, A[index].op2, to)) : (deal(0, A[index].op1, to) * deal(0, A[index].op2, to));else if (A[index].which == 4) return Record[c][index][to] = c ? exp(deal(0, A[index].op1, to)) * deal(1, A[index].op1, to) : exp(deal(0, A[index].op1, to));else if (A[index].which == 5) return Record[c][index][to] = c ? 1.0 / deal(0, A[index].op1, to) * deal(1, A[index].op1, to) : log(deal(0, A[index].op1, to));else  return Record[c][index][to] = c ? cos(deal(0, A[index].op1, to)) * deal(1, A[index].op1, to) : sin(deal(0, A[index].op1, to));
}
int main() {scanf("%d", &N);for (int i = 0; i < N; i++) {scanf("%d", &A[i].which);if (A[i].which == 0) {++cnt;scanf("%lf", &A[i].value);} else if (A[i].which < 4) {scanf("%d%d", &A[i].op1, &A[i].op2);de[A[i].op1] = de[A[i].op2] = 1;} else {scanf("%d", &A[i].op1);de[A[i].op1] = 1;}}while(de[++start]);printf("%.3lf\n", deal(0, start, N));for (int i = 0; i < N; i++) {if (A[i].which == 0) printf("%.3lf%c", deal(1, start, i), --cnt ? ' ' : '\n');}return 0;
}

L3-023 计算图 (30 分)--PAT 团体程序设计天梯赛 GPLT相关推荐

  1. L3-011 直捣黄龙 (30 分)-PAT 团体程序设计天梯赛 GPLT

    本题是一部战争大片 -- 你需要从己方大本营出发,一路攻城略地杀到敌方大本营.首先时间就是生命,所以你必须选择合适的路径,以最快的速度占领敌方大本营.当这样的路径不唯一时,要求选择可以沿途解放最多城镇 ...

  2. L3-017 森森快递 (30 分)-PAT 团体程序设计天梯赛 GPLT

    森森开了一家快递公司,叫森森快递.因为公司刚刚开张,所以业务路线很简单,可以认为是一条直线上的N个城市,这些城市从左到右依次从0到(N−1)编号.由于道路限制,第i号城市(i=0,⋯,N−2)与第(i ...

  3. L3-012 水果忍者 (30 分)-PAT 团体程序设计天梯赛 GPLT

    2010年风靡全球的"水果忍者"游戏,想必大家肯定都玩过吧?(没玩过也没关系啦~)在游戏当中,画面里会随机地弹射出一系列的水果与炸弹,玩家尽可能砍掉所有的水果而避免砍中炸弹,就可以 ...

  4. L3-021 神坛 (30 分)-PAT 团体程序设计天梯赛 GPLT

    在古老的迈瑞城,巍然屹立着 n 块神石.长老们商议,选取 3 块神石围成一个神坛.因为神坛的能量强度与它的面积成反比,因此神坛的面积越小越好.特殊地,如果有两块神石坐标相同,或者三块神石共线,神坛的面 ...

  5. L3-020 至多删三个字符 (30 分)-PAT 团体程序设计天梯赛 GPLT

    给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串? 输入格式: 输入在一行中给出全部由小写英文字母组成的.长度在区间 [4, 106] 内的字符串. ...

  6. L3-016 二叉搜索树的结构 (30 分)-PAT 团体程序设计天梯赛 GPLT

    二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值:若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值:它的左.右子树也分别 ...

  7. L3-009 长城 (30 分)-PAT 团体程序设计天梯赛 GPLT

    正如我们所知,中国古代长城的建造是为了抵御外敌入侵.在长城上,建造了许多烽火台.每个烽火台都监视着一个特定的地区范围.一旦某个地区有外敌入侵,值守在对应烽火台上的士兵就会将敌情通报给周围的烽火台,并迅 ...

  8. L3-006 迎风一刀斩 (30 分)-PAT 团体程序设计天梯赛 GPLT

    迎着一面矩形的大旗一刀斩下,如果你的刀够快的话,这笔直一刀可以切出两块多边形的残片.反过来说,如果有人拿着两块残片来吹牛,说这是自己迎风一刀斩落的,你能检查一下这是不是真的吗? 注意摆在你面前的两个多 ...

  9. L3-022 地铁一日游 (30 分)-PAT 团体程序设计天梯赛 GPLT

    森森喜欢坐地铁.这个假期,他终于来到了传说中的地铁之城--魔都,打算好好过一把坐地铁的瘾! 魔都地铁的计价规则是:起步价 2 元,出发站与到达站的最短距离(即计费距离)每 K 公里增加 1 元车费. ...

最新文章

  1. Nexus Repository Manager 3 远程命令执行漏洞 CVE-2019-7238
  2. java 如何判定消息已在队列_Java面试—消息队列
  3. bat批处理延迟运行脚本
  4. 【UDP协议头解析】
  5. 异常处理 Exception
  6. Cygwin 的代理设置(同 Linux)
  7. 95-110-026-源码-Env-RemoteStreamEnvironment
  8. alias自定义别名
  9. 提高局域网速度的21招
  10. 零基础计算机编程入门自学需要什么条件
  11. springcloud 01 euraka整理
  12. 安徽计算机软件工程学院,安徽软件工程专业大学排名
  13. 许凯拍《招摇》冻到嘴唇发紫 夸赞导演更敬业
  14. 基于树莓派raspberry: 移植 2.4寸TFT显示屏以及源码分析
  15. IJCAI 2021丨时间序列相关研究论文汇总
  16. 屏蔽高通8953长按电源键的截屏按钮
  17. 一种隐私保护边云协同训练
  18. 如何把一个数字x最右侧那个1拿出来,变成00...10..的格式
  19. iOS小技能:安全措施
  20. 你即将拥有HDMI2.1,纯光纤HDMI最高支持72Gbps试用体验

热门文章

  1. Android应用开发基础 余永佳,Android应用开发基础(基于Android4.2、任务驱动式)教学课件作者余永佳赵佩华习题课件.doc...
  2. python如何爬取网站所有目录_用python爬虫爬取网站的章节目录及其网址
  3. 开源 Android pdf 阅读器开发总结
  4. 记一次new Map()
  5. 【Javascript第二重境界】序
  6. CentOS4.4平台下安装EXTMAIL手记V1.3
  7. DELETE_FAILED_INTERNAL_ERROR Error while Installing APK
  8. 《CCNP TSHOOT 300-135学习指南》——1.2节结构化故障检测与排除方法
  9. HttpURLConnection类的使用
  10. WinForm员工信息表