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.