001/**
002 * Copyright (C) 2007 - 2016, 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 */
019package org.dllearner.utilities.owl;
020
021import java.util.Collection;
022import java.util.LinkedList;
023import java.util.List;
024import java.util.NavigableSet;
025import java.util.TreeSet;
026
027import org.dllearner.core.AbstractClassExpressionLearningProblem;
028import org.dllearner.core.EvaluatedDescription;
029import org.dllearner.core.Score;
030import org.dllearner.learningproblems.EvaluatedDescriptionPosNeg;
031import org.semanticweb.owlapi.model.OWLClassExpression;
032
033/**
034 * A set of evaluated descriptions, which is bound by a maximum size. Can be
035 * used by algorithms to store the most promising n class descriptions.
036 * 
037 * @author Jens Lehmann
038 *
039 */
040public class EvaluatedDescriptionSet {
041
042        private EvaluatedDescriptionComparator comp = new EvaluatedDescriptionComparator();
043
044        private NavigableSet<EvaluatedDescription<? extends Score>> set = new TreeSet<>(comp);
045
046        private int maxSize;
047
048        /**
049         * @param maxSize the maximum number of elements contained in this set
050         */
051        public EvaluatedDescriptionSet(int maxSize) {
052                this.maxSize = maxSize;
053        }
054
055        /**
056         * Adds an class expression to this set. Some kind of lazy evaluation is applied, 
057         * i.e. an evaluated description is only generated if the given accuracy
058         * is higher than the accuracy value of the worst evaluated description 
059         * contained in this set.
060         * @param description the class expression
061         * @param accuracy the accuracy of the class expression
062         * @param problem the learning problem
063         */
064        public void add(OWLClassExpression description, double accuracy,
065                        AbstractClassExpressionLearningProblem<? extends Score> problem) {
066                // bug
067                // http://sourceforge.net/tracker/?func=detail&atid=986319&aid=3029181&group_id=203619
068                // -> set should be filled up to max size before we compare acc. with
069                // the worst result
070                if (set.size() < maxSize || getWorst().getAccuracy() <= accuracy) {
071                        set.add(problem.evaluate(description));
072                }
073                // delete the worst element if set is full
074                if (set.size() > maxSize) {
075                        set.pollFirst();
076                }
077        }
078
079        /**
080         * Adds an evaluated description to this set and ensures that the size does not
081         * exceed the limit.
082         * @param ed the evaluated description to add
083         */
084        public void add(EvaluatedDescription<? extends Score> ed) {
085                set.add(ed);
086                // delete the worst element if set is full
087                if (set.size() > maxSize) {
088                        set.pollFirst();
089                }
090        }
091
092        /**
093         * Adds a collection of evaluated description to this set and ensures that the size does not
094         * exceed the limit.
095         * @param eds the evaluated descriptions to add
096         */
097        public void addAll(Collection<EvaluatedDescriptionPosNeg> eds) {
098                for(EvaluatedDescriptionPosNeg ed : eds) {
099                        add(ed);
100                }
101        }
102
103        /**
104         * @return true if this set with a maximum size of n contains n elements.
105         */
106        public boolean isFull() {
107                return (set.size() >= maxSize);
108        }
109
110        /**
111         * @return true if this set contains no elements. 
112         */
113        public boolean isEmpty() {
114                return (set.isEmpty());
115        }
116
117        /**
118         * @return the size of this set
119         */
120        public int size() {
121                return set.size();
122        }
123
124        /**
125         * @return the best evaluated description or <code>null</code> if this set is empty.
126         */
127        public EvaluatedDescription<? extends Score> getBest() {
128                return set.isEmpty() ? null : set.last();
129        }
130        
131        /**
132         * @return the worst evaluated description or <code>null</code> if this set is empty.
133         */
134        public EvaluatedDescription<? extends Score> getWorst() {
135                return set.isEmpty() ? null : set.first();
136        }
137
138        /**
139         * @return the best accuracy so far or -Infinity if this set is empty.
140         */
141        public double getBestAccuracy() {
142                return set.isEmpty() ? Double.NEGATIVE_INFINITY : set.last().getAccuracy();
143        }
144
145        /**
146         * @return the underlying set of evaluated descriptions.
147         */
148        public NavigableSet<EvaluatedDescription<? extends Score>> getSet() {
149                return set;
150        }
151
152        /**
153         * @return a list which contains only the class expressions of this set.
154         */
155        public List<OWLClassExpression> toDescriptionList() {
156                List<OWLClassExpression> list = new LinkedList<>();
157                for(EvaluatedDescription<? extends Score> ed : set.descendingSet()) {
158                        list.add(ed.getDescription());
159                }
160                return list;
161        }
162        
163        /**
164         * @return the maximum size of this set.
165         */
166        public int getMaxSize() {
167                return maxSize;
168        }
169
170        @Override
171        public String toString() {
172                return set.toString();
173        }
174}