001    /**
002     * CompromiseDrivenSelection.java
003     * jCOLIBRI2 framework. 
004     * @author Juan A. Recio-García.
005     * GAIA - Group for Artificial Intelligence Applications
006     * http://gaia.fdi.ucm.es
007     * 21/11/2007
008     */
009    package jcolibri.method.retrieve.selection.compromiseDriven;
010    
011    import java.util.ArrayList;
012    import java.util.Collection;
013    import java.util.HashSet;
014    import java.util.Set;
015    
016    import jcolibri.cbrcore.Attribute;
017    import jcolibri.cbrcore.CBRCase;
018    import jcolibri.cbrcore.CBRQuery;
019    import jcolibri.exception.NoApplicableFilterPredicateException;
020    import jcolibri.method.retrieve.RetrievalResult;
021    import jcolibri.method.retrieve.FilterBasedRetrieval.FilterConfig;
022    import jcolibri.method.retrieve.FilterBasedRetrieval.predicates.FilterPredicate;
023    import jcolibri.method.retrieve.selection.SelectCases;
024    import jcolibri.util.AttributeUtils;
025    
026    /**
027     * Cases selection approach that chooses cases according to their compromises with the user's query.
028     * The compromises are those attributes that do not satisfy the user's requirement.
029     * That way cases are selected according to the number of compromises and their similarity.
030     * 
031     * See: 
032     * D. McSherry. Similarity and compromise. In Case-Based Reasoning Research
033     * and Development, 5th International Conference on Case-Based Reasoning,
034     * ICCBR, pages 291-305, 2003.
035     * 
036     * @author Juan A. Recio-Garcia
037     * @author Developed at University College Cork (Ireland) in collaboration with Derek Bridge.
038     * @version 1.0
039     */
040    public class CompromiseDrivenSelection
041    {
042        /**
043         * Returns a list of cases according with their compromises and similarity
044         * @param query to compare with
045         * @param cases to compare
046         * @param preferences define the predicates that evaluate the user preferences
047         * @return a CDRSet object that stores the list of selected cases, the "like" sets and the "covered" sets (see paper for details).
048         */
049        public static CDRSet CDR(CBRQuery query, Collection<RetrievalResult> cases, FilterConfig preferences)
050        {
051            CDRSet rs = new CDRSet();
052            
053            ArrayList<CBRCase> candidates = new ArrayList<CBRCase>(SelectCases.selectAll(cases));
054            while(!candidates.isEmpty())
055            {
056                CBRCase c1 = candidates.get(0);
057                rs.add(c1);
058                rs.addToLikeSet(c1, c1);
059                rs.addToCoveredSet(c1, c1);
060                candidates.remove(0);
061                for(CBRCase c2 : candidates)
062                {
063                    Set<Attribute> compromises1 = getCompromises(c1,query,preferences);
064                    Set<Attribute> compromises2 = getCompromises(c2,query,preferences);
065                    if( compromises1.equals(compromises2))
066                        rs.addToLikeSet(c1, c2);
067                    if( compromises2.containsAll(compromises1) )
068                        rs.addToCoveredSet(c1, c2);
069                }
070                candidates.removeAll(rs.getCoveredSet(c1));
071            }
072            return rs;
073        }
074        
075        /**
076         * Returns the compromises of a case
077         * @param _case to find the compromises
078         * @param query to compare
079         * @param preferences define the predicates that evaluate the user preferences
080         * @return a set of attributes
081         */
082        public static Set<Attribute> getCompromises(CBRCase _case, CBRQuery query, FilterConfig preferences)
083        {
084            Set<Attribute> compromises = new HashSet<Attribute>();
085            
086            for(Attribute at : preferences.getDefinedAttributes())
087            {
088                try
089                {
090                    FilterPredicate predicate = preferences.getPredicate(at);
091                    Object caseObject = AttributeUtils.findValue(at, _case.getDescription());
092                    Object queryObject = AttributeUtils.findValue(at, query.getDescription());
093                    if(!predicate.compute(caseObject, queryObject))
094                    compromises.add(at);
095                } catch (NoApplicableFilterPredicateException e)
096                {
097                    org.apache.commons.logging.LogFactory.getLog(CompromiseDrivenSelection.class).error(e);
098                }
099            }
100            
101            return compromises;
102        }
103    }