001 package jcolibri.method.retrieve.NNretrieval.similarity.local.recommenders; 002 003 import jcolibri.exception.NoApplicableSimilarityFunctionException; 004 import jcolibri.method.retrieve.NNretrieval.similarity.LocalSimilarityFunction; 005 006 007 008 /** 009 * This function returns the similarity of two numbers following 010 * the McSherry - Less is Better formulae 011 * 012 * sim(c.a,q.a)= (max(a) - c.a) / (max(a)-min(a)) 013 * 014 * min(a) and max(a) must be defined by the designer. q.a is not taken into account. 015 */ 016 public class McSherryLessIsBetter implements LocalSimilarityFunction { 017 018 /** InrecaLessIsBetter. */ 019 double maxValue; 020 double minValue; 021 022 /** 023 * Constructor. max and min values are ignored for enum types. 024 */ 025 public McSherryLessIsBetter(double maxAttributeValue, double minAttributeValue) { 026 this.maxValue = maxAttributeValue; 027 this.minValue = minAttributeValue; 028 } 029 030 /** 031 * Applies the similarity function. 032 * 033 * @param caseObject is a Number 034 * @param queryObject is a Number 035 * @return result of apply the similarity function. 036 */ 037 public double compute(Object caseObject, Object queryObject) throws NoApplicableSimilarityFunctionException{ 038 if ((caseObject == null)) 039 return 0; 040 if (! ((caseObject instanceof java.lang.Number)||(caseObject instanceof Enum))) 041 throw new jcolibri.exception.NoApplicableSimilarityFunctionException(this.getClass(), caseObject.getClass()); 042 043 double caseValue; 044 double max; 045 double min; 046 if(caseObject instanceof Number) 047 { 048 Number n1 = (Number) caseObject; 049 caseValue = n1.doubleValue(); 050 max = maxValue; 051 min = minValue; 052 } 053 else 054 { 055 Enum enum1 = (Enum)caseObject; 056 caseValue = enum1.ordinal(); 057 max = caseObject.getClass().getEnumConstants().length; 058 min = 0; 059 } 060 061 062 063 return (max-caseValue) / (max - min); 064 065 } 066 067 /** Applicable to any Number subinstance */ 068 public boolean isApplicable(Object o1, Object o2) 069 { 070 if((o1==null)&&(o2==null)) 071 return true; 072 else if(o1==null) 073 return (o2 instanceof Number)||(o2 instanceof Enum); 074 else if(o2==null) 075 return (o1 instanceof Number)||(o1 instanceof Enum); 076 else 077 return ((o1 instanceof Number)&&(o2 instanceof Number)) || 078 ((o1 instanceof Enum)&&(o2 instanceof Enum)); 079 } 080 081 }