我需要使用Microsoft Excel的RANDBETWEEN函数,并且知道在您在工作表上的任何位置进行任何其他操作时,都会生成一组新的随机数。我也知道可以“冻结”已生成的一组随机数的解决方法,例如,用于在a和b之间对n个随机数列表进行排序。我的问题是:为什么生成的随机数会发生变化?算法中是否有某些必要?FWIW,Google表格,LibreOffice Calc,Apple Numbers都表现出相同的行为。
我需要使用Microsoft Excel的RANDBETWEEN函数,并且知道在您在工作表上的任何位置进行任何其他操作时,都会生成一组新的随机数。我也知道可以“冻结”已生成的一组随机数的解决方法,例如,用于在a和b之间对n个随机数列表进行排序。我的问题是:为什么生成的随机数会发生变化?算法中是否有某些必要?FWIW,Google表格,LibreOffice Calc,Apple Numbers都表现出相同的行为。
Answers:
Charles Williams对Excel如何计算事物以及原因有很好的解释。
http://www.decisionmodels.com/calcsecretsi.htm
本质上,如果工作簿包含易失函数(请参阅Charles的列表,因为多年来不同的Excel版本改变了易失函数),当工作簿中的任何单元格发生更改时,整个工作簿的重新计算将被触发(如果Excel设置为自动计算)。如果工作簿中没有易失函数,则仅重新计算受最后更改影响的单元格。
这里的其他人指出,更改任何单元格时,自动计算将始终计算工作簿中的所有内容,但这是错误的。仅易失性函数会导致自动重新计算工作簿中的所有单元格。没有易失性函数,Excel仅重新计算需要重新计算的内容。
这就是为什么像我这样了解差异的人强烈建议在可能的情况下避免在工作表单元格中使用诸如OFFSET()或INDIRECT()之类的易失函数,因为乳清会通过在每次单元格更改后进行完全重新计算而减慢工作簿的速度。学会使用INDEX()而不是OFFSET()可以显着提高速度,因为Index并不是不稳定的(有关更多详细信息,请参阅Charles的文章)。
Excel的计算引擎基于“重新计算或死亡”的理念,该理念使Excel在开发时就与竞争产品区分开来。查看这篇文章:https : //www.geekwire.com/2015/recalc-or-die-30-years-later-microsoft-excel-1-0-vets-recount-a-project-that-defied-the -赔率/
其他答案集中在重新计算的机制和易失函数的作用上,但是我认为这遗漏了问题的要点。它解决了已经采用的规则,但没有解决“为什么”的问题。我将专注于此。
设计理念
让我从一个设计概念和大多数现代电子表格的构建块开始。有一个“责任划分”。函数是专用程序,它们执行特定任务,并在每次被要求时执行。与此分开的是,电子表格应用程序控制何时询问他们。
这些函数本身不包含任何选择重新计算或不重新计算的逻辑。所有Excel函数的本质都是在触发时执行某种类型的操作。任何函数都没有其自己的当前值“内存”,也没有其过去计算的历史记录。它无法知道这是否是第一次要求其执行工作。因此,没有任何本机函数只能运行一次。如果重新计算任何函数,它将执行其设计工作并产生新的值。
电子表格应用程序确实包含一些智能,可以通过跳过不必要的重新计算来节省时间(如teylyn的答案所述)。该唯一的时间重新计算跳过的是,如果应用程序知道函数的值不会受到触发需要重新计算事物的电子表格的变化。
那么,如果您需要一次运行一个函数然后保留其值怎么办?以产生随机数然后结果不变的示例为例。这描述了创建随机生成的常量,您可以使用Excel来完成。
Excel无法知道您想如何使用其功能;您是要继续产生新值还是保留上一个值。每个选项都是Excel支持的用例。Excel通过为您提供计算新值的工具和保留旧值的工具来适应两种情况。您可以构建任何您想要的东西。但是用户有责任使其按自己的意愿去做。
功能逻辑
因此,让我们看一下函数的逻辑。重新计算逻辑跳过随机函数是否有意义,因为其值不应受到电子表格中其他更改的影响?
函数值在重新计算时是否更改取决于函数的用途及其基础。对常数值的计算将始终产生相同的结果。基于未更改的单元格值的操作将产生相同的结果。
但是,某些功能的设计目的是每次产生不同的结果。例如,考虑基于当前时间的功能。他们将根据重新计算的时间产生新的结果。您不能有一个函数,该函数的目的是根据当前时间生成一个值,并且在重新计算时不更新它。
重新计算控制的目标是在重新计算触发时始终使所有内容反映事物的当前状态。如果基于当前时间的功能未更新,将无法满足该标准。
像RANDBETWEEN这样的“随机”函数的目的是在重新计算时产生一个新的随机数。那就是他们打算做的。您可能会争辩说可以跳过重新计算,因为该值不应受到电子表格上发生的其他情况的影响。
如果这是默认行为,则您将更新电子表格,但随机值将保持不变。那不是很随机的行为。那将支持一个用例,但不支持另一个用例。回到基本的设计概念,它的处理方式与其他任何功能一样。默认行为是让Excel重新计算它。如果要保留用例的先前值,则可以使用可用工具来做到这一点。
工作表中的每个更改都会启动所有公式的自动重新计算,这是默认行为。
您可以禁用它或通过将其转换为纯值来冻结实际值(与公式相反)。
它被归类为“易失性”公式,因此是检测到更改或输入新函数时重新计算的函数列表的一部分。
要考虑的另一种选择是将工作表切换为手动计算,以便您控制何时发生-只需确保记住记得重新计算即可,因为对值或公式的任何更改都不会导致重新计算...
尽管做出了种种努力,使声音听起来像是功能而不是错误,但我发现这种行为通常不太可能具有优势。“功能”使我们的生活更轻松,“错误”使我们的生活更艰难。在我的情况下,在没有任何其他单元格引用的单元格中输入标签或说明会导致重新随机化,这很麻烦。我将其称为“错误”。
是的,我可以手动控制重新计算(很痛苦),也可以粘贴值来防止它再次出现(很痛苦),但是在什么情况下,由于在纸张的偏远区域输入文本而导致的重新随机化使生活更轻松?
即使“易失”功能的处理背后有某种逻辑,通过适当的条件触发重新计算似乎也很容易,而不是在不相关和不引用的单元格中输入文本后简单点击“输入”,或者通过其他完全不相关的编辑。阻止它应该是默认设置,我无法想象这将很难实现。如果有人想要该“功能”,则可以将其打开,但是我无法想象何时会是一件好事。充其量来说,它可能相对无害。对于我来说,这是一个很大的麻烦,因为我要创建的工作表类型。
最后-Analysis Toolpak允许您以多种方式创建随机数分布,并且除非您告知这样做,否则如此创建的数字范围根本不会重新计算(重新随机化)。因此,我建议人们在需要时使用Analysis ToolPak。