001    package org.jaga.exampleApplications.proteinLocation;
002    
003    import org.jaga.selection.AbsoluteFitness;
004    import org.jaga.individualRepresentation.proteinLocation.*;
005    import org.jaga.definitions.*;
006    import org.jaga.util.*;
007    import org.jaga.masterAlgorithm.*;
008    import org.jaga.reproduction.*;
009    import org.jaga.reproduction.proteinLocation.*;
010    import org.jaga.hooks.*;
011    
012    /**
013     * TODO: Complete these comments.
014     *
015     * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
016     *
017     * <p><u>Company:</u> University College London and JAGA.Org
018     *    (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
019     * </p>
020     *
021     * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
022     *    This program is free software; you can redistribute it and/or modify
023     *    it under the terms of the GNU General Public License as published by
024     *    the Free Software Foundation, ONLY if you include a note of the original
025     *    author(s) in any redistributed/modified copy.<br/>
026     *    This program is distributed in the hope that it will be useful,
027     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
028     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
029     *    GNU General Public License for more details.<br/>
030     *    You should have received a copy of the GNU General Public License
031     *    along with this program; if not, write to the Free Software
032     *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
033     *    or see http://www.gnu.org/licenses/gpl.html</p>
034     *
035     * @author Greg Paperin (greg@jaga.org)
036     *
037     * @version JAGA public release 1.0 beta
038     */
039    
040    public class ProgressiveTestGroupSizeHook extends SimpleGAHook {
041    
042            private double mutationBoost = 3.0;
043            private int boostStartTimeout = 75;
044            private int boostStopTimeout = 5;
045    
046            private ProteinGroup allPositives = null;
047            private ProteinGroup allNegatives = null;
048            private ProteinGroup testPositives = null;
049            private ProteinGroup testNegatives = null;
050            private int testSetSizeDelta = 0;
051            private double triggerFitness = 0;
052            private int allPositivesIndex = 0;
053            private int allNegativesIndex = 0;
054    
055            private AnalysisHook cooperator = null;
056    
057            private double averagePatternLen = 0;
058            private int averagePatternLenGen = 0;
059            private double mutProb = 0;
060            private int lastSizeIncreaseGen = 0;
061            private boolean boosting = false;
062            private int timeToBoost = boostStartTimeout;
063            private int timeToStopBoost = 0;
064    
065            private ProgressiveTestGroupSizeHook() {}
066    
067            public ProgressiveTestGroupSizeHook(ProteinGroup allPositives, ProteinGroup allNegatives,
068                                                                                    ProteinGroup testPositives, ProteinGroup testNegatives,
069                                                                                    int initialTestSetSize, int testSetSizeDelta,
070                                                                                    double triggerFitness, double mutationBoost,
071                                                                                    int boostStartTimeout, int boostStopTimeout,
072                                                                                    GAParameterSet params) {
073                    this.mutationBoost = mutationBoost;
074                    this.boostStartTimeout = boostStartTimeout;
075                    this.boostStopTimeout = boostStopTimeout;
076                    this.timeToBoost = boostStartTimeout;
077                    this.allPositives = allPositives;
078                    this.allNegatives = allNegatives;
079                    this.testPositives = testPositives;
080                    this.testNegatives = testNegatives;
081                    this.testSetSizeDelta = testSetSizeDelta;
082                    this.triggerFitness = triggerFitness;
083                    this.allPositivesIndex = 0;
084                    this.allNegativesIndex = 0;
085                    allPositives.flatten();
086                    allPositives.randomise(params.getRandomGenerator());
087                    allNegatives.flatten();
088                    allNegatives.randomise(params.getRandomGenerator());
089                    while (allPositivesIndex < allPositives.size()
090                               && testPositives.size() < initialTestSetSize) {
091                            testPositives.add(allPositives.getProtein(allPositivesIndex));
092                            allPositivesIndex++;
093                    }
094                    while (allNegativesIndex < allNegatives.size()
095                               && testNegatives.size() < initialTestSetSize) {
096                            testNegatives.add(allNegatives.getProtein(allNegativesIndex));
097                            allNegativesIndex++;
098                    }
099                    printInfo();
100            }
101    
102            private void startBoost(GAParameterSet params) {
103    
104                    ReproductionAlgorithm a = params.getReproductionAlgorithm();
105                    if (!(a instanceof CombinedReproductionAlgorithm))
106                            return;
107                    CombinedReproductionAlgorithm algs = (CombinedReproductionAlgorithm) a;
108    
109                    for (int i = 0; i < algs.countCombinedAlgorithms(); i++) {
110                            a = algs.getReproductionAlgorithm(i);
111                            if (a instanceof PolypeptidePatternMutation) {
112                                    mutProb = ((PolypeptidePatternMutation) a).getMutationProbability();
113                                    double newProb = mutProb * mutationBoost;
114                                    if (newProb > 1)
115                                            newProb = 1;
116                                    ((PolypeptidePatternMutation) a).setMutationProbability(newProb);
117                            }
118                    }
119    
120                    boosting = true;
121                    timeToStopBoost = boostStopTimeout;
122    
123            }
124    
125            private void stopBoost(GAParameterSet params) {
126                    ReproductionAlgorithm a = params.getReproductionAlgorithm();
127                    if (!(a instanceof CombinedReproductionAlgorithm))
128                            return;
129                    CombinedReproductionAlgorithm algs = (CombinedReproductionAlgorithm) a;
130    
131                    for (int i = 0; i < algs.countCombinedAlgorithms(); i++) {
132                            a = algs.getReproductionAlgorithm(i);
133                            if (a instanceof PolypeptidePatternMutation) {
134                                    ((PolypeptidePatternMutation) a).setMutationProbability(mutProb);
135                            }
136                    }
137    
138                    boosting = false;
139                    timeToBoost = boostStartTimeout;
140            }
141    
142            public void foundNewResult(SimpleGA caller, Population pop, int age,
143                                                               GAResult result, GAParameterSet params) {
144                    if (boosting)
145                            stopBoost(params);
146                    this.timeToBoost = this.boostStartTimeout;
147                    averagePatternLen = 0;
148                    for (int i = 0; i < pop.getSize(); i++) {
149                            final Individual ind = pop.getMember(i);
150                            averagePatternLen += ((ProteinLocationClassifier) ind).getPattern().getLength();
151                    }
152                    averagePatternLen /= (double) pop.getSize();
153                    averagePatternLenGen = age;
154            }
155    
156            public void generationChanged(SimpleGA caller, Population pop, int age,
157                                                                      GAResult result, GAParameterSet params) {
158    
159                    printInfo();
160    
161                    // Get currently best fitness:
162    
163                    if (null == result)
164                            return;
165    
166                    Individual bestInd = ((FittestIndividualResult) result).
167                                                             getFittestIndividual();
168                    if (null == bestInd)
169                            return;
170    
171                    AbsoluteFitness bestFit = (AbsoluteFitness) bestInd.getFitness();
172                    if (null == bestFit)
173                            return;
174    
175                    // Check if fitness reched the trigger level:
176    
177                    if (boosting) {
178                            if (timeToStopBoost == 0)
179                                    stopBoost(params);
180                            else
181                                    timeToStopBoost--;
182                    } else { // if (!boosting)
183                            if (timeToBoost == 0)
184                                    startBoost(params);
185                            else
186                                    timeToBoost--;
187    
188                    }
189    
190                    if (bestFit.getValue() < triggerFitness)
191                            return;
192    
193                    if (boosting) // if still boosting but noe better fitness, stop boosting
194                            stopBoost(params);
195    
196                    if (allPositives.size() == testPositives.size()
197                                    && allNegatives.size() == testNegatives.size()) {
198                            return;
199                    }
200    
201                    // Enlarge test sets:
202    
203                    int targetSize = testPositives.size() + testSetSizeDelta;
204                    while (allPositivesIndex < allPositives.size()
205                               && testPositives.size() < targetSize) {
206                            testPositives.add(allPositives.getProtein(allPositivesIndex));
207                            allPositivesIndex++;
208                    }
209    
210                    targetSize = testNegatives.size() + testSetSizeDelta;
211                    while (allNegativesIndex < allNegatives.size()
212                               && testNegatives.size() < targetSize) {
213                            testNegatives.add(allNegatives.getProtein(allNegativesIndex));
214                            allNegativesIndex++;
215                    }
216    
217                    // Recalculate fitnesses:
218    
219                    lastSizeIncreaseGen = age;
220                    timeToBoost = boostStartTimeout;
221                    averagePatternLen = 0;
222                    int bestI = -1;
223                    double bestF = Double.NEGATIVE_INFINITY;
224                    FitnessEvaluationAlgorithm tester = params.getFitnessEvaluationAlgorithm();
225                    for (int i = 0; i < pop.getSize(); i++) {
226                            final Individual ind = pop.getMember(i);
227                            averagePatternLen += ((ProteinLocationClassifier) ind).getPattern().getLength();
228                            final Fitness newIndFit = tester.evaluateFitness(ind, age, pop,
229                                      params);
230                            final double fVal = ((AbsoluteFitness) newIndFit).getValue();
231                            ind.setFitness(newIndFit);
232                            if (fVal > bestF) {
233                                    bestI = i;
234                                    bestF = fVal;
235                            }
236                    }
237                    ((FittestIndividualResult) result).setFittestIndividual(pop.getMember(bestI));
238                    averagePatternLen /= (double) pop.getSize();
239    
240                    if (null != cooperator) {
241                            cooperator.populationReinitialised(pop, age, result, params);
242                    }
243            }
244    
245            public void setAnalysisHookForCooperation(AnalysisHook cooperator) {
246                    this.cooperator = cooperator;
247            }
248    
249            private void printInfo() {
250                    System.out.println();
251                    System.out.println(" *** **  Active positive test set size: " + testPositives.size()
252                                                       + " ( can grow up to " + allPositives.size() + ")");
253                    System.out.println(" *** **  Active negative test set size: " + testNegatives.size()
254                                                       + " ( can grow up to " + allNegatives.size() + ")");
255                    System.out.println(" *** **  Test set last increased in generation " + lastSizeIncreaseGen);
256                    System.out.println("     **  Avegare length of classifier in generation "
257                                                       + averagePatternLenGen + " was: " + averagePatternLen);
258                    if (boosting)
259                            System.out.println(" *** **  BOOSTING mustation probability. Time left: "
260                                                               + timeToStopBoost);
261                    else
262                            System.out.println(" *** **  Time till mutation boost: " + timeToBoost);
263            }
264    
265    }