You are on page 1of 8

Tecnicas de pruebas automaticas para

algoritmos evolutivos
Daniel Molina Juan Manuel Dodero
Resumen El uso de pruebas autom
aticas es una herramienta muy u
til para detectar errores en el c
odigo,
pero el comportamiento no-determinista de ciertos
operadores de los algoritmos evolutivos impide que
los resultados sean repetibles, con lo que se suele considerar que no son aplicables. En este trabajo se proponen nuevas estrategias de pruebas especficas para
estos casos. Las estrategias propuestas permiten comprobar las caractersticas de los operadores, y hacer
pruebas de bajo nivel sobre los operadores a pesar del
uso de n
umeros seudoaleatorios. Para demostar el uso
estas estrategias, se aplican a un algoritmo gen
etico
estacionario, comprobando c
omo se pueden realizar
pruebas autom
aticas sobre los algoritmos evolutivos.
Palabras clave algoritmos evolutivos, tests, pruebas autom
aticas, no determinismo, behavior driven
development

n
I. Introduccio
Los algoritmos evolutivos [1], AEs, son algoritmos
no deterministas que han demostrado obtener muy
buenos resultados en todo tipo de problemas complejos [2].
Como todo programa, las implementaciones de los
AEs son susceptibles de tener errores en su programaci
on, errores que pueden reducirse por medio de
tecnicas como el uso de pruebas autom
aticas [3].
Especialmente interesante es el uso de Test-Driven
Development que planea desarrollar el software partiendo de la especificaci
on de los tests [4], [5]. Este
enfoque parece permitir obtener una mejora visible
en el ratio de errores [6].
Lamentablemente, el car
acter no determinista
(por el uso de operadores seudoaleatorios) de los AEs
impiden que los resultados sean repetibles, dificultando las pruebas [7], [8], lo que conduce a una falta
de pruebas en partes del algoritmo que pueden ser
crticas.
Sin embargo, en los u
ltimos a
nos han surgido nuevos enfoques, tecnicas y herramientas que abren nuevas posibilidades. Uno de estos nuevos enfoques es
la metodologa Behavior Driven Development, BDD,
que predica especificar las pruebas desde el punto de
vista del cliente, describiendo las funcionalidades requeridas en vez de detalles de implementacion [9].
A la hora de probar una clase, hay que valorar las
dependencias con otras, ya que la parte que se desea
probar puede llamar a su vez a clases auxiliares, lo
cual dificulta las pruebas. Para resolver este problema, ha surgido la tecnica de definir objetos mocks
que mantienen el mismo interfaz de las clases auxiliares, y que permiten probar la clase cuando a
un

no se han terminado de implementar las auxiliares,


as como comprobar sus interacciones [10].
En este trabajo planteamos como dichas nuevas
tecnicas pueden ser utilizadas de forma conjunta para realizar un modelo de pruebas automaticas sobre
un algoritmo evolutivo. En concreto, se aplican sobre
un algoritmo genetico con codificacion real [11], aunque el enfoque planteado puede extenderse a otros
AEs.
En nuestro trabajo abordamos la problematica del
no-determinismo por medio de dos vas. Por un lado,
aplicamos el enfoque BDD para poder definir comprobaciones sobre el comportamiento deseado en vez
de sobre la implementacion; y, por otro lado, definimos tests de caja blanca mediante el uso de objetos
mocks para simular la generacion de n
umeros seudoalealeatorios.
II. Entorno BDD
El enfoque BDD plantea la idea de realizar tests
que no dependen de la estructura interna del codigo a
probar, sino de la funcionalidad que debe ofrecer. De
esta manera, se pueden plantear tests que pueden ser
comprendidos por el cliente. En nuestro caso, pueden
ser entendibles por otro investigador que conozca la
descripcion del algoritmo pero no la implementaci
on.
Para hacer esa separacion a
un mas clara las libreras mas modernas que siguen el enfoque BDD
separan los tests en dos partes bien diferenciadas.
Por un lado, una descripcion que permite indicar por
medio de frases en lenguaje natural tanto las condiciones como los resultados esperados; y por otro,
ficheros que asocian las expresiones anteriores con
codigo ejecutable que realiza las tareas a probar y la
comprobacion de la condicion.
Hay m
ultiples herramientas BDD, y para los distintos lenguajes: En Ruby, Cucumber 1 es la mas popular, en Java JBehave 2 , y en Python, hay otros
como Lettuce 3 . En este trabajo hemos usado Lettuce bajo Python. En todas ellas se trabaja de igual
forma, y admiten el mismo formato de definici
on de
tests.
En el directorio tests/features se crean distintos
ficheros tests con extension .feature en el que cada
uno contiene los tests asociados a una caracterstica
del algoritmo.
En cada uno de estos ficheros se define una serie
de escenarios, con el formato indicado en la Figu1 http://cukes.info/

