# Fitness is sum of z-scores # ZScoresGA.tz (c) 2010 Jacob Schrum. # See Simulation.tz for more copyright information # WARNING: The hard-coded weighting only makes sense for the Battle Domain with three objectives @include "Abstract.tz". @include "Selection.tz". @define COEFF_ASSIST 2.0. @define COEFF_RECEIVED 1.0. @define COEFF_ALIVE 0.5. #@define COEFF_ASSIST 1.0. #@define COEFF_RECEIVED 1.0. #@define COEFF_ALIVE 1.0. @define Z_SCORE_OUTPUT 0. @define ZSLOT_ID 0. @define ZSLOT_OBJECTIVES 1. @define ZSLOT_ZSCORE 1. @define ZSLOT_ZSUM 2. Selection : ZScoresGA { + variables: mod-fitnesses (list). objective-means (list). objective-standard-deviations (list). # Trivial archiving, since state is simple + to archive: return 1. + to dearchive: return 1. # Only works after selection + to get-best-fitness: return mod-fitnesses{0}{ZSLOT_ZSUM}. + to init: + to fill-objective-means from fitnesses (list): i (int). j (int). objective-means = {}. for i=0, i<|fitnesses{0}{ZSLOT_OBJECTIVES}|, i++ : push 0.0 onto objective-means. for i=0, i<|fitnesses|, i++ : { for j=0, j<|fitnesses{i}{ZSLOT_OBJECTIVES}|, j++ : { objective-means{j} += ((fitnesses{i}{ZSLOT_OBJECTIVES}{j}) - (objective-means{j}))/(i + 1). } } if (Z_SCORE_OUTPUT == 1) : { print "Means gen $generation". print objective-means. } + to fill-objective-standard-deviations from fitnesses (list): i (int). j (int). ss-list (list). ss-list = {}. objective-standard-deviations = {}. for i=0, i<|fitnesses{0}{ZSLOT_OBJECTIVES}|, i++ : { push 0.0 onto ss-list. } for i=0, i<|fitnesses|, i++ : { for j=0, j<|fitnesses{i}{ZSLOT_OBJECTIVES}|, j++ : { ss-list{j} += (fitnesses{i}{ZSLOT_OBJECTIVES}{j} - objective-means{j})^2. } } for j=0, j<|fitnesses{0}{ZSLOT_OBJECTIVES}|, j++ : { push (sqrt(ss-list{j} / |fitnesses|)) onto objective-standard-deviations. } if (Z_SCORE_OUTPUT == 1) : { print "STDV gen $generation". print objective-standard-deviations. } # Side-effects to mod-fitnesses + to calculate-z-scores of fitnesses (list): i (int). j (int). mod-fitnesses = {}. for i=0, i<|fitnesses|, i++ : { push {} onto mod-fitnesses. push {fitnesses{i}{ZSLOT_ID}} onto mod-fitnesses{i}. push {} onto mod-fitnesses{i}. for j=0, j<|fitnesses{i}{ZSLOT_OBJECTIVES}|, j++ : { if (objective-standard-deviations{j} == 0) : push 0.0 onto (mod-fitnesses{i}{ZSLOT_ZSCORE}). else push (((fitnesses{i}{ZSLOT_OBJECTIVES}{j}) - (objective-means{j})) / (objective-standard-deviations{j})) onto (mod-fitnesses{i}{ZSLOT_ZSCORE}). } } # Side-effects to mod-fitnesses + to sum-z-scores: i (int). j (int). coeffs (list). coeffs = {COEFF_ASSIST,COEFF_RECEIVED,COEFF_ALIVE}. for i=0, i<|mod-fitnesses|, i++ : { push 0 onto mod-fitnesses{i}. for j=0, j<|mod-fitnesses{i}{ZSLOT_ZSCORE}|, j++ : { mod-fitnesses{i}{ZSLOT_ZSUM} += (coeffs{j} * mod-fitnesses{i}{ZSLOT_ZSCORE}{j}). } } + to get-best choose n (int) of-population fitnesses (list): i (int). if ( ((controller get-current-game-mode) != MODE_FIGHT) || (( |fitnesses{0}{ZSLOT_OBJECTIVES}| ) != 3) ) : { print "ERROR: Z-Scores method is only meant to be used with the Battle Domain/Fight Mode using". print "standard objectives for dealing damage, avoiding damage and staying alive.". print "In order to use the z-scores method with other domains, the code for this error must". print "be removed, and coefficients for weighting the objectives must be specified in ZScoresGA.tz". controller end-simulation. return. } if (Z_SCORE_OUTPUT == 1) : { print "Raw fitnesses: ". for i = 0, i < |fitnesses|, i++ : { print fitnesses{i}. } } self fill-objective-means from fitnesses. self fill-objective-standard-deviations from fitnesses. self calculate-z-scores of fitnesses. self sum-z-scores. return (self elitist-selection get n). + to compare-by-third value val1 (list) to val2 (list): return (val2{2} - val1{2}). + to elitist-selection get n (int): i (int). keepers (list). sort mod-fitnesses with compare-by-third. keepers = {}. if (Z_SCORE_OUTPUT == 1) : print "Z sums". for i=0, i