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 * <SolutionMappingFile>es/ucm/fdi/gaia/jcolibri/test/test4/TravelSolution.hbm.xml</SolutionMappingFile> 082 * <SolutionClassName>es.ucm.fdi.gaia.jcolibri.test.test4.TravelSolution</SolutionClassName> 083 * </pre> 084 * <li><b>TravelSolution.hbm.xml</b><br> 085 * This is a simple mapping file for the solution bean: 086 * <pre> 087 * <hibernate-mapping default-lazy="false"> 088 * <class name="es.ucm.fdi.gaia.jcolibri.test.test4.TravelSolution" table="travel"> 089 * <id name="id" column="caseId"></id> 090 * <property name="price" column="Price"/> 091 * <property name="hotel" column="Hotel"/> 092 * </class> 093 * </hibernate-mapping> 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}