CHARS =: ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'
randomize =: (fivePct f.)`(mutation f.)}
fivePct =: 0.05 >: $ ?...@$ 0:
mutation =: CHARS&(] ,: [ {~ $...@] ?...@$#@[)
score =: +/@:~:"1
copy100 =: 100 $ ,:
NotDone =: 1 - -:
initial =: CHARS ([ {~ ?...@$&#~ ) [
next =: ([ (] {~ (i. <./)@:score) randomize@:copy100@:])
The following is a simple practical workaround; of course, it still has a limit
(which often is a good thing to have) but it is user-controlled and it has an
overhead but it might be possible, or it might not be possible, for the
implementation to eventually catch up).
evolve=: (next ^: NotDone ^: 1e5 initial) f.
evolve'METHINKS IT IS LIKE A WEASEL'
METHINKS IT IS LIKE A WEASEL
A one-liner that seems open for reduction:
(([ (] {~ (i. <./)@:(
________________________________
From: Dan Bron <[email protected]>
To: Programming Forum <[email protected]>
Sent: Thursday, October 8, 2009 11:43:59 AM
Subject: [Jprogramming] Limit limitation
I'm seeking a stylish workaround to the a constraint on applications of
^:_ .
The idiom ^:_ is well designed and well documented. It is one of the
most useful tools in the J kit and has broad applicability. However,
there are some cases where it's almost, but not quite, applicable.
Consider the form f^:g^:_ where g is a conditional which determines if
f is to be applied (again). Of course if g returns 0, then f isn't
applied, and f^:g becomes an identity function, which means its output
will match its input, and ^:_ will terminate. So usually ^:g^:_ acts
as a while loop, independent of the operation of f, terminating iff g is
0.
But now consider an f that is not one-to-one. That is, an f where two or
more distinct inputs may produce identical outputs. Using this f in
f^:g^:_ becomes problematic. If f receives two inputs in a row which map
to the same output, then the loop will terminate early (that is, even if g
is 1).
Here's a recent example. I'm trying to code the "evoluationary algorithm"
from RC http://rosettacode.org/wiki/Evolutionary_algorithm . The code I
have so far reads [1]:
CHARS =: ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'
randomize =: fivePct`mutation}
fivePct =: 0.05 >: $ ?...@$ 0:
mutation =: (UCALPHA,' ')&(] ,: [ {~ $...@] ?...@$ #...@[)
score =: +/@:~:"1
copy100 =: 100 $ ,:
done =: 1 - -:
initial =: CHARS ([ {~ ?...@$&#~ ) [
f =: ([ (] {~ (i. <./)@:score) randomize@:copy100@:])
(f^:done^:_: initial) 'METHINKS IT IS LIKE A WEASEL'
The problem I'm hitting is that f here isn't deterministic. It takes a
"parent", generates a random population, and selects the fittest member of
that population -- which could legitimately be the original parent. Hence
input and output are identical and f^:done^:_: terminates "early". What
is I want is for f^:done^:_: to terminate iff done is true (that is,
'METHINKS IT IS LIKE A WEASEL' -: y ).
Now, I understand that ^:_ is doing the right thing. I just want it to
do a slightly different thing, and I'm asking for elegant ways to achieve
that. I know I've hit this wall before. Has anyone else? Can you
suggest a stylish workaround?
One method I'm considering is artificially (but reversibly) changing the
output of f at every iteration, as in defining f_new =: -.&.>@:{. ,&<
f (that is, concatenating a boolean and negating it every iteration).
-Dan
[1] Bear in mind this code is still in development, and may suffer from
problems other than the one in question.
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
+/@:~:"1)) (0.05 >: $ ?...@$0:)`(' ABCDEFGHIJKLMNOPQRSTUVWXYZ'&(] ,: [ {~
$...@] ?...@$#@[))}@:(100$ ,:)@:])^:(1 - -:)^:1e5 ('
ABCDEFGHIJKLMNOPQRSTUVWXYZ' ([ {~ ?...@$&#~) [)) 'METHINKS IT IS LIKE A WEASEL'
METHINKS IT IS LIKE A WEASEL
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm