1 Nov 2008 11:00
howto: agent-based model
bOR_ <boris.schmid <at> gmail.com>
2008-11-01 10:00:03 GMT
2008-11-01 10:00:03 GMT
Hi all, I'm in the process of converting an agent-based model I've written in ruby (don't ask, it is slower, but the code is a nice 150 lines rather than the 4000 my predecessor left behind in C) to Clojure, while at the same time using the screencasts to learn clojure (which works excellently, by the way). The question I have is this: based on ants, and the explanations of refs and agents I can see quite a number of ways in which I could rewrite the model, but I don't have the overview yet of seeing what ways are handy / horrible when it comes to spawning multiple threads etc. The ruby model is written with the 'one thing at a time' mindset, and I was looking for way to start using the multiple processors that most computers at my work have available (up to 8 cores per comp, and one cluster of about 40 processors). Running the ants simulation, I was somewhat surprised seeing about 70 threads running on a single processor at the same time (in a single-procesor computer). I had expected something like n threads + 2, where n is the number of processors in the computer. Briefly, the model as it was: fixed-size array, each position possibly holding a host. Some of the hosts are infected with a virus. Hosts can give birth, die, have the virus inside them evolve, and infect another host. The basic structure of the model was to pick a random host, pick a random event (birth,die,evolve,infect), pick some other hosts if the event requires that, and complete the event. Repeat endlessly. Possible ways to rewrite it: 1. List-of-events. Create something of an infinite list of "random event + random position", and dispatch (send-off) processes as I foreach through the list. I'm slightly worried that this will try to produce an endless number of threads as well (but I might just try to do it, and learn by experience), as I'm not sure if there is some hidden thread-pool beneath clojure that limits the number of threads that exist at the same time. 2. Host-locations centered. Like the ants in ants.clj, make a thread for every position in the array, which just keeps trying to execute any of the 4 events. If one of the positions happens to be empty (for example, after successfully executing a 'death' event to the content of a position), the events just keep failing (this worries me a bit), until some other position in the array manages a succesfull birth event to be placed in that empty position, after which the agent in that position can start doing useful things again with its content. If my max host population would happen to be of size 10.000, I think this would spawn 10.000 threads at the same time.. which also worries me a bit. 3. Host-centered. Spawn each host as a independent agent. Haven't thought this one through yet, but loses some of the nice properties of the fixed-size hosts array, while still spawning close to 10.000 threads (as in the simulations, the population is most of the time close the maximum. I am not that worried about events happening in the wrong order.. as long as the frequency of the events stays at their respective weight (i.e. death 1, birth 0.5, evolution 0.5, infection 10). Can any of you recommend a strategy to use (1, 2, 3 or possibly a 4 ;) that respects the relative frequency of the events, and doesn't grind computers to a halt when it is trying to juggle n threads? Thanks in advance.