June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -10,8 +10,8 @@ Starting with:
|
|||
|
||||
|
||||
;See also:
|
||||
* [[wp:Weasel_program#Weasel_algorithm|Weasel algorithm]].
|
||||
* [[wp:Evolutionary algorithm|Evolutionary algorithm]].
|
||||
* Wikipedia entry: [[wp:Weasel_program#Weasel_algorithm|Weasel algorithm]].
|
||||
* Wikipedia entry: [[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>
|
||||
|
|
|
|||
|
|
@ -1,33 +1,24 @@
|
|||
integer
|
||||
fitness(data t, data b)
|
||||
{
|
||||
integer f, i;
|
||||
integer c, f, i;
|
||||
|
||||
f = 0;
|
||||
|
||||
i = b_length(t);
|
||||
while (i) {
|
||||
i -= 1;
|
||||
f += sign(t[i] ^ b[i]);
|
||||
for (i, c in b) {
|
||||
f += sign(t[i] ^ c);
|
||||
}
|
||||
|
||||
return f;
|
||||
f;
|
||||
}
|
||||
|
||||
void
|
||||
mutate(data c, data b, data u)
|
||||
mutate(data e, data b, data u)
|
||||
{
|
||||
integer i, l;
|
||||
integer c;
|
||||
|
||||
l = b_length(b);
|
||||
i = 0;
|
||||
while (i < l) {
|
||||
if (drand(15)) {
|
||||
b_append(c, b[i]);
|
||||
} else {
|
||||
b_append(c, u[drand(26)]);
|
||||
}
|
||||
i += 1;
|
||||
for (, c in b) {
|
||||
e.append(drand(15) ? c : u[drand(26)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -35,17 +26,15 @@ integer
|
|||
main(void)
|
||||
{
|
||||
data b, t, u;
|
||||
integer f, i, l;
|
||||
integer f, i;
|
||||
|
||||
b_cast(t, "METHINK IT IS LIKE A WEASEL");
|
||||
b_cast(u, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ");
|
||||
t = "METHINK IT IS LIKE A WEASEL";
|
||||
u = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
|
||||
|
||||
l = b_length(t);
|
||||
|
||||
i = l;
|
||||
i = ~t;
|
||||
while (i) {
|
||||
i -= 1;
|
||||
b_append(b, u[drand(26)]);
|
||||
b.append(u[drand(26)]);
|
||||
}
|
||||
|
||||
f = fitness(t, b);
|
||||
|
|
@ -53,7 +42,7 @@ main(void)
|
|||
data n;
|
||||
integer a;
|
||||
|
||||
o_form("/lw4/~\n", f, b_string(b));
|
||||
o_form("/lw4/~\n", f, b);
|
||||
|
||||
n = b;
|
||||
|
||||
|
|
@ -73,7 +62,7 @@ main(void)
|
|||
b = n;
|
||||
}
|
||||
|
||||
o_form("/lw4/~\n", f, b_string(b));
|
||||
o_form("/lw4/~\n", f, b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
USING: arrays formatting io kernel literals math prettyprint
|
||||
random sequences strings ;
|
||||
FROM: math.extras => ... ;
|
||||
IN: rosetta-code.evolutionary-algorithm
|
||||
|
||||
CONSTANT: target "METHINKS IT IS LIKE A WEASEL"
|
||||
CONSTANT: mutation-rate 0.1
|
||||
CONSTANT: num-children 25
|
||||
CONSTANT: valid-chars
|
||||
$[ CHAR: A ... CHAR: Z >array { 32 } append ]
|
||||
|
||||
: rand-char ( -- n )
|
||||
valid-chars random ;
|
||||
|
||||
: new-parent ( -- str )
|
||||
target length [ rand-char ] replicate >string ;
|
||||
|
||||
: fitness ( str -- n )
|
||||
target [ = ] { } 2map-as sift length ;
|
||||
|
||||
: mutate ( str rate -- str/str' )
|
||||
[ random-unit > [ drop rand-char ] when ] curry map ;
|
||||
|
||||
: next-parent ( str -- str/str' )
|
||||
dup [ mutation-rate mutate ] curry num-children 1 - swap
|
||||
replicate [ 1array ] dip append [ fitness ] supremum-by ;
|
||||
|
||||
: print-parent ( str -- )
|
||||
[ fitness pprint bl ] [ print ] bi ;
|
||||
|
||||
: main ( -- )
|
||||
0 new-parent
|
||||
[ dup target = ]
|
||||
[ next-parent dup print-parent [ 1 + ] dip ] until drop
|
||||
"Finished in %d generations." printf ;
|
||||
|
||||
MAIN: main
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
fitness(a::AbstractString, b::AbstractString) = count(l == t for (l, t) in zip(a, b))
|
||||
function mutate(str::AbstractString, rate::Float64)
|
||||
L = collect(Char, " ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
return map(str) do c
|
||||
if rand() < rate rand(L) else c end
|
||||
end
|
||||
end
|
||||
|
||||
function evolve(parent::String, target::String, mutrate::Float64, nchild::Int)
|
||||
println("Initial parent is $parent, its fitness is $(fitness(parent, target))")
|
||||
gens = 0
|
||||
while parent != target
|
||||
children = collect(mutate(parent, mutrate) for i in 1:nchild)
|
||||
bestfit, best = findmax(fitness.(children, target))
|
||||
parent = children[best]
|
||||
gens += 1
|
||||
if gens % 10 == 0
|
||||
println("After $gens generations, the new parent is $parent and its fitness is $(fitness(parent, target))")
|
||||
end
|
||||
end
|
||||
println("After $gens generations, the parent evolved into the target $target")
|
||||
end
|
||||
|
||||
evolve("IU RFSGJABGOLYWF XSMFXNIABKT", "METHINKS IT IS LIKE A WEASEL", 0.08998, 100)
|
||||
|
|
@ -14,7 +14,7 @@ class CreationFactory
|
|||
var f = USize(0)
|
||||
for i in Range(0, s.size()) do
|
||||
try
|
||||
if s(i) == _desired(i) then
|
||||
if s(i)? == _desired(i)? then
|
||||
f = f +1
|
||||
end
|
||||
end
|
||||
|
|
@ -57,7 +57,7 @@ class Mutator
|
|||
|
||||
fun ref _random_letter(): U8 =>
|
||||
let ln = _rand.int(_possibilities.size().u64()).usize()
|
||||
try _possibilities(ln) else ' ' end
|
||||
try _possibilities(ln)? else ' ' end
|
||||
|
||||
class Generation
|
||||
let _size: USize
|
||||
|
|
|
|||
34
Task/Evolutionary-algorithm/R/evolutionary-algorithm-2.r
Normal file
34
Task/Evolutionary-algorithm/R/evolutionary-algorithm-2.r
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Setup
|
||||
set.seed(42)
|
||||
target= unlist(strsplit("METHINKS IT IS LIKE A WEASEL", ""))
|
||||
chars= c(LETTERS, " ")
|
||||
C= 100
|
||||
|
||||
# Fitness function; high value means higher fitness
|
||||
fitness= function(x){
|
||||
sum(x == target)
|
||||
}
|
||||
|
||||
# Mutate function
|
||||
mutate= function(x, rate= 0.01){
|
||||
idx= which(runif(length(target)) <= rate)
|
||||
x[idx]= replicate(n= length(idx), expr= sample(x= chars, size= 1, replace= T))
|
||||
x
|
||||
}
|
||||
|
||||
# Evolve function
|
||||
evolve= function(x){
|
||||
parents= rep(list(x), C+1) # Repliction
|
||||
parents[1:C]= lapply(parents[1:C], function(x) mutate(x)) # Mutation
|
||||
idx= which.max(lapply(parents, function(x) fitness(x))) # Selection
|
||||
parents[[idx]]
|
||||
}
|
||||
|
||||
# Initialize first parent
|
||||
parent= sample(x= chars, size= length(target), replace= T)
|
||||
|
||||
# Main program
|
||||
while (fitness(parent) < fitness(target)) {
|
||||
parent= evolve(parent)
|
||||
cat(paste0(parent, collapse=""), "\n")
|
||||
}
|
||||
60
Task/Evolutionary-algorithm/Ring/evolutionary-algorithm.ring
Normal file
60
Task/Evolutionary-algorithm/Ring/evolutionary-algorithm.ring
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# Project : Evolutionary algorithm
|
||||
# Date : 2018/03/28
|
||||
# Author : Gal Zsolt [~ CalmoSoft ~]
|
||||
# Email : <calmosoft@gmail.com>
|
||||
|
||||
target = "METHINKS IT IS LIKE A WEASEL"
|
||||
parent = "IU RFSGJABGOLYWF XSMFXNIABKT"
|
||||
num = 0
|
||||
mutationrate = 0.5
|
||||
children = len(target)
|
||||
child = list(children)
|
||||
while parent != target
|
||||
bestfitness = 0
|
||||
bestindex = 0
|
||||
for index = 1 to children
|
||||
child[index] = mutate(parent, mutationrate)
|
||||
fitness = fitness(target, child[index])
|
||||
if fitness > bestfitness
|
||||
bestfitness = fitness
|
||||
bestindex = index
|
||||
ok
|
||||
next
|
||||
if bestindex > 0
|
||||
parent = child[bestindex]
|
||||
num = num + 1
|
||||
see "" + num + ": " + parent + nl
|
||||
ok
|
||||
end
|
||||
|
||||
func fitness(text, ref)
|
||||
f = 0
|
||||
for i = 1 to len(text)
|
||||
if substr(text, i, 1) = substr(ref, i, 1)
|
||||
f = f + 1
|
||||
ok
|
||||
next
|
||||
return (f / len(text))
|
||||
|
||||
func mutate(text, rate)
|
||||
rnd = randomf()
|
||||
if rate > rnd
|
||||
c = 63+random(27)
|
||||
if c = 64
|
||||
c = 32
|
||||
ok
|
||||
rnd2 = random(len(text))
|
||||
if rnd2 > 0
|
||||
text[rnd2] = char(c)
|
||||
ok
|
||||
ok
|
||||
return text
|
||||
|
||||
func randomf()
|
||||
decimals(10)
|
||||
str = "0."
|
||||
for i = 1 to 10
|
||||
nr = random(9)
|
||||
str = str + string(nr)
|
||||
next
|
||||
return number(str)
|
||||
101
Task/Evolutionary-algorithm/Rust/evolutionary-algorithm.rust
Normal file
101
Task/Evolutionary-algorithm/Rust/evolutionary-algorithm.rust
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
//! Author : Thibault Barbie
|
||||
//!
|
||||
//! A simple evolutionary algorithm written in Rust.
|
||||
|
||||
extern crate rand;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
fn main() {
|
||||
let target = "METHINKS IT IS LIKE A WEASEL";
|
||||
let copies = 100;
|
||||
let mutation_rate = 20; // 1/20 = 0.05 = 5%
|
||||
|
||||
let mut rng = rand::weak_rng();
|
||||
|
||||
// Generate first sentence, mutating each character
|
||||
let start = mutate(&mut rng, target, 1); // 1/1 = 1 = 100%
|
||||
|
||||
println!("{}", target);
|
||||
println!("{}", start);
|
||||
|
||||
evolve(&mut rng, target, start, copies, mutation_rate);
|
||||
}
|
||||
|
||||
/// Evolution algorithm
|
||||
///
|
||||
/// Evolves `parent` to match `target`. Returns the number of evolutions performed.
|
||||
fn evolve<R: Rng>(
|
||||
rng: &mut R,
|
||||
target: &str,
|
||||
mut parent: String,
|
||||
copies: usize,
|
||||
mutation_rate: u32,
|
||||
) -> usize {
|
||||
let mut counter = 0;
|
||||
let mut parent_fitness = target.len() + 1;
|
||||
|
||||
loop {
|
||||
counter += 1;
|
||||
|
||||
let (best_fitness, best_sentence) = (0..copies)
|
||||
.map(|_| {
|
||||
// Copy and mutate a new sentence.
|
||||
let sentence = mutate(rng, &parent, mutation_rate);
|
||||
// Find the fitness of the new mutation
|
||||
(fitness(target, &sentence), sentence)
|
||||
})
|
||||
.min_by_key(|&(f, _)| f) // find the closest mutation to the target
|
||||
.unwrap(); // fails if `copies == 0`
|
||||
|
||||
// If the best mutation of this generation is better than `parent` then "the fittest
|
||||
// survives" and the next parent becomes the best of this generation.
|
||||
if best_fitness < parent_fitness {
|
||||
parent = best_sentence;
|
||||
parent_fitness = best_fitness;
|
||||
println!(
|
||||
"{} : generation {} with fitness {}",
|
||||
parent, counter, best_fitness
|
||||
);
|
||||
|
||||
if best_fitness == 0 {
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the fitness of a sentence against a target string, returning the number of
|
||||
/// incorrect characters.
|
||||
fn fitness(target: &str, sentence: &str) -> usize {
|
||||
sentence
|
||||
.chars()
|
||||
.zip(target.chars())
|
||||
.filter(|&(c1, c2)| c1 != c2)
|
||||
.count()
|
||||
}
|
||||
|
||||
/// Mutation algorithm.
|
||||
///
|
||||
/// It mutates each character of a string, according to a `mutation_rate`.
|
||||
fn mutate<R: Rng>(rng: &mut R, sentence: &str, mutation_rate: u32) -> String {
|
||||
let maybe_mutate = |c| {
|
||||
if rng.gen_weighted_bool(mutation_rate) {
|
||||
random_char(rng)
|
||||
} else {
|
||||
c
|
||||
}
|
||||
};
|
||||
sentence.chars().map(maybe_mutate).collect()
|
||||
}
|
||||
|
||||
/// Generates a random letter or space.
|
||||
fn random_char<R: Rng>(rng: &mut R) -> char {
|
||||
// Returns a value in the range [A, Z] + an extra slot for the space character. (The `u8`
|
||||
// values could be cast to larger integers for a better chance of the RNG hitting the proper
|
||||
// range).
|
||||
match rng.gen_range(b'A', b'Z' + 2) {
|
||||
c if c == b'Z' + 1 => ' ', // the `char` after 'Z'
|
||||
c => c as char,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
String subclass: Mutant [
|
||||
<shape: #character>
|
||||
|
||||
Target := Mutant from: 'METHINKS IT IS LIKE A WEASEL'.
|
||||
Letters := ' ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
|
||||
|
||||
Mutant class >> run: c rate: p
|
||||
["Run Evolutionary algorighm, using c copies and mutate rate p."
|
||||
| pool parent |
|
||||
parent := self newRandom.
|
||||
pool := Array new: c+1.
|
||||
|
||||
[parent displayNl.
|
||||
parent = Target] whileFalse:
|
||||
[1 to: c do: [:i | pool at: i put: (parent copy mutate: p)].
|
||||
pool at: c+1 put: parent.
|
||||
parent := pool fold: [:winner :each | winner fittest: each]]]
|
||||
|
||||
Mutant class >> newRandom
|
||||
[^(self new: Target size)
|
||||
initializeToRandom;
|
||||
yourself]
|
||||
|
||||
initializeToRandom
|
||||
[self keys do: [:i | self at: i put: self randomLetter]]
|
||||
|
||||
mutate: p
|
||||
[self keys do:
|
||||
[:i |
|
||||
Random next <= p ifTrue: [self at: i put: self randomLetter]]]
|
||||
|
||||
fitness
|
||||
[| score |
|
||||
score := 0.
|
||||
self with: Target do:
|
||||
[:me :you |
|
||||
me = you ifTrue: [score := score + 1]].
|
||||
^score]
|
||||
|
||||
fittest: aMutant
|
||||
[^self fitness > aMutant fitness
|
||||
ifTrue: [self]
|
||||
ifFalse: [aMutant]]
|
||||
|
||||
randomLetter
|
||||
[^Letters at: (Random between: 1 and: Letters size)]
|
||||
]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
st> Mutant run: 2500 rate: 0.1
|
||||
QJUUIQHYXEZORSXGJCAHEWACH KG
|
||||
QJUUIQHYXEZORSXGJCAHEWWCMSKG
|
||||
QEUUIUHYXEZORSOGICAHYWWCSSKG
|
||||
QETUIUHGXEZORS GICE YWWCSSEG
|
||||
METUIUHSXOZORS OICE YWWCSSEG
|
||||
METUIUHSXOZORS OICE Y WCSSEG
|
||||
METUIUHSXOZMIS OIOE Y WCNSEG
|
||||
METKIUKSTOFMIS LIOE Y WCNSEG
|
||||
METKINKSTOFMIS LIKE E WCNSEG
|
||||
METKINKSTOFMIS LIKE F WCNSEL
|
||||
METHINKSTOF IS LIKE F WCNSEL
|
||||
METHINKS OW IS LIKE F WCNSEL
|
||||
METHINKS IW IS LIKE F WCNSEL
|
||||
METHINKS IW IS LIKE C WCASEL
|
||||
METHINKS IW IS LIKE C WCASEL
|
||||
METHINKS IW IS LIKE A WCASEL
|
||||
METHINKS IW IS LIKE A WCASEL
|
||||
METHINKS IW IS LIKE A WEASEL
|
||||
METHINKS IT IS LIKE A WEASEL
|
||||
Mutant
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
Object subclass: Evolution [
|
||||
|target parent mutateRate c alphabet fitness|
|
||||
|
||||
Evolution class >> newWithRate: rate andTarget: aTarget [
|
||||
|r| r := super new.
|
||||
^r initWithRate: rate andTarget: aTarget.
|
||||
]
|
||||
|
||||
initWithRate: rate andTarget: aTarget [
|
||||
target := aTarget.
|
||||
self mutationRate: rate.
|
||||
self maxCount: 100.
|
||||
self defaultAlphabet.
|
||||
self changeParent.
|
||||
self fitness: (self defaultFitness).
|
||||
^self
|
||||
]
|
||||
|
||||
defaultFitness [
|
||||
^ [:p :t |
|
||||
|t1 t2 s|
|
||||
t1 := p asOrderedCollection.
|
||||
t2 := t asOrderedCollection.
|
||||
s := 0.
|
||||
t2 do: [:e| (e == (t1 removeFirst)) ifTrue: [ s:=s+1 ] ].
|
||||
s / (target size)
|
||||
]
|
||||
]
|
||||
|
||||
defaultAlphabet [ alphabet := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' asOrderedCollection. ]
|
||||
|
||||
maxCount: anInteger [ c := anInteger ]
|
||||
|
||||
mutationRate: aFloat [ mutateRate := aFloat ]
|
||||
|
||||
changeParent [
|
||||
parent := self generateStringOfLength: (target size) withAlphabet: alphabet.
|
||||
^ parent.
|
||||
]
|
||||
|
||||
generateStringOfLength: len withAlphabet: ab [
|
||||
|r|
|
||||
r := String new.
|
||||
1 to: len do: [ :i |
|
||||
r := r , ((ab at: (Random between: 1 and: (ab size))) asString)
|
||||
].
|
||||
^r
|
||||
]
|
||||
|
||||
fitness: aBlock [ fitness := aBlock ]
|
||||
|
||||
randomCollection: d [
|
||||
|r| r := OrderedCollection new.
|
||||
1 to: d do: [:i|
|
||||
r add: (Random next)
|
||||
].
|
||||
^r
|
||||
]
|
||||
|
||||
mutate [
|
||||
|r p nmutants s|
|
||||
r := parent copy.
|
||||
p := self randomCollection: (r size).
|
||||
nmutants := (p select: [ :e | (e < mutateRate)]) size.
|
||||
(nmutants > 0)
|
||||
ifTrue: [ |t|
|
||||
s := (self generateStringOfLength: nmutants withAlphabet: alphabet) asOrderedCollection.
|
||||
t := 1.
|
||||
(p collect: [ :e | e < mutateRate ]) do: [ :v |
|
||||
v ifTrue: [ r at: t put: (s removeFirst) ].
|
||||
t := t + 1.
|
||||
]
|
||||
].
|
||||
^r
|
||||
]
|
||||
|
||||
evolve [
|
||||
|children es mi mv|
|
||||
es := self getEvolutionStatus.
|
||||
children := OrderedCollection new.
|
||||
1 to: c do: [ :i |
|
||||
children add: (self mutate)
|
||||
].
|
||||
children add: es.
|
||||
mi := children size.
|
||||
mv := fitness value: es value: target.
|
||||
children doWithIndex: [:e :i|
|
||||
(fitness value: e value: target) > mv
|
||||
ifTrue: [ mi := i. mv := fitness value: e value: target ]
|
||||
].
|
||||
parent := children at: mi.
|
||||
^es "returns the parent, not the evolution"
|
||||
]
|
||||
|
||||
printgen: i [
|
||||
('%1 %2 "%3"' % {i . (fitness value: parent value: target) . parent }) displayNl
|
||||
]
|
||||
|
||||
evoluted [ ^ target = parent ]
|
||||
getEvolutionStatus [ ^ parent ]
|
||||
|
||||
].
|
||||
|
||||
|organism j|
|
||||
|
||||
organism := Evolution newWithRate: 0.01 andTarget: 'METHINKS IT IS LIKE A WEASEL'.
|
||||
|
||||
j := 0.
|
||||
[ organism evoluted ]
|
||||
whileFalse: [
|
||||
j := j + 1.
|
||||
organism evolve.
|
||||
((j rem: 20) = 0) ifTrue: [ organism printgen: j ]
|
||||
].
|
||||
|
||||
organism getEvolutionStatus displayNl.
|
||||
Loading…
Add table
Add a link
Reference in a new issue