001    package jcolibri.method.maintenance.algorithms;
002    
003    import java.util.Collection;
004    import java.util.LinkedList;
005    import java.util.List;
006    
007    import jcolibri.cbrcore.CBRCase;
008    import jcolibri.exception.InitializingException;
009    import jcolibri.method.maintenance.AbstractCaseBaseEditMethod;
010    import jcolibri.method.maintenance.CompetenceModel;
011    import jcolibri.method.maintenance.solvesFunctions.CBESolvesFunction;
012    import jcolibri.method.reuse.classification.KNNClassificationConfig;
013    
014    import org.apache.commons.logging.LogFactory;
015    
016    /**
017     * Provides the ability to run the RC case base editing algorithm 
018     * on a case base to eliminate redundancy.
019     * 
020     * @author Lisa Cummins
021     * @author Derek Bridge
022     * 18/05/07
023     */
024    public class RCRedundancyRemoval extends AbstractCaseBaseEditMethod {
025            
026            /**
027             * Simulates the RC case base editing algorithm, returning the cases
028             * that would be deleted by the algorithm.
029             * @param cases The group of cases on which to perform editing.
030             * @param simConfig The similarity configuration for these cases.
031             * @return the list of cases that would be deleted by the 
032             * RC algorithm.
033             */
034            public Collection<CBRCase> retrieveCasesToDelete(Collection<CBRCase> cases, KNNClassificationConfig simConfig) 
035            {       /* 
036                     * RC Algorithm:
037                     *      
038                     * T: Original training cases
039                     * CM: Competence Model
040                     * RC(c): Sum_c' E CoverageSet(C) (1/|ReachabilitySet(c')|)
041                     * 
042                     * Edit(T,CM,RC):
043                     * 
044                     * R-Set = RENN(T) {that is, repeated ENN}
045                     * (Not included here, RENN performed separately)
046                     * E-Set = {}
047                     * While R-Set is not empty
048                     *              c = Next case in R-Set according to RC
049                     *              E-Set = E-Set U {c}
050                     *              R-Set = R-Set – CoverageSet(c)
051                     *              Update(CM)
052                     * EndWhile
053                     * 
054                     * Return (E-Set)
055                     */
056                    jcolibri.util.ProgressController.init(this.getClass(),"RC Redundancy Removal",jcolibri.util.ProgressController.UNKNOWN_STEPS);
057                    List<CBRCase> localCases = new LinkedList<CBRCase>();
058                    for(CBRCase c: cases)
059                    {       localCases.add(c);
060                    }
061                            
062                    CompetenceModel sc = new CompetenceModel();
063                    
064                    LinkedList<CBRCase> keepCases = new LinkedList<CBRCase>();
065                    
066                    while(localCases.size() > 0)
067                    {       double topRCScore = 0.0;
068                            CBRCase topRCCase = null;
069    
070                            sc.computeCompetenceModel(new CBESolvesFunction(), simConfig, localCases);
071                            
072                            try
073                            {   for(CBRCase c: localCases)
074                                {   double rcScore = 0.0;
075                                    Collection<CBRCase> cCov = sc.getCoverageSet(c);
076                                    for(CBRCase c1: cCov)
077                                    {       rcScore += (1/(double)sc.getReachabilitySet(c1).size());
078                                    }
079                                    if(rcScore > topRCScore)
080                                    {       topRCScore = rcScore;
081                                            topRCCase = c;
082                                    }
083                                }
084                                
085                                keepCases.add(topRCCase);
086                                
087                                Collection<CBRCase> cSet = sc.getCoverageSet(topRCCase);
088                                List<CBRCase> toRemove = new LinkedList<CBRCase>();
089                                for(CBRCase c: cSet)
090                                {   toRemove.add(c);
091                                }
092                                localCases.removeAll(toRemove);
093                            } catch (InitializingException e)
094                            {   LogFactory.getLog(this.getClass()).error(e);
095                            }
096                            jcolibri.util.ProgressController.step(this.getClass());
097                    }
098                    
099                    //Add all cases that are not being kept to the list of deleted cases
100                    List<CBRCase> allCasesToBeRemoved = new LinkedList<CBRCase>();
101                    for(CBRCase c: cases)
102                    {       if(!keepCases.contains(c))
103                                    allCasesToBeRemoved.add(c);
104                    }
105                    jcolibri.util.ProgressController.finish(this.getClass());
106                    return allCasesToBeRemoved;
107            }
108    }