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