/**
* Copyright (c) 2011, SOCIETIES Consortium
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.societies.personalisation.CRISTUserIntentDiscovery.impl;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.societies.personalisation.CRIST.api.CRISTUserIntentDiscovery.ICRISTUserIntentDiscovery;
import org.societies.personalisation.CRIST.api.model.CRISTUserAction;
public class CRISTUserIntentDiscovery implements ICRISTUserIntentDiscovery {
private static final Logger LOG = LoggerFactory.getLogger(CRISTUserIntentDiscovery.class);
public static final int MAX_PREDICTION_STEP = 1;
private LinkedHashMap<String, Integer> intentModel = new LinkedHashMap<String, Integer>();
public CRISTUserIntentDiscovery(){
LOG.info("Hello! I'm the CRIST User Intent Discovery!");
}
public void initialiseCRISTDiscovery() {
LOG.info("Yo!! I'm a brand new service and my interface is: "
+ this.getClass().getName());
//registerForContextChanges();
}
/*
* (non-Javadoc)
*
* @see org.societies.personalisation.CRIST.api.CRISTUserIntentDiscovery.
* ICRISTUserIntentDiscovery#enableCRISTUIDiscovery(boolean)
*/
@Override
public void enableCRISTUIDiscovery(boolean bool) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see org.societies.personalisation.CRIST.api.CRISTUserIntentDiscovery.
* ICRISTUserIntentDiscovery#generateNewCRISTUIModel()
*/
@SuppressWarnings("rawtypes")
@Override
public LinkedHashMap generateNewCRISTUIModel() {
// TODO Auto-generated method stub
// get context from broker?
return intentModel;
}
/*
* (non-Javadoc)
* update intentModel at the same time.
* @see org.societies.personalisation.CRIST.api.CRISTUserIntentDiscovery.
* ICRISTUserIntentDiscovery#generateNewCRISTUIModel(java.util.ArrayList)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public LinkedHashMap generateNewCRISTUIModel(ArrayList historyData) {
// here we learn from the whole history, so create new intentModel.
// further we can learn incrementally.
intentModel = new LinkedHashMap<String, Integer>();
// TODO Auto-generated method stub
//ensure not return null
ArrayList<CRISTHistoryData> historyList = historyData;
int historySize = historyList.size();
ArrayList<String> behaviorRecords_unique = new ArrayList<String>();
ArrayList<String> behaviorRecords = new ArrayList<String>();
// TODO
// Construct User Intent Model based on one's history data
// By mining user behavior patterns
// Identify all the possible user behaviors
String lastActionID = "STARTING_ACTION";
for (int i = 0; i < historySize; i++) {
CRISTHistoryData currentHisData = historyList.get(i);
String currentHisSituation = currentHisData.getSituation().getSituationID();
String currentBehavior = lastActionID + "@"
+ currentHisSituation;
behaviorRecords.add(currentBehavior);
if (!behaviorRecords_unique.contains(currentBehavior)) {
behaviorRecords_unique.add(currentBehavior);
}
lastActionID = ((CRISTUserAction)currentHisData.getAction()).getActionID();
}
// Identify patterns
int behaviorNum = behaviorRecords_unique.size();
for (int i = 0; i < behaviorNum; i++) {
int[] indexList = getAllOccurences(behaviorRecords,
behaviorRecords_unique.get(i));
ArrayList<String> cadidateActionList = new ArrayList<String>();
for (int j = 0; j < indexList.length; j++) {
String currentCadidate = "";
for (int k = 0; k < MAX_PREDICTION_STEP; k++) {
int currentIndex = indexList[j] + k;
if (currentIndex >= historyList.size()) {
break;
}
String situationID = historyList.get(currentIndex).getSituation().getSituationID();
if (situationID == null) {
LOG.debug("situationID is null. delete it in historyList");
historyList.remove(currentIndex);
continue;
}
if (indexList[j] + k < historySize
&& behaviorRecords_unique.get(i).endsWith(situationID)) {
currentCadidate = currentCadidate
+ "#" +
((CRISTUserAction)historyList.get(currentIndex).getAction()).getActionID();
}
else {
break;
}
}
if (currentCadidate.length() > 0){
cadidateActionList.add(currentCadidate);
}
}
for (int j = 0; j < cadidateActionList.size(); j++) {
String currentActionPattern = behaviorRecords_unique.get(i)
+ cadidateActionList.get(j);
if (this.intentModel.containsKey(currentActionPattern)) {
Integer currentScore = this.intentModel
.get(currentActionPattern);
this.intentModel
.put(currentActionPattern, currentScore + 1);
} else {
this.intentModel.put(currentActionPattern, 1);
}
}
}
return intentModel;
}
private int[] getAllOccurences(ArrayList<String> strList, String str) {
ArrayList<Integer> indexList = new ArrayList<Integer>();
List<String> localList = strList;
int currentOffset = 0;
while (localList.size() > 0) {
int aIndex = localList.indexOf(str);
if (aIndex < 0) {
break;
} else {
indexList.add(currentOffset + aIndex);
currentOffset += aIndex + 1;
localList = localList.subList(aIndex + 1,
localList.size());
}
}
int[] localIndex = new int[indexList.size()];
for (int i = 0; i < indexList.size(); i++) {
localIndex[i] = indexList.get(i);
}
return localIndex;
}
}