001    package jcolibri.method.maintenance.algorithms;
002    
003    import java.util.Collection;
004    import java.util.LinkedList;
005    import java.util.List;
006    import java.util.Map;
007    
008    import jcolibri.cbrcore.CBRCase;
009    import jcolibri.method.maintenance.AbstractCaseBaseEditMethod;
010    import jcolibri.method.maintenance.CompetenceModel;
011    import jcolibri.method.maintenance.solvesFunctions.ICFSolvesFunction;
012    import jcolibri.method.reuse.classification.KNNClassificationConfig;
013    
014    /**
015     * Provides the ability to run the ICF case base editing algorithm 
016     * on a case base to eliminate redundancy.
017     * 
018     * @author Lisa Cummins
019     * @author Derek Bridge
020     * 18/05/07
021     */
022    public class ICFRedundancyRemoval extends AbstractCaseBaseEditMethod {
023            
024            /**
025             * Simulates the ICF case base editing algorithm, returning the cases
026             * that would be deleted by the algorithm.
027             * @param cases The group of cases on which to perform editing.
028             * @param simConfig The similarity configuration for these cases.
029             * @return the list of cases that would be deleted by the 
030             * ICF algorithm.
031             */
032            public Collection<CBRCase> retrieveCasesToDelete(Collection<CBRCase> cases, KNNClassificationConfig simConfig)
033            {       /* ICF Algorithm:
034                     * T: Training Set
035                     * 
036                     * Run RENN on T
037                     * (Not included here, RENN performed seperately)
038                     *
039                     * Repeat
040                     *              For all x E T do
041                     *                      compute reachable(x)
042                     *                      compute coverage(x)
043                     *              End-For
044                     *              progress = false
045                     *              For all x E T do
046                     *                      If |reachable(x)| > |coverage(x)| then
047                     *                              flag x for removal
048                     *                              process = true
049                     *                      End-If
050                     *              End-For
051                     *              For all x E T do        
052                     *                      If x flagged for removal then
053                     *                              T = T - {x}
054                     *                      End-If
055                     *              End-For
056                     * Until not progress
057                     * 
058                     * Return T
059                     */
060                    jcolibri.util.ProgressController.init(this.getClass(),"ICF Redundancy Removal",jcolibri.util.ProgressController.UNKNOWN_STEPS);
061                    List<CBRCase> localCases = new LinkedList<CBRCase>();
062                    for(CBRCase c: cases)
063                    {       localCases.add(c);
064                    }
065    
066                    CompetenceModel sc = new CompetenceModel();
067                    Map<CBRCase, Collection<CBRCase>> coverageSets = null, reachabilitySets = null;
068                    List<CBRCase> allCasesToBeRemoved = new LinkedList<CBRCase>();
069            
070                    boolean changes = true;
071                    while(changes)
072                    {       changes = false;
073                            List<CBRCase> casesToBeRemoved = new LinkedList<CBRCase>();
074                            
075                            sc.computeCompetenceModel(new ICFSolvesFunction(), simConfig, localCases);
076                            coverageSets = sc.getCoverageSets();
077                            reachabilitySets = sc.getReachabilitySets();
078            
079                            for(CBRCase c: localCases)
080                            {       Collection<CBRCase> coverageSet = coverageSets.get(c);
081                                    Collection<CBRCase> reachabilitySet = reachabilitySets.get(c);
082                                    if(reachabilitySet.size() > coverageSet.size())
083                                    {       casesToBeRemoved.add(c);
084                                            changes = true;
085                                    }
086                            }
087            
088                            allCasesToBeRemoved.addAll(casesToBeRemoved);
089                            localCases.removeAll(casesToBeRemoved);
090                            jcolibri.util.ProgressController.step(this.getClass());
091                    }
092                    jcolibri.util.ProgressController.finish(this.getClass());
093                    return allCasesToBeRemoved;
094            }       
095    }