001    package org.jaga.fitnessEvaluation.multiplexer;
002    
003    
004    import org.jaga.individualRepresentation.booleanFormulas.*;
005    import org.jaga.definitions.*;
006    import org.jaga.selection.*;
007    
008    
009    /**
010     * TODO: Complete these comments.
011     *
012     * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
013     *
014     * <p><u>Company:</u> University College London and JAGA.Org
015     *    (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
016     * </p>
017     *
018     * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
019     *    This program is free software; you can redistribute it and/or modify
020     *    it under the terms of the GNU General Public License as published by
021     *    the Free Software Foundation, ONLY if you include a note of the original
022     *    author(s) in any redistributed/modified copy.<br/>
023     *    This program is distributed in the hope that it will be useful,
024     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
025     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
026     *    GNU General Public License for more details.<br/>
027     *    You should have received a copy of the GNU General Public License
028     *    along with this program; if not, write to the Free Software
029     *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030     *    or see http://www.gnu.org/licenses/gpl.html</p>
031     *
032     * @author Greg Paperin (greg@jaga.org)
033     *
034     * @version JAGA public release 1.0 beta
035     */
036    
037    public class MultiplexerFitness implements FitnessEvaluationAlgorithm {
038    
039            private class TestEntry {
040                    private boolean [] testVals = null;
041                    private boolean refResult = false;
042                    private TestEntry() {assert false : "Dont use!";}
043                    public TestEntry(Multiplexer refMulti, int encodedVals) {
044                            testVals = new boolean[refMulti.getTotalLines()];
045                            for (int i = refMulti.getTotalLines() - 1; i >= 0; i--) {
046                                    testVals[i] = (0 != (encodedVals & 0x1));
047                                    encodedVals >>>= 1;
048                            }
049                            refResult = refMulti.evaluate(testVals);
050                    }
051                    public boolean [] getTestVals() {
052                            return testVals;
053                    }
054                    public boolean getReferenceResult() {
055                            return refResult;
056                    }
057                    public String toString() {
058                            StringBuffer s = new StringBuffer("[");
059                            for (int i = 0; i < testVals.length; i++) {
060                                    if (i > 0)
061                                            s.append(", ");
062                                    s.append(testVals[i] ? "1" : "0");
063                            }
064                            s.append("] => ");
065                            s.append(refResult ? "1" : "0");
066                            return s.toString();
067                    }
068            }
069    
070            private TestEntry [] tests = null;
071            private double pressForShortResultFactor = 0.0;
072    
073            public MultiplexerFitness() {
074                    initTests(new Multiplexer());
075            }
076    
077            public MultiplexerFitness(Multiplexer referenceMultiplexer) {
078                    if (null == referenceMultiplexer)
079                            throw new NullPointerException("referenceMultiplexer may not be null");
080                    initTests(referenceMultiplexer);
081            }
082    
083            public MultiplexerFitness(double pressForShortFactor) {
084                    this.pressForShortResultFactor = pressForShortFactor;
085                    initTests(new Multiplexer());
086            }
087    
088            public MultiplexerFitness(Multiplexer referenceMultiplexer, double pressForShortFactor) {
089                    if (null == referenceMultiplexer)
090                            throw new NullPointerException("referenceMultiplexer may not be null");
091                    this.pressForShortResultFactor = pressForShortFactor;
092                    initTests(referenceMultiplexer);
093            }
094    
095            public Class getApplicableClass() {
096                    return BooleanFormulaTree.class;
097            }
098    
099            public double getPressForShortFactor() {
100                    return this.pressForShortResultFactor;
101            }
102    
103            public void setPressForShortFactor(double pressForShortFactor) {
104                    this.pressForShortResultFactor = pressForShortFactor;
105            }
106    
107            private void initTests(Multiplexer referenceMultiplexer) {
108                    int testCount = (int) Math.round(Math.pow(2, referenceMultiplexer.getTotalLines()));
109                    tests = new TestEntry[testCount];
110                    for (int encodedTstVals = 0; encodedTstVals < testCount; encodedTstVals++) {
111                            tests[encodedTstVals] = new TestEntry(referenceMultiplexer, encodedTstVals);
112                    }
113            }
114    
115            public Fitness evaluateFitness(Individual individual, int age, Population population, GAParameterSet params) {
116                    BooleanFormulaTree formula = (BooleanFormulaTree) individual;
117                    int correct = 0;
118                    for (int i = 0; i < tests.length; i++) {
119                            boolean expected = tests[i].getReferenceResult();
120                            boolean [] args = tests[i].getTestVals();
121                            boolean actual = formula.evaluate(args);
122                            if (expected == actual)
123                                    ++correct;
124                    }
125                    double fract = ((double) correct) / ((double) tests.length);
126                    double whole = (double) correct;
127    
128                    // double fitVal = whole + fract;
129    
130                    double fitVal = Math.round(whole -
131                                            pressForShortResultFactor * Math.log(formula.getNodeCount()) / Math.log(2)
132                                                     ) + fract;
133    
134                    AbsoluteFitness fitness = new AbsoluteFitness(fitVal);
135                    return fitness;
136            }
137    
138            /*
139            //TEST:
140            public static void main(String[] args) {
141                    Multiplexer mult = new Multiplexer(4);
142                    MutliplexorFitness fitEval = new MutliplexorFitness(mult);
143                    for (int t = 0; t < fitEval.tests.length; ++t)
144                            System.out.println(fitEval.tests[t]);
145            }
146            */
147    
148    }