#NEWLINE# @ crossover #NEWLINE# def simulated_binary_crossover( random , mom , dad , args ) : #NEWLINE# #INDENT# 'Return the offspring of simulated binary crossover on the candidates.\n    \n    This function performs simulated binary crossover (SBX), following the \n    implementation in NSGA-II \n    `(Deb et al., ICANNGA 1999) <http://vision.ucsd.edu/~sagarwal/icannga.pdf>`_.\n \n    .. Arguments:\n       random -- the random number generator object\n       mom -- the first parent candidate\n       dad -- the second parent candidate\n       args -- a dictionary of keyword arguments\n\n    Optional keyword arguments in args:\n\n    - *crossover_rate* -- the rate at which crossover is performed \n      (default 1.0)\n    - *sbx_distribution_index* -- the non-negative distribution index \n      (default 10)\n    \n    A small value of the `sbx_distribution_index` optional argument allows \n    solutions far away from parents to be created as child solutions, \n    while a large value restricts only near-parent solutions to be created as\n    child solutions.\n    \n    ' #NEWLINE# crossover_rate = args . setdefault ( 'crossover_rate' , 1.0 ) #NEWLINE# if ( random . random ( ) < crossover_rate ) : #NEWLINE# #INDENT# di = args . setdefault ( 'sbx_distribution_index' , 10 ) #NEWLINE# bounder = args [ '_ec' ] . bounder #NEWLINE# bro = copy . copy ( dad ) #NEWLINE# sis = copy . copy ( mom ) #NEWLINE# for ( i , ( m , d , lb , ub ) ) in enumerate ( zip ( mom , dad , bounder . lower_bound , bounder . upper_bound ) ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# if ( m > d ) : #NEWLINE# #INDENT# ( m , d ) = ( d , m ) #NEWLINE# #UNINDENT# beta = ( 1.0 + ( ( 2 * min ( ( m - lb ) , ( ub - d ) ) ) / float ( ( d - m ) ) ) ) #NEWLINE# alpha = ( 2.0 - ( 1.0 / ( beta ** ( di + 1.0 ) ) ) ) #NEWLINE# u = random . random ( ) #NEWLINE# if ( u <= ( 1.0 / alpha ) ) : #NEWLINE# #INDENT# beta_q = ( ( u * alpha ) ** ( 1.0 / float ( ( di + 1.0 ) ) ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# beta_q = ( ( 1.0 / ( 2.0 - ( u * alpha ) ) ) ** ( 1.0 / float ( ( di + 1.0 ) ) ) ) #NEWLINE# #UNINDENT# bro_val = ( 0.5 * ( ( m + d ) - ( beta_q * ( d - m ) ) ) ) #NEWLINE# bro_val = max ( min ( bro_val , ub ) , lb ) #NEWLINE# sis_val = ( 0.5 * ( ( m + d ) + ( beta_q * ( d - m ) ) ) ) #NEWLINE# sis_val = max ( min ( sis_val , ub ) , lb ) #NEWLINE# if ( random . random ( ) > 0.5 ) : #NEWLINE# #INDENT# ( bro_val , sis_val ) = ( sis_val , bro_val ) #NEWLINE# #UNINDENT# bro [ i ] = bro_val #NEWLINE# sis [ i ] = sis_val #NEWLINE# #UNINDENT# except ZeroDivisionError : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# #UNINDENT# return [ bro , sis ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# return [ mom , dad ]