001    package jcolibri.method.maintenance;
002    
003    import java.util.Collection;
004    import java.util.HashMap;
005    import java.util.LinkedList;
006    import java.util.List;
007    
008    import jcolibri.cbrcore.CBRCase;
009    import jcolibri.method.retrieve.KNNretrieval.KNNConfig;
010    
011    /**
012     * Implements the RC Maintenance Algorithm to remove 
013     * redundancy from the case base 
014     * 
015     * @author Lisa Cummins
016     */
017    public class RCAlgorithm extends MaintenanceAlgorithm {
018            
019            /**
020             * Runs the RC maintenance algorithm, returning the cases
021             * deleted by the algorithm
022             * @param cases The group of cases on which to perform maintenance
023             * @param simConfig The KNNConfig for these cases
024             * @return the list of cases deleted by the algorithm
025             */
026            public LinkedList<CBRCase> runMaintenance(Collection<CBRCase> cases, KNNConfig simConfig) 
027            {       /* 
028                     * RC Algorithm:
029                     *      
030                     * T: Original training cases
031                     * CM: Competence Model
032                     * 
033                     * Edit(T,CM,RC):
034                     * 
035                     * R-Set = RENN(T) {that is, repeated ENN} 
036                     * (Not included here, RENN performed seperately)
037                     * E-Set = {}
038                     * While R-Set is not empty
039                     *              c = Next case in R-Set according to RC
040                     *              E-Set = E-Set U {c}
041                     *              R-Set = R-Set – CoverageSet(c)
042                     *              Update(CM)
043                     * EndWhile
044                     * 
045                     * Return (E-Set)
046                     */
047                    
048                    List<CBRCase> localCases = new LinkedList<CBRCase>();
049                    for(CBRCase c: cases)
050                    {       localCases.add(c);
051                    }
052                            
053                    SetCalculator sc = new SetCalculator();
054                    HashMap<String, HashMap<CBRCase, LinkedList<CBRCase>>> sets = null;
055                    HashMap<CBRCase, LinkedList<CBRCase>> coverageSets = null, reachabilitySets = null;
056            
057                    LinkedList<CBRCase> keepCases = new LinkedList<CBRCase>();
058                    
059                    //RC(c) = Sum_c' E CoverageSet(C) (1/|ReachabilitySet(c')|)
060                    while(localCases.size() > 0)
061                    {       double topRCScore = 0.0;
062                            CBRCase topRCCase = null;
063    
064                            sets = sc.calculateCRRSets(localCases, simConfig);
065                            coverageSets = sets.get(SetCalculator.COVERAGE_SET);
066                            reachabilitySets = sets.get(SetCalculator.REACHABILITY_SET);
067    
068                            for(CBRCase c: localCases)
069                            {       double rcScore = 0.0;
070                                    LinkedList<CBRCase> cCov = coverageSets.get(c);
071                                    for(CBRCase c1: cCov)
072                                    {       LinkedList<CBRCase> c1Reach = reachabilitySets.get(c1);
073                                            rcScore += (1/(double)c1Reach.size());
074                                    }
075                                    if(rcScore > topRCScore)
076                                    {       topRCScore = rcScore;
077                                            topRCCase = c;
078                                    }
079                            }
080                            
081                            LinkedList<CBRCase> rSet = reachabilitySets.get(topRCCase);
082                            LinkedList<CBRCase> toRemove = new LinkedList<CBRCase>();
083                            for(CBRCase r: rSet)
084                            {       toRemove.add(r);
085                            }
086                            keepCases.add(topRCCase);
087                            localCases.removeAll(toRemove);
088                    }
089                    
090                    //Add all cases that are not being kept to the list of deleted cases
091                    LinkedList<CBRCase> allCasesToBeRemoved = new LinkedList<CBRCase>();
092                    for(CBRCase c: cases)
093                    {       if(!keepCases.contains(c))
094                                    allCasesToBeRemoved.add(c);
095                    }
096    
097                    return allCasesToBeRemoved;
098            }
099    }