001 /**
002 * Copyright (C) 2007-2008, 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
021 package org.dllearner.algorithms.refinement2;
022
023 import org.dllearner.utilities.owl.ConceptComparator;
024
025 public class LexicographicHeuristic implements ExampleBasedHeuristic {
026
027 // Vergleich von Konzepten, falls alle anderen Kriterien fehlschlagen
028 ConceptComparator conceptComparator = new ConceptComparator();
029
030 // implementiert einfach die Definition in der Diplomarbeit
031 public int compare(ExampleBasedNode n1, ExampleBasedNode n2) {
032
033 // sicherstellen, dass Qualität ausgewertet wurde
034 if(n1.isQualityEvaluated() && n2.isQualityEvaluated() && !n1.isTooWeak() && !n2.isTooWeak()) {
035 if(n1.getCoveredNegatives().size()<n2.getCoveredNegatives().size())
036 return 1;
037 else if(n1.getCoveredNegatives().size()>n2.getCoveredNegatives().size())
038 return -1;
039 else {
040 //TODO: es wäre geringfügig effizienter die Länge nicht mehrfach zu berechnen
041 // Besser: Länge wird einfach ignoriert und stattdessen horizontal expansion
042 // genommen => das ist günstiger, da so verhindert wird, dass das gleiche
043 // Konzept lange ausgeschlachtet wird, obwohl es ein gleich gutes Element gibt,
044 // was vielleicht nur um 1 länger ist;
045 // => damit trotzdem die jeweils besten gefundenen Elemente ermittelt werden
046 // können (da fällt die horizontal expansion dann natürlich als Kriterium
047 // weg, da die nur während des Algorithmus eine Rolle spielt) wird zusätzlich
048 // ein separator NodeComparator genutzt
049 // if(n1.getConcept().getLength()<n2.getConcept().getLength())
050 // return 1;
051 // else if(n1.getConcept().getLength()>n2.getConcept().getLength())
052 // return -1;
053 // else {
054 if(n1.getHorizontalExpansion()<n2.getHorizontalExpansion())
055 return 1;
056 else if(n1.getHorizontalExpansion()>n2.getHorizontalExpansion())
057 return -1;
058 //else
059 // return 0;
060
061 // Vorsicht: es darf nur 0 zurückgegeben werden, wenn die Konzepte identisch sind,
062 // in dem Fall werden sie vom Algorithmus ignoriert
063 // TODO: hier müsste also gleich eine Vergleichsfunktion für Konzepte in
064 // ordered negation normal form einbringen und hätte damit sofort den redundancy
065 // check erledigt (??) => horizontalExpansion könnte allerdings bei gleichen
066 // Konzepten unterschiedlich sein, also ev. doch keine so gute Idee
067
068 else {
069
070 //if(n1.getConcept().hashCode()<n2.getConcept().hashCode())
071 // return 1;
072 //else if(n1.getConcept().hashCode()>n2.getConcept().hashCode())
073 // return -1;
074
075 // throw new RuntimeException("Current implementation cannot cope with candidate concepts with equal hash codes");
076
077 // TODO: es ist nicht sehr gut nur Strings zu vergleichen
078 // int test = n1.getConcept().toString().compareTo(n2.getConcept().toString());
079 return conceptComparator.compare(n1.getConcept(), n2.getConcept());
080 //if(test>0)
081 // return 1;
082 //else if(test<0)
083 // return -1;
084
085 // dieser Fall sollte eigentlich nicht eintreten, außer wenn
086 // node entfernt wird => das ist notwendig, wenn horiz. exp.
087 // eines Knotens geändert wird; der muss dann gelöscht und
088 // wieder eingefügt werden
089
090 // System.out.println("equal nodes:");
091 // System.out.println(n1 + " chain: " + n1.getRefinementChainString());
092 // System.out.println(n2 + " chain: " + n2.getRefinementChainString());
093
094 // throw new RuntimeException("same node twice");
095 // return 0;
096 // Absicherung das keine gleichen Konzepte vorkommen
097 // throw new RuntimeException("Current implementation cannot cope with concepts with equal string representations.");
098 }
099
100
101 //}
102 }
103 }
104
105 throw new RuntimeException("Cannot compare nodes, which have no evaluated quality or are too weak.");
106 }
107
108
109 // alle NodeComparators führen zur gleichen Ordnung
110 @Override
111 public boolean equals(Object o) {
112 return (o instanceof LexicographicHeuristic);
113 }
114
115 }