Evolutionary algorithm: Difference between revisions
Content added Content deleted
(→{{header|Forth}}: added fortran header) |
(→{{header|Fortran}}: add fortran algorithm) |
||
Line 832: | Line 832: | ||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|2003}} |
|||
<lang fortran> |
|||
!*************************************************************************************************** |
|||
module evolve_routines |
|||
!*************************************************************************************************** |
|||
implicit none |
|||
!the target string: |
|||
character(len=*),parameter :: targ = 'METHINKS IT IS LIKE A WEASEL' |
|||
contains |
|||
!*************************************************************************************************** |
|||
!******************************************************************** |
|||
pure elemental function fitness(member) result(n) |
|||
!******************************************************************** |
|||
! The fitness function. The lower the value, the better the match. |
|||
! It is zero if they are identical. |
|||
!******************************************************************** |
|||
implicit none |
|||
integer :: n |
|||
character(len=*),intent(in) :: member |
|||
integer :: i |
|||
n=0 |
|||
do i=1,len(targ) |
|||
n = n + abs( ichar(targ(i:i)) - ichar(member(i:i)) ) |
|||
end do |
|||
!******************************************************************** |
|||
end function fitness |
|||
!******************************************************************** |
|||
!******************************************************************** |
|||
pure elemental subroutine mutate(member,factor) |
|||
!******************************************************************** |
|||
! mutate a member of the population. |
|||
!******************************************************************** |
|||
implicit none |
|||
character(len=*),intent(inout) :: member !population member |
|||
real,intent(in) :: factor !mutation factor |
|||
integer,parameter :: n_chars = 27 !number of characters in set |
|||
character(len=n_chars),parameter :: chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' |
|||
real :: rnd_val |
|||
integer :: i,j,n |
|||
n = len(member) |
|||
do i=1,n |
|||
rnd_val = rand() |
|||
if (rnd_val<=factor) then !mutate this element |
|||
rnd_val = rand() |
|||
j = int(rnd_val*n_chars)+1 !an integer between 1 and n_chars |
|||
member(i:i) = chars(j:j) |
|||
end if |
|||
end do |
|||
end subroutine mutate |
|||
!*************************************************************************************************** |
|||
end module evolve_routines |
|||
!*************************************************************************************************** |
|||
!*************************************************************************************************** |
|||
program evolve |
|||
!*************************************************************************************************** |
|||
! The main program |
|||
!*************************************************************************************************** |
|||
use evolve_routines |
|||
implicit none |
|||
!Tuning parameters: |
|||
integer,parameter :: seed = 12345 !random number generator seed |
|||
integer,parameter :: max_iter = 10000 !maximum number of iterations |
|||
integer,parameter :: population_size = 100 !size of the population |
|||
real,parameter :: factor = 0.05 ![0,1] mutation factor |
|||
integer,parameter :: iprint = 5 !print every iprint iterations |
|||
!local variables: |
|||
integer :: i,iter |
|||
integer,dimension(1) :: i_best |
|||
character(len=len(targ)),dimension(population_size) :: population |
|||
!initialize random number generator: |
|||
call srand(seed) |
|||
!create initial population: |
|||
! [the first element of the population will hold the best member] |
|||
population(1) = 'PACQXJB CQPWEYKSVDCIOUPKUOJY' !initial guess |
|||
iter=0 |
|||
write(*,'(A10,A30,A10)') 'iter','best','fitness' |
|||
write(*,'(I10,A30,I10)') iter,population(1),fitness(population(1)) |
|||
do |
|||
iter = iter + 1 !iteration counter |
|||
!check exit conditions: |
|||
if ( iter>max_iter .or. fitness(population(1))==0 ) exit |
|||
!copy best member and mutate: |
|||
population = population(1) |
|||
do i=2,population_size |
|||
call mutate(population(i),factor) |
|||
end do |
|||
!select the new best population member: |
|||
! [the best has the lowest value] |
|||
i_best = minloc(fitness(population)) |
|||
population(1) = population(i_best(1)) |
|||
!write the iteration: |
|||
if (mod(iter,iprint)==0) write(*,'(I10,A30,I10)') iter,population(1),fitness(population(1)) |
|||
end do |
|||
!write the last iteration: |
|||
if (mod(iter,iprint)/=0) write(*,'(I10,A30,I10)') iter,population(1),fitness(population(1)) |
|||
if (iter>max_iter) then |
|||
write(*,*) 'No solution found.' |
|||
else |
|||
write(*,*) 'Solution found.' |
|||
end if |
|||
!*************************************************************************************************** |
|||
end program evolve |
|||
!*************************************************************************************************** |
|||
</lang> |
|||
The output is: |
|||
<lang> |
|||
iter best fitness |
|||
0 PACQXJB CQPWEYKSVDCIOUPKUOJY 459 |
|||
5 PATNXJBUCQP EYCSVDOIOUPLKOJO 316 |
|||
10 PATNNJHU SP ELCSGPHIO PLDOJO 188 |
|||
15 PATNNJHU NP EL LGPH O PEDOJO 93 |
|||
20 PBTFNJHU NP GX LGJH C PEDOJL 65 |
|||
25 PBTFIOHU HP GX LGJF C ZEDSIL 42 |
|||
30 PFTHIOHU HS HX LGJF C WEDSIL 31 |
|||
35 PFTHIOKU HS HU LGJE C WEDSDL 21 |
|||
40 NFTHIOKS HS HU LGJE C WEDSDL 17 |
|||
45 NETHIOKS HT HR LGJE C WEDSDL 14 |
|||
50 NETHIOKS HT HR LGJE C WEDSDL 14 |
|||
55 METHIOKS HT HR LGJE C WEASDL 10 |
|||
60 METHIOKS HT HR LGJE B WEASDL 9 |
|||
65 METHIOKS HT HR LGJE A WEASEL 7 |
|||
70 METHIOKS IT HR LGKE A WEASEL 5 |
|||
75 METHIOKS IT HR LGKE A WEASEL 5 |
|||
80 METHINKS IT IS LGKE A WEASEL 2 |
|||
85 METHINKS IT IS LHKE A WEASEL 1 |
|||
90 METHINKS IT IS LHKE A WEASEL 1 |
|||
95 METHINKS IT IS LHKE A WEASEL 1 |
|||
100 METHINKS IT IS LIKE A WEASEL 0 |
|||
101 METHINKS IT IS LIKE A WEASEL 0 |
|||
</lang> |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |