一般来说,一个<年代trong>不变的一个量在给定的执行过程中保持不变吗<一个href="//www.parkandroid.com/wiki/algorithm/" class="wiki_link" title="算法" target="_blank">算法.换句话说,所有允许的操作都不会改变不变量的值。在分析算法的最终结果(或可能的最终结果)时,不变式原理非常有用,因为我们可以丢弃任何具有不同不变式值的潜在结果,认为不可能达到。
考虑一组状态<年代pan class="katex">
,以及一组转换<年代pan class="katex">
,定义如下:<年代pan class="katex">
当且仅当我们能从状态转变<年代pan class="katex">
州<年代pan class="katex">
.一个
特别是,给定一个起始状态<年代pan class="katex"> 还有一个关于转换的规则,不变量允许我们确定我们可以从哪些状态到达<年代pan class="katex"> .
许多问题给出了起始状态和转换规则,然后询问是否可以实现某个结果(或者等效地,询问哪些结果是可以实现的)。例如,
爱丽丝把数字1、2、3、4、5、6写在黑板上。鲍勃从这些数字中选择两个,擦掉它们,并在黑板上写下它们的和。例如,如果Bob选择了数字3和4,那么黑板上将包含数字1、2、5、6和7。鲍勃继续,直到黑板上只剩下一个数字。这个数可能的值是多少?
在这个问题中,不变量是黑板上数字的和,<年代pan class="katex"> .如果鲍勃选择擦掉这些数字<年代pan class="katex"> 而且<年代pan class="katex"> ,他会写道<年代pan class="katex"> 在黑板上做新的和<年代pan class="katex"> ,所以<年代pan class="katex"> 确实是一个不变量。这意味着在这个过程的任何时候,黑板上数字的和将是<年代pan class="katex"> ,这意味着最终的数字<年代trong>必须是21。
在更正式的意义上,这个问题的状态是黑板上可能的数集,起始状态是<年代pan class="katex"> 这个问题中的过渡就是擦掉两个数,写出它们的和。不变的函数,<年代pan class="katex"> 的数字之和<年代pan class="katex"> 并对上述不变规律进行了验证。因此,自<年代pan class="katex"> 最终的状态<年代pan class="katex"> 还必须满足<年代pan class="katex"> 由于<年代pan class="katex"> 只有一个数字,一定是21。<年代pan class="katex">
尽管不变量能够精确地确定
爱丽丝把数字1、2、3、4、5、6写在黑板上。Bob选择其中两个数字,擦除它们,并写下它们的<年代trong>积极的区别在黑板上。例如,如果Bob选择了数字3和4,那么黑板上将包含数字1、1、2、5和6。鲍勃继续,直到黑板上只剩下一个数字。这个数可能的值是多少?
那么就可能产生许多不同的结果。然而,不变量在排除可能性时仍然有用:
如果鲍勃选了这些数字<年代pan class="katex"> 而且<年代pan class="katex"> ,在那里<年代pan class="katex"> 和从<年代pan class="katex"> 来<年代pan class="katex"> .因此,总和的变化总是一个偶数,这意味着<年代pan class="katex"> 是一个不变量。原来,黑板上数字的和是<年代pan class="katex"> ,所以在这个过程的任何一点,这些数字的和一定是奇数。因此,最终的数字不可能是偶数。<年代pan class="katex">
注意,不变量没有说明是否所有奇数的最终结果都是可能的;它只是说,不可能出现偶数结果。
一个<年代trong>单变非常类似于不变式,但在转换下不是保持不变,而是在转换下增加或减少。它们在显示算法终止时非常有用;例如,如果一个特定的单变量是一个在算法的每一步都递减的正整数,算法最终必须终止,因为递减的整数不可能永远保持正。
在更正式的语言中,a
注意,定义使用<年代pan class="katex"> 而且<年代pan class="katex"> 而不是<年代pan class="katex"> 而且<年代pan class="katex"> .这是因为如果一个算法可以让单变量等于它之前的值,那么它在演示算法终止时就变得不那么有用了。然而,如果可以证明算法必须在有限的步骤内改变单变量的值,那么非严格不等式就足够了。
作为一般规则,当可能有几种不同的操作时,不变量非常有用,特别是当问题询问特定的结果是否可能时。特别地,不变量在分析时特别有用<一个href="//www.parkandroid.com/wiki/combinatorial-games-definition/" class="wiki_link" title="组合游戏" target="_blank">组合游戏,其中潜在的转移由合法的移动给出,被问及的结果是游戏的赢家。
爱丽丝和鲍勃有一个大巧克力棒,形状像一个<年代pan class="katex"> 网格。在每个回合中,玩家可以吃掉一整块巧克力,也可以将任何一块巧克力沿着网格线分成两个更小的矩形巧克力。移动的玩家
最后的输了。这场比赛谁赢了?(改编自尼莫地平)
每个回合,巧克力棒的数量要么增加1(如果玩家将一块巧克力棒分成两块),要么减少1(如果玩家吃掉一块巧克力棒)。因此,Alice要选择的巧克力棒的数量是不变模2。在游戏开始时,Alice只有一块巧克力棒可以选择。因为玩家不可能永远打破巧克力棒(因为他们必须沿着网格线打破巧克力),最终Alice将不得不吃掉最后一块巧克力,所以不管玩家选择如何玩游戏,Bob都会获胜。<年代pan class="katex">
在更高级的问题中,不变量的使用不会以这样明显的方式建立起来。在这种情况下,通常需要以某种方式将问题转化为过渡性问题。许多<一个href="//www.parkandroid.com/wiki/coloring-definition/" class="wiki_link" title="着色" target="_blank">着色问题属于这一类。例如,一个询问是否可能用多米诺骨牌平铺某个形状的问题可以被认为是一个过渡问题,其中起始状态是整个形状,过渡集是移除两个相邻的正方形,而结束状态是一个空的板。
从标准棋盘上取下两个相对的角。是否有可能用多米诺骨牌铺成板子?
假设去掉的角都是白色的正方形。在每一个过渡中,我们移除一个白色方块和一个黑色方块,所以<年代pan class="katex"> 是不变的。本来,有32个黑色方块和30个白色方块,所以<年代pan class="katex"> 在任何时候。空的黑板<年代pan class="katex"> ,所以不可能从原板上够到;换句话说,板子不能用多米诺骨牌平铺。<年代pan class="katex">
许多问题也会以一种不明显的方式使用单变式,通常要求证明某种排列是可能的。解决这些问题的方法通常是从一个随机排列开始,描述在每一步改善情况的算法,并显示算法在单变量的帮助下终止。
在锡金尼亚的议会中,每个成员都有<年代trong>最多三个敌人.证明房子可以分成两个房子,这样每个成员都有<年代trong>最多一个敌人在他自己家里。(恩格尔,《问题解决策略》,第2页)
最初,以任何方式将成员分成两个议院。让<年代pan class="katex"> 成为每个成员在自己的房子里所有敌人的总和。现在假设有一个人<年代pan class="katex"> 在自己家里至少有两个敌人的人。那么他在另一间屋子里最多只有一个敌人,所以如果<年代pan class="katex"> 开关的房子,<年代pan class="katex"> 将会减少。自<年代pan class="katex"> 一定是非负整数,它不可能一直递减,所以在某一点这个过程结束了。这意味着我们再也找不到一个在自己家里至少有两个敌人的人了,这正是我们要求的任务。<年代pan class="katex">
一个涉及到不变量的问题的另一个重要线索是被要求证明某事<年代trong>所有可能的输入,如平面上的点。解决这些问题的一种常用策略是选择一个随机点,并检查当这个点移动时会发生什么变化。
如前两个问题所示,所有数字的和(可能对某个常数取模)是一个要尝试的公共不变量。更一般地说,加权和通常是有用的,例如<年代pan class="katex"> 或<年代pan class="katex"> .在处理数字的转换列表时,另一个常见的不变量是的个数<年代trong>反演,或对<年代pan class="katex"> 这样<年代pan class="katex"> ,但<年代pan class="katex"> 元素大于<年代pan class="katex"> 元素。例如,列表<年代pan class="katex"> 有四个倒置。
在处理数字元组时,要注意的一个常见的单变量是到原点的距离。在许多情况下,过渡集要么导致到原点的距离总是减小,通常证明最终结果必须减小<年代pan class="katex"> ;在某些情况下,这甚至是一个不变量。