I am a littlebit puzzeled about the chosen structure.
First we have the functions for the algorithm and the agents which performs
the function. There are the creator agents in the domicilems, which adds
new tested individuals into the populatin. Then the grimreaper which
removes individuals from the population and at last the start-stop-agent
which "controls" the process.
But this agent has only one status, which is not stet by any function which
is send to the agent. The status is set by the function start-evolution and
by track-evolution.
Would it be more idomatic and correct to set the conditions when the
algorithm should finish during 'prepare-evolution' or as a parameter in
'start-evolution' instead in 'track-evolution' which is normal only a
function to log the sideeffects during the algorithm runtime?

What would the better way to give the 'start-stop-agents' more control over
the algorithm?

Am Mittwoch, 4. April 2012 schrieb Marcus Lindner <
marcus.goldritter.lind...@googlemail.com>:
> Thanks for the answer.
>
> I wondered too why the GA took so long to solve this small problem.
> I tried send for the grimreaper, but this does not solve the population
increase problem. On a test run the population even increses much faster,
wehen I used only send.
>
> But I must say I liked the idea to use agents. This is more like real
live. There the individuals are also "created", "tested" and "removed"
asynchron :P.
>
>
>
> Am 03.04.2012 23:40, schrieb Stefan Kamphausen:
>>
>> Hi,
>>
>> sorry to be late to the party...
>>
>> Please let me try to answer some of your questions in one post.
>>
>> 1. The main purpose for the code was to show how many threads could work
on one shared data-structure and how the introduction of concurrent
programming can change the algorithms: in this case moving from generations
of populations to one population being continuously changed by threads.  In
addition to that I wanted to demo the concept of self-calling agents while
another agent indicates the current state of the whole system.
>>
>> 2. The problem with the increasing of the population depending on the
number of threads for creating new individuals and removing other from the
population was initially unforeseen.  However, I kept it in the book
because it indicates that there are new issues for the programmer to
handle, when concurrent programming is introduced.  In addition to that, I
personally think that the management of resources like seen in this example
will become an issues as soon as we are talking about more than -say- 16
cores.  I think we will need more control than just one thread pool.
>>
>> 3. This examples does not use Refs and thus it has nothing to do with
the integration of agents into the STM system.  BTW the integration means
that the STM will take care that any function sent to an agent within a
transaction will only be sent exactly one, not for every retry of the
dosync-body.
>>
>> 4. When I wrote the code it usually evolved within some 10-20 seconds.
 On a dual core machine.  I wouldn't have put code in the book that took
several minutes on my machines.  So, I wonder why it is so slow on your
machines.  (Sidenote: I'd expect a reasonably well tunes GA written
single-threadedly in C to find the solution in a few seconds at max.)
>>
>> 5. The pmap that you introduced when sending the functions to the agents
would only queue the functions faster, as Jim mentioned in his last post.
 In my understanding that should not really make any difference.  The
overhead in that piece of code would be small, because it is only created
once, not in a tight loop or something.  The increase of memory *might* be
related to garbage collection being too slow.  Did you try to use parallel
GC?
>>
>> 6. My use of send-off in the grim reaper agent fn is an error.  send-off
is supposed to be used for potentially blocking functions, e.g. I/O.  Maybe
this one is the reason for the problems with growing populations?  send-off
uses a different thread pool which is not of fixed size (IIRC).  I will
have to try that out, but it will take a few days.
>>
>> 7. The whole example is rather artificial: usually the fitness function
would be expensive, whereas in this example it is just boils down to some
cheap comparisons.  Thus, there will probably be many collisions when
trying to change the population Atom.  This would decrease the amount of
concurrency that is possible.  You might want to try to apply the general
GA idea to a more complicated problem which makes the calculation of the
fitness more expensive.  In that case the reading an writing on the atom
would become less, compared to the calculation of the fitness, thereby
reducing the amount of collisions and repetitions of the update function.
>>
>> After all that has been said, I sincerely hope, that playing with that
example helped you understand things better. :-)
>>
>>
>> Kind regards,
>> Stefan
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to