2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -8,11 +8,15 @@ Starting with:
|
|||
:* Assess the <code>fitness</code> of the parent and all the copies to the <code>target</code> and make the most fit string the new <code>parent</code>, discarding the others.
|
||||
:* repeat until the parent converges, (hopefully), to the target.
|
||||
|
||||
Cf: [[wp:Weasel_program#Weasel_algorithm|Weasel algorithm]] and [[wp:Evolutionary algorithm|Evolutionary algorithm]]
|
||||
|
||||
;Related tasks:
|
||||
* [[wp:Weasel_program#Weasel_algorithm|Weasel algorithm]].
|
||||
* [[wp:Evolutionary algorithm|Evolutionary algorithm]].
|
||||
|
||||
<br>
|
||||
<small>Note: to aid comparison, try and ensure the variables and functions mentioned in the task description appear in solutions</small>
|
||||
|
||||
===========
|
||||
<br>
|
||||
A cursory examination of a few of the solutions reveals that the instructions have not been followed rigorously in some solutions. Specifically,
|
||||
* While the <code>parent</code> is not yet the <code>target</code>:
|
||||
:* copy the <code>parent</code> C times, each time allowing some random probability that another character might be substituted using <code>mutate</code>.
|
||||
|
|
@ -33,3 +37,4 @@ As illustration of this error, the code for 8th has the following remark.
|
|||
Clearly, this algo will be applying the mutation function only to the parent characters that don't match to the target characters!
|
||||
|
||||
To ensure that the new parent is never less fit than the prior parent, both the parent and all of the latest mutations are subjected to the fitness test to select the next parent.
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
identification division.
|
||||
program-id. evolutionary-program.
|
||||
data division.
|
||||
working-storage section.
|
||||
01 evolving-strings.
|
||||
05 target pic a(28)
|
||||
value 'METHINKS IT IS LIKE A WEASEL'.
|
||||
05 parent pic a(28).
|
||||
05 offspring-table.
|
||||
10 offspring pic a(28)
|
||||
occurs 50 times.
|
||||
01 fitness-calculations.
|
||||
05 fitness pic 99.
|
||||
05 highest-fitness pic 99.
|
||||
05 fittest pic 99.
|
||||
01 parameters.
|
||||
05 character-set pic a(27)
|
||||
value 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.
|
||||
05 size-of-generation pic 99
|
||||
value 50.
|
||||
05 mutation-rate pic 99
|
||||
value 5.
|
||||
01 counters-and-working-variables.
|
||||
05 character-position pic 99.
|
||||
05 randomization.
|
||||
10 random-seed pic 9(8).
|
||||
10 random-number pic 99.
|
||||
10 random-letter pic 99.
|
||||
05 generation pic 999.
|
||||
05 child pic 99.
|
||||
05 temporary-string pic a(28).
|
||||
procedure division.
|
||||
control-paragraph.
|
||||
accept random-seed from time.
|
||||
move function random(random-seed) to random-number.
|
||||
perform random-letter-paragraph,
|
||||
varying character-position from 1 by 1
|
||||
until character-position is greater than 28.
|
||||
move temporary-string to parent.
|
||||
move zero to generation.
|
||||
perform output-paragraph.
|
||||
perform evolution-paragraph,
|
||||
varying generation from 1 by 1
|
||||
until parent is equal to target.
|
||||
stop run.
|
||||
evolution-paragraph.
|
||||
perform mutation-paragraph varying child from 1 by 1
|
||||
until child is greater than size-of-generation.
|
||||
move zero to highest-fitness.
|
||||
move 1 to fittest.
|
||||
perform check-fitness-paragraph varying child from 1 by 1
|
||||
until child is greater than size-of-generation.
|
||||
move offspring(fittest) to parent.
|
||||
perform output-paragraph.
|
||||
output-paragraph.
|
||||
display generation ': ' parent.
|
||||
random-letter-paragraph.
|
||||
move function random to random-number.
|
||||
divide random-number by 3.80769 giving random-letter.
|
||||
add 1 to random-letter.
|
||||
move character-set(random-letter:1)
|
||||
to temporary-string(character-position:1).
|
||||
mutation-paragraph.
|
||||
move parent to temporary-string.
|
||||
perform character-mutation-paragraph,
|
||||
varying character-position from 1 by 1
|
||||
until character-position is greater than 28.
|
||||
move temporary-string to offspring(child).
|
||||
character-mutation-paragraph.
|
||||
move function random to random-number.
|
||||
if random-number is less than mutation-rate
|
||||
then perform random-letter-paragraph.
|
||||
check-fitness-paragraph.
|
||||
move offspring(child) to temporary-string.
|
||||
perform fitness-paragraph.
|
||||
fitness-paragraph.
|
||||
move zero to fitness.
|
||||
perform character-fitness-paragraph,
|
||||
varying character-position from 1 by 1
|
||||
until character-position is greater than 28.
|
||||
if fitness is greater than highest-fitness
|
||||
then perform fittest-paragraph.
|
||||
character-fitness-paragraph.
|
||||
if temporary-string(character-position:1) is equal to
|
||||
target(character-position:1) then add 1 to fitness.
|
||||
fittest-paragraph.
|
||||
move fitness to highest-fitness.
|
||||
move child to fittest.
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#import system.
|
||||
#import system'routines.
|
||||
#import extensions.
|
||||
|
||||
#symbol Target = "METHINKS IT IS LIKE A WEASEL".
|
||||
#symbol AllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZ".
|
||||
#symbol C = 100.
|
||||
#symbol P = 0.05r.
|
||||
#symbol rnd = randomGenerator.
|
||||
|
||||
#symbol randomChar
|
||||
= AllowedCharacters @ (rnd nextInt:(AllowedCharacters length)).
|
||||
|
||||
#class(extension) evoHelper
|
||||
{
|
||||
#method randomString
|
||||
= 0 repeat &till:self &each:x [ randomChar ] summarize:(String new) literal.
|
||||
|
||||
#method fitness &of:s
|
||||
= self zip:s &into:(:a:b)[ (a == b)iif:1:0 ] summarize:(Integer new) int.
|
||||
|
||||
#method mutate : p
|
||||
= self select &each: ch [ (rnd nextReal <= p) iif:randomChar:ch ] summarize:(String new) literal.
|
||||
}
|
||||
|
||||
#class EvoAlgorithm :: Enumerator
|
||||
{
|
||||
#field theTarget.
|
||||
#field theCurrent.
|
||||
#field theVariantCount.
|
||||
|
||||
#constructor new : s &of:count
|
||||
[
|
||||
theTarget := s.
|
||||
theVariantCount := count int.
|
||||
]
|
||||
|
||||
#method get = theCurrent.
|
||||
|
||||
#method next
|
||||
[
|
||||
($nil == theCurrent)
|
||||
? [ theCurrent := theTarget length randomString. ^ true. ].
|
||||
|
||||
(theTarget == theCurrent)
|
||||
? [ ^ false. ].
|
||||
|
||||
#var variants := Array new:theVariantCount set &every:(&index:x) [ theCurrent mutate:P ].
|
||||
|
||||
theCurrent := variants array sort:(:a:b) [ a fitness &of:Target > b fitness &of:Target ] getAt:0.
|
||||
|
||||
^ true.
|
||||
]
|
||||
}
|
||||
|
||||
#symbol program =
|
||||
[
|
||||
#var attempt := Integer new.
|
||||
EvoAlgorithm new:Target &of:C run &each:current
|
||||
[
|
||||
console
|
||||
writeLiteral:"#":(attempt += 1) &paddingLeft:10
|
||||
writeLine:" ":current:" fitness: ":(current fitness &of:Target).
|
||||
].
|
||||
].
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
defmodule Log do
|
||||
def show(offspring,i) do
|
||||
IO.puts "Generation: #{i}, Offspring: #{offspring}"
|
||||
end
|
||||
|
||||
def found({target,i}) do
|
||||
IO.puts "#{target} found in #{i} iterations"
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Evolution do
|
||||
# char list from A to Z; 32 is the ord value for space.
|
||||
@chars [32 | Enum.to_list(?A..?Z)]
|
||||
|
||||
def select(target) do
|
||||
(1..String.length(target)) # Creates parent for generation 0.
|
||||
|> Enum.map(fn _-> Enum.random(@chars) end)
|
||||
|> mutate(to_char_list(target),0)
|
||||
|> Log.found
|
||||
end
|
||||
|
||||
# w is used to denote fitness in population genetics.
|
||||
|
||||
defp mutate(parent,target,i) when target == parent, do: {parent,i}
|
||||
defp mutate(parent,target,i) do
|
||||
w = fitness(parent,target)
|
||||
prev = reproduce(target,parent,mu_rate(w))
|
||||
|
||||
# Check if the most fit member of the new gen has a greater fitness than the parent.
|
||||
if w < fitness(prev,target) do
|
||||
parent = prev
|
||||
Log.show(parent,i)
|
||||
end
|
||||
mutate(parent,target,i+1)
|
||||
end
|
||||
|
||||
# Generate 100 offspring and select the one with the greatest fitness.
|
||||
|
||||
defp reproduce(target,parent,rate) do
|
||||
[parent | Enum.map(1..100, fn _-> mutation(parent,rate) end)]
|
||||
|> Enum.max_by(fn n -> fitness(n,target) end)
|
||||
end
|
||||
|
||||
# Calculate fitness by checking difference between parent and offspring chars.
|
||||
|
||||
defp fitness(t,r) do
|
||||
Enum.zip(t,r)
|
||||
|> Enum.reduce(0, fn {tn,rn},sum -> abs(tn - rn) + sum end)
|
||||
|> calc
|
||||
end
|
||||
|
||||
# Generate offspring based on parent.
|
||||
|
||||
defp mutation(p,r) do
|
||||
# Copy the parent chars, then check each val against the random mutation rate
|
||||
Enum.map(p, fn n -> if :rand.uniform <= r, do: Enum.random(@chars), else: n end)
|
||||
end
|
||||
|
||||
defp calc(sum), do: 100 * :math.exp(sum/-10)
|
||||
defp mu_rate(n), do: 1 - :math.exp(-(100-n)/400)
|
||||
end
|
||||
|
||||
Evolution.select("METHINKS IT IS LIKE A WEASEL")
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
target="METHINKS IT IS LIKE A WEASEL";
|
||||
fitness(s)=-dist(Vec(s),Vec(target));
|
||||
dist(u,v)=sum(i=1,min(#u,#v),u[i]!=v[i])+abs(#u-#v);
|
||||
letter()=my(r=random(27)); if(r==26, " ", Strchr(r+65));
|
||||
insert(v,x=letter())=
|
||||
{
|
||||
my(r=random(#v+1));
|
||||
if(r==0, return(concat([x],v)));
|
||||
if(r==#v, return(concat(v,[x])));
|
||||
concat(concat(v[1..r],[x]),v[r+1..#v]);
|
||||
}
|
||||
delete(v)=
|
||||
{
|
||||
if(#v<2, return([]));
|
||||
my(r=random(#v)+1);
|
||||
if(r==1, return(v[2..#v]));
|
||||
if(r==#v, return(v[1..#v-1]));
|
||||
concat(v[1..r-1],v[r+1..#v]);
|
||||
}
|
||||
mutate(s,rateM,rateI,rateD)=
|
||||
{
|
||||
my(v=Vec(s));
|
||||
if(random(1.)<rateI, v=insert(v));
|
||||
if(random(1.)<rateD, v=delete(v));
|
||||
for(i=1,#v,
|
||||
if(random(1.)<rateM, v[i]=letter())
|
||||
);
|
||||
concat(v);
|
||||
}
|
||||
evolve(C,rate)=
|
||||
{
|
||||
my(parent=concat(vector(#target,i,letter())),ct=0);
|
||||
while(parent != target,
|
||||
print(parent" "fitness(parent));
|
||||
my(v=vector(C,i,mutate(parent,rate,0,0)),best,t);
|
||||
best=fitness(parent=v[1]);
|
||||
for(i=2,C,
|
||||
t=fitness(v[i]);
|
||||
if(t>best, best=t; parent=v[i])
|
||||
);
|
||||
ct++
|
||||
);
|
||||
print(parent" "fitness(parent));
|
||||
ct;
|
||||
}
|
||||
evolve(35,.05)
|
||||
|
|
@ -1,69 +1,71 @@
|
|||
Define.i Pop = 100 ,Mrate = 6
|
||||
Define.s targetS = "METHINKS IT IS LIKE A WEASEL"
|
||||
Define.s CsetS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
|
||||
Define population = 100, mutationRate = 6
|
||||
Define.s target$ = "METHINKS IT IS LIKE A WEASEL"
|
||||
Define.s charSet$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
|
||||
|
||||
Procedure.i fitness (Array aspirant.c(1),Array target.c(1))
|
||||
Protected.i i ,len, fit
|
||||
Procedure.i fitness(Array aspirant.c(1), Array target.c(1))
|
||||
Protected i, len, fit
|
||||
len = ArraySize(aspirant())
|
||||
For i=0 To len
|
||||
If aspirant(i)=target(i): fit +1: EndIf
|
||||
For i = 0 To len
|
||||
If aspirant(i) = target(i): fit +1: EndIf
|
||||
Next
|
||||
ProcedureReturn fit
|
||||
EndProcedure
|
||||
|
||||
Procedure mutatae(Array parent.c(1),Array child.c(1),Array CsetA.c(1),rate.i)
|
||||
Protected i.i ,L.i,maxC
|
||||
Procedure mutatae(Array parent.c(1), Array child.c(1), Array charSetA.c(1), rate.i)
|
||||
Protected i, L, maxC
|
||||
L = ArraySize(child())
|
||||
maxC = ArraySize(CsetA())
|
||||
maxC = ArraySize(charSetA())
|
||||
For i = 0 To L
|
||||
If Random(100) < rate
|
||||
child(i)= CsetA(Random(maxC))
|
||||
child(i) = charSetA(Random(maxC))
|
||||
Else
|
||||
child(i)=parent(i)
|
||||
child(i) = parent(i)
|
||||
EndIf
|
||||
Next
|
||||
EndProcedure
|
||||
|
||||
Procedure.s Carray2String(Array A.c(1))
|
||||
Protected S.s ,len.i
|
||||
len = ArraySize(A())+1 : S = LSet("",len," ")
|
||||
CopyMemory(@A(0),@S, len *SizeOf(Character))
|
||||
Procedure.s cArray2string(Array A.c(1))
|
||||
Protected S.s, len
|
||||
len = ArraySize(A())+1 : S = Space(len)
|
||||
CopyMemory(@A(0), @S, len * SizeOf(Character))
|
||||
ProcedureReturn S
|
||||
EndProcedure
|
||||
|
||||
Define.i Mrate , maxC ,Tlen ,i ,maxfit ,gen ,fit,bestfit
|
||||
Dim targetA.c(Len(targetS)-1)
|
||||
CopyMemory(@targetS, @targetA(0), StringByteLength(targetS))
|
||||
Define mutationRate, maxChar, target_len, i, maxfit, gen, fit, bestfit
|
||||
Dim targetA.c(Len(target$) - 1)
|
||||
CopyMemory(@target$, @targetA(0), StringByteLength(target$))
|
||||
|
||||
Dim CsetA.c(Len(CsetS)-1)
|
||||
CopyMemory(@CsetS, @CsetA(0), StringByteLength(CsetS))
|
||||
Dim charSetA.c(Len(charSet$) - 1)
|
||||
CopyMemory(@charSet$, @charSetA(0), StringByteLength(charSet$))
|
||||
|
||||
maxC = Len(CsetS)-1
|
||||
maxfit = Len(targetS)
|
||||
Tlen = Len(targetS)-1
|
||||
Dim parent.c(Tlen)
|
||||
Dim child.c(Tlen)
|
||||
Dim Bestchild.c(Tlen)
|
||||
maxChar = Len(charSet$) - 1
|
||||
maxfit = Len(target$)
|
||||
target_len = Len(target$) - 1
|
||||
Dim parent.c(target_len)
|
||||
Dim child.c(target_len)
|
||||
Dim Bestchild.c(target_len)
|
||||
|
||||
For i = 0 To Tlen
|
||||
parent(i)= CsetA(Random(maxC))
|
||||
|
||||
For i = 0 To target_len
|
||||
parent(i) = charSetA(Random(maxChar))
|
||||
Next
|
||||
|
||||
fit = fitness (parent(),targetA())
|
||||
fit = fitness (parent(), targetA())
|
||||
OpenConsole()
|
||||
|
||||
PrintN(Str(gen)+": "+Carray2String(parent())+" Fitness= "+Str(fit)+"/"+Str(maxfit))
|
||||
PrintN(Str(gen) + ": " + cArray2string(parent()) + ": Fitness= " + Str(fit) + "/" + Str(maxfit))
|
||||
|
||||
While bestfit <> maxfit
|
||||
gen +1 :
|
||||
For i = 1 To Pop
|
||||
mutatae(parent(),child(),CsetA(),Mrate)
|
||||
fit = fitness (child(),targetA())
|
||||
gen + 1
|
||||
For i = 1 To population
|
||||
mutatae(parent(),child(),charSetA(), mutationRate)
|
||||
fit = fitness (child(), targetA())
|
||||
If fit > bestfit
|
||||
bestfit = fit : Swap Bestchild() , child()
|
||||
bestfit = fit: CopyArray(child(), Bestchild())
|
||||
EndIf
|
||||
Next
|
||||
Swap parent() , Bestchild()
|
||||
PrintN(Str(gen)+": "+Carray2String(parent())+" Fitness= "+Str(bestfit)+"/"+Str(maxfit))
|
||||
CopyArray(Bestchild(), parent())
|
||||
PrintN(Str(gen) + ": " + cArray2string(parent()) + ": Fitness= " + Str(bestfit) + "/" + Str(maxfit))
|
||||
Wend
|
||||
|
||||
PrintN("Press any key to exit"): Repeat: Until Inkey() <> ""
|
||||
|
|
|
|||
|
|
@ -1,34 +1,33 @@
|
|||
/*REXX program demonstrates an evolutionary algorithm (by using mutation). */
|
||||
parse arg children MR seed . /*get optional arguments from the C.L. */
|
||||
if children=='' then children = 10 /*# children produced each generation. */
|
||||
if MR =='' then MR = '4%' /*the character Mutation Rate each gen.*/
|
||||
if right(MR,1)=='%' then MR=strip(MR,,'%')/100 /*expressed as %? Then adjust*/
|
||||
if seed\=='' then call random ,,seed /*SEED allow the runs to be repeatable.*/
|
||||
/*REXX program demonstrates an evolutionary algorithm (by using mutation). */
|
||||
parse arg children MR seed . /*get optional arguments from the C.L. */
|
||||
if children=='' then children = 10 /*# children produced each generation. */
|
||||
if MR =='' then MR = "4%" /*the character Mutation Rate each gen.*/
|
||||
if right(MR,1)=='%' then MR=strip(MR,,"%")/100 /*expressed as a percent? Then adjust.*/
|
||||
if seed\=='' then call random ,,seed /*SEED allow the runs to be repeatable.*/
|
||||
abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' ; Labc=length(abc)
|
||||
target= 'METHINKS IT IS LIKE A WEASEL' ; Ltar=length(target)
|
||||
parent= mutate( left('',Ltar), 1) /*gen rand string,same length as target*/
|
||||
say center('target string',Ltar,'─') "children" 'mutationRate'
|
||||
say target center(children,8) center((MR*100/1)'%',12); say
|
||||
say center('new string',Ltar,'─') "closeness" 'generation'
|
||||
parent= mutate( left('',Ltar), 1) /*gen rand string,same length as target*/
|
||||
say center('target string', Ltar, "─") 'children' "mutationRate"
|
||||
say target center(children,8) center((MR*100/1)'%', 12); say
|
||||
say center('new string' ,Ltar, "─") "closeness" 'generation'
|
||||
|
||||
do gen=0 until parent==target; close=fitness(parent)
|
||||
do gen=0 until parent==target; close=fitness(parent)
|
||||
almost=parent
|
||||
do children; child=mutate(parent,MR)
|
||||
_=fitness(child); if _<=close then iterate
|
||||
close=_; almost=child
|
||||
say almost right(close,9) right(gen,10)
|
||||
end /*children*/
|
||||
do children; child=mutate(parent,MR)
|
||||
_=fitness(child); if _<=close then iterate
|
||||
close=_; almost=child
|
||||
say almost right(close, 9) right(gen,10)
|
||||
end /*children*/
|
||||
parent=almost
|
||||
end /*gen*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
fitness: parse arg x; $=0
|
||||
do k=1 for Ltar; $=$+(substr(x,k,1)==substr(target,k,1)); end /*k*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
fitness: parse arg x; $=0; do k=1 for Ltar; $=$+(substr(x,k,1)==substr(target,k,1)); end
|
||||
return $
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
mutate: parse arg x,rate $ /*set X to 1st argument, RATE to 2nd.*/
|
||||
$=; do j=1 for Ltar; r=random(1,100000) /*REXX's max.*/
|
||||
if .00001*r<=rate then $=$ || substr(abc,r//Labc+1,1)
|
||||
else $=$ || substr(x,j,1)
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
mutate: parse arg x,rate; $= /*set X to 1st argument, RATE to 2nd.*/
|
||||
do j=1 for Ltar; r=random(1,100000) /*REXX's max for RANSOM*/
|
||||
if .00001*r<=rate then $=$ || substr(abc,r//Labc+1, 1)
|
||||
else $=$ || substr(x ,j , 1)
|
||||
end /*j*/
|
||||
return $
|
||||
|
|
|
|||
|
|
@ -1,43 +1,42 @@
|
|||
/*REXX program demonstrates an evolutionary algorithm (by using mutation). */
|
||||
parse arg children MR seed . /*get optional arguments from the C.L. */
|
||||
if children=='' then children = 10 /*# children produced each generation. */
|
||||
if MR =='' then MR = '4%' /*the character Mutation Rate each gen.*/
|
||||
if right(MR,1)=='%' then MR=strip(MR,,'%')/100 /*expressed as %? Then adjust*/
|
||||
if seed\=='' then call random ,,seed /*SEED allow the runs to be repeatable.*/
|
||||
/*REXX program demonstrates an evolutionary algorithm (by using mutation). */
|
||||
parse arg children MR seed . /*get optional arguments from the C.L. */
|
||||
if children=='' then children = 10 /*# children produced each generation. */
|
||||
if MR =='' then MR = "4%" /*the character Mutation Rate each gen.*/
|
||||
if right(MR,1)=='%' then MR=strip(MR,,"%")/100 /*expressed as a percent? Then adjust.*/
|
||||
if seed\=='' then call random ,,seed /*SEED allow the runs to be repeatable.*/
|
||||
abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '; Labc=length(abc)
|
||||
|
||||
do i=0 for Labc /*define array (for faster compare), */
|
||||
@.i=substr(abc,i+1,1) /* it's better than picking out a */
|
||||
end /*i*/ /* byte from a character string. */
|
||||
do i=0 for Labc /*define array (for faster compare), */
|
||||
@.i=substr(abc, i+1, 1) /* it's better than picking out a */
|
||||
end /*i*/ /* byte from a character string. */
|
||||
|
||||
target= 'METHINKS IT IS LIKE A WEASEL' ; Ltar=length(target)
|
||||
|
||||
do i=1 for Ltar /*define an array (for faster compare),*/
|
||||
T.i=substr(target,i,1) /* it's better than a byte-by-byte */
|
||||
end /*i*/ /* compare using character strings.*/
|
||||
do i=1 for Ltar /*define an array (for faster compare),*/
|
||||
T.i=substr(target, i, 1) /* it's better than a byte-by-byte */
|
||||
end /*i*/ /* compare using character strings.*/
|
||||
|
||||
parent= mutate( left('',Ltar), 1) /*gen rand string, same length as tar. */
|
||||
say center('target string',Ltar,'─') "children" 'mutationRate'
|
||||
say target center(children,8) center((MR*100/1)'%',12); say
|
||||
say center('new string',Ltar,'─') "closeness" 'generation'
|
||||
parent= mutate( left('', Ltar), 1) /*gen rand string, same length as tar. */
|
||||
say center('target string', Ltar, "─") 'children' "mutationRate"
|
||||
say target center(children, 8) center((MR*100/1)'%',12); say
|
||||
say center('new string' , Ltar, "─") 'closeness' "generation"
|
||||
|
||||
do gen=0 until parent==target; close=fitness(parent)
|
||||
do gen=0 until parent==target; close=fitness(parent)
|
||||
almost=parent
|
||||
do children; child=mutate(parent,MR)
|
||||
_=fitness(child); if _<=close then iterate
|
||||
close=_; almost=child
|
||||
say almost right(close,9) right(gen,10)
|
||||
do children; child=mutate(parent,MR)
|
||||
_=fitness(child); if _<=close then iterate
|
||||
close=_; almost=child
|
||||
say almost right(close, 9) right(gen, 10)
|
||||
end /*children*/
|
||||
parent=almost
|
||||
end /*gen*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
fitness: parse arg x; $=0; do k=1 for Ltar; $=$+(substr(x,k,1)==T.k); end
|
||||
return $
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
mutate: parse arg x,rate /*set X to 1st argument, RATE to 2nd.*/
|
||||
$=; do j=1 for Ltar; r=random(1,100000) /*REXX's max.*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
fitness: parse arg x; $=0; do k=1 for Ltar; $=$+(substr(x,k,1)==T.k); end; return $
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
mutate: parse arg x,rate /*set X to 1st argument, RATE to 2nd.*/
|
||||
$=; do j=1 for Ltar; r=random(1, 100000) /*REXX's max for RANDOM*/
|
||||
if .00001*r<=rate then do; _=r//Labc; $=$ || @._; end
|
||||
else $=$ || substr(x,j,1)
|
||||
else $=$ || substr(x, j, 1)
|
||||
end /*j*/
|
||||
return $
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue