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 */
009package es.ucm.fdi.gaia.jcolibri.test.test4;
010
011
012import java.util.Collection;
013import java.util.HashMap;
014
015import es.ucm.fdi.gaia.jcolibri.casebase.LinealCaseBase;
016import es.ucm.fdi.gaia.jcolibri.cbraplications.StandardCBRApplication;
017import es.ucm.fdi.gaia.jcolibri.cbrcore.Attribute;
018import es.ucm.fdi.gaia.jcolibri.cbrcore.CBRCase;
019import es.ucm.fdi.gaia.jcolibri.cbrcore.CBRCaseBase;
020import es.ucm.fdi.gaia.jcolibri.cbrcore.CBRQuery;
021import es.ucm.fdi.gaia.jcolibri.cbrcore.Connector;
022import es.ucm.fdi.gaia.jcolibri.connector.DataBaseConnector;
023import es.ucm.fdi.gaia.jcolibri.exception.ExecutionException;
024import es.ucm.fdi.gaia.jcolibri.method.retrieve.RetrievalResult;
025import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.NNConfig;
026import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.NNScoringMethod;
027import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.similarity.global.Average;
028import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.similarity.local.Equal;
029import es.ucm.fdi.gaia.jcolibri.method.retrieve.NNretrieval.similarity.local.Interval;
030import es.ucm.fdi.gaia.jcolibri.method.retrieve.selection.SelectCases;
031import es.ucm.fdi.gaia.jcolibri.method.reuse.CombineQueryAndCasesMethod;
032import es.ucm.fdi.gaia.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;es/ucm/fdi/gaia/jcolibri/test/test4/TravelSolution.hbm.xml&lt;/SolutionMappingFile&gt;
082 * &lt;SolutionClassName&gt;es.ucm.fdi.gaia.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="es.ucm.fdi.gaia.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 es.ucm.fdi.gaia.jcolibri.test.test4.TravelDescription
107 * @see es.ucm.fdi.gaia.jcolibri.test.test4.Region
108 * @see es.ucm.fdi.gaia.jcolibri.test.test5.TravelSolution
109 * @see jcolibri.method.reuse.NumericDirectProportionMethod
110 *
111 */
112public 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(es.ucm.fdi.gaia.jcolibri.util.FileIO.findFile("es/ucm/fdi/gaia/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(es.ucm.fdi.gaia.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(es.ucm.fdi.gaia.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                es.ucm.fdi.gaia.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                es.ucm.fdi.gaia.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                        es.ucm.fdi.gaia.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}