Mindwerks / worldengine

World generator using simulation of plates, rain shadow, erosion, etc.
MIT License
982 stars 128 forks source link

random.seed() #133

Closed tcld closed 8 years ago

tcld commented 8 years ago

I noticed that several calls to the seed()-function are spread all over different files. This changes the seed for every part of the program that comes afterwards.

Either seed() should be called exactly once per program (as done in main() ) or if a change of seeds is really necessary, the seed should be reset to its original value after the current function finishes. E.g.:

def a(seed):
    random.seed(seed*5)
    importantnumber=random.randint(0, 4096)
    random.seed(seed) #reset

I think the first approach is the cleanest and best, though. Python uses a Mersenne Twister for its random number generation, and when it comes to pseudo-random numbers that is about as good as it gets.

Two notes on this:

  1. Should this commit be merged, results of generated worlds (permeability, precipitation, temperature) will change (since the files in question now use a different seed). I guess that blessed images would have to be regenerated and every saved world out there would change.
  2. I noticed calls to seed() in the tests. I guess it would be best if random.seed() was called exactly once during the tests, but I don't know if the tests are run as separate programs (each of which would have to initiate the RNG) or if they all share the same RNG. Any idea?
  3. Is there any combination of parameters that could allow worldengine to bypass the call to random.seed() in the main() function? If so, the RNG should be initiated earlier than that to make sure that a passed seed is actually made use of.
tcld commented 8 years ago

It seems the test against the blessed images failed. I should have seen that coming.^^

I'll await your input on this. Most of the time I work with C++ so my habits when it comes to "clean" code may be a bit too strict.

tcld commented 8 years ago

I thought about this: Reinitiating the RNG at every step along the way could have the effect that the order of those steps has little influence on the final result. If that was the goal there is probably a better way to do things. Because this method does not get rid of all possible problems, the seed cannot be reset to its previous value anyway. And if it was set back to seed the random generation would just spit out the same values it already gave us.

I think this needs a bit of brainstorming. In my opinion seed(seed) should be called exactly once and everything else should be derived from it in a hopefully deterministic way.

psi29a commented 8 years ago

rebuild based on new master.

tcld commented 8 years ago

I guess this needs some more work anyway. I do not yet have a clean idea of how to make things 100% deterministic. Removing all the calls to seed() I feel is a good step, but if the different simulations were called out of order, that would change the outcome. The random numbers should probably be managed somehow.

tcld commented 8 years ago

Closed since it is going to be redundant by the upcoming fixes to the random()-calls.