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 ICF Maintenance Algorithm to remove 
013     * redundancy from the case base 
014     * 
015     * @author Lisa Cummins
016     */
017    public class ICFAlgorithm extends MaintenanceAlgorithm {
018            
019            /**
020             * Runs the ICF 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 NumericSimConfig 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            {       /* ICF Algorithm:
028                     * T: Training Set
029                     * 
030                     * Run RENN on T
031                     * (Not included here, RENN performed seperately)
032                     *
033                     * Repeat
034                     *              For all x E T do
035                     *                      compute reachable(x)
036                     *                      compute coverage(x)
037                     *              End-For
038                     *              progress = false
039                     *              For all x E T do
040                     *                      If |reachable(x)| > |coverage(x)| then
041                     *                              flag x for removal
042                     *                              process = true
043                     *                      End-If
044                     *              End-For
045                     *              For all x E T do        
046                     *                      If x flagged for removal then
047                     *                              T = T - {x}
048                     *                      End-If
049                     *              End-For
050                     * Until not progress
051                     * 
052                     * Return T
053                     */
054                    LinkedList<CBRCase> localCases = new LinkedList<CBRCase>();
055                    for(CBRCase c: cases)
056                    {       localCases.add(c);
057                    }
058    
059                    SetCalculator sc = new SetCalculator();
060                    HashMap<String, HashMap<CBRCase, LinkedList<CBRCase>>> sets = null;
061                    HashMap<CBRCase, LinkedList<CBRCase>> coverageSets = null, reachabilitySets = null;
062                    LinkedList<CBRCase> allCasesToBeRemoved = new LinkedList<CBRCase>();
063            
064                    boolean changes = true;
065                    while(changes)
066                    {       changes = false;
067                            List<CBRCase> casesToBeRemoved = new LinkedList<CBRCase>();
068                            
069                            sets = sc.calculateICFSets(localCases, simConfig);
070                            coverageSets = sets.get(SetCalculator.COVERAGE_SET);
071                            reachabilitySets = sets.get(SetCalculator.REACHABILITY_SET);
072            
073                            for(CBRCase c: localCases)
074                            {       LinkedList<CBRCase> coverageSet = coverageSets.get(c);
075                                    LinkedList<CBRCase> reachabilitySet = reachabilitySets.get(c);
076                                    
077                                    if(reachabilitySet.size() > coverageSet.size())
078                                    {       casesToBeRemoved.add(c);
079                                            changes = true;
080                                    }
081                            }
082            
083                            allCasesToBeRemoved.addAll(casesToBeRemoved);
084                            localCases.removeAll(casesToBeRemoved);
085                    }
086            
087                    return allCasesToBeRemoved;
088            }       
089    }