001    /**
002     * Test4.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     * 11/01/2007
008     */
009    package jcolibri.test.test4;
010    
011    
012    import java.util.Collection;
013    import java.util.HashMap;
014    
015    import jcolibri.casebase.LinealCaseBase;
016    import jcolibri.cbraplications.StandardCBRApplication;
017    import jcolibri.cbrcore.Attribute;
018    import jcolibri.cbrcore.CBRCase;
019    import jcolibri.cbrcore.CBRCaseBase;
020    import jcolibri.cbrcore.CBRQuery;
021    import jcolibri.cbrcore.Connector;
022    import jcolibri.connector.DataBaseConnector;
023    import jcolibri.exception.ExecutionException;
024    import jcolibri.method.retrieve.RetrievalResult;
025    import jcolibri.method.retrieve.NNretrieval.NNConfig;
026    import jcolibri.method.retrieve.NNretrieval.NNScoringMethod;
027    import jcolibri.method.retrieve.NNretrieval.similarity.global.Average;
028    import jcolibri.method.retrieve.NNretrieval.similarity.local.Equal;
029    import jcolibri.method.retrieve.NNretrieval.similarity.local.Interval;
030    import jcolibri.method.retrieve.selection.SelectCases;
031    import jcolibri.method.reuse.CombineQueryAndCasesMethod;
032    import jcolibri.method.reuse.NumericDirectProportionMethod;
033    
034    /**
035     * This example shows how to manage a complete case with solution and execute some adaptation methods.
036     * Now the case has also a solution bean with a few attributes. That way, the structure of the case is:
037     * <pre>
038     * Case
039     *  |
040     *  +- Description
041     *  |       |
042     *  |       +- caseId
043     *  |       +- HollidayType
044     *  |       +- Price
045     *  |       +- NumberOfPersons
046     *  |       +- Region
047     *  |       |     |
048     *  |       |     +- regionId
049     *  |       |     +- regionName
050     *  |       |     +- NearestCity
051     *  |       |     +- Airport
052     *  |       |     +- Currency
053     *  |       +- Transportation
054     *  |       +- Duration
055     *  |       +- Season
056     *  |       +- Accomodation
057     *  |       +- Hotel
058     *  |
059     *  +- Solution
060     *          |
061     *          +- id
062     *          +- price
063     *          +- hotel
064     * </pre>
065     * Solution is stored in the TravelSolution bean (CaseComponent). 
066     * This bean could be saved into a separate table, but here were are going to show how to use the same table than the description.
067     * This way, the mapping is:
068     * <ul>
069     * <li>Description is saved into the travel table.
070     * <li>Solution is also saved into the travel table (using different columns, of course).
071     * <li>Region (the compound attribute) of the description is saved into its own table region.
072     * </ul>
073     * Following picture shows how attibutes are mapped into the database:<p>
074     * <img src="mappingTest4.jpg"/>
075     * <p>
076     * To configure these mapping we must modify or create the following files:
077     * <ul>
078     * <li><b>databaseconfig.xml</b><br>
079     * In this file we include the solution class namea and its mapping file:
080     * <pre>
081     * &lt;SolutionMappingFile&gt;jcolibri/test/test4/TravelSolution.hbm.xml&lt;/SolutionMappingFile&gt;
082     * &lt;SolutionClassName&gt;jcolibri.test.test4.TravelSolution&lt;/SolutionClassName&gt;
083     * </pre>
084     * <li><b>TravelSolution.hbm.xml</b><br>
085     * This is a simple mapping file for the solution bean:
086     * <pre>
087     * &lt;hibernate-mapping default-lazy="false"&gt;
088     *   &lt;class name="jcolibri.test.test4.TravelSolution" table="travel"&gt;
089     *     &lt;id name="id" column="caseId"&gt;&lt/id&gt;
090     *     &lt;property name="price" column="Price"/&gt;
091     *     &lt;property name="hotel" column="Hotel"/&gt;    
092     *   &lt;/class&gt;
093     * &lt;/hibernate-mapping&gt;
094     * </pre>
095     * </ul>
096     * Doing these changes the connector will manage the new case structure without problems.
097     * <p>
098     * This method also shows how to perform a simple adaptation based in the DirectProportion method that
099     * modifies the value of an attribute of the solution depending on the value in the query and retrieved case of other attribute of the description.
100     * 
101     *
102     * 
103     * @author Juan A. Recio-Garcia
104     * @version 1.0
105     * 
106     * @see jcolibri.test.test4.TravelDescription
107     * @see jcolibri.test.test4.Region
108     * @see jcolibri.test.test5.TravelSolution
109     * @see jcolibri.method.reuse.NumericDirectProportionMethod
110     *
111     */
112    public class Test4 implements StandardCBRApplication {
113    
114            Connector _connector;
115            CBRCaseBase _caseBase;
116            
117            /* (non-Javadoc)
118             * @see jcolibri.cbraplications.BasicCBRApplication#configure()
119             */
120            public void configure() throws ExecutionException{
121                    try{
122                    _connector = new DataBaseConnector();
123                    _connector.initFromXMLfile(jcolibri.util.FileIO.findFile("jcolibri/test/test4/databaseconfig.xml"));
124                    _caseBase  = new LinealCaseBase();
125                    } catch (Exception e){
126                            throw new ExecutionException(e);
127                    }
128            }
129    
130            
131            /* (non-Javadoc)
132             * @see jcolibri.cbraplications.BasicCBRApplication#preCycle()
133             */
134            public CBRCaseBase preCycle() throws ExecutionException {
135                    _caseBase.init(_connector);     
136                    for(jcolibri.cbrcore.CBRCase c: _caseBase.getCases())
137                            System.out.println(c);
138                    return _caseBase;
139            }
140            
141            /* (non-Javadoc)
142             * @see jcolibri.cbraplications.BasicCBRApplication#cycle()
143             */
144            public void cycle(CBRQuery query) throws ExecutionException 
145            {               
146                    /********* NumericSim Retrieval **********/
147                    
148                    NNConfig simConfig = new NNConfig();
149                    simConfig.setDescriptionSimFunction(new Average());
150                    simConfig.addMapping(new Attribute("Accommodation", TravelDescription.class), new Equal());
151                    Attribute duration = new Attribute("Duration", TravelDescription.class);
152                    simConfig.addMapping(duration, new Interval(31));
153                    simConfig.setWeight(duration, 0.5);
154                    simConfig.addMapping(new Attribute("HolidayType", TravelDescription.class), new Equal());
155                    simConfig.addMapping(new Attribute("NumberOfPersons", TravelDescription.class), new Equal());
156                    
157                    simConfig.addMapping(new Attribute("Region",   TravelDescription.class), new Average());
158                    simConfig.addMapping(new Attribute("region",   Region.class), new Equal());
159                    simConfig.addMapping(new Attribute("city",     Region.class), new Equal());
160                    simConfig.addMapping(new Attribute("airport",  Region.class), new Equal());
161                    simConfig.addMapping(new Attribute("currency", Region.class), new Equal());
162    
163                    
164                    System.out.println("Query:");
165                    System.out.println(query);
166                    System.out.println();
167                    
168                    /********* Execute NN ************/
169                    Collection<RetrievalResult> eval = NNScoringMethod.evaluateSimilarity(_caseBase.getCases(), query, simConfig);
170                    
171                    /********* Select cases **********/
172                    Collection<CBRCase> selectedcases = SelectCases.selectTopK(eval, 1);
173                    
174                    /********* Reuse **********/
175                    // Compute a direct proportion between the "NumberOfPersons" and "Price" attributes.
176                    NumericDirectProportionMethod.directProportion( new Attribute("NumberOfPersons",TravelDescription.class), 
177                                                                                                                    new Attribute("price",TravelSolution.class), 
178                                                                                                                    query, selectedcases);
179                    // Compute a direct proportion between the "Duration" and "Price" attributes.
180                    NumericDirectProportionMethod.directProportion( new Attribute("Duration",TravelDescription.class), 
181                                                                                                                    new Attribute("price",TravelSolution.class), 
182                                                                                                                    query, selectedcases);
183                    
184                    
185                    Collection<CBRCase> newcases = CombineQueryAndCasesMethod.combine(query, selectedcases);
186                    System.out.println("Combined cases");
187                    for(jcolibri.cbrcore.CBRCase c: newcases)
188                            System.out.println(c);
189                    
190                    /********* Revise **********/
191                    CBRCase bestCase = newcases.iterator().next();
192                    
193                    HashMap<Attribute, Object> componentsKeys = new HashMap<Attribute,Object>();
194                    componentsKeys.put(new Attribute("caseId",TravelDescription.class), "test3id"); 
195                    componentsKeys.put(new Attribute("id",TravelSolution.class), "test3id");        
196                    //componentsKeys.put(new Attribute("id",Region.class), 7);      
197                    jcolibri.method.revise.DefineNewIdsMethod.defineNewIdsMethod(bestCase, componentsKeys);
198                    
199                    System.out.println("Case with new Id");
200                    System.out.println(bestCase);
201                    
202                    /********* Retain **********/
203                    
204    //               Uncomment next line to store cases into persistence
205                    //jcolibri.method.retain.StoreCasesMethod.storeCase(_caseBase, bestCase);
206            }
207    
208            /* (non-Javadoc)
209             * @see jcolibri.cbraplications.BasicCBRApplication#postCycle()
210             */
211            public void postCycle() throws ExecutionException {
212                    this._caseBase.close();
213    
214            }
215    
216            /**
217             * @param args
218             */
219            public static void main(String[] args) {
220                    // Launch DDBB manager
221                    jcolibri.test.database.HSQLDBserver.init();
222    
223                    Test4 test4 = new Test4();
224                    try {
225                            test4.configure();
226                            test4.preCycle();
227                            
228                            //BufferedReader reader  = new BufferedReader(new InputStreamReader(System.in));                        
229                            //do
230                            //{             
231                            /********* Query Definition **********/
232                            TravelDescription queryDesc = new TravelDescription();
233                            queryDesc.setAccommodation(TravelDescription.AccommodationTypes.ThreeStars);
234                            queryDesc.setDuration(10);
235                            queryDesc.setHolidayType("Recreation");
236                            queryDesc.setNumberOfPersons(4);
237                            
238                            Region region = new Region();
239                            region.setRegion("Bulgaria");
240                            region.setCity("Sofia");
241                            region.setCurrency("Euro");
242                            region.setAirport("airport");
243                            queryDesc.setRegion(region);
244                            
245                            CBRQuery query = new CBRQuery();
246                            query.setDescription(queryDesc);
247                            
248                            test4.cycle(query);
249                            
250                            
251                            //      System.out.println("Cycle finished. Type exit to idem");
252                            //}while(!reader.readLine().equals("exit"));
253                            
254                            test4.postCycle();
255                            
256                            //Shutdown DDBB manager
257                            jcolibri.test.database.HSQLDBserver.shutDown();
258    
259                    } catch (ExecutionException e) {
260                            System.out.println(e.getMessage());
261                            e.printStackTrace();
262                    } catch (Exception e) {
263                            // TODO Auto-generated catch block
264                            e.printStackTrace();
265                    }
266            }
267    
268    }