001    /**
002     * Copyright (C) 2007-2011, Jens Lehmann
003     *
004     * This file is part of DL-Learner.
005     *
006     * DL-Learner is free software; you can redistribute it and/or modify
007     * it under the terms of the GNU General Public License as published by
008     * the Free Software Foundation; either version 3 of the License, or
009     * (at your option) any later version.
010     *
011     * DL-Learner is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015     *
016     * You should have received a copy of the GNU General Public License
017     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018     */
019    
020    package org.dllearner.algorithms;
021    
022    import java.util.Collection;
023    import java.util.LinkedList;
024    
025    import org.apache.log4j.Logger;
026    import org.dllearner.algorithms.gp.GPUtilities;
027    import org.dllearner.core.EvaluatedDescription;
028    import org.dllearner.core.AbstractCELA;
029    import org.dllearner.core.AbstractLearningProblem;
030    import org.dllearner.core.AbstractReasonerComponent;
031    import org.dllearner.core.Score;
032    import org.dllearner.core.configurators.RandomGuesserConfigurator;
033    import org.dllearner.core.options.ConfigEntry;
034    import org.dllearner.core.options.ConfigOption;
035    import org.dllearner.core.options.IntegerConfigOption;
036    import org.dllearner.core.options.InvalidConfigOptionValueException;
037    import org.dllearner.core.owl.Description;
038    
039    /**
040     * This learning algorithm provides a random guessing technique to solve
041     * learning problems in description logics/OWL. Solutions of such problems
042     * are concepts, which can be viewed as trees. The algorithm takes as input
043     * the number of guesses (how many concepts to generate) and the maximum depth
044     * of the concepts/trees. Using this, it randomly creates trees by calling the
045     * "grow" method of a genetic programming algorithm. The target language is
046     * currently ALC.
047     * 
048     * @author Jens Lehmann
049     *
050     */
051    public class RandomGuesser extends AbstractCELA {
052    
053            private RandomGuesserConfigurator configurator;
054            @Override
055            public RandomGuesserConfigurator getConfigurator(){
056                    return configurator;
057            }
058            
059        private Description bestDefinition = null;
060        private Score bestScore;
061        private double bestFitness = Double.NEGATIVE_INFINITY;
062        private boolean isRunning = false;
063    
064        private double lengthPenalty = 0.02;
065            private int numberOfTrees = 100;
066            private int maxDepth = 5;
067        
068            private static Logger logger = Logger.getLogger(RandomGuesser.class);
069            
070            public RandomGuesser(AbstractLearningProblem learningProblem, AbstractReasonerComponent rs) {
071                    super(learningProblem, rs);
072                    this.configurator = new RandomGuesserConfigurator(this);
073            }
074            
075            public static String getName() {
076                    return "random guesser learning algorithm";
077            }       
078            
079            public static Collection<Class<? extends AbstractLearningProblem>> supportedLearningProblems() {
080                    Collection<Class<? extends AbstractLearningProblem>> problems = new LinkedList<Class<? extends AbstractLearningProblem>>();
081                    problems.add(AbstractLearningProblem.class);
082                    return problems;
083            }
084            
085            public static Collection<ConfigOption<?>> createConfigOptions() {
086                    Collection<ConfigOption<?>> options = new LinkedList<ConfigOption<?>>();
087                    options.add(new IntegerConfigOption("numberOfGuesses", "number of randomly generated concepts/trees", 100));
088                    options.add(new IntegerConfigOption("maxDepth", "maximum depth of generated concepts/trees", 5));
089                    return options;
090            }
091            
092            /* (non-Javadoc)
093             * @see org.dllearner.core.Component#applyConfigEntry(org.dllearner.core.ConfigEntry)
094             */
095            @Override
096            public <T> void applyConfigEntry(ConfigEntry<T> entry) throws InvalidConfigOptionValueException {
097                    String name = entry.getOptionName();
098                    if (name.equals("numberOfGuesses")) {
099                            numberOfTrees = (Integer) entry.getValue();
100                    } else if(name.equals("maxDepth")) {
101                            maxDepth = (Integer) entry.getValue();
102                    }
103            }
104    
105            /* (non-Javadoc)
106             * @see org.dllearner.core.Component#init()
107             */
108            @Override
109            public void init() {
110    
111            }       
112            
113            @Override
114            public void start() {
115                    isRunning = true;
116                    
117                    Description d;
118                    
119                    for(int i=0; i<numberOfTrees; i++) {
120    //                      p = GPUtilities.createGrowRandomProgram(learningProblem, reasoner, maxDepth, false);
121                            d = GPUtilities.createGrowRandomTree(learningProblem, reasoner, maxDepth, false);
122                            
123                            double acc = learningProblem.getAccuracy(d);
124                            double fitness = acc - lengthPenalty * d.getLength();
125                            
126                            if(fitness>bestFitness) {
127                                    bestFitness = fitness;
128                                    bestScore = learningProblem.computeScore(d);
129                                    bestDefinition = d; // p.getTree();
130                            }
131                    }
132                    
133                    logger.info("Random-Guesser (" + numberOfTrees + " trials, maximum depth " + maxDepth + ")");
134                    logger.info("best solution: " + bestDefinition);
135                    logger.info("fitness: " + bestFitness);
136                    
137                    isRunning = false;
138            }
139    
140    //      @Override
141            public Score getSolutionScore() {
142                    return bestScore;
143            }
144    
145            @Override
146            public Description getCurrentlyBestDescription() {
147                    return bestDefinition;
148            }       
149            
150            @Override
151            public EvaluatedDescription getCurrentlyBestEvaluatedDescription() {
152                    return learningProblem.evaluate(bestDefinition);
153    //              return new EvaluatedDescriptionPosNeg(bestDefinition,bestScore);
154            }
155    
156            @Override
157            public void stop() {
158                    
159            }
160    
161            /* (non-Javadoc)
162             * @see org.dllearner.core.LearningAlgorithm#isRunning()
163             */
164            @Override
165            public boolean isRunning() {
166                    return isRunning;
167            }
168    
169    }