如果以前曾经问过这个问题,我很抱歉,但我不确定我在寻找什么,而且我缺乏领域知识来正确构建问题,这使得答案难以找到!
无论如何,我试图用Python实现模拟退火算法(IBM J. Res.Dev。,2001; 45(3/4); 545)。作者给出了他在C ++中实现的算法的清晰概述,但是在他的定义结束时他陈述了以下内容
“为了避免重复且可能昂贵的内存分配,S和S *被实现为单个对象,能够在不利的突变后恢复到其初始状态。”
(S和S *表示正在优化的任何内容的原始和步骤更改状态。)
在之前更天真的版本中,我使用了两个列表来保存每个州,但他的评论似乎表明这种方法是内存效率低下的。因此,我的问题是:
答案 0 :(得分:2)
理论上,你可以记录并重放所有对可变Python对象的操作,以便在误导突变之前实现它的状态。但那是痛苦和昂贵的。因此,将记录的事件映射到反函数,以便可以恢复突变。
然而,函数式编程的趋势似乎强烈鼓励扩展使用不可变数据...... 尤其是并发编程。这种思维方式不仅限于Haskell,OCaml和Erlang等函数式语言。它甚至是infiltrated the Java world:如果一个对象的状态在其后不能改变,则该对象被认为是不可变的 是建造的。最大程度上依赖于不可变对象 被认为是创建简单,可靠代码的合理策略。
不可变对象在并发应用程序中特别有用。 由于它们无法改变状态,因此它们不会被线程破坏 干扰或观察到不一致的状态。
程序员通常不愿意使用不可变对象,因为 他们担心创建新对象的成本而不是 更新对象。对象创建的影响通常是 过高估计,可以通过一些效率来抵消 与不可变对象相关联。这些包括减少的开销 由于垃圾收集,并消除了所需的代码 保护可变对象免受腐败。
以下小节介绍了一个实例可变的类 从中派生出具有不可变实例的类。这样做,他们 给出这种转换的一般规则并演示一些 不可变对象的优点。
使用地图或列表推导生成新列表并相应地进行修改。如果Ram确实是一个问题,请考虑使用generator,这样可以获得具有所需修改和较低内存占用量的迭代。
答案 1 :(得分:1)
这取决于正在创建的对象。如果它是一个大对象(内存中),那么创建其中两个S
和S'
作为列表,否则将会降低内存效率,然后设计转换S
的方法 - > S'
,反之亦然,只要转换本身不会占用太多内存。
这些类型的数据结构被归类为RetroActive Data Structures以及其他一些同义词,例如Kinetic data structures。
使用deque
并管理所有对象状态是这样做的一种方式。