This is perfectly clear and obvious in hindsight. Thanks -- Matthias


On Oct 14, 2015, at 11:23 AM, chi <nguyenlinhch...@gmail.com> wrote:

> Thanks for answering me many times. I really appreciate.
> For the question, if we dont accumulate and randomise that way, how can we 
> spawn new automata regarding their fitness?
> 
> For example,
> population: a b c d
> payoff: 5 0 8 3 (sum = 16)
> relative payoff: 5/16 0/16 8/16 3/16
> 
> -> The replacement process is a lottery that gives automaton a 5/16 
> probability to be chosen, 0 for automaton b, 1/2 for automaton c, 3/16 for 
> automaton d.
> 
> In practice, option 1: this process is usually been done by drawing a unit 
> line, marking intervals with different lengths:
> 
> +-----++-------+---+
> 
> then you throw a ball randomly in this line, if we see it landing in the 
> interval with length 3/16, automaton a is chosen. Bigger interval means 
> better chance of being chosen and it can proliferate over time (counted by 
> cycles).
> 
> Or option 2: we can mark each point on the line associating with an automaton 
> (however the line is continuous, hence it has infinite points) at random 
> order. In this marking process, we just need to be sure about one thing: the 
> number of points for automaton a has to sum up to 5/16 ~ 25% length of the 
> whole line, the number of points for automaton c has to sum up to 50% the 
> length of the line....
> 
> -> it's better to put all the points for the same automaton next to each 
> other so they form a continuous interval (like in option1).
> 
> In coding, it's similar. The (random) function throws a ball, and gives a 
> point but the computer doesnt simply see which automaton the point belongs to.
> 
> So we accumulate the payoff according to the order of the automata in the 
> population. It's called a cumulative function.
> F(a) = p(a) = 5/16
> F(b) = p(a) + p(b) = 5/16
> ...
> F(d) = p(a) + p(b) + p(c) + p(d) = 1
> 
> so the actual payoff of b will be F(b) - F(a) and so on..
> (We can accumulate from the left or from the right).
> 
> And now the computer can compare r = (random) with the end point of each 
> interval, then it knows what automaton interval the point belongs to.
> 
> (I dont know who do this first, it's like every person who starts to do 
> evolution simulation will ask this question, and a person who already did 
> this practice will tell them, and so on...)
> 
> 
> 
> On 14/10/2015 16:42, Matthias Felleisen wrote:
>> 
>> On Oct 13, 2015, at 11:52 PM, Nguyen Linh Chi <nguyenlinhch...@gmail.com> 
>> wrote:
>> 
>>> Isnt this the reason we should add 0 at the beginning of the list?
>>> 
>>> On 13/ott/2015, at 22:38, Matthias Felleisen <matth...@ccs.neu.edu> wrote:
>>> 
>>>> Welcome to Racket v6.3.0.1.
>>>>> (define r .8)
>>>>> (for/last ([p '(a b c d)][f '(.2 .5 .7 1)] #:break (< r f)) p)
>>>> 'c
>>>> 
>>>> Or WORSE:
>>>> 
>>>>> (define r (random))
>>>>> r
>>>> 0.011105628290672482
>>>>> (for/last ([p '(a b c d)][f '(.2 .5 .7 1)] #:break (< r f)) p)
>>>> #f
>> 
>> No, it is bad programming practice to add a sentinel in one function
>> that is used by another function. The locations are too far apart,
>> because programmers reason about function-sized pieces when they
>> approach code. (I did, I refactored, and I got the failure).
>> 
>> When you code, keep in mind that you write this code for other
>> people (possibly your older self in six months from now when you
>> revise the program) and it accidentally runs on a computer.
>> 
>> 
>> 
>> Here is how I rewrote your function and added a test:
>> 
>> ;; 
>> -----------------------------------------------------------------------------
>> ;; [Vectorof Automaton] N -> [Listof Automaton]
>> ;; (randomise-over-fitness v n) spawn a list of n fittest automata
>> 
>> ;; Nguyen Linh Chi says:
>> ;; This procedure uses an independent Bernoulli draw. We independently
>> ;; draw a random number (associated with an automaton) for 10 times. How
>> ;; likely an automaton is chosen depends on its own fitness (its interval
>> ;; in the unit scale of the accumulated percentages.)
>> 
>> (module+ test
>>   (define p0 (vector (automaton 0 1 't1)  (automaton 0 90 't1)))
>>   (define p1 (list (automaton 0 90 't1)))
>>   ;; this test case fails if (random) picks a number < .01
>>   (check-equal?
>>    (randomise-over-fitness p0 1) (list (automaton 0 90 't1))))
>> 
>> (define (randomise-over-fitness population0 speed)
>>   (define fitness (payoff-percentages population0))
>>   ;; (= (length fitness) (length population))
>>   ;; fitness is sorted and the last number is ~1.0
>>   (define population (vector->list population0))
>>   (for/list ([n (in-range speed)])
>>     [define r (random)]
>>     (define last (for/last ([p population] [f fitness] #:final (< r f)) p))
>>     (or last (error 'randomise "the unlikely happened: r = ~e is too large" 
>> r))))
>> 
>> the for/last combined with #:final brings across this intention.
>> 
>> The way I have written it, the code also points out that,
>> at least in principle, the world of floating point numbers
>> allows for a failure to find a fit enough automaton in this
>> list. (Yes, it is a very small chance.)
>> 
>> ***
>> 
>> QUESTION: why do you accumulate fitness across different automata?
>> That is, why does payoff-percentages add the payoff of automata_i
>> to automata_{i+1}? I understand that this means the last automata
>> will have a fitness level of close to 1 (modulo rounding floating
>> point numbers).
>> 
>> 
>> 
>> 
>> 
>> 
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to