1 10 package examples.energy; 11 12 import org.jgap.*; 13 14 21 public class CoinsEnergyFitnessFunction 22 extends FitnessFunction { 23 24 private final static String CVS_REVISION = "$Revision: 1.4 $"; 25 26 private final int m_targetAmount; 27 28 private final double m_maxWeight; 29 30 public static final int MAX_BOUND = 10000; 31 public static final double MAX_WEIGHT = 500; 32 33 private static final double ZERO_DIFFERENCE_FITNESS = Math.sqrt(MAX_BOUND); 34 35 public CoinsEnergyFitnessFunction(int a_targetAmount, double a_maxWeight) { 36 if (a_targetAmount < 1 || a_targetAmount >= MAX_BOUND) { 37 throw new IllegalArgumentException ( 38 "Change amount must be between 1 and " + MAX_BOUND + " cents."); 39 } 40 41 if (a_maxWeight < 0 || a_maxWeight >= MAX_WEIGHT) { 42 throw new IllegalArgumentException ( 43 "Max weight must be greater than 0 and not greater than " 44 + MAX_WEIGHT + " grammes"); 45 } 46 m_targetAmount = a_targetAmount; 47 m_maxWeight = a_maxWeight; 48 } 49 50 62 public double evaluate(IChromosome a_subject) { 63 int changeAmount = amountOfChange(a_subject); 74 int totalCoins = getTotalNumberOfCoins(a_subject); 75 int changeDifference = Math.abs(m_targetAmount - changeAmount); 76 77 double fitness; 78 79 double totalWeight = getTotalWeight(a_subject); 84 if (totalWeight > m_maxWeight) { 85 if (a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1)) { 86 return 1.0d; 87 } 88 else { 89 return MAX_BOUND; 90 } 91 } 92 93 if (a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1)) { 94 fitness = MAX_BOUND; 95 } 96 else { 97 fitness = 0.0d; 98 } 99 100 if (a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1)) { 104 fitness -= changeDifferenceBonus(MAX_BOUND/3, changeDifference); 105 } 106 else { 107 fitness += changeDifferenceBonus(MAX_BOUND/3, changeDifference); 108 } 109 110 if (a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1)) { 117 fitness -= computeCoinNumberPenalty(MAX_BOUND/3, totalCoins); 118 } 119 else { 120 fitness += computeCoinNumberPenalty(MAX_BOUND/3, totalCoins); 121 } 122 123 if (a_subject.getConfiguration().getFitnessEvaluator().isFitter(2, 1)) { 126 fitness -= computeWeightPenalty(MAX_BOUND/3, totalWeight); 127 } 128 else { 129 fitness += computeWeightPenalty(MAX_BOUND/3, totalWeight); 130 } 131 132 return Math.max(1.0d, fitness); 135 } 136 137 145 protected double changeDifferenceBonus(double a_maxFitness, 146 int a_changeDifference) { 147 if (a_changeDifference == 0) { 148 return a_maxFitness; 149 } 150 else { 151 return Math.min(a_maxFitness, Math.pow(a_changeDifference, 2.2d)); 154 } 155 } 156 157 168 protected double computeCoinNumberPenalty(double a_maxFitness, int a_coins) { 169 if (a_coins == 1) { 170 return 0; 172 } 173 else { 174 if (a_coins < 1) { 175 return a_maxFitness; 176 } 177 return (Math.min(a_maxFitness, Math.pow(a_coins, 1.3d))); 181 } 182 } 183 184 195 public static int amountOfChange(IChromosome a_potentialSolution) { 196 int numQuarters = getNumberOfCoinsAtGene(a_potentialSolution, 0); 197 int numDimes = getNumberOfCoinsAtGene(a_potentialSolution, 1); 198 int numNickels = getNumberOfCoinsAtGene(a_potentialSolution, 2); 199 int numPennies = getNumberOfCoinsAtGene(a_potentialSolution, 3); 200 return (numQuarters * 25) + (numDimes * 10) + (numNickels * 5) + 201 numPennies; 202 } 203 204 216 public static int getNumberOfCoinsAtGene(IChromosome a_potentialSolution, 217 int a_position) { 218 Integer numCoins = 219 (Integer ) a_potentialSolution.getGene(a_position).getAllele(); 220 return numCoins.intValue(); 221 } 222 223 233 public static int getTotalNumberOfCoins(IChromosome a_potentialsolution) { 234 int totalCoins = 0; 235 int numberOfGenes = a_potentialsolution.size(); 236 for (int i = 0; i < numberOfGenes; i++) { 237 totalCoins += getNumberOfCoinsAtGene(a_potentialsolution, i); 238 } 239 return totalCoins; 240 } 241 242 251 public static double getTotalWeight(IChromosome a_potentialSolution) { 252 double totalWeight = 0.0d; 253 int numberOfGenes = a_potentialSolution.size(); 254 for (int i = 0; i < numberOfGenes; i++) { 255 int coinsNumber = getNumberOfCoinsAtGene(a_potentialSolution,i); 256 totalWeight += a_potentialSolution.getGene(i).getEnergy() * coinsNumber; 257 } 258 return totalWeight; 259 } 260 261 269 protected double computeWeightPenalty(double a_maxFitness, double a_weight) { 270 if (a_weight <= 0) { 271 return 0; 273 } 274 else { 275 return (Math.min(a_maxFitness, a_weight * a_weight)); 279 } 280 } 281 282 } 283 | Popular Tags |