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 - More is Better formulae 011 * 012 * sim(c.a,q.a)= 1 - ((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 McSherryMoreIsBetter 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 */ 026 027 public McSherryMoreIsBetter(double maxAttributeValue, double minAttributeValue) { 028 this.maxValue = maxAttributeValue; 029 this.minValue = minAttributeValue; 030 } 031 032 /** 033 * Applies the similarity function. 034 * 035 * @param caseObject is a Number 036 * @param queryObject is a Number 037 * @return result of apply the similarity function. 038 */ 039 public double compute(Object caseObject, Object queryObject) throws NoApplicableSimilarityFunctionException{ 040 if ((caseObject == null)) 041 return 0; 042 if (! ((caseObject instanceof java.lang.Number)||(caseObject instanceof Enum))) 043 throw new jcolibri.exception.NoApplicableSimilarityFunctionException(this.getClass(), caseObject.getClass()); 044 045 double caseValue; 046 double max; 047 double min; 048 if(caseObject instanceof Number) 049 { 050 Number n1 = (Number) caseObject; 051 caseValue = n1.doubleValue(); 052 max = maxValue; 053 min = minValue; 054 } 055 else 056 { 057 Enum enum1 = (Enum)caseObject; 058 caseValue = enum1.ordinal(); 059 max = caseObject.getClass().getEnumConstants().length; 060 min = 0; 061 } 062 063 064 return 1 - ( (max-caseValue) / (max - min) ); 065 066 } 067 068 /** Applicable to any Number subinstance */ 069 public boolean isApplicable(Object o1, Object o2) 070 { 071 if((o1==null)&&(o2==null)) 072 return true; 073 else if(o1==null) 074 return (o2 instanceof Number)||(o2 instanceof Enum); 075 else if(o2==null) 076 return (o1 instanceof Number)||(o1 instanceof Enum); 077 else 078 return ((o1 instanceof Number)&&(o2 instanceof Number)) || 079 ((o1 instanceof Enum)&&(o2 instanceof Enum)); 080 } 081 082 }