001 package org.jaga.masterAlgorithm;
002
003
004 import org.jaga.util.FittestIndividualResult;
005 import org.jaga.selection.*;
006 import org.jaga.definitions.*;
007 import java.util.Arrays;
008
009
010 /**
011 * TODO: Complete these comments.
012 *
013 * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
014 *
015 * <p><u>Company:</u> University College London and JAGA.Org
016 * (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
017 * </p>
018 *
019 * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
020 * This program is free software; you can redistribute it and/or modify
021 * it under the terms of the GNU General Public License as published by
022 * the Free Software Foundation, ONLY if you include a note of the original
023 * author(s) in any redistributed/modified copy.<br/>
024 * This program is distributed in the hope that it will be useful,
025 * but WITHOUT ANY WARRANTY; without even the implied warranty of
026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
027 * GNU General Public License for more details.<br/>
028 * You should have received a copy of the GNU General Public License
029 * along with this program; if not, write to the Free Software
030 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
031 * or see http://www.gnu.org/licenses/gpl.html</p>
032 *
033 * @author Greg Paperin (greg@jaga.org)
034 *
035 * @version JAGA public release 1.0 beta
036 */
037
038 public class ElitistGA extends ReusableSimpleGA {
039
040 private double eliteProportion = 0.2;//propotion
041 private double badProportion = 0.05;
042
043 public ElitistGA() {}
044
045 public ElitistGA(double eliteProportion) {
046 setEliteProportion(eliteProportion);
047 }
048
049 public ElitistGA(double eliteProportion, double badProportion) {
050 setEliteProportion(eliteProportion);
051 setBadProportion(badProportion);
052 }
053
054
055 public ElitistGA(GAParameterSet parameters, double eliteProportion) {
056 super(parameters);
057 setEliteProportion(eliteProportion);
058 }
059
060 public ElitistGA(GAParameterSet parameters, double eliteProportion, double badProportion) {
061 super(parameters);
062 setEliteProportion(eliteProportion);
063 setBadProportion(badProportion);
064 }
065
066
067 public double getEliteProportion() {
068 return this.eliteProportion;
069 }
070
071 public void setEliteProportion(double eliteProportion) {
072 if (eliteProportion < 0 || 1 < eliteProportion)
073 throw new IllegalArgumentException("Elite proportion must be in [0, 1]");
074 this.eliteProportion = eliteProportion;
075 }
076
077 public double getBadProportion() {
078 return this.badProportion;
079 }
080
081 public void setBadProportion(double badProportion) {
082 if (badProportion < 0 || 1 < badProportion)
083 throw new IllegalArgumentException("Bad proportion must be in [0, 1]");
084 this.badProportion = badProportion;
085 }
086
087 protected Population generateNextPopulation(Population oldPop, int age,
088 GAResult result, GAParameterSet params) {
089
090 FittestIndividualResult res = (FittestIndividualResult) result;
091 Population newPop = createEmptyPopulation(params);
092 final IndividualsFactory fact = params.getIndividualsFactory();
093
094 // Cut bad:
095
096 Individual [] pop = oldPop.getAllMembers();
097 Arrays.sort(pop, new AbsoluteFitnessIndividualComparator());
098 int cutSize = (int) ((double) pop.length * (1.0 - badProportion));
099 Individual [] cutPop = new Individual[cutSize];
100 System.arraycopy(pop, pop.length - cutSize, cutPop, 0, cutSize);
101 // the population we want is cutPop
102 // Copy elite:
103
104 int eliteSize = (int) ((double) params.getPopulationSize() * getEliteProportion());
105 int p = cutSize - 1;
106 while (newPop.getSize() < eliteSize) {
107 Individual kid = fact.createSpecificIndividual(cutPop[p], params);
108 kid.setFitness(cutPop[p].getFitness());
109 newPop.add(kid);
110 if (--p < 0)
111 p = cutSize - 1;
112 }
113
114 // Copy rest:
115
116 while (newPop.getSize() < params.getPopulationSize()) {
117
118 Individual [] parents = selectForReproduction(oldPop, age, params);
119 notifySelectedForReproduction(parents, oldPop, age, result, params);
120
121 Individual [] children = haveSex(parents, params);
122 for (int i = 0; i < children.length; i++) {
123 if (null != children[i].getFitness())
124 continue;
125 updateIndividualFitness(children[i], oldPop, age, params);
126 if (children[i].getFitness().isBetter(res.getBestFitness()))
127 res.setFittestIndividual(children[i]);
128 }
129
130 notifyReproduced(children, parents, oldPop, age, result, params);
131 newPop.addAll(children);
132 }
133
134 return newPop;
135 }
136 }