2

很抱歉,如果之前有人问过这个问题,但我不确定我在寻找什么,而且我缺乏正确构建问题的领域知识,这使得答案很难找到!

无论如何,我正在尝试在 Python 中实现一篇论文中的模拟退火算法(IBM J. Res. Dev., 2001; 45(3/4); 545)。作者给出了他在 C++ 中实现的算法的清晰概述,但是在他的定义结束时,他陈述了以下内容

“为了避免重复和可能昂贵的内存分配,S 和 S* 被实现为单个对象,能够在不利的突变后恢复到其初始状态。”

(S 和 S* 表示正在优化的任何东西的原始状态和阶跃变化状态)。

在以前更天真的版本中,我使用两个列表来保存每个状态,但他的评论似乎表明这种方法内存效率低下。因此,我的问题是:

  1. 他的评论是 C++ 特定的吗?在 Python 中我可以继续使用列表而不用担心吗?
  2. 如果我确实需要担心它,我应该使用什么 Python 数据结构?只需定义一个具有原始和变异属性的类以及一个进行变异的方法,还是我还缺少其他东西?
  3. 我仍然需要这两种状态,那么将其包装在一个类中会改变内存分配方式以使类表示更紧凑吗?
4

2 回答 2

2

理论上,您可以记录并重播对可变 Python 对象的所有操作,以实现其在误导突变之前的状态。但这是痛苦和昂贵的。以可以恢复突变的方式将记录的事件映射到反函数也是如此。

然而,函数式编程的趋势似乎强烈鼓励扩展使用不可变数据……尤其是并发编程。这种思维方式不仅限于 Haskell、OCaml 和 Erlang 等函数式语言。它甚至渗透到了 Java 世界

如果一个对象在构造后它的状态不能改变,那么它就被认为是不可变的。最大限度地依赖不可变对象被广泛认为是创建简单、可靠代码的合理策略。

不可变对象在并发应用程序中特别有用。由于它们无法更改状态,因此它们不会被线程干扰破坏或观察到不一致的状态。

程序员通常不愿意使用不可变对象,因为他们担心创建新对象而不是就地更新对象的成本。对象创建的影响通常被高估,并且可以被与不可变对象相关的一些效率所抵消。这些包括由于垃圾收集而减少的开销,以及消除保护可变对象免受损坏所需的代码。

以下小节采用实例可变的类,并从中派生具有不可变实例的类。通过这样做,他们给出了这种转换的一般规则,并展示了不可变对象的一些优点。

使用地图或列表理解生成一个新列表并进行相应修改。如果 Ram 确实是一个问题,请考虑使用生成器,它可以为您提供具有所需修改和更低内存占用的迭代。

于 2012-10-02T08:06:30.253 回答
1

这取决于正在创建的对象。如果它是一个大对象(在内存中),那么创建其中两个SS'作为列表或其他方式会降低内存效率,然后设计一种转换方式S->S'反之亦然,只要转换本身不消耗太多内存即可。

这些类型的数据结构被归类为追溯数据结构与一些其他同义词,如动力学数据结构

使用 adeque并管理所有对象状态是一种方法。

于 2012-10-02T07:28:21.203 回答