Universidad de C
adiz. E-mail: daniel.molina@uca.es
Universidad de C
adiz. E-mail: juanma.dodero@uca.es

2 http://jbehave.org/
3 http://lettuce.it/

Scenario : <D e s c r i p c i o
n>
Given < s e n t e n c e i n i t >
When <s e n t e n c e c o n d i t i o n >
Then <s e n t e n c e e x p e c t e d >

Fig. 1. Formato de un escenario

ra 1, en donde la secci
on Given describe el estado
del sistema antes de un evento, When describe las
condiciones del evento que se quiere probar, y Then
indica el resultado esperado tras el evento. La Figura
2 muestra, como ejemplo, una definici
on de pruebas
sobre el operador factorial.
F e a t u r e : Compute f a c t o r i a l
I n o r d e r t o p l a y w i t h BDD
As b e g i n n e r s
We l l implement f a c t o r i a l

funciones, y por medio del decorador step se asocian


a la frase correspondiente. En dos funciones se utiliza
en step una expresion regular, que permite al sistema llamar a la funcion utilizando el valor numerico
indicado en la frase. Una funcion recupera el valor
numerico y lo guarda en la variable world.number
(world es un almacen de datos para compartir variables entre funciones); otra realiza la operaci
on a
probar; y la u
ltima comprueba, mediante una sentencia assert, el resultado obtenido con el esperado.
from l e t t u c e i m p o r t
@step ( I have t h e number ( \ d + ) )
d e f h a v e t h e n u m b e r ( s t e p , number ) :
w o r l d . number = i n t ( number )
@step ( I compute i t s f a c t o r i a l )
def c om pu te it s fa to ri al ( step ) :
w o r l d . number = f a c t o r i a l ( w o r l d . number )

Scenario : F a c t o r i a l o f 0
Given I have t h e number 0
When I compute i t s f a c t o r i a l
Then I s e e t h e number 1

@step ( I s e e t h e number ( \ d + ) )
d e f check number ( s t e p , e x p e c t e d ) :
expected = int ( expected )
a s s e r t w o r l d . number == e x p e c t e d

Scenario : F a c t o r i a l o f 1
Given I have t h e number 1
When I compute i t s f a c t o r i a l
Then I s e e t h e number 1
Scenario : F a c t o r i a l o f 2
Given I have t h e number 2
When I compute i t s f a c t o r i a l
Then I s e e t h e number 2
Scenario : F a c t o r i a l o f 5
Given I have t h e number 5
When I compute i t s f a c t o r i a l
Then I s e e t h e number 120

Fig. 2. Definici
on de los tests sobre el operador factorial

Tambien se puede indicar de forma m


as concisa,
tal y como se ve en la Figura 3.

Fig. 4. Fichero steps.py

Para hacer la prueba se usa el programa BDD asociado (lettuce en este caso). En la Figura 5 se observa la salida cuando no hay error, y en la Figura 6 la
salida cuando el test detecta un error. Se puede observar que indica la comprobacion concreta que no
se cumple.
$ l e t t u c e v 2 .
F a c t o r i a l o f s e v e r a l numbers
1 f e a t u r e (1 passed )
4 s c e n a r i o s (4 passed )
12 s t e p s ( 1 2 p a s s e d )

...

Fig. 5. Salida por pantalla si no hay error


F e a t u r e : Compute f a c t o r i a l
I n o r d e r t o p l a y w i t h BDD
As b e g i n n e r s
We l l implement f a c t o r i a l
Scenario : F a c t o r i a l o f s e v e r a l numbers
Given I have t h e number <number>
When I compute i t s f a c t o r i a l
Then I s e e t h e number <e x p e c t e d r e s u l t >
Examples :
| number
| 0
| 1
| 2
| 5

|
|
|
|
|

expected result
1
1
2
120

|
|
|
|
|

Fig. 3. Definici
on concisa de tests sobre factorial

Una vez definidos los tests, es necesario un fichero


que asocia cada expresi
on en lenguaje natural de las
secciones Given, When y Then con el c
odigo asociado de test. Dicha asociaci
on se realiza por medio del
fichero steps situado en el mismo directorio.
Por ejemplo, la Figura 4 muestra el contenido del
fichero tests/features/steps.py, que contiene el codigo de las pruebas asociado a los casos de tests de las
Figuras 2
o 3. Se puede observar que se definen tres

$ l e t t u c e v 3 .
F e a t u r e : Compute f a c t o r i a l
# tests / features / factorial . feature :1
...
Tr ac eb ack ( most r e c e n t c a l l l a s t ) :
F i l e . . . / l e t t u c e / c o r e . py , l i n e 1 1 3 , i n \
call
r e t = s e l f . f u n c t i o n ( s e l f . s t e p , a r g s , kw )
F i l e . . . / t e s t s / f e a t u r e s / s t e p s . py , l i n e 15 \
i n check number
a s s e r t w o r l d . number == e x p e c t e d
AssertionError
1 f e a t u r e (0 passed )
4 s c e n a r i o s (3 passed )
12 s t e p s ( 1 f a i l e d , 11 p a s s e d )

Fig. 6. Salida por pantalla en caso de error

III. Algoritmo de referencia


Vamos a describir el algoritmo sobre el que se van
a definir las comprobaciones 4 .
4 Tanto

los

tests

el c
odigo del algoritmo como
est
a libremente disponible en

el
la

de
url

F e a t u r e : SSGA I n i t
I n o r d e r t o t e s t SSGA we t e s t t h a t t h e i n i t
p o p u l a t i o n h as t h e r i g h t p o p s i z e ,
d i m e n s i o n , and t h a t i n i t i a l f i t n e s s between
the i n d i v i d u a l s are d i f f e r e n t .
Scenario : I n i t P o p u l a t i o n
Given I have an SSGA a l g o r i t h m \
f o r d i m e n s i o n <d i m e n s i o n >
When I i n i t t h e p o p u l a t i o n w i t h \
<p o p s i z e > i n d i v i d u a l s
Then t h e p o p u l a t i o n s i z e i s <p o p s i z e >
Then d i m e n s i o n f o r e a c h i n d i v i d u a l \
i s <d i m e n s i o n >
Then f i t n e s s i s i n i t i a l i z e d

Fig. 7. Fichero init.feature

El algoritmo elegido es un algoritmo genetico estacionario, SSGA, que hace uso del operador de cruce BLX [12]. Como mecanismo de seleccion de
padres, se aplica el criterio Negative Assortative Mating, NAM. El primer padre es elegido de forma aleatoria de la poblaci
on, y para calcular el segundo padre se seleccionan aleatoriamente Nnum soluciones
y se elige la soluci
on m
as alejada del primer padre.
Como mecanismo de reemplazo se elige el Replacement Worst, en el que el nuevo individuo reemplaza
al peor individuo de la poblaci
on, si lo mejora. Se
ha demostrado que esta combinaci
on de seleccion y
reemplazo permite un adecuado equilibrio entre exploraci
on y explotaci
on [13].
Se puede observar que es un algoritmo que aunque simple posee caractersticas tpicas de un algoritmo evolutivo tpico: Es un algoritmo poblacional,
elitista, y con distintas operaciones con componente
aleatorio: cruce, y selecci
on.

el codigo del test sera una repeticion del original,


por lo que si hubiese un error en su implementaci
on,
dicho error se trasladara al test, no detectandose.
Por tanto, no es un modelo recomendable.
El enfoque que proponemos es el siguiente: aprovechar que el resultado del operador define una serie
de caractersticas que se deben cumplir si est
a implementado de forma correcta. Por tanto, nos centramos en comprobar el comportamiento esperado
en vez del codigo. Evidentemente, no es una prueba completa, pero s nos puede ser de utilidad para
detectar errores.
F e a t u r e : SSGA NNAM
I n o r d e r t o t e s t t h e NAM s e l e c t i o n we c h e c k
t h a t t h e two p a r e n t s a r r e n o t t h e same one ,
and than c r i t e r i o n between t h e t h e f i r s t
p a r e n t and t h e s e c o n d p a r e n t i s r g i h t .
Scenario : NAM s e l e c t s d i f f e r e n t p a r e n t s
Given I have an SSGA a l g o r i t h m f o r \
d i m e n s i o n 10
Given I i n i t t h e p o p u l a t i o n w i t h \
<p o p s i z e > i n d i v i d u a l s
When I s e l e c t p a r e n t s w i t h tournament \
s i z e <t o u r n a m e n t s i z e >
Then t h e p a r e n t s a r e d i f f e r e n t \
a f t e r <numruns> t e s t s
Examples :
| p o p s i z e | t o u r n a m e n t s i z e | numruns |
|
50
|
3
| 300
|
...
Scenario : NAM S e l e c t t h e f a r away p a r e n t
Given I have an SSGA a l g o r i t h m f o r \
d i m e n s i o n 10
Given I i n i t t h e p o p u l a t i o n w i t h \
50 i n d i v i d u a l s
When I s e l e c t p a r e n t s w i t h tournament \
s i z e 49
Then t h e d i s t a n c e between p a r e n t s i s \
the l o n g e s t

IV. Pruebas de comportamiento


El uso de pruebas BDD permite establecer pruebas de los distintos elementos del algoritmo como la
inicializaci
on, selecci
on, y cruce, en un formato legibles por alguien experto en el algoritmo. En este
apartado se mostrar
an las definiciones de los tests,
el fichero steps.py asociado se incluye en el apendice,
en las Figuras 13, 14, y 15.
A. Inicializaci
on
Para comprobar la inicializaci
on hemos definido
unos tests que comprueben el estado de la poblacion
inicial. La Figura 7 muestra la especificacion de los
tests. Este test es relativamente sencillo, pero permite comprobar la coherencia de la poblaci
on inicial.
B. Selecci
on
Para probar la selecci
on NAM, un primer intento
sera crear un test a bajo nivel que probase que cada
elecci
on de padre siguiese el criterio indicado. Este
enfoque tiene dos graves inconvenientes. Por un lado,
el comportamiento aleatorio del operador impide que
los resultados sean repetibles. Adem
as, en este caso
https://github.com/dmolina/ssgatests

Fig. 8. Fichero selection.feature

En este caso, nos podemos basar en el requisito


que ambos padres sean siempre diferentes y; por otro
lado, si el grupo de torneo incluyese al resto de la poblacion, el segundo padre debe ser el individuo m
as
distante al primero. La Figura 8 muestra la especificacion de dichos tests.
C. Cruce
Para probar el algoritmo BLX , aplicamos el
mismo enfoque que en el anterior. En este caso, nos
centramos en el comportamiento con = 0. Los
comportamientos que queremos probar son que el
cruce de un individuo consigo mismo devuelve ese
mismo individuo, y que el cruce de dos padres genera un hijo que esta entre dichos padres. La Figura 9
muestra la especificacion.
D. Ejecutando el Algoritmo
Para que el algoritmo sea correcto, existen dos
comportamientos que debe de cumplir: que el algoritmo sea elitista; y que el n
umero de evaluaciones
que realmente realice sea el que se le indica. La Fi-

F e a t u r e : SSGA C r o s s o v e r
Check f o r BLX0 t h a t c r o s s i n g a s o l u t i o n
w i t h i t s e l f g i v e s t h e same s o l u t i o n ,
and t h a t o f f s p r i n g a r e a l w a y s between
their parents
Scenario : C r o s s o v e r w i t h i t s e l f
Given I have an SSGA a l g o r i t h m
When I i n i t t h e p o p u l a t i o n w i t h \
50 i n d i v i d u a l s
When I s e t t h e same p a r e n t a s mother
When I c r o s s w i t h a l p h a 0
Then t h e c h i l d r e n i s t h e same
Scenario : O f f s p r i n g i s between t h e i r p a r e n t s
Given I have an SSGA a l g o r i t h m
When I i n i t t h e p o p u l a t i o n w i t h \
50 i n d i v i d u a l s
When I s e t randomly two p a r e n t s
When I c r o s s w i t h a l p h a 0
Then t h e c h i l d r e n i s between them

Fig. 9. Fichero crossover.feature


F e a t u r e : SSGA run
Check two f e a t u r e s o f t h e a l g o r i t h m . F i r s t ,
t h e r e a l e v a l u a t i o n s number i s r i g h t , and
the e l i t i s m of the algorithm .
Scenario : SSGA a c t u a l l y u s e t h e \
maximum e v a l u a t i o n number
Given I have a SSGA a l g o r i t h m
When I i n i t t h e p o p u l a t i o n \
w i t h <p o p u l a t i o n s i z e >
When I run t h e a l g o r i t h m d u r i n g \
<n u m i t e r a > i t e r a t i o n s
Then t h e y were e v a l u a t e d \
<num eval> s o l u t i o n s
Examples :
| population size
|
50
...

| n u m i t e r a | num eval |
|
1000
|
1000
|

Scenario : SSGA i s e l i t i s t
Given I have a SSGA a l g o r i t h m
When I i n i t t h e p o p u l a t i o n w i t h \
50 i n d i v i d u a l s
When I s t u d y t h e e v o l u t i o n o f t h e \
<i n d i v i d u a l > i n d i v i d u a l
When I run t h e a l g o r i t h m d u r i n g \
<n u m i t e r a > i t e r a t i o n s
Then i t s f i t n e s s i s a l w a y s b e t t e r
Examples :
| individual
|
best
|
worst
|
mean

| num itera
|
1000
|
1000
|
1000

|
|
|
|

Fig. 10. Fichero run.feature

gura 10 muestra la especificaci


on de dichas comprobaciones.
meros seudoaleatorios
V. Pruebas con nu
Hasta ahora hemos abordado el problema del nodeterminismo por medio de pruebas sobre caractersticas que debe cumplir un algoritmo, en vez de
sobre los resultados concretos, es decir, tests de caja negra. Sin embargo, sera deseable poder complementarlo con tests de caja blanca.
Para conseguir hacer tests de caja blanca mas cercanos al c
odigo sera necesario que el resultado fuese
reproducible, pero el uso de n
umero seudoaleatorios
lo impide. En la pr
actica, sera posible hacerlo mo-

dificando el codigo para que en vez generar n


umeros
aleatorios utilizase un conjunto de n
umeros generados inicialmente. Sin embargo, este enfoque requerira una modificacion del codigo para las pruebas,
lo que no es deseable.
Una alternativa es utilizar herramientas que permitan sustituir de forma dinamica las clases que realizan una determinada tarea por objetos mocks que
simulan dicho comportamiento. Un ejemplo, es la librera mocks5 de Python.
Con una herramienta como esta, se puede modificar el comportamiento de un metodo o funcion para
que, durante el test, cuando se vaya a llamar a una
determinada funcion, su ejecucion se sustituya por
otra (usando mocks) con el mismo interfaz y que simula su comportamiento.
En nuestro caso, podemos reemplazar durante el
test el codigo que realiza la generacion de n
umeros
aleatorios por codigo que devuelve n
umeros previamente fijados en el test. De esta manera, se puede
simular el comportamiento del codigo ante distintas
secuencias de n
umero seudoaleatorios sin tener que
cambiar el codigo original.
Scenario : Checking c r o s s o v e r w i t h \
seudorandoms and a l p h a=0
Given I have a SSGA a l g o r i t h m
When I i n i t t h e p o p u l a t i o n \
w i t h 50 i n d i v i d u a l s
When I s e t randomly two p a r e n t s
When I u s e pseudorandoms=<seudo random>
When I c r o s s w i t h a l p h a 0
Then t h e c h i l d r e n i s e q u a l s t o \
the <c r i t e r i o n > o f i t s parents
Examples :
| seudo random |
|
0
|
|
1
|
|
0.5
|

criterion
minimum
maximum
mean

|
|
|
|

Fig. 11. Escenario de cruce usando seudoaleatorios

from mock i m p o r t patch , Mock


@step ( When I u s e pseudorandoms = ( [ \ d . ] + ) )
def set pseudorandoms ( step , expected random ) :
# Change t h e random g e n e r a t i o n i n t o t h e t e s t
w o r l d . newRandom = p a t c h ( earandom . r a n d r e a l ,
s p e c=True )
# S e t t h e r e t u r n s when i t i s c a l l e d
w o r l d . random = w o r l d . newRandom . s t a r t ( )
expected random = f l o a t ( expected random )
r e t u r n s = e x p e c t e d r a n d o m np . o n e s ( dim )
w o r l d . random . r e t u r n v a l u e = r e t u r n s

Fig. 12. C
odigo que modifica los n
umeros seudoaleatorios

Como ejemplo, podemos complementar los tests


anteriores sobre el operador de cruce con el test indicado en la Figura 11, en donde la asignaci
on de
generacion de n
umeros aleatorios se realiza de forma
sencilla al interpretar la sentencia I use pseudorandoms. . . con el codigo asociado indicado en la Figura 12 del fichero steps.py. En dicho codigo se indica,
5 http://www.voidspace.org.uk/python/mock/

por medio de la funci


on patch que cuando durante el
test se desee llamar a la funci
on erandom.randreal,
se llame, en cambio, al objeto mock newRandom. Y
luego se configura la salida que devuelve cuando se
realicen dichas llamadas. Puede consultarse una explicaci
on mucho m
as detallada en la documentacion
oficial de la librera mocks.
El uso de pruebas autom
aticas es una herramienta
muy u
til para detectar errores en el c
odigo, pero el
comportamiento no-determinista de los AEs se suele
ver como un impedimento para poder realizarlas.
En este trabajo se plantean dos estrategias para
aplicar pruebas autom
aticas sobre AEs, a pesar del
uso de n
umeros seudoaleatorios, que hace que los
resultados no sean repetibles.
En la primera, en vez de aplicar tests sobre resultados concretos de un operador, se propone realizar
comprobaciones sobre el comportamiento que dichos
operadores deben ofrecer. Se muestra el uso de esta
estrategia aplic
andola a los operadores de inicializaci
on, cruce y ejecuci
on de un SSGA.
La otra estrategia propuesta es utilizar libreras
que permiten reemplazar durante los tests el codigo
de generaci
on de n
umeros seudoaleatorios por codigo que devuelve secuencias de n
umeros definidos de
antemano, para hacer comprobaciones de mas bajo
nivel, o de caja blanca. Se ha mostrado el uso de esta
estrategia para tests adicionales sobre el operador de
cruce BLX .
En conclusi
on, en este trabajo se proponen estrategias que permiten aplicar pruebas automaticas a
las implementaciones de AEs, con lo que se puede
detectar m
as f
acilmente errores de implementacion,
al mismo tiempo que son entendibles por cualquier
investigador en AEs sin necesidad de conocer los detalles concretos de su implementaci
on. Por tanto, se
prueba que los AEs pueden (y deberan) incorporar
pruebas autom
aticas para mejorar la confianza en la
implementaci
on de los algoritmos.
VI. Agradecimientos
Este trabajo fue financiado por los proyectos de
investigaci
on TIN2008-05854 y P08-TIC-4173.
ndice
Ape
Las Figuras 13, 14 y 15 muestran el c
odigo de test
asociado a las definici
on de las pruebas del artculo. El c
odigo est
a libremente disponible en la url
https://github.com/dmolina/ssgatests.
Referencias
[1]
[2]
[3]
[4]

T B
ack, D B Fogel, and Z Michalewicz, Eds., Handbook of Evolutionary Computation, IOP Publishing Ltd.,
Bristol, UK, 1997.
Patrick Siarry and Zbigniew Michalewicz, Advances in
metaheuristics for hard optimization, Springer-Verlag
New York Inc, springer edition, 2007.
G J Myers, C Sandler, T Badgett, and T M Thomas,
The art of software testing, 2004.
K Beck, Test-driven development: by example, AddisonWesley Professional, 2003.

[5]

[6]

[7]

[8]

[9]

[10]

[11]

[12]
[13]

Forrest Shull, Grigori Melnik, Burak Turhan, Lucas Layman, Madeline Diep, and Hakan Erdogmus, What Do
We Know about Test-Driven Development?, IEEE Software, vol. 27, no. 6, pp. 1619, 2010.
Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat, and Laurie Williams, Realizing quality
improvement through test driven development: results
and experiences of four industrial teams, Empirical
Software Engineering, vol. 13, no. 3, pp. 289302, Feb.
2008.
R.M. Hierons, Testing from a nondeterministic finite state machine using adaptive state counting, IEEE
Transactions on Computers, vol. 53, no. 10, pp. 1330
1342, Oct. 2004.
Gordon Fraser and Franz Wotawa, Test-Case Generation and Coverage Analysis for Nondeterministic Systems Using Model-Checkers, International Conference
on Software Engineering Advances (ICSEA 2007), pp.
4545, 2007.
D Chelimsky, D Astels, Z Dennis, A Hellesoy, B Helmkamp, and D North, The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends,
Pragmatic Bookshelf, 2010.
Madhuri R. Marri, Nikolai Tillmann, Jonathan de Halleux, and Wolfram Schulte, An empirical study of testing file-system-dependent software with mock objects,
2009 ICSE Workshop on Automation of Software Test,
pp. 149153, May 2009.
F Herrera, M Lozano, and A.M. Sanchez, A Taxonomy
for the Crossover Operator for Real-coded Genetic Algorithms, International Journal of Intelligent Systems,
vol. 18, no. 3, pp. 204217, 2003.
L.J. Eshelman and J.D. Schaffer, Real-coded Genetic
Algorithms in Genetic Algorithms by Preventing Incest,
Foundation of Genetic Algorithms 2, pp. 187202, 1993.
D Whitley, The GENITOR Algorithm and Selection
Pressure: Why Rank-Based Allocation of Reproductive
Trials is Best, Proc. of the Third Int. Conf. on Genetic
Algorithms, pp. 116121, 1989.

Inicializaci
on
@step ( I have a SSGA a l g o r i t h m f o r d i m e n s i o n ( \ d + ) )
d e f h a v e c o n f i g u r a t i o n ( s t e p , dim ) :
dim = i n t ( dim )
w o r l d . s s g a = SSGA( f i t n e s s , domain , dim , s i z e=p o p s i z e )
@step ( I i n i t t h e p o p u l a t i o n w i t h ( \ d+) i n d i v i d u a l s )
def i n i t p o p u l a t i o n ( step , popsize ) :
world . p o p s i z e = i n t ( p o p s i z e )
world . s s g a . i n i t P o p u l a t i o n ( i n t ( p o p s i z e ) )
@step ( p o p u l a t i o n s i z e i s ( \ d + ) )
def p o p s i z e r i g h t ( step , p op si z e e xp ec t ed ) :
popsize expected = int ( popsize expected )
( v a l u e s s i z e , v a l u e s d i m )= w o r l d . s s g a . p o p u l a t i o n ( ) . s h a p e
a s s e r t v a l u e s s i z e == p o p s i z e e x p e c t e d
@step ( f i t n e s s i s i n i t i a l i z e d )
def f i t n e s s r i g h t ( step ) :
f i t s = world . s s g a . p o p u l a t i o n f i t n e s s ( )
a s s e r t f i t s . s i z e == w o r l d . p o p s i z e
@step ( a l l f i t n e s s v a l u e s a r e d i f f e r e n t )
def fitness not same ( step ) :
f i t s = world . s s g a . p o p u l a t i o n f i t n e s s ( )
# Check t h e s i z e o f removing e q u a l s f i t n e s s
a s s e r t np . u n i q u e ( f i t s ) . s i z e == w o r l d . p o p s i z e

Selecci
on
@step ( I s e l e c t p a r e n t s w i t h tournament s i z e ( \ d + ) )
def s e t p a r e n t s ( step , t s i z e ) :
w o r l d . n a m t s i z e=i n t ( t s i z e )
@step ( t h e p a r e n t s a r e d i f f e r e n t a f t e r ( \ d+) t e s t s )
def m o t h e r p a r e n t d i f f e r e n t ( step , t e s t s ) :
tests = int ( tests )
for

i in range ( t e s t s ) :
[ mother , p a r e n t ]= w o r l d . s s g a . g e t P a r e n t s ( w o r l d . n a m t s i z e )
a s s e r t mother != p a r e n t

@step ( t h e d i s t a n c e between p a r e n t s i s t h e l o n g e s t )
def best parent ( step ) :
s s g a = world . s s g a
[ motherId , p a r e n t I d ]= s s g a . g e t P a r e n t s ( w o r l d . n a m t s i z e )
population = ssga . population ()
mother = p o p u l a t i o n [ motherId ]
parent = population [ parentId ]
d i s t a n c e s = [ u t i l s . d i s t a n c e ( p o p u l a t i o n [ i ] , mother ) f o r
m a x d i s t a n c e s = np . a r r a y ( d i s t a n c e s ) . max ( )
d i s t a n c e = u t i l s . d i s t a n c e ( p a r e n t , mother )
a s s e r t d i s t a n c e == m a x d i s t a n c e s

i n range ( world . p o p s i z e ) ]

Fig. 13. Fichero steps.py (Parte 1)

Cruce
@step ( I s e t t h e same p a r e n t a s mother )
def set parents same ( s e l f ) :
p o p u l a t i o n = world . s s g a . p o p u l a t i o n ( )
motherId = random . r a n d i n t ( 0 , w o r l d . s s g a . p o p s i z e )
w o r l d . mother = p o p u l a t i o n [ motherId ]
w o r l d . p a r e n t = w o r l d . mother
@step ( I s e t randomly two p a r e n t s )
def cross set random ( step ) :
p o p u l a t i o n = world . s s g a . p o p u l a t i o n ( )
[ motherId , p a r e n t I d ] = random . r a n d i n t ( 0 , w o r l d . s s g a . p o p s i z e , 2 )
w o r l d . mother = p o p u l a t i o n [ motherId ]
w o r l d . p a r e n t= p o p u l a t i o n [ p a r e n t I d ]
@step ( I c r o s s w i t h a l p h a ( [ \ d . ] + ) )
def a p p l y c r o s s ( s e l f , alpha ) :
alpha = f l o a t ( alpha )
w o r l d . c h i l d r e n = w o r l d . s s g a . c r o s s ( w o r l d . mother , w o r l d . p a r e n t , a l p h a )
@step ( The c h i l d r e n i s t h e same )
def has same children ( s e l f ) :
a s s e r t u t i l s . d i s t a n c e ( w o r l d . c h i l d r e n , w o r l d . p a r e n t )==0
@step ( The c h i l d r e n i s between them )
def is between then ( s e l f ) :
p a r e n t s = np . a r r a y ( [ w o r l d . mother , w o r l d . p a r e n t ] )
m i n p a r e n t = np . amin ( p a r e n t s , a x i s =0)
max parent = np . amax ( p a r e n t s , a x i s =0)
a s s e r t ( w o r l d . c h i l d r e n >= m i n p a r e n t ) . a l l ( ) , B r o k e s i n f e r i o r
a s s e r t ( w o r l d . c h i l d r e n <= max parent ) . a l l ( ) , B r o k e s s u p e r i o r

limit
limit

@step ( t h e p a r e n t s a r e d i f f e r e n t a f t e r ( \ d+) t e s t s )
def m o t h e r p a r e n t d i f f e r e n t ( step , t e s t s ) :
tests = int ( tests )
for

i in range ( t e s t s ) :
[ mother , p a r e n t ]= w o r l d . s s g a . g e t P a r e n t s ( w o r l d . n a m t s i z e )
a s s e r t mother != p a r e n t

@step ( t h e d i s t a n c e between p a r e n t s i s t h e l o n g e s t )
def best ! ! parent ( step ) :
s s g a = world . s s g a
[ motherId , p a r e n t I d ]= s s g a . g e t P a r e n t s ( w o r l d . n a m t s i z e )
population = ssga . population ()
mother = p o p u l a t i o n [ motherId ]
parent = population [ parentId ]
d i s t a n c e s = [ u t i l s . d i s t a n c e ( p o p u l a t i o n [ i ] , mother ) f o r
m a x d i s t a n c e s = np . a r r a y ( d i s t a n c e s ) . max ( )
d i s t a n c e = u t i l s . d i s t a n c e ( p a r e n t , mother )
a s s e r t d i s t a n c e == m a x d i s t a n c e s

i n range ( world . p o p s i z e ) ]

Fig. 14. Fichero steps.py (Parte 2)

Ejecuci
on
\ begin { l s t l i s t i n g }
d e f m e a s u r e F i t n e s s ( a r g s , kwargs ) :
i f w o r l d . f i t E v a l == [ ] :
w o r l d . f i t E v a l . append ( w o r l d . g e t f i t n e s s ( w o r l d . s s g a . p o p u l a t i o n f i t n e s s ( ) ) )
y i e l d aspects . proceed
w o r l d . f i t E v a l . append ( w o r l d . g e t f i t n e s s ( w o r l d . s s g a . p o p u l a t i o n f i t n e s s ( ) ) )
@step ( I s t u d y t h e e v o l u t i o n o f t h e ( \w+) i n d i v i d u a l )
def study population ( s e l f , individual ) :
if

i n d i v i d u a l == b e s t :
w o r l d . g e t f i t n e s s = np . min
e l i f i n d i v i d u a l == worst :
w o r l d . g e t f i t n e s s = np . max
e l i f i n d i v i d u a l == mean :
w o r l d . g e t f i t n e s s = np . mean
else :
a s s e r t F a l s e , E r r o r , i n d i v i d u a l %s

i s n o t known %i n d i v i d u a l

w o r l d . w r a p i d = a s p e c t s . w i t h w r a p ( m e a s u r e F i t n e s s , SSGA . updateWorst )
@step ( I run t h e a l g o r i t h m d u r i n g ( \ d+) i t e r a t i o n s )
d e f r u n i t e r a t i o n s ( s e l f , numevals ) :
numevals = i n t ( numevals )
world . f i t E v a l = [ ]
w o r l d . numevals = 0
w o r l d . s s g a . run ( maxeval=numevals )
@step ( t h e y were e v a l u a t e d ( \ d+) s o l u t i o n s )
def check eval ( s e l f , solutions ) :
a s s e r t w o r l d . numevals == i n t ( s o l u t i o n s )
@step ( i t s f i t n e s s i s a l w a y s b e t t e r )
def c h e c k f i t n e s s ( s e l f ) :
s i z e = l e n ( world . f i t E v a l )
f i t E v a l = world . f i t E v a l
for

e v a l i n xrange ( s i z e 1):
before = f l o a t ( fitEval [ eval ] )
a f t e r = f l o a t ( f i t E v a l [ e v a l +1])
a s s e r t a f t e r <= b e f o r e

a s p e c t s . w i t h o u t w r a p ( m e a s u r e F i t n e s s , w o r l d . s s g a . updateWorst )

Fig. 15. Fichero steps.py (Parte 3)

You might also like