2

I'm sorry if this has been asked before, but I'm not really sure what I'm looking for and I lack the domain knowledge to correctly frame the question which make answers rather hard to find!

Anyway, I am trying to implement in Python a simulated annealing algorithm from a paper (IBM J. Res. Dev., 2001; 45(3/4); 545). The author gives a clear outline of the algorithm which he has implemented in C++, however at the end of his definition he states the follwing

"To avoid repeated and potentially expensive memory allocation S and S* are implemented as a single object that is able to revert to its initial state after an unfavourable mutation."

(S and S* represent the original and step changed state of whatever is being optimised).

In a previous more naive version I have used two lists to hold each state, but his comment seems to suggest that such an approach is memory inefficient. Thus, my questions are:

  1. Is his comment C++ specific and in Python I can continue to use lists and not worry about it?
  2. If I do need to worry about it, what Python data structure should I use? Simply define a class with original and mutated attributes and a method to do the mutation or is there something else I'm missing?
  3. I still need the two states, so does wrapping that in a class change the way the memory is allocated to make the class representation more compact?
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Hassantm
  • 563
  • 1
  • 4
  • 14
  • That paper was written in 2001. Chances are you have a bit more RAM to play with than he did. Do you really need to worry about this? – David Steele Oct 02 '12 at 07:19
  • That's very true! On thinking about it a little more, I guess I could use one list, mutate it in place but record the mutation. Calculate the new cost function and if it's better keep the new list if not undo the mutation, so there's only ever one state list in play. The disadvantage of that would, I think, be clarity which is something of a Pythonic objective. – Hassantm Oct 02 '12 at 07:31

2 Answers2

2

You could theoretically log and replay all manipulations to a mutable Python object to achieve it's state prior to the misguided mutation. But that's painful and expensive. So is mapping logged events to inverse functions in such a way that a mutation can be reverted.

The trend with functional programming, however seems to strongly encourage expanded use of immutable data...especially with concurrent programming. This mindset isn't just limited to functional languages like Haskell, OCaml, and Erlang. It's even infiltrated the Java world:

An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code.

Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

Programmers are often reluctant to employ immutable objects, because they worry about the cost of creating a new object as opposed to updating an object in place. The impact of object creation is often overestimated, and can be offset by some of the efficiencies associated with immutable objects. These include decreased overhead due to garbage collection, and the elimination of code needed to protect mutable objects from corruption.

The following subsections take a class whose instances are mutable and derives a class with immutable instances from it. In so doing, they give general rules for this kind of conversion and demonstrate some of the advantages of immutable objects.

Generate a new list with a map or list comprehension and modify accordingly. If Ram really is an issue, consider using a generator with that gives you an iterable with desired modification and a lower memory footprint.

damzam
  • 1,921
  • 15
  • 18
1

It depends on the object being created. If it is a large object (in-memory) then creating two of them S and S' as lists or otherwise would be less memory efficient then designing a way to transform S -> S' and vice versa as long as the transformation itself does not consume much memory.

These type of Data Structures are classified as RetroActive Data Structures with a few other synonyms like Kinetic data structures.

Using a deque and managing all the object states is one way of doing it.

Pratik Mandrekar
  • 9,362
  • 4
  • 45
  • 65