001    /**
002     * Travel1.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     * 23/10/2007
008     */
009    package jcolibri.test.recommenders.rec1;
010    
011    import java.util.ArrayList;
012    import java.util.Collection;
013    
014    import jcolibri.casebase.LinealCaseBase;
015    import jcolibri.cbraplications.StandardCBRApplication;
016    import jcolibri.cbrcore.Attribute;
017    import jcolibri.cbrcore.CBRCase;
018    import jcolibri.cbrcore.CBRCaseBase;
019    import jcolibri.cbrcore.CBRQuery;
020    import jcolibri.cbrcore.Connector;
021    import jcolibri.connector.DataBaseConnector;
022    import jcolibri.datatypes.Instance;
023    import jcolibri.exception.ExecutionException;
024    import jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod;
025    import jcolibri.extensions.recommendation.casesDisplay.UserChoice;
026    import jcolibri.extensions.recommendation.conditionals.BuyOrQuit;
027    import jcolibri.method.gui.formFilling.ObtainQueryWithFormMethod;
028    import jcolibri.method.retrieve.RetrievalResult;
029    import jcolibri.method.retrieve.NNretrieval.NNConfig;
030    import jcolibri.method.retrieve.NNretrieval.NNScoringMethod;
031    import jcolibri.method.retrieve.NNretrieval.similarity.global.Average;
032    import jcolibri.method.retrieve.NNretrieval.similarity.local.EnumCyclicDistance;
033    import jcolibri.method.retrieve.NNretrieval.similarity.local.Equal;
034    import jcolibri.method.retrieve.NNretrieval.similarity.local.Interval;
035    import jcolibri.method.retrieve.NNretrieval.similarity.local.Threshold;
036    import jcolibri.method.retrieve.NNretrieval.similarity.local.ontology.OntCosine;
037    import jcolibri.method.retrieve.NNretrieval.similarity.local.recommenders.InrecaLessIsBetter;
038    import jcolibri.method.retrieve.NNretrieval.similarity.local.recommenders.McSherryMoreIsBetter;
039    import jcolibri.method.retrieve.selection.SelectCases;
040    import jcolibri.test.recommenders.travelData.TravelDescription;
041    import jcolibri.test.recommenders.travelData.TravelDescription.AccommodationTypes;
042    import jcolibri.test.recommenders.travelData.TravelDescription.Seasons;
043    import jcolibri.util.FileIO;
044    import es.ucm.fdi.gaia.ontobridge.OntoBridge;
045    import es.ucm.fdi.gaia.ontobridge.OntologyDocument;
046    
047    /**
048     * Simple Single-Shot flats recommender using form-filling, Nearest Neighbour retrieval and top k selection .
049     * <br>
050     * This recommender allows user to define his/her requirements using a form. 
051     * Then, it retrieves the k most similar cases using Nearest Neighbour retrieval.
052     * These k cases are displayed to the user in a table and the system finishes.
053     * <br>Summary:
054     * <ul>
055     * <li>Type: Single-Shot
056     * <li>Case base: travel
057     * <li>One off Preference Elicitation: Form Filling with initial values
058     * <li>Retrieval:  NN + topKselection
059     * <li>Display: In table
060     * </ul>
061     * This recommender implements the following template:<br>
062     * <center><img src="../Template1_Cycle.jpg"/></center>
063     * 
064     * <br>Read the documentation of the recommenders extension for details about templates
065     * and recommender strategies: {@link jcolibri.extensions.recommendation}
066     * 
067     * @see jcolibri.method.gui.formFilling.ObtainQueryWithFormMethod
068     * @see jcolibri.method.retrieve.NNretrieval.NNScoringMethod
069     * @see jcolibri.method.retrieve.selection.SelectCases
070     * @see jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod
071     * 
072     * @author Juan A. Recio-Garcia
073     * @author Developed at University College Cork (Ireland) in collaboration with Derek Bridge.
074     * @version 1.0
075     *
076     */
077    public class Travel1 implements StandardCBRApplication
078    {
079        /** Connector object */
080        Connector _connector;
081        /** CaseBase object */
082        CBRCaseBase _caseBase;
083    
084        NNConfig simConfig;
085        
086        public void configure() throws ExecutionException
087        {
088            //Emulate data base server
089            jcolibri.test.database.HSQLDBserver.init();
090            
091            // Create a data base connector
092            _connector = new DataBaseConnector();
093            // Init the ddbb connector with the config file
094            _connector.initFromXMLfile(jcolibri.util.FileIO
095                            .findFile("jcolibri/test/recommenders/travelData/databaseconfig.xml"));
096            // Create a Lineal case base for in-memory organization
097            _caseBase = new LinealCaseBase();
098            
099            // Obtain a reference to OntoBridge
100            OntoBridge ob = jcolibri.util.OntoBridgeSingleton.getOntoBridge();
101            // Configure it to work with the Pellet reasoner
102            ob.initWithPelletReasoner();
103            // Setup the main ontology
104            OntologyDocument mainOnto = new OntologyDocument("http://gaia.fdi.ucm.es/ontologies/travel-destinations.owl", 
105                                                             FileIO.findFile("jcolibri/test/recommenders/travelData/travel-destinations.owl").toExternalForm());
106            // There are not subontologies
107            ArrayList<OntologyDocument> subOntologies = new ArrayList<OntologyDocument>();
108            // Load the ontology
109            ob.loadOntology(mainOnto, subOntologies, false);
110            
111            
112            // Now configure the KNN
113            simConfig = new NNConfig();
114            // Set the average() global similarity function for the description of the case
115            simConfig.setDescriptionSimFunction(new Average());
116            // HolidayType --> equal()
117            simConfig.addMapping(new Attribute("HolidayType", TravelDescription.class), new Equal());
118            // NumberOfPersons --> Threshold(2)
119            simConfig.addMapping(new Attribute("NumberOfPersons", TravelDescription.class), new Threshold(2));
120            // Region --> ontCosine()
121            simConfig.addMapping(new Attribute("Region", TravelDescription.class), new OntCosine());
122            // Transportation --> equal()
123            simConfig.addMapping(new Attribute("Transportation", TravelDescription.class), new Equal());
124            // Duration --> interval(31)
125            simConfig.addMapping(new Attribute("Duration", TravelDescription.class), new Interval(31));
126            // Season --> EnumCyclicDistance
127            simConfig.addMapping(new Attribute("Season", TravelDescription.class), new EnumCyclicDistance());
128            // Accomodation --> McSherryMoreIsBetter
129            simConfig.addMapping(new Attribute("Accommodation", TravelDescription.class), new McSherryMoreIsBetter(0,0));
130            // Price --> InrecaLessIsBetter(4000)
131            simConfig.addMapping(new Attribute("Price", TravelDescription.class), new InrecaLessIsBetter(4000, 0.5));
132            
133            
134    
135        }
136    
137        public void cycle(CBRQuery query) throws ExecutionException
138        {
139            //Obtain query
140            ObtainQueryWithFormMethod.obtainQueryWithInitialValues(query,null,null);
141            
142            // Execute KNN
143            Collection<RetrievalResult> eval = NNScoringMethod.evaluateSimilarity(_caseBase.getCases(), query, simConfig);
144            
145            // Select cases
146            Collection<CBRCase> retrievedCases = SelectCases.selectTopK(eval, 5);
147            
148            // Display cases
149            UserChoice choice = DisplayCasesTableMethod.displayCasesInTableBasic(retrievedCases);
150    
151            // Buy or Quit?
152            if(BuyOrQuit.buyOrQuit(choice))
153                System.out.println("Finish - User Buys: "+choice.getSelectedCase());
154            
155            else
156                System.out.println("Finish - User Quits");
157    
158        }
159    
160        public void postCycle() throws ExecutionException
161        {
162        }
163    
164        public CBRCaseBase preCycle() throws ExecutionException
165        {
166            // Load cases from connector into the case base
167            _caseBase.init(_connector);             
168            // Print the cases
169            java.util.Collection<CBRCase> cases = _caseBase.getCases();
170            for(CBRCase c: cases)
171                    System.out.println(c);
172            return _caseBase;
173        }
174        
175        public static void main(String[] args) {
176            StandardCBRApplication recommender = new Travel1();
177            try
178            {
179                recommender.configure();
180                
181                recommender.preCycle();
182                
183                CBRQuery query = new CBRQuery();
184                
185                TravelDescription td = new TravelDescription();
186                td.setAccommodation(AccommodationTypes.ThreeStars);
187                td.setDuration(7);
188                td.setHolidayType("bathing");
189                td.setNumberOfPersons(2);
190                td.setRegion(new Instance("Spain"));
191                td.setSeason(Seasons.July);
192                td.setTransportation("plane");
193                td.setPrice(1000);
194    
195                query.setDescription(td);
196                
197                recommender.cycle(query);
198                
199                recommender.postCycle();
200                
201                System.exit(0);
202            } catch (Exception e)
203            {
204                org.apache.commons.logging.LogFactory.getLog(Travel1.class).error(e);
205                
206            }
207            
208    
209        }
210    
211    }