001/** 002 * Test3.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 * 10/01/2007 008 */ 009package es.ucm.fdi.gaia.jcolibri.test.test3; 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; 032 033/** 034 * This example shows how to use a compound attribute in the description of a case and how to complete the CBR cycle. 035 * <br> 036 * Now, the description has not a string defining the region. Instead that, it has other bean named "Region" that stores different attributes about the region (nearest city, airport, currency...). 037 * This way, the structure of the case is: 038 * <pre> 039 * Case 040 * | 041 * +- Description 042 * | 043 * +- caseId 044 * +- HollidayType 045 * +- Price 046 * +- NumberOfPersons 047 * +- Region 048 * | | 049 * | +- regionId 050 * | +- regionName 051 * | +- NearestCity 052 * | +- Airport 053 * | +- Currency 054 * +- Transportation 055 * +- Duration 056 * +- Season 057 * +- Accomodation 058 * +- Hotel 059 * </pre> 060 * <br> 061 * This structure is mapped to the travelext data base that can be created using the travelext.sql file. 062 * It is composed by two tables: travel and region. Travel has a number in the regionid column identifying the row in the region table that contains the information: 063 * <pre> 064 * travel: 065 * +-----------+-------------+-------+-----------------+----------+----------------+----------+-----------+---------------+-----------------------------+ 066 * | caseId | HolidayType | Price | NumberOfPersons | regionId | Transportation | Duration | Season | Accommodation | Hotel | 067 * +-----------+-------------+-------+-----------------+----------+----------------+----------+-----------+---------------+-----------------------------+ 068 * | Journey11 | City | 1978 | 2 | 1 | Plane | 7 | April | ThreeStars | Hotel Victoria, Cairo | 069 * | Journey21 | Recreation | 1568 | 2 | 2 | Car | 14 | May | TwoStars | Hotel Ostend, Belgium | 070 * ... 071 * region: 072 * +----------+------------+-------------+---------------------------+----------------+ 073 * | regionId | RegionName | NearestCity | Airport | Currency | 074 * +----------+------------+-------------+---------------------------+----------------+ 075 * | 1 | Cairo | Cairo | Cairo Airport | Egyptian Pound | 076 * | 2 | Belgium | Brussels | Brussels National Airport | Euro | 077 * ... 078 * </pre> 079 * To map the case structure with the data base we have to modify these lines in hibernate.cfg.xml: 080 * <pre> 081 * <hibernate-mapping default-lazy="false"> 082 * <class name="es.ucm.fdi.gaia.jcolibri.test.test3.TravelDescription" table="travel"> 083 * ... 084 * <many-to-one name="Region" column="regionId" not-null="true" cascade="save-update"/> 085 * ... 086 * </class> 087 * <class name="es.ucm.fdi.gaia.jcolibri.test.test3.Region" table="region"> 088 * <id name="id" column="regionId"> 089 * </id> 090 * <property name="region" column="RegionName"/> 091 * <property name="city" column="NearestCity"/> 092 * <property name="airport" column="Airport"/> 093 * <property name="currency" column="Currency"/> 094 * </class> 095 * </hibernate-mapping> 096 * </pre> 097 * The many-to-one tag indicates the association between the regionId column in the travel table with the values of the region table. 098 * <p> 099 * This example also shows how to complete the CBR cycle including reuse, revise and retain methods: 100 * <ul> 101 * <li>Reuse. To reuse a case we have to combine its solution with the description of the query. 102 * It is done by the method: CombineQueryAndCasesMethod.combine() 103 * <li>Revise. A simple revision consists on defining new values for the ids of the compound attributes to save the new case into the persistence layer. 104 * It is done by: DefineNewIdsMethod.defineNewIdsMethod() 105 * <li>Retain. Consists on saving a new case into the persistence layer. This is performed by: StoreCasesMethod.storeCase() 106 * </ul> 107 * 108 * @author Juan A. Recio-Garcia 109 * @version 1.0 110 * @see es.ucm.fdi.gaia.jcolibri.test.test3.TravelDescription 111 * @see es.ucm.fdi.gaia.jcolibri.test.test3.Region 112 * @see jcolibri.method.reuse.CombineQueryAndCasesMethod 113 * @see jcolibri.method.revise.DefineNewIdsMethod 114 * @see jcolibri.method.retain.StoreCasesMethod 115 * 116 */ 117public class Test3 implements StandardCBRApplication { 118 119 Connector _connector; 120 CBRCaseBase _caseBase; 121 122 /* (non-Javadoc) 123 * @see jcolibri.cbraplications.BasicCBRApplication#configure() 124 */ 125 public void configure() throws ExecutionException{ 126 try{ 127 _connector = new DataBaseConnector(); 128 _connector.initFromXMLfile(es.ucm.fdi.gaia.jcolibri.util.FileIO.findFile("es/ucm/fdi/gaia/jcolibri/test/test3/databaseconfig.xml")); 129 _caseBase = new LinealCaseBase(); 130 } catch (Exception e){ 131 throw new ExecutionException(e); 132 } 133 } 134 135 136 /* (non-Javadoc) 137 * @see jcolibri.cbraplications.BasicCBRApplication#preCycle() 138 */ 139 public CBRCaseBase preCycle() throws ExecutionException { 140 _caseBase.init(_connector); 141 for(es.ucm.fdi.gaia.jcolibri.cbrcore.CBRCase c: _caseBase.getCases()) 142 System.out.println(c); 143 return _caseBase; 144 } 145 146 /* (non-Javadoc) 147 * @see jcolibri.cbraplications.BasicCBRApplication#cycle() 148 */ 149 public void cycle(CBRQuery query) throws ExecutionException 150 { 151 /********* NumericSim Retrieval **********/ 152 153 NNConfig simConfig = new NNConfig(); 154 simConfig.setDescriptionSimFunction(new Average()); 155 simConfig.addMapping(new Attribute("Accommodation", TravelDescription.class), new Equal()); 156 Attribute duration = new Attribute("Duration", TravelDescription.class); 157 simConfig.addMapping(duration, new Interval(31)); 158 simConfig.setWeight(duration, 0.5); 159 simConfig.addMapping(new Attribute("HolidayType", TravelDescription.class), new Equal()); 160 simConfig.addMapping(new Attribute("NumberOfPersons", TravelDescription.class), new Equal()); 161 simConfig.addMapping(new Attribute("Price", TravelDescription.class), new Interval(4000)); 162 163 simConfig.addMapping(new Attribute("Region", TravelDescription.class), new Average()); 164 simConfig.addMapping(new Attribute("region", Region.class), new Equal()); 165 simConfig.addMapping(new Attribute("city", Region.class), new Equal()); 166 simConfig.addMapping(new Attribute("airport", Region.class), new Equal()); 167 simConfig.addMapping(new Attribute("currency", Region.class), new Equal()); 168 169 170 System.out.println("Query:"); 171 System.out.println(query); 172 System.out.println(); 173 174 175 /********* Execute NN ************/ 176 Collection<RetrievalResult> eval = NNScoringMethod.evaluateSimilarity(_caseBase.getCases(), query, simConfig); 177 178 /********* Select cases **********/ 179 Collection<CBRCase> selectedcases = SelectCases.selectTopK(eval, 1); 180 181 /********* Reuse **********/ 182 183 //Combine query description with cases solutions, obtaining a list of new cases. 184 Collection<CBRCase> newcases = CombineQueryAndCasesMethod.combine(query, selectedcases); 185 System.out.println("Combined cases"); 186 for(es.ucm.fdi.gaia.jcolibri.cbrcore.CBRCase c: newcases) 187 System.out.println(c); 188 189 /********* Revise **********/ 190 // Lets store only the best case 191 CBRCase bestCase = newcases.iterator().next(); 192 193 // Define new ids for the compound attributes 194 HashMap<Attribute, Object> componentsKeys = new HashMap<Attribute,Object>(); 195 componentsKeys.put(new Attribute("caseId",TravelDescription.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("Cases 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 Test3 test3 = new Test3(); 224 try { 225 test3.configure(); 226 test3.preCycle(); 227 228 //BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 229 //do 230 //{ 231 232 /********* Query Definition **********/ 233 TravelDescription queryDesc = new TravelDescription(); 234 queryDesc.setAccommodation(TravelDescription.AccommodationTypes.ThreeStars); 235 queryDesc.setDuration(7); 236 queryDesc.setHolidayType("Recreation"); 237 queryDesc.setNumberOfPersons(2); 238 queryDesc.setPrice(700); 239 240 Region region = new Region(); 241 region.setRegion("Bulgaria"); 242 region.setCity("Sofia"); 243 region.setCurrency("Euro"); 244 region.setAirport("airport"); 245 queryDesc.setRegion(region); 246 247 CBRQuery query = new CBRQuery(); 248 query.setDescription(queryDesc); 249 250 test3.cycle(query); 251 252 // System.out.println("Cycle finished. Type exit to idem"); 253 //}while(!reader.readLine().equals("exit")); 254 255 test3.postCycle(); 256 257 //Shutdown DDBB manager 258 es.ucm.fdi.gaia.jcolibri.test.database.HSQLDBserver.shutDown(); 259 260 } catch (ExecutionException e) { 261 System.out.println(e.getMessage()); 262 e.printStackTrace(); 263 } catch (Exception e) { 264 // TODO Auto-generated catch block 265 e.printStackTrace(); 266 } 267 } 268 269}