V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hakunamatata11
V2EX  ›  程序员

看完《信条》后,我觉得诺兰一定是个程序员.....

  •  
  •   hakunamatata11 · 2020-09-22 16:59:48 +08:00 · 1159 次点击
    这是一个创建于 1534 天前的主题,其中的信息可能已经有所发展或是发生改变。

    诺兰大神的新作《信条》正在热映,很多人从电影院出来就是一脸懵逼:这到底讲了个啥?

    不知道大家有没有看懂,反正小编也是看得云里雾里。这部结合麦克斯韦妖、热力学第二定律等等物理知识,以及各种时间悖论糅合而成的科幻之作给了观众一个全新的设定,和以往所有的时空类科幻电影都不同。

    今天我们不做剧情解析,而是从算法的角度来解析《信条》。不止如此,诺兰的其他大作也都可以和算法挂钩。看完这篇文章,你也许会感叹:诺兰怕不是个程序员吧!

    信条 - 回溯算法( TENET - Backtracking )

    信条里最核心的科幻设定就是通过熵减达成逆向时间的操作。

    这和回溯算法有着异曲同工之妙:有正向的操作就有反向操作,在深度优先搜索中,我们对参数进行的修改,在递归调用之后,都要改回来。

    1 path.add(node)
    2 visited.add(node)
    3 recursion(path, visited) // (注释:这个就相当于电影中用来逆转时间的机器)
    4 path.remove(node)  // backtracking 
    5 visited.remove(node)  // backtracking
    

    而最后时间钳形作战的高潮部分也是最让观众疑惑的地方,正派反派、红队蓝队、正向逆向的一套“组合拳”直接把观众打晕!

    其实有时候算法面试也是如此:纵使一道题目有千百种方法去解答,我们挠破头皮还想不明白。只能叹一句:是我基础不够扎实!

    小编只能用电影里的一句话来安慰大家:别去试图理解它,去感受它。

    盗梦空间 - 递归 ( INCEPTION - Recursion )

    《盗梦空间》作为诺兰最著名的科幻片之一,在刚上映的时候带给了观众无限的震撼——原来科幻片的脑洞还能这么大?当然小李子的演绎也让这部电影更上一层楼。

    《盗梦空间》里层层梦境的设定和递归算法的有着极高的相似度。

    假设我们要进入第 i 层梦境,首先要进入第 i-1 层。而递归也是如此,要进入第 i 层递归,首先要完成第 i-1 层递归

    盗梦者在某一层梦境里死亡,回到的是上一层梦境,而不是最初始的梦境。

    同样地,在递归算法里面进行 return 的时候,是销毁了当前这一层递归的所有局部变量,回到上一层递归,而不是最开始的递归入口

    1 void recursion(int deep) {
    2       if (deep == 0) {
    3         return;
    4    }
    5    recursion(deep + 1);// 递归了上一层梦境,而不是第一层
    6   return;// return 代表了销毁
    7 }
    

    盗梦者在某一层梦境里死了或者发生了改变,不影响上一层梦境的状态。举例来说,盗梦空间里多层梦境里的小李子虽然都叫小李子,但在这层梦境里沉睡后,下一层里的小李子和上一层完全不相干。

    **递归下一层的变量 i 被修改之后,上一层的 i 不受影响。**即使变量是同样的名字,但实际是不同的变量,处于内存的不同位置。

    从这个角度看,诺兰的逻辑就有了更加靠谱严谨的解释,也难怪他的科幻电影会让一大堆人着迷,并且大家都为探究电影的“真相”趋之若鹜。

    敦刻尔克 - 分治法 ( DUNKIRK - divide and conquer )

    一位士兵设法混上敦刻尔克撤退的救援船,一架战机与德军展开激烈的遭遇战,还有一艘民船义无反顾地支援敦刻尔克,最后所有人事物在敦刻尔克海滩上汇合,完成时间线的收束。

    这就是诺导难得的历史战争题材的电影《敦刻尔克》。这种**“分开处理(叙事),然后把处理的结果合并到一起”**的做法,是不是很像我们经常会遇到的“分治法”?

    (《敦刻尔克》里最经典的“无声胜有声”的镜头之一)

    分治法顾名思义就是“分而治之”。通常我们用来把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。是十分经典的优化算法之一。

    1 void divide(int left, int right) {
    2     if(left == right) {
    3         return;
    4     }
    5     //divide into parts
    6     int mid = (left + right) / 2;
    7     divide(left, mid);
    8     divide(mid + 1, right);
    9     // conquer left to right
    10     return;
    11 }
    

    这么一解释,小编好像都没法“正常”地看电影了——大半时间都在思考这里用了啥算法逻辑,那里又怎么用编程来解释。诺神的电影,原来就是骗我去二刷的!

    大家对诺神的片子还有什么有趣的解读,不妨在评论区留言哦~

    3 条回复
    northlov
        1
    northlov  
       2020-09-22 17:25:33 +08:00
    那恐怖游轮一定是内存溢出了[手动狗头]
    kyuuseiryuu
        2
    kyuuseiryuu  
       2020-09-23 09:23:04 +08:00 via iPhone
    楼主和很多人一样弄颠倒关系。

    算法是从现实世界抽象出来到计算机世界用来解决现实世界问题的,从现实世界找到计算机世界中对应的算法是很正常的必然的现象。
    kyuuseiryuu
        3
    kyuuseiryuu  
       2020-09-23 09:28:25 +08:00 via iPhone
    简单比喻,就像月饼和月饼模子。
    现实世界是月饼模子,计算机算法是月饼。

    你发现月饼和模子一样,哇,好惊叹!觉得这个月饼世界的基石是月饼。

    看电影找算法就是拿着模子去找月饼,但事实上,可能这个模子型的月饼还没做出来呢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5525 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 03:41 · PVG 11:41 · LAX 19:41 · JFK 22:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.