/* * Copyright 2011 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.chance.distribution.probability.discrete; import org.drools.chance.degree.Degree; import org.drools.chance.degree.DegreeType; import org.drools.chance.degree.ChanceDegreeTypeRegistry; import org.drools.chance.degree.simple.SimpleDegree; import org.drools.chance.distribution.DiscreteProbabilityDistribution; import org.drools.chance.distribution.Distribution; import org.drools.chance.distribution.DistributionStrategies; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.*; /** * Strategy and level III factory for discrete probability distributions * @param <T> */ public class DiscreteDistributionStrategy<T> implements DistributionStrategies<T> { private DegreeType degreeType; private Class<T> domainType; private Constructor degreeStringConstr = null; DiscreteDistributionStrategy(DegreeType degreeType, Class<T> domainType){ this.degreeType = degreeType; this.domainType = domainType; } private Constructor getDegreeStringConstructor() { if (degreeStringConstr == null) { degreeStringConstr = ChanceDegreeTypeRegistry.getSingleInstance().getConstructorByString(degreeType); } return degreeStringConstr; } public Distribution<T> merge(Distribution<T> current, Distribution<T> newBit) { //ToDo iterare sull indice piu corto DiscreteProbabilityDistribution<T> currentDD= (DiscreteProbabilityDistribution<T>) current; DiscreteProbabilityDistribution<T> newBitDD= (DiscreteProbabilityDistribution<T>) newBit; Map<T,Degree> map = new HashMap<T,Degree>(); Degree denominator=null; int i=0; for( Iterator<T> currIt = currentDD.getSupport().iterator(); currIt.hasNext() ;){ T tempT=currIt.next(); if (newBitDD.getDistribution().containsKey(tempT)) { if(i==0){ denominator=newBitDD.getDegree(tempT).mul(current.getDegree(tempT)); i++; } else denominator=denominator.sum(newBitDD.getDegree(tempT).mul(current.getDegree(tempT))); } } for( Iterator<T> currIt = currentDD.getSupport().iterator(); currIt.hasNext() ;){ T tempT = currIt.next(); if (newBitDD.getDistribution().containsKey(tempT)) { Degree temp = (newBitDD.getDegree(tempT).mul(current.getDegree(tempT))).div(denominator); map.put(tempT,temp); } } currentDD.getDistribution().clear(); currentDD.getDistribution().putAll(map); return currentDD; } public Distribution<T> merge(Distribution<T> current, Distribution<T> newBit, String strategy) { return merge(current,newBit); } public Distribution<T> merge(Distribution<T> current, Distribution<T> newBit, Object... params) { if ( ((DiscreteProbabilityDistribution) newBit).size() == 1 ) { return mergeFocal(current, newBit); } else { return merge( current, newBit ); } } private Distribution<T> mergeFocal(Distribution<T> current, Distribution<T> newBit) { DiscreteProbabilityDistribution<T> currentDD = (DiscreteProbabilityDistribution<T>) current; DiscreteProbabilityDistribution<T> newBitDD = (DiscreteProbabilityDistribution<T>) newBit; T target = newBitDD.getDistribution().keySet().iterator().next(); if ( currentDD.getDistribution().containsKey( target ) ) { currentDD.getDistribution().put( target, currentDD.getDegree(target).mul( newBitDD.getDegree(target) ) ); } else { // } return currentDD; } public Distribution<T> mergeAsNew(Distribution<T> current, Distribution<T> newBit) { DiscreteProbabilityDistribution<T> currentDD= (DiscreteProbabilityDistribution<T>) current; DiscreteProbabilityDistribution<T> newBitDD= (DiscreteProbabilityDistribution<T>) newBit; DiscreteDistribution<T> ret=new DiscreteDistribution<T>(); Degree denominator=null; int i=0; if (newBitDD.getSupport().size() < currentDD.getSupport().size()) { for( Iterator<T> newBitIt = newBitDD.getSupport().iterator(); newBitIt.hasNext() ;){ T tempT=newBitIt.next(); if (currentDD.getDistribution().containsKey(tempT)) { if(i==0) { denominator = currentDD.getDegree(tempT).mul(newBit.getDegree(tempT)); i++; } else denominator =denominator.sum(currentDD.getDegree(tempT).mul(newBit.getDegree(tempT))); } } for( Iterator<T> newBitIt = newBitDD.getSupport().iterator(); newBitIt.hasNext() ;){ T tempT = newBitIt.next(); if (currentDD.getDistribution().containsKey(tempT)) { Degree temp = (currentDD.getDegree(tempT).mul( newBit.getDegree(tempT))).div(denominator); ret.put(tempT, temp); } } } else { i=0; for( Iterator<T> currIt = currentDD.getSupport().iterator(); currIt.hasNext() ;){ T tempT=currIt.next(); if (newBitDD.getDistribution().containsKey(tempT)) { if(i==0) { denominator = newBitDD.getDegree(tempT).mul(current.getDegree(tempT)); i++; } else denominator = denominator.sum(newBitDD.getDegree(tempT).mul(current.getDegree(tempT))); } } for( Iterator<T> currIt = currentDD.getSupport().iterator(); currIt.hasNext() ;){ T tempT = currIt.next(); if (newBitDD.getDistribution().containsKey(tempT)) { Degree temp = (newBitDD.getDegree(tempT).mul(current.getDegree(tempT))).div(denominator) ; ret.put(tempT, temp); } } } return ret; } public Distribution<T> mergeAsNew(Distribution<T> current, Distribution<T> newBit, String strategy) { return this.mergeAsNew(current,newBit); } public Distribution<T> mergeAsNew(Distribution<T> current, Distribution<T> newBit, Object... params) { return this.mergeAsNew(current,newBit); } public Distribution<T> remove(Distribution<T> current, Distribution<T> newBit) { return null; //To change body of implemented methods use File | Settings | File Templates. } public Distribution<T> remove(Distribution<T> current, Distribution<T> newBit, String strategy) { return null; //To change body of implemented methods use File | Settings | File Templates. } public Distribution<T> remove(Distribution<T> current, Distribution<T> newBit, Object... params) { return null; //To change body of implemented methods use File | Settings | File Templates. } public Distribution<T> removeAsNew(Distribution<T> current, Distribution<T> newBit) { return null; //To change body of implemented methods use File | Settings | File Templates. } public Distribution<T> removeAsNew(Distribution<T> current, Distribution<T> newBit, String strategy) { return null; //To change body of implemented methods use File | Settings | File Templates. } public Distribution<T> removeAsNew(Distribution<T> current, Distribution<T> newBit, Object... params) { return null; //To change body of implemented methods use File | Settings | File Templates. } public void normalize(Distribution<T> distr) { Degree deg; Iterator<Map.Entry<T,Degree>> iter = ((DiscreteDistribution) distr).getDistribution().entrySet().iterator(); deg = iter.next().getValue(); while ( iter.hasNext() ) { deg = deg.sum( iter.next().getValue() ); } iter = ((DiscreteDistribution) distr).getDistribution().entrySet().iterator(); while ( iter.hasNext() ) { Map.Entry<T,Degree> entry = iter.next(); entry.setValue( entry.getValue().div( deg ) ); } distr.setNormalized( true ); } public Distribution<T> newDistribution() { if ( Boolean.class.equals( domainType ) ) { return createUniformDistribution( (Collection<T>) Arrays.asList( Boolean.TRUE, Boolean.FALSE ) ); } else { return new DiscreteDistribution<T>(); } } public Distribution<T> newDistribution(Set<T> focalElements) { return createUniformDistribution( focalElements ); } private Distribution<T> createUniformDistribution( Collection<T> focalElements) { DiscreteDistribution<T> ret = new DiscreteDistribution<T>(); for( Iterator<? extends T> currIt = focalElements.iterator(); currIt.hasNext() ; ) { ret.put( currIt.next(), ChanceDegreeTypeRegistry.getSingleInstance().buildDegree( degreeType, 1.0 / focalElements.size()) ); } return ret; } public Distribution<T> newDistribution(Map<? extends T, ? extends Degree> elements) { DiscreteDistribution<T> ret = new DiscreteDistribution<T>(); for( Iterator<? extends T> currIt = elements.keySet().iterator(); currIt.hasNext() ;) { T temp=currIt.next(); ret.put(temp,elements.get(temp)); } return ret; } public T toCrispValue(Distribution<T> dist) { return ((DiscreteDistribution<T>) dist).getBest(); } public T toCrispValue(Distribution<T> dist, String strategy) { return ((DiscreteDistribution<T>) dist).getBest(); } public T toCrispValue(Distribution<T> dist, Object... params) { return ((DiscreteDistribution<T>) dist).getBest(); } public T sample(Distribution<T> dist) { // double p = Math.random(); // double acc = 0.0; // T result = null; // Iterator<ValueDegreePair<T>> iter = _multipleValue.descendingIterator(); // while ( acc < p ) { // ValueDegreePair<T> pair = iter.next(); // result = pair.getValue(); // acc += pair.getDegree().getValue(); // } // return result; return null; } public T sample(Distribution<T> dist, String strategy) { return null; //To change body of implemented methods use File | Settings | File Templates. } public T sample(Distribution<T> dist, Object... params) { return null; //To change body of implemented methods use File | Settings | File Templates. } public Distribution<T> toDistribution(T value) { DiscreteDistribution<T> dist = new DiscreteDistribution<T>(); dist.put(value, new SimpleDegree(1.0)); return dist; } public Distribution<T> toDistribution(T value, String strategy) { DiscreteDistribution<T> dist = new DiscreteDistribution<T>(); dist.put(value, new SimpleDegree(1.0)); return dist; } public Distribution<T> toDistribution(T value, Object... params) { DiscreteDistribution<T> dist = new DiscreteDistribution<T>(); if ( params.length > 0 && params[0] instanceof Degree ) { dist.put( value, (Degree) params[0] ); } else { dist.put( value, new SimpleDegree(1.0) ); } return dist; } public Distribution<T> parse(String distrAsString) { DiscreteDistribution<T> dist = new DiscreteDistribution<T>(); StringTokenizer tok = new StringTokenizer(distrAsString,","); while (tok.hasMoreElements()) { String pair = tok.nextToken().trim(); StringTokenizer sub = new StringTokenizer(pair,"/"); try { T value = (T) domainType.getConstructor( String.class ).newInstance( sub.nextToken().trim() ); Degree deg = (Degree) getDegreeStringConstructor().newInstance( sub.nextToken().trim() ); dist.put(value,deg); } catch (NoSuchMethodException nsme) { nsme.printStackTrace(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } catch (InstantiationException ie) { ie.printStackTrace(); } catch (InvocationTargetException ite) { ite.printStackTrace(); } } return dist; } }