Find the value of x that maximizes the function f(x)=sin(pi x/256) where values of x
are restricted to integers between 0 and 255.
The values between 0 and 255 can be represented as 8-bit binary numbers for the population of individuals.
Use this population for testing - 8 individuals with 8 bits each. (a better version would randomly generate
these 8-bit strings.
1 0 1 1 1 1 0 1
1 1 0 1 1 0 0 0
0 1 1 0 0 0 1 1
1 1 1 0 1 1 0 0
1 0 1 0 1 1 1 0
0 1 0 0 1 0 1 0
0 0 1 0 0 0 1 1
0 0 1 1 0 1 0 1
Here's example Scheme code to do this initialization:
(define teststring '((1 0 1 1 1 1 0 1) (1 1 0 1 1 0 0 0) (0 1 1 0 0 0 1 1) (1 1 1 0 1 1 0 0) (1 0 1 0 1 1 1 0) (0 1 0 0 1 0 1 0) (0 0 1 0 0 0 1 1) (0 0 1 1 0 1 0 1)))Same example in Smalltalk:
! Object methodsFor: 'algorithms' ! testString "(FileStream oldFileNamed: 'gaprogram.st') fileIn." ^#((1 0 1 1 1 1 0 1) #(1 1 0 1 1 0 0 0) #(0 1 1 0 0 0 1 1) #(1 1 1 0 1 1 0 0) #(1 0 1 0 1 1 1 0) #(0 1 0 0 1 0 1 0) #(0 0 1 0 0 0 1 1) #(0 0 1 1 0 1 0 1)).Same example in Prolog
testString([[1,0,1,1,1,1,0,1], [1,1,0,1,1,0,0,0], [0,1,1,0,0,0,1,1], [1,1,1,0,1,1,0,0], [1,0,1,0,1,1,1,0], [0,1,0,0,1,0,1,0], [0,0,1,0,0,0,1,1], [0,0,1,1,0,1,0,1]]). /* ?-consult(gaprogram). ?-testString(X). X = [[1,0,1,1,1,1,0,1], [1,1,0,1,1,0,0,0],[0,1,1,0,0,0,1,1], [1,1,1,0,1,1,0,0], [1,0,1,0,1,1,1,0], [0,1,0,0,1,0,1,0], [0,0,1,0,0,0,1,1], [0,0,1,1,0,1,0,1]]Same example in ML (SML):
val testString = [[1,0,1,1,1,1,0,1], [1,1,0,1,1,0,0,0], [0,1,1,0,0,0,1,1], [1,1,1,0,1,1,0,0], [1,0,1,0,1,1,1,0], [0,1,0,0,1,0,1,0], [0,0,1,0,0,0,1,1], [0,0,1,1,0,1,0,1]]; (* - use "gaprogram.sml"; - testString; val it = [[1,0,1,1,1,1,0,1],[1,1,0,1,1,0,0,0],[0,1,1,0,0,0,1,1],[1,1,1,0,1,1,0,0], [1,0,1,0,1,1,1,0],[0,1,0,0,1,0,1,0],[0,0,1,0,0,0,1,1],[0,0,1,1,0,1,0,1]] : int list list *)
Individuals x 1 0 1 1 1 1 0 1 189 1 1 0 1 1 0 0 0 216 0 1 1 0 0 0 1 1 99 1 1 1 0 1 1 0 0 236 1 0 1 0 1 1 1 0 174 0 1 0 0 1 0 1 0 74 0 0 1 0 0 0 1 1 35 0 0 1 1 0 1 0 1 53Example Scheme code to do this (using an iterative loop to evaluate):
(define (evalstring str) (do ((str2 (reverse str) (cdr str2)) (ans 0) (mult 1 (* 2 mult)) ;; Use a 2 because these are binary, base 2, numbers (count (length str)) (i 0 (+ i 1))) ((= i count) ans) (set! ans (+ ans (* mult (car str2))))))Same example in Smalltalk (using an iterative loop to evaluate and build answer list):
! evalString "Object new testString first evalString. Evaluates the first bit string. #(1 0 1 1 1 1 0 1) evalString. 189 Evaluates to 189." | ans mult i str2 count | ans := 0. mult := 1. i := 0. str2 := self reversed. count := str2 size. [i < count] whileTrue: [ OR USE count timesRepeat: ans := ans + (mult * str2 first). str2 := str2 allButFirst. mult := mult*2. i := i + 1. ]. ^ans. ! evaluateStrings " Object new testString evaluateStrings #(189 216 99 236 174 74 35 53)" |ans count tempStr| ans := Array new: 8. count := ans size. tempStr := self. 1 to: count do: [:index| ans at: index put: ((tempStr first) evalString). tempStr := tempStr allButFirst. ]. ^ans. !Same example in Prolog (using recursion to evaluate and build answer list):
evalList(EvalList) :- testString(X), reverse(X,Y), /* write('Y='),write(Y),nl, */ getEvalList(Y,[],EvalList). getEvalList([], EvalList, EvalList). getEvalList([X|Y],EvalList,Ans) :- evalString(X, Eval), getEvalList(Y,[Eval|EvalList],Ans). evalString(X, Eval) :- reverse(X,Y), evalStringAux(Y, 0, 1,Eval). evalStringAux([],Eval, _,Eval). evalStringAux([X|Y], Eval, Mult,Evaluate) :- Eval1 is Eval + X*Mult, Mult1 is Mult*2, evalStringAux(Y,Eval1,Mult1,Evaluate). ?- consult(gaprogram). ?- evalList(X). X = [189, 216, 99, 236, 174, 74, 35, 53]Recursive version in Scheme (as opposed to the iterative version above):
(define (evalstringRec str) (evalstringRecAux (reverse str) 0 1)) (define (evalstringRecAux str sum mult) (if (empty? str) sum (evalstringRecAux (cdr str) (+ sum (* mult (car str))) (* mult 2)))) (define (evalList) (getevalList teststring '())) (define (getevalList lis answerlist) (if (empty? lis) answerlist (cons (evalstringRec (car lis)) (getevalList (cdr lis) answerlist)))) SAMPLE RUN: > (evalList) (189 216 99 236 174 74 35 53)Recursive version in Smalltalk (as opposed to the iterative Smalltalk above):
evalStringRec "#(1 0 1 1 1 1 0 1) evalStringRec. 189 Evaluates to 189." ^(self reversed) evalStringRecAux: 0 multiplier: 1. ! evalStringRecAux: sum multiplier: mult | localsum | self size = 0 ifTrue: [^sum]. localsum := mult*(self first). ^(self allButFirst) evalStringRecAux: (sum + localsum) multiplier: (mult * 2). ! evalList "Recursive version of evalList Object new evalList. (189 216 99 236 174 74 35 53 ) " | tester | tester := Object new testString. ^tester getEvalList: (Array new: 8) counter: 1. ! getEvalList: ans counter: index self size = 0 ifTrue:[^ans]. ans at: index put: (self first evalStringRec). ^(self allButFirst) getEvalList: ans counter: (index+1). !Example using SML:
fun reverse(L) = if L = nil then nil else reverse(tl(L)) @ [hd(L)]; fun evalStringAux(str:int list, sum:int, mult:int):int = if str = nil then sum else evalStringAux(tl(str), sum+mult*hd(str), mult*2); fun evalString(str:int list) : int = evalStringAux(reverse(str), 0, 1); fun getEvalList(strings: int list list, ans: int list):int list = if strings = nil then ans else evalString(hd(strings)) :: getEvalList(tl(strings),ans); fun evalList(strings: int list list): int list = getEvalList(strings,[]); (* - use "gaprogram.sml"; - evalList(testString); val it = [189,216,99,236,174,74,35,53] : int list *)
Individuals x f(x) 1 0 1 1 1 1 0 1 189 0.733 1 1 0 1 1 0 0 0 216 0.471 0 1 1 0 0 0 1 1 99 0.937 1 1 1 0 1 1 0 0 236 0.243 1 0 1 0 1 1 1 0 174 0.845 0 1 0 0 1 0 1 0 74 0.788 0 0 1 0 0 0 1 1 35 0.416 0 0 1 1 0 1 0 1 53 0.650Example Scheme code to evaluate f(x) for a list of these individuals
(define (fstrings strlis) (do ((ans '()) (templis (reverse strlis) (cdr templis))) ((= (length templis) 0) ans) (set! ans (cons (sin (* pi (/ (car templis) 256))) ans))))Same example in Smalltalk (using an iterative loop to build lists):
! fstrings "Object new testString evaluateStrings fstrings #(0.732654271672413 0.471396736825998 0.937339011912575 0.242980179903264 0.844853565249707 0.788346427626606 0.416429560097637 0.6055110414043255)" | ans count tempString | ans := Array new: 8. tempString := self. count := tempString size. 1 to: count do: [:index | ans at: index put: (((tempString first) * Float pi / 256.0) sin). tempString := tempString allButFirst. ]. ^ans.Same example in Prolog (using recursion to build lists):
f(X,Y) :- Y is sin(pi*X/256). flist(FList) :- evalList(EvalList), reverse(EvalList,RevList), evalFList(RevList,[],FList). evalFList([],FList,FList). evalFList([X|Rest], EvalList, FList) :- f(X,Y), evalFList(Rest,[Y|EvalList],FList). ?- consult(gaprogram). ?- flist(X). X = [0.732654, 0.471397, 0.937339, 0.24298, 0.844854, 0.788346, 0.41643, 0.605511] ?-halt.Recursive version in Scheme (as opposed to the Scheme iterative version above):
(define (fstringsRec) (evalFList (evalList) '())) (define (evalFList lis answerlist) (if (empty? lis) answerlist (cons (f (car lis)) (evalFList (cdr lis) '())))) (define (f x) (sin (* pi (/ x 256)))) SAMPLE RUN: > (fstringsRec) (0.7326542716724128 0.47139673682599786 0.937339011912575 0.24298017990326407 0.8448535652497072 0.7883464276266062 0.41642956009763715 0.6055110414043256)Recursive version in Smalltalk (as opposed to the iterative Smalltalk version above):
flistRec " Object new flistRec. (0.732654271672413 0.471396736825998 0.937339011912575 0.242980179903264 0.844853565249707 0.788346427626606 0.416429560097637 0.6055110414043255 ) " | tester | tester := self evalList. ^tester evalFList: (Array new:8) counter: 1 ! evalFList: ans counter: index self size = 0 ifTrue:[^ans]. ans at:index put: (self first func). ^(self allButFirst) evalFList: ans counter: (index+1). ! func ^(self * Float pi/256) sin. !Same example using SML:
fun f(x:real):real = Math.sin(Math.pi * x / 256.0); fun evalFList(lis: int list, ans:real list) : real list = if lis = nil then ans else f(real(hd(lis))) :: evalFList(tl(lis),ans); fun flist(strings: int list list): real list = evalFList(evalList(strings), []); (* - use "gaprogram.sml"; - flist(testString); val it = [0.732654271672,0.471396736826,0.937339011913,0.242980179903,0.84485356525, 0.788346427627,0.416429560098,0.605511041404] : real list *)
Individuals x f(x) fnorm 1 0 1 1 1 1 0 1 189 0.733 0.144 1 1 0 1 1 0 0 0 216 0.471 0.093 0 1 1 0 0 0 1 1 99 0.937 0.184 1 1 1 0 1 1 0 0 236 0.243 0.048 1 0 1 0 1 1 1 0 174 0.845 0.166 0 1 0 0 1 0 1 0 74 0.788 0.155 0 0 1 0 0 0 1 1 35 0.416 0.082 0 0 1 1 0 1 0 1 53 0.650 0.128
Individuals x f(x) fnorm Cumulative fnorm 1 0 1 1 1 1 0 1 189 0.733 0.144 0.144 1 1 0 1 1 0 0 0 216 0.471 0.093 0.237 0 1 1 0 0 0 1 1 99 0.937 0.184 0.421 1 1 1 0 1 1 0 0 236 0.243 0.048 0.469 1 0 1 0 1 1 1 0 174 0.845 0.166 0.635 0 1 0 0 1 0 1 0 74 0.788 0.155 0.790 0 0 1 0 0 0 1 1 35 0.416 0.082 0.872 0 0 1 1 0 1 0 1 53 0.650 0.128 1.000
0.293 0.971 0.160 0.469 0.664 0.568 0.371 0.109Correlate each random number with the Cumulative fnorm list above to choose corresponding individuals to live on.
Using the random numbers above, the following individuals are picked to live on: individuals 3, 8, 2, 5, 6, 5, 3