/** * Copyright (c) 2011, SOCIETIES Consortium (WATERFORD INSTITUTE OF TECHNOLOGY (TSSG), HERIOT-WATT UNIVERSITY (HWU), SOLUTA.NET * (SN), GERMAN AEROSPACE CENTRE (Deutsches Zentrum fuer Luft- und Raumfahrt e.V.) (DLR), Zavod za varnostne tehnologije * informacijske družbe in elektronsko poslovanje (SETCCE), INSTITUTE OF COMMUNICATION AND COMPUTER SYSTEMS (ICCS), LAKE * COMMUNICATIONS (LAKE), INTEL PERFORMANCE LEARNING SOLUTIONS LTD (INTEL), PORTUGAL TELECOM INOVAÇÃO, SA (PTIN), IBM Corp., * INSTITUT TELECOM (ITSUD), AMITEC DIACHYTI EFYIA PLIROFORIKI KAI EPIKINONIES ETERIA PERIORISMENIS EFTHINIS (AMITEC), TELECOM * ITALIA S.p.a.(TI), TRIALOG (TRIALOG), Stiftelsen SINTEF (SINTEF), NEC EUROPE LTD (NEC)) * 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.dianne.model; import java.util.Iterator; import org.societies.api.schema.servicelifecycle.model.ServiceResourceIdentifier; public class OutcomeGroup extends Group { private OutcomeNode winnerNode; private OutcomeNode previousWinner; private ServiceResourceIdentifier serviceId; private String serviceType; public boolean newOutput; //gradient variables private double gradient; private double step; private double upperBound; private double lowerBound; //boosting variables private OutcomeNode boost; private OutcomeNode unboost; public OutcomeGroup(String groupName){ super(groupName); step = 10; upperBound = step; lowerBound = -step; gradient = 2/(upperBound-lowerBound); boost = null; unboost = null; winnerNode = null; } public OutcomeGroup(ServiceResourceIdentifier serviceId, String serviceType, String groupName){ super(groupName); this.serviceId = serviceId; this.serviceType = serviceType; step = 10; upperBound = step; lowerBound = -step; gradient = 2/(upperBound-lowerBound); boost = null; unboost = null; winnerNode = null; newOutput = false; } /* * Over-ride inherited method */ public void addNode(OutcomeNode node) { node.initialiseGradient(gradient); groupNodes.add(node); if(groupNodes.size()<2)//if first node added { winnerNode = node; } } public void userActivateNode(OutcomeNode node){ activateNode(node); } /* * Context change methods */ public void refreshOutcomes() //User input so calculate highest potential and activate { if(inputAvailable()) { updateNodePotentials(); //calculate new potentials activateHighestPotential(); //get node with highest potential and activate checkGradient(); //check group gradient } } private void updateNodePotentials() { Iterator<Node> groupNodes_it = groupNodes.iterator(); while(groupNodes_it.hasNext()) { OutcomeNode nextNode = (OutcomeNode)groupNodes_it.next(); nextNode.calculatePotential(); } } private void activateHighestPotential() { OutcomeNode highestPotentialNode = getHighestPotentialNode(); activateNode(highestPotentialNode); } public boolean inputAvailable() { boolean input = false; if(!groupNodes.isEmpty()) { //check if first node in group has synapses if(groupNodes.get(0).getSynapses().size()>0) { input = true; } } return input; } /* * Reinforcement cycle methods */ public void updateGroupOutput() { if(inputAvailable()) { updateNodePotentials(); //calculate new potentials calculateWinnerNode(); //get winner node checkGradient(); //check group gradient //check for conflicts if(conflicts()) //conflicts have occurred { resolveConflicts(); }else{ //no conflicts boost = null; unboost = null; //check if we have a new winner node if(!winnerNode.equals(previousWinner)) //new winner node { //alert services to new network output sendOutput(); } } } } private void calculateWinnerNode() //find winner and activate if new { //get node with the highest potential OutcomeNode highestPotentialNode = getHighestPotentialNode(); //set as the winner node previousWinner = winnerNode; winnerNode = highestPotentialNode; } private boolean conflicts() { if(!winnerNode.equals(activeNode)) { return true; }else{ return false; } } public void sendOutput() { System.out.println("******DIANNE setting new outcome: "+activeNode.getGroupName()+" = "+activeNode.getNodeName()); newOutput = true; } /* * Gradient methods */ private void checkGradient() { double highPotential = winnerNode.getPotential(); double lowPotential = getLoserPotential(); if(highPotential >= 1 || lowPotential <= -1) { //potentials about to saturate //increase gradient upperBound = upperBound+step; lowerBound = lowerBound-step; gradient = 2/(upperBound-lowerBound); //alert nodes of new gradient setGroupGradient(); } } private double getLoserPotential() { double loserPot; Iterator<Node> groupNodes_it = groupNodes.iterator(); OutcomeNode firstNode = (OutcomeNode)groupNodes_it.next(); loserPot = firstNode.getPotential(); while(groupNodes_it.hasNext()) { OutcomeNode nextNode = (OutcomeNode)groupNodes_it.next(); if(loserPot > nextNode.getPotential()) { loserPot = nextNode.getPotential(); } } return loserPot; } private void setGroupGradient() { Iterator<Node> groupNodes_it = groupNodes.iterator(); while(groupNodes_it.hasNext()) { OutcomeNode nextNode = (OutcomeNode)groupNodes_it.next(); nextNode.setGradient(gradient); } } /* * Conflict resolution methods */ public void resolveConflicts() { //check if ongoing conflict if(!winnerNode.equals(unboost) || !activeNode.equals(boost)) { //new conflict boost = (OutcomeNode)activeNode; unboost = winnerNode; resolve(); } } private void resolve() { double winnerNode_p = winnerNode.getPotential(); double activeNode_p = ((OutcomeNode)activeNode).getPotential(); double delta_p = winnerNode_p - activeNode_p; //difference in potentials double step_value = ((delta_p)*(delta_p))/2; //get step value double activeNode_p_prime = activeNode_p + step_value; //calculate new sigmoid_potential of active node and set ((OutcomeNode)activeNode).setPotential(activeNode_p_prime); //calculate weight update value double activeNode_raw = activeNode_p / gradient; double activeNode_raw_prime = activeNode_p_prime/gradient; double activeNode_raw_delta = Math.abs(activeNode_raw_prime - activeNode_raw); ((OutcomeNode)activeNode).boost(activeNode_raw_delta); } /* * Helper methods */ private OutcomeNode getHighestPotentialNode() { double highestPot; OutcomeNode highestPotNode; Iterator<Node> groupNodes_it = groupNodes.iterator(); OutcomeNode firstNode = (OutcomeNode)groupNodes_it.next(); highestPot = firstNode.getPotential(); highestPotNode = firstNode; while(groupNodes_it.hasNext()) { OutcomeNode nextNode = (OutcomeNode)groupNodes_it.next(); if(highestPot < nextNode.getPotential()) { highestPot = nextNode.getPotential(); highestPotNode = nextNode; } } return highestPotNode; } /* * Getter methods */ public OutcomeNode getWinnerNode(){ return winnerNode; } public Node getNewOutput(){ newOutput = false; return activeNode; } public ServiceResourceIdentifier getServiceId(){ return serviceId; } public String getServiceType(){ return serviceType; } public double getGradient(){ return this.gradient; } public void setGradient(double gradient){ this.gradient = gradient; } }