KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > examples > supergene > AbstractChangeFitnessFunction


1 /*
2  * This file is part of JGAP.
3  *
4  * JGAP offers a dual license model containing the LGPL as well as the MPL.
5  *
6  * For licencing information please see the file license.txt included with JGAP
7  * or have a look at the top of class org.jgap.Chromosome which representatively
8  * includes the JGAP license policy applicable for any file delivered with JGAP.
9  */

10 package examples.supergene;
11
12 import org.jgap.*;
13 import org.jgap.impl.*;
14 import examples.supergene.*;
15
16 /**
17  * Sample fitness function for the MakeChange example, including supergenes.
18  *
19  * @author Neil Rotstan
20  * @author Klaus Meffert
21  * @author Audrius Meskauskas (subsequent adaptation)
22  * @since 2.0
23  */

24 public abstract class AbstractChangeFitnessFunction
25     extends FitnessFunction {
26   /** String containing the CVS revision. Read out via reflection!*/
27   private final static String JavaDoc CVS_REVISION = "$Revision: 1.1 $";
28
29   private final int m_targetAmount;
30
31   public AbstractChangeFitnessFunction(int a_targetAmount) {
32     if (a_targetAmount < 1 || a_targetAmount > 99) {
33       throw new IllegalArgumentException JavaDoc(
34           "Change amount must be between 1 and 99 cents.");
35     }
36     m_targetAmount = a_targetAmount;
37   }
38
39   /**
40    * Determine the fitness of the given Chromosome instance. The higher the
41    * return value, the more fit the instance. This method should always
42    * return the same fitness value for two equivalent Chromosome instances.
43    *
44    * @param a_subject the Chromosome instance to evaluate
45    *
46    * @return positive integer reflecting the fitness rating of the given
47    * Chromosome
48    * @since 2.0 (until 1.1: return type int)
49    */

50   public double evaluate(IChromosome a_subject) {
51     // The fitness value measures both how close the value is to the
52
// target amount supplied by the user and the total number of coins
53
// represented by the solution. We do this in two steps: first,
54
// we consider only the represented amount of change vs. the target
55
// amount of change and return higher fitness values for amounts
56
// closer to the target, and lower fitness values for amounts further
57
// away from the target. If the amount equals the target, then we go
58
// to step 2, which returns a higher fitness value for solutions
59
// representing fewer total coins, and lower fitness values for
60
// solutions representing more total coins.
61
// ------------------------------------------------------------------
62
int changeAmount = amountOfChange(a_subject);
63     int totalCoins = getTotalNumberOfCoins(a_subject);
64     int changeDifference = Math.abs(m_targetAmount - changeAmount);
65     // Step 1: Determine distance of amount represented by solution from
66
// the target amount. Since we know the maximum amount of change is
67
// 99 cents, we'll subtract the difference in change between the
68
// solution amount and the target amount from 99. That will give
69
// the desired effect of returning higher values for amounts
70
// closer to the target amount and lower values for amounts
71
// further away from the target amount.
72
// -----------------------------------------------------------------
73
int fitness = (99 - changeDifference);
74     // Step 2: If the solution amount equals the target amount, then
75
// we add additional fitness points for solutions representing fewer
76
// total coins.
77
// -----------------------------------------------------------------
78
if (changeAmount == m_targetAmount) {
79       // was fitness += 100 - (10 * totalCoins);
80
// The function should be more tolearant to the large amount of coins:
81
// -------------------------------------------------------------------
82
fitness += 100 - totalCoins;
83     }
84     // Make sure fitness value is always positive.
85
// -------------------------------------------
86
return Math.max(1, fitness);
87   }
88
89   /**
90    * Calculates the total amount of change (in cents) represented by
91    * the given potential solution and returns that amount.
92    *
93    * @param a_potentialSolution the potential solution to evaluate
94    * @return the total amount of change (in cents) represented by the
95    * given solution
96    */

97   public int amountOfChange(IChromosome a_potentialSolution) {
98     int numQuarters = getNumberOfCoinsAtGene(a_potentialSolution,
99                                              SupergeneSample.QUARTERS);
100     int numDimes = getNumberOfCoinsAtGene(a_potentialSolution,
101                                           SupergeneSample.DIMES);
102     int numNickels = getNumberOfCoinsAtGene(a_potentialSolution,
103                                             SupergeneSample.NICKELS);
104     int numPennies = getNumberOfCoinsAtGene(a_potentialSolution,
105                                             SupergeneSample.PENNIES);
106     return AbstractSupergeneTest.amountOfChange(numQuarters, numDimes,
107                                                 numNickels, numPennies);
108   }
109
110   /**
111    * Retrieves the number of coins represented by the given potential
112    * solution at the given gene position.
113    *
114    * @param a_potentialSolution the potential solution to evaluate
115    * @param a_code index of gene
116    * @return the number of coins represented by the potential solution
117    * at the given gene position
118    */

119   public int getNumberOfCoinsAtGene(IChromosome a_potentialSolution,
120                                     int a_code) {
121     Gene g = getResponsibleGene(a_potentialSolution, a_code);
122     return ( (IntegerGene) g).intValue();
123   }
124
125   /**
126    * Returns the total number of coins represented by all of the genes in
127    * the given potential solution.
128    *
129    * @param a_potentialsolution the potential solution to evaluate
130    * @return the total number of coins represented by the given Chromosome
131    */

132   public int getTotalNumberOfCoins(IChromosome a_potentialsolution) {
133     return
134         getNumberOfCoinsAtGene(a_potentialsolution, SupergeneSample.QUARTERS)
135         + getNumberOfCoinsAtGene(a_potentialsolution, SupergeneSample.DIMES)
136         + getNumberOfCoinsAtGene(a_potentialsolution, SupergeneSample.NICKELS)
137         + getNumberOfCoinsAtGene(a_potentialsolution, SupergeneSample.PENNIES);
138   }
139
140   /**
141    * Get the gene, responsible for the number of coins, corresponding
142    * this code.
143    *
144    * @param a_chromosome Chromosome to evaluate
145    * @param a_code index of Gene
146    * @return responsible gene
147    */

148   public abstract Gene getResponsibleGene(IChromosome a_chromosome, int a_code);
149 }
150
Popular Tags