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