bigtop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rnowl...@apache.org
Subject [09/23] bigtop git commit: BIGTOP-1983. Move BigPetStore data generator to bigtop-data-generators
Date Tue, 25 Aug 2015 13:48:09 GMT
http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/products/rules/Rule.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/products/rules/Rule.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/products/rules/Rule.java
new file mode 100644
index 0000000..4aa7945
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/products/rules/Rule.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.products.rules;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+
+public interface Rule
+{
+	public boolean ruleMatches(Product product) throws IllegalArgumentException;
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovModelProductCategorySampler.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovModelProductCategorySampler.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovModelProductCategorySampler.java
new file mode 100644
index 0000000..c842ff1
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovModelProductCategorySampler.java
@@ -0,0 +1,119 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.markovmodels.MarkovModel;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.markovmodels.MarkovModelBuilder;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.Maps;
+
+public class MarkovModelProductCategorySampler implements Sampler<MarkovModel<Product>>
+{
+	final ProductCategory productCategory;
+	final Sampler<Double> fieldSimilarityWeightSampler;
+	final Sampler<Double> loopbackWeightSampler;
+
+	final Map<String, Double> fieldWeights;
+	Map<String, Double> fieldSimilarityWeights;
+	double loopbackWeight;
+
+	public MarkovModelProductCategorySampler(ProductCategory productCategory,
+			Map<String, Double> fieldWeights, Sampler<Double> fieldSimilarityWeightSampler,
+			Sampler<Double> loopbackWeightSampler)
+	{
+		this.productCategory = productCategory;
+
+		this.fieldSimilarityWeightSampler = fieldSimilarityWeightSampler;
+		this.fieldWeights = fieldWeights;
+		this.loopbackWeightSampler = loopbackWeightSampler;
+	}
+
+	protected void generateWeights() throws Exception
+	{
+		fieldSimilarityWeights = Maps.newHashMap();
+
+		for(String fieldName : productCategory.getFieldNames())
+		{
+			fieldSimilarityWeights.put(fieldName,fieldSimilarityWeightSampler.sample());
+		}
+
+		loopbackWeight = loopbackWeightSampler.sample();
+	}
+
+	protected double productPairWeight(Product product1, Product product2)
+	{
+		double weightSum = 0.0;
+		for(String fieldName : productCategory.getFieldNames())
+		{
+			double fieldWeight = this.fieldWeights.get(fieldName);
+
+			if(product1.getFieldValue(fieldName).equals(product2.getFieldValue(fieldName)))
+			{
+				fieldWeight *= this.fieldSimilarityWeights.get(fieldName);
+			}
+			else
+			{
+				fieldWeight *= (1.0 - this.fieldSimilarityWeights.get(fieldName));
+			}
+
+			weightSum += fieldWeight;
+		}
+		return weightSum;
+	}
+
+	public MarkovModel<Product> sample() throws Exception
+	{
+		generateWeights();
+
+		MarkovModelBuilder<Product> builder = new MarkovModelBuilder<Product>();
+
+		for(Product product1 : productCategory.getProducts())
+		{
+			builder.addStartState(product1, 1.0);
+
+			double weightSum = 0.0;
+			for(Product product2 : productCategory.getProducts())
+			{
+				if(!product1.equals(product2))
+				{
+					weightSum += productPairWeight(product1, product2);
+				}
+			}
+
+			for(Product product2 : productCategory.getProducts())
+			{
+				double weight = 0.0;
+				if(!product1.equals(product2))
+				{
+					weight = (1.0 - loopbackWeight) * productPairWeight(product1, product2) / weightSum;
+				}
+				else
+				{	weight = loopbackWeight;
+
+				}
+
+				builder.addTransition(product1, product2, weight);
+			}
+		}
+
+		return builder.build();
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModel.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModel.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModel.java
new file mode 100644
index 0000000..8b22660
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModel.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.markovmodels.MarkovModel;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.markovmodels.MarkovProcess;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+public class MarkovPurchasingModel implements PurchasingModel<MarkovModel<Product>>
+{
+
+	private static final long serialVersionUID = 3098355461347511619L;
+	ImmutableMap<String, MarkovModel<Product>> productCategoryProfiles;
+	
+	public MarkovPurchasingModel(Map<String, MarkovModel<Product>> productCategoryProfiles)
+	{
+		this.productCategoryProfiles = ImmutableMap.copyOf(productCategoryProfiles);
+	}
+	
+	@Override
+	public ImmutableSet<String> getProductCategories()
+	{
+		return productCategoryProfiles.keySet();
+	}
+
+	@Override
+	public MarkovModel<Product> getProfile(String productCategory)
+	{
+		return productCategoryProfiles.get(productCategory);
+	}
+
+	@Override
+	public PurchasingProcesses buildProcesses(SeedFactory seedFactory)
+	{
+		Map<String, Sampler<Product>> processes = Maps.newHashMap();
+		for(String category : getProductCategories())
+		{
+			MarkovModel<Product> model = getProfile(category);
+			processes.put(category, new MarkovProcess<Product>(model, seedFactory));
+		}
+		
+		return new PurchasingProcesses(processes);
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModelSampler.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModelSampler.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModelSampler.java
new file mode 100644
index 0000000..6291213
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModelSampler.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.markovmodels.MarkovModel;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.Maps;
+
+public class MarkovPurchasingModelSampler implements Sampler<MarkovPurchasingModel>
+{
+	final Map<ProductCategory, Sampler<MarkovModel<Product>>> categorySamplers;
+	
+	public MarkovPurchasingModelSampler(Map<ProductCategory, Sampler<MarkovModel<Product>>> categorySamplers)
+	{
+		this.categorySamplers = categorySamplers;
+	}
+	
+	public MarkovPurchasingModel sample() throws Exception
+	{
+		Map<String, MarkovModel<Product>> markovModels = Maps.newHashMap();
+		for(ProductCategory productCategory : categorySamplers.keySet())
+		{
+			Sampler<MarkovModel<Product>> sampler = categorySamplers.get(productCategory);
+			markovModels.put(productCategory.getCategoryLabel(), sampler.sample());
+		}
+		
+		return new MarkovPurchasingModel(markovModels);
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModel.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModel.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModel.java
new file mode 100644
index 0000000..336a898
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModel.java
@@ -0,0 +1,67 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.MultinomialPDF;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.RouletteWheelSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+public class MultinomialPurchasingModel implements PurchasingModel<MultinomialPDF<Product>>
+{
+
+	private static final long serialVersionUID = 5863830733003282570L;
+
+	private final ImmutableMap<String, MultinomialPDF<Product>> productPDFs;
+
+	public MultinomialPurchasingModel(Map<String, MultinomialPDF<Product>> productPDFs)
+	{
+		this.productPDFs = ImmutableMap.copyOf(productPDFs);
+	}
+
+	@Override
+	public ImmutableSet<String> getProductCategories()
+	{
+		return productPDFs.keySet();
+	}
+
+	@Override
+	public MultinomialPDF<Product> getProfile(String category)
+	{
+		return productPDFs.get(category);
+	}
+
+	@Override
+	public PurchasingProcesses buildProcesses(SeedFactory seedFactory)
+	{
+		Map<String, Sampler<Product>> processes = Maps.newHashMap();
+		for(String category : getProductCategories())
+		{
+			MultinomialPDF<Product> pdf = productPDFs.get(category);
+			processes.put(category, RouletteWheelSampler.create(pdf, seedFactory));
+		}
+
+		return new PurchasingProcesses(processes);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModelSampler.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModelSampler.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModelSampler.java
new file mode 100644
index 0000000..7fcfbe5
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MultinomialPurchasingModelSampler.java
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.bigtop.bigpetstore.datagenerator.Constants;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.MultinomialPDF;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.UniformIntSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.UniformSampler;
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+
+public class MultinomialPurchasingModelSampler implements Sampler<MultinomialPurchasingModel>
+{
+	private final SeedFactory seedFactory;
+	private final Collection<ProductCategory> productCategories;
+
+	public MultinomialPurchasingModelSampler(Collection<ProductCategory> productCategories, SeedFactory seedFactory)
+	{
+		this.seedFactory = seedFactory;
+		this.productCategories = productCategories;
+	}
+
+	protected <T> List<T> shuffle(Collection<T> input) throws Exception
+	{
+		Vector<T> shuffled = new Vector<>(input);
+		for(int i = 0; i < input.size() - 1; i++)
+		{
+			int swapIdx = new UniformIntSampler(i, input.size() - 1, seedFactory).sample();
+			T tmp = shuffled.get(i);
+			shuffled.set(i, shuffled.get(swapIdx));
+			shuffled.set(swapIdx, tmp);
+		}
+		
+		return shuffled;
+	}
+
+	protected Map<Pair<String, Object>, Double> generateFieldValueWeights(ProductCategory productCategory) throws Exception
+	{
+		// Get all values for each field by iterating over all products
+		Multimap<String, Object> allFieldValues = HashMultimap.create();
+		for(String fieldName : productCategory.getFieldNames())
+		{
+			if(!Constants.PRODUCT_MODEL_EXCLUDED_FIELDS.contains(fieldName))
+			{
+				for(Product p : productCategory.getProducts())
+				{
+					Object fieldValue = p.getFieldValue(fieldName);
+					allFieldValues.put(fieldName, fieldValue);
+				}
+			}
+		}
+		
+		Sampler<Double> sampler = new UniformSampler(seedFactory);
+		
+		// shuffle field values
+		Map<Pair<String, Object>, Double> fieldValueWeights = Maps.newHashMap();
+		for(Map.Entry<String, Collection<Object>> entry : allFieldValues.asMap().entrySet())
+		{
+			String fieldName = entry.getKey();
+			List<Object> shuffled = shuffle(entry.getValue());
+			
+			for(int i = 0; i < shuffled.size(); i++)
+			{
+				double weight = Constants.PRODUCT_MULTINOMIAL_POSITIVE_WEIGHT;
+				if ((i + 1) > Constants.PRODUCT_MULTINOMIAL_POSITIVE_COUNT_MIN)
+				{
+					double r = sampler.sample();
+					if (r >= Constants.PRODUCT_MULTINOMIAL_POSITIVE_FREQUENCY)
+					{
+						weight = Constants.PRODUCT_MULTINOMIAL_NEGATIVE_WEIGHT;
+					}
+				}
+				
+				Object fieldValue = shuffled.get(i);
+				fieldValueWeights.put(Pair.of(fieldName, fieldValue), weight);
+			}
+		}
+		
+
+		return ImmutableMap.copyOf(fieldValueWeights);
+	}
+
+	protected Map<Product, Double> generateProductWeights(Map<Pair<String, Object>, Double> fieldValueWeights,
+			ProductCategory productCategory) throws Exception
+	{
+		Map<Product, Double> productWeights = Maps.newHashMap();
+		for(Product p : productCategory.getProducts())
+		{
+			double weight = 1.0;
+			for(String fieldName : productCategory.getFieldNames())
+			{
+				if(!Constants.PRODUCT_MODEL_EXCLUDED_FIELDS.contains(fieldName))
+				{
+					Object fieldValue = p.getFieldValue(fieldName);
+					Pair<String, Object> key = Pair.of(fieldName, fieldValue);
+					weight *= fieldValueWeights.get(key);
+				}
+			}
+			productWeights.put(p, weight);
+		}
+
+		return productWeights;
+	}
+
+	public MultinomialPurchasingModel sample() throws Exception
+	{
+		Map<String, MultinomialPDF<Product>> pdfs = Maps.newHashMap();
+		for(ProductCategory productCategory : productCategories)
+		{
+			Map<Pair<String, Object>, Double> fieldWeights = this.generateFieldValueWeights(productCategory);
+			Map<Product, Double> productWeights = this.generateProductWeights(fieldWeights, productCategory);
+			pdfs.put(productCategory.getCategoryLabel(), new MultinomialPDF<Product>(productWeights));
+		}
+
+		return new MultinomialPurchasingModel(pdfs);
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java
new file mode 100644
index 0000000..d460c3b
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.io.Serializable;
+
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+
+import com.google.common.collect.ImmutableSet;
+
+public interface PurchasingModel<T> extends Serializable
+{
+	public ImmutableSet<String> getProductCategories();
+	
+	public T getProfile(String category);
+
+	public PurchasingProcesses buildProcesses(SeedFactory seedFactory);
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java
new file mode 100644
index 0000000..43808c7
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.bigtop.bigpetstore.datagenerator.Constants;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.markovmodels.MarkovModel;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.BoundedMultiModalGaussianSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+
+public class PurchasingModelSamplerBuilder
+{
+	final ImmutableList<ProductCategory> productCategories;
+	final SeedFactory seedFactory;
+	
+	public PurchasingModelSamplerBuilder(Collection<ProductCategory> productCategories, SeedFactory seedFactory)
+	{
+		this.productCategories = ImmutableList.copyOf(productCategories);
+		this.seedFactory = seedFactory;
+	}
+	
+	protected Map<String, Double> generateFieldWeights(Sampler<Double> fieldWeightSampler) throws Exception
+	{
+		Set<String> fieldNames = new HashSet<String>();
+		for(ProductCategory pc : productCategories)
+		{
+			for(String fieldName : pc.getFieldNames())
+			{
+				fieldNames.add(fieldName);
+			}
+		}
+		
+		Map<String, Double> fieldWeights = Maps.newHashMap();
+		for(String fieldName : fieldNames)
+		{
+			double weight = fieldWeightSampler.sample();
+			fieldWeights.put(fieldName, weight);
+		}
+		
+		return fieldWeights;
+	}
+	
+	public Sampler<MarkovPurchasingModel> buildMarkovPurchasingModel() throws Exception
+	{
+		
+		Sampler<Double> fieldWeightSampler = new BoundedMultiModalGaussianSampler(Constants.PRODUCT_MSM_FIELD_WEIGHT_GAUSSIANS, 
+				Constants.PRODUCT_MSM_FIELD_WEIGHT_LOWERBOUND, 
+				Constants.PRODUCT_MSM_FIELD_WEIGHT_UPPERBOUND,
+				seedFactory);
+	
+		Sampler<Double> fieldSimilarityWeightSampler = new BoundedMultiModalGaussianSampler(Constants.PRODUCT_MSM_FIELD_SIMILARITY_WEIGHT_GAUSSIANS,
+				Constants.PRODUCT_MSM_FIELD_SIMILARITY_WEIGHT_LOWERBOUND, 
+				Constants.PRODUCT_MSM_FIELD_SIMILARITY_WEIGHT_UPPERBOUND,
+				seedFactory);
+		
+		Sampler<Double> loopbackWeightSampler = new BoundedMultiModalGaussianSampler(Constants.PRODUCT_MSM_LOOPBACK_WEIGHT_GAUSSIANS,
+				Constants.PRODUCT_MSM_LOOPBACK_WEIGHT_LOWERBOUND,
+				Constants.PRODUCT_MSM_LOOPBACK_WEIGHT_UPPERBOUND,
+				seedFactory);
+		
+		Map<String, Double> fieldWeights = generateFieldWeights(fieldWeightSampler);
+		
+		Map<ProductCategory, Sampler<MarkovModel<Product>>> categorySamplers = Maps.newHashMap();
+		for(ProductCategory productCategory : productCategories)
+		{
+			MarkovModelProductCategorySampler sampler = new MarkovModelProductCategorySampler(productCategory,
+					fieldWeights, fieldSimilarityWeightSampler, loopbackWeightSampler);
+			categorySamplers.put(productCategory, sampler);
+		}
+		
+		return new MarkovPurchasingModelSampler(categorySamplers);
+	}
+	
+	public Sampler<? extends PurchasingModel> build() throws Exception
+	{
+		if(Constants.PURCHASING_MODEL_TYPE.equals(Constants.PurchasingModelType.MARKOV))
+		{
+			return buildMarkovPurchasingModel();
+		}
+		else
+		{
+			return new MultinomialPurchasingModelSampler(productCategories, seedFactory);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.java
new file mode 100644
index 0000000..d9a9849
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.purchase;
+
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.ConditionalSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.ImmutableMap;
+
+public class PurchasingProcesses implements ConditionalSampler<Product, String>
+{
+	ImmutableMap<String, Sampler<Product>> processes;
+	
+	public PurchasingProcesses(Map<String, Sampler<Product>> processes)
+	{
+		this.processes = ImmutableMap.copyOf(processes);
+	}
+	
+	public Product sample(String productCategory) throws Exception
+	{
+		return this.processes.get(productCategory).sample();
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationIncomePDF.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationIncomePDF.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationIncomePDF.java
new file mode 100644
index 0000000..345956f
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationIncomePDF.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.store;
+
+import java.util.List;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ZipcodeRecord;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.ProbabilityDensityFunction;
+
+public class StoreLocationIncomePDF implements ProbabilityDensityFunction<ZipcodeRecord>
+{
+	double incomeNormalizationFactor;
+	double minIncome;
+	double k;
+	
+	public StoreLocationIncomePDF(List<ZipcodeRecord> zipcodeTable, double incomeScalingFactor)
+	{
+		
+		double maxIncome = 0.0;
+		minIncome = Double.MAX_VALUE;
+		
+		for(ZipcodeRecord record : zipcodeTable)
+		{
+			maxIncome = Math.max(maxIncome, record.getMedianHouseholdIncome());
+			minIncome = Math.min(minIncome, record.getMedianHouseholdIncome());
+		}
+		
+		k = Math.log(incomeScalingFactor) / (maxIncome - minIncome);
+		
+		incomeNormalizationFactor = 0.0d;
+		for(ZipcodeRecord record : zipcodeTable)
+		{
+			double weight = incomeWeight(record);
+			incomeNormalizationFactor += weight;
+		}
+	}
+	
+	private double incomeWeight(ZipcodeRecord record)
+	{
+		return Math.exp(k * (record.getMedianHouseholdIncome() - minIncome));
+	}
+	
+	
+	@Override
+	public double probability(ZipcodeRecord datum)
+	{
+		double weight = incomeWeight(datum);
+		
+		return weight / this.incomeNormalizationFactor;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationPopulationPDF.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationPopulationPDF.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationPopulationPDF.java
new file mode 100644
index 0000000..8c6f43c
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationPopulationPDF.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.store;
+
+import java.util.List;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ZipcodeRecord;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.ProbabilityDensityFunction;
+
+public class StoreLocationPopulationPDF implements ProbabilityDensityFunction<ZipcodeRecord>
+{
+	double populationSum = 0.0;
+	
+	public StoreLocationPopulationPDF(List<ZipcodeRecord> zipcodeTable)
+	{
+		long populationSum = 0L;
+		for(ZipcodeRecord record : zipcodeTable)
+		{
+			populationSum += record.getPopulation();
+		}
+		
+		this.populationSum = ((double) populationSum);
+	}
+	
+	public double probability(ZipcodeRecord record)
+	{
+		return ((double) record.getPopulation()) / populationSum;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSampler.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSampler.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSampler.java
new file mode 100644
index 0000000..d118611
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSampler.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.store;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Store;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ZipcodeRecord;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+public class StoreSampler implements Sampler<Store>
+{
+
+	private final Sampler<ZipcodeRecord> locationSampler;
+	private final Sampler<Integer> idSampler;
+	
+	public StoreSampler(Sampler<Integer> idSampler, Sampler<ZipcodeRecord> locationSampler)
+	{
+		this.locationSampler = locationSampler;
+		this.idSampler = idSampler;
+	}
+	
+	public Store sample() throws Exception
+	{
+		Integer id = idSampler.sample();
+		String name = "Store_" + id;
+		ZipcodeRecord location = locationSampler.sample();
+		
+		Store store = new Store(id, name, location);
+		
+		return store;
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSamplerBuilder.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSamplerBuilder.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSamplerBuilder.java
new file mode 100644
index 0000000..68e4e57
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSamplerBuilder.java
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.store;
+
+import java.util.List;
+
+import org.apache.bigtop.bigpetstore.datagenerator.Constants;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Store;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ZipcodeRecord;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.JointPDF;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.ProbabilityDensityFunction;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.RouletteWheelSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.SequenceSampler;
+
+public class StoreSamplerBuilder
+{
+	private final List<ZipcodeRecord> zipcodeTable;
+	private final SeedFactory seedFactory;
+	
+	public StoreSamplerBuilder(List<ZipcodeRecord> zipcodeTable, SeedFactory seedFactory)
+	{
+		this.zipcodeTable = zipcodeTable;
+		this.seedFactory = seedFactory;
+	}
+	
+	public Sampler<Store> build()
+	{
+		Sampler<Integer> idSampler = new SequenceSampler();
+		
+		ProbabilityDensityFunction<ZipcodeRecord> locationPopulationPDF = 
+				new StoreLocationPopulationPDF(zipcodeTable);
+		ProbabilityDensityFunction<ZipcodeRecord> locationIncomePDF = 
+				new StoreLocationIncomePDF(zipcodeTable, Constants.INCOME_SCALING_FACTOR);
+		ProbabilityDensityFunction<ZipcodeRecord> locationJointPDF = 
+				new JointPDF<ZipcodeRecord>(zipcodeTable, locationPopulationPDF, locationIncomePDF);
+		
+		Sampler<ZipcodeRecord> locationSampler = RouletteWheelSampler.create(zipcodeTable, locationJointPDF, seedFactory);
+		
+		return new StoreSampler(idSampler, locationSampler);
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java
new file mode 100644
index 0000000..09b7327
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.ExponentialPDF;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.ProbabilityDensityFunction;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.wfs.ConditionalWeightFunction;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.wfs.WeightFunction;
+
+public class CategoryWeightFunction implements ConditionalWeightFunction<Double, Double>
+{
+	private final ProbabilityDensityFunction<Double> pdf;
+	
+	public CategoryWeightFunction(double averagePurchaseTriggerTime)
+	{
+		double lambda = 1.0 / averagePurchaseTriggerTime;
+		pdf = new ExponentialPDF(lambda);
+	}
+	
+	@Override
+	public double weight(Double exhaustionTime, Double transactionTime)
+	{
+		double remainingTime = Math.max(0.0, exhaustionTime - transactionTime);
+		return pdf.probability(remainingTime);
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventory.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventory.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventory.java
new file mode 100644
index 0000000..f0f538a
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventory.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.Constants;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+public class CustomerInventory
+{
+	final private ImmutableMap<String, ProductCategoryInventory> productCategoryInventories;
+	
+	public CustomerInventory(Map<String, ProductCategoryInventory> productCategoryInventories)
+	{
+		this.productCategoryInventories = ImmutableMap.copyOf(productCategoryInventories);
+	}
+	
+	public void simulatePurchase(double time, Product product) throws Exception
+	{
+		String category = product.getFieldValueAsString(Constants.PRODUCT_CATEGORY);
+		ProductCategoryInventory inventory = productCategoryInventories.get(category);
+		inventory.simulatePurchase(time, product);
+	}
+	
+	public ImmutableMap<String, Double> getInventoryAmounts(double time)
+	{
+		Map<String, Double> amounts = Maps.newHashMap();
+		for(String category : productCategoryInventories.keySet())
+		{
+			double amount = productCategoryInventories.get(category).findRemainingAmount(time);
+			amounts.put(category, amount);
+		}
+		
+		return ImmutableMap.copyOf(amounts);
+	}
+	
+	public ImmutableMap<String, Double> getExhaustionTimes()
+	{
+		Map<String, Double> times = Maps.newHashMap();
+		for(String category : productCategoryInventories.keySet())
+		{
+			double time = productCategoryInventories.get(category).findExhaustionTime();
+			times.put(category, time);
+		}
+		
+		return ImmutableMap.copyOf(times);
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventoryBuilder.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventoryBuilder.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventoryBuilder.java
new file mode 100644
index 0000000..80ed944
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventoryBuilder.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+public class CustomerInventoryBuilder
+{
+	final private List<ProductCategory> productCategories;
+	final private SeedFactory seedFactory;
+	final private CustomerTransactionParameters parameters;
+	
+	public CustomerInventoryBuilder(CustomerTransactionParameters parameters,
+			SeedFactory seedFactory)
+	{
+		productCategories = Lists.newArrayList();
+		this.seedFactory = seedFactory;
+		this.parameters = parameters;
+	}
+	
+	public void addProductCategory(ProductCategory productCategory)
+	{
+		this.productCategories.add(productCategory);
+	}
+	
+	public void addAllProductCategories(Collection<ProductCategory> productCategories)
+	{
+		this.productCategories.addAll(productCategories);
+	}
+	
+	public CustomerInventory build()
+	{
+		Map<String, ProductCategoryInventory> inventories = Maps.newHashMap();
+		for(ProductCategory productCategory : productCategories)
+		{
+			if(parameters.countPetsBySpecies(productCategory.getApplicableSpecies()) > 0)
+			{
+				ProductCategoryInventory inventory = new ProductCategoryInventory(productCategory,
+					parameters, seedFactory);
+				inventories.put(productCategory.getCategoryLabel(), inventory);
+			}
+		}
+		
+		return new CustomerInventory(inventories);
+	}
+}
+
+

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParameters.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParameters.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParameters.java
new file mode 100644
index 0000000..9267635
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParameters.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.PetSpecies;
+
+import com.google.common.collect.ImmutableMultiset;
+import com.google.common.collect.Multiset;
+import com.google.common.collect.Sets;
+
+public class CustomerTransactionParameters
+{
+	final ImmutableMultiset<PetSpecies> petCounts;
+	final double averageTransactionTriggerTime;
+	final double averagePurchaseTriggerTime;
+	
+	public CustomerTransactionParameters(Multiset<PetSpecies> petCounts,
+			double averageTransactionTriggerTime, double averagePurchaseTriggerTime)
+	{
+		this.petCounts = ImmutableMultiset.copyOf(petCounts);
+		this.averageTransactionTriggerTime = averageTransactionTriggerTime;
+		this.averagePurchaseTriggerTime = averagePurchaseTriggerTime;
+	}
+
+	public double getAverageTransactionTriggerTime()
+	{
+		return averageTransactionTriggerTime;
+	}
+
+	public double getAveragePurchaseTriggerTime()
+	{
+		return averagePurchaseTriggerTime;
+	}
+	
+	public int countPetsBySpecies(PetSpecies species)
+	{
+		return petCounts.count(species);
+	}
+	
+	public int countPetsBySpecies(Collection<PetSpecies> allSpecies)
+	{
+		int count = 0;
+		Set<PetSpecies> speciesSet = Sets.newHashSet(allSpecies);
+		for(PetSpecies species : speciesSet)
+		{
+			count += countPetsBySpecies(species);
+		}
+		
+		return count;
+	}
+	
+	public int countPets()
+	{
+		return petCounts.size();
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersBuilder.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersBuilder.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersBuilder.java
new file mode 100644
index 0000000..9adfa4c
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersBuilder.java
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.PetSpecies;
+
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Multiset;
+
+public class CustomerTransactionParametersBuilder
+{
+	private Multiset<PetSpecies> petCounts;
+	private double averageTransactionTriggerTime;
+	private double averagePurchaseTriggerTime;
+	
+	public CustomerTransactionParametersBuilder()
+	{
+		this.petCounts = HashMultiset.create();
+		this.averagePurchaseTriggerTime = 0.0;
+		this.averageTransactionTriggerTime = 0.0;
+	}
+	
+	public void addPet(PetSpecies species)
+	{
+		this.petCounts.add(species);
+	}
+
+	public void setAverageTransactionTriggerTime(
+			double averageTransactionTriggerTime)
+	{
+		this.averageTransactionTriggerTime = averageTransactionTriggerTime;
+	}
+
+	public void setAveragePurchaseTriggerTime(double averagePurchaseTriggerTime)
+	{
+		this.averagePurchaseTriggerTime = averagePurchaseTriggerTime;
+	}
+	
+	public CustomerTransactionParameters build()
+	{
+		return new CustomerTransactionParameters(this.petCounts,
+				this.averageTransactionTriggerTime,
+				this.averagePurchaseTriggerTime);
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSampler.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSampler.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSampler.java
new file mode 100644
index 0000000..8495fd9
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSampler.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.PetSpecies;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+public class CustomerTransactionParametersSampler implements Sampler<CustomerTransactionParameters>
+{
+	final private Sampler<Integer> nPetsSampler;
+	final private Sampler<PetSpecies> petSpeciesSampler;
+	final private Sampler<Double> purchaseTriggerTimeSampler;
+	final private Sampler<Double> transactionTriggerTimeSampler;
+
+	public CustomerTransactionParametersSampler(Sampler<Integer> nPetsSampler,
+			Sampler<PetSpecies> petSpeciesSampler, 
+			Sampler<Double> purchaseTriggerTimeSampler,
+			Sampler<Double> transactionTriggerTimeSampler)
+	{
+
+		this.nPetsSampler = nPetsSampler;
+		this.petSpeciesSampler = petSpeciesSampler;
+		this.purchaseTriggerTimeSampler = purchaseTriggerTimeSampler;
+		this.transactionTriggerTimeSampler = transactionTriggerTimeSampler;
+	}
+	
+	protected void generatePets(CustomerTransactionParametersBuilder builder) throws Exception
+	{
+		int nPets = this.nPetsSampler.sample();
+		
+		for(int i = 0; i < nPets; i++)
+		{
+			PetSpecies species = this.petSpeciesSampler.sample();
+			builder.addPet(species);	
+		}
+	}
+	
+	public CustomerTransactionParameters sample() throws Exception
+	{
+		CustomerTransactionParametersBuilder builder = new CustomerTransactionParametersBuilder();
+		
+		this.generatePets(builder);
+		builder.setAveragePurchaseTriggerTime(this.purchaseTriggerTimeSampler.sample());
+		builder.setAverageTransactionTriggerTime(this.transactionTriggerTimeSampler.sample());
+		
+		return builder.build();
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSamplerBuilder.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSamplerBuilder.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSamplerBuilder.java
new file mode 100644
index 0000000..249a456
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSamplerBuilder.java
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import java.util.Arrays;
+
+import org.apache.bigtop.bigpetstore.datagenerator.Constants;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.PetSpecies;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.BoundedMultiModalGaussianSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.RouletteWheelSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.UniformIntSampler;
+
+public class CustomerTransactionParametersSamplerBuilder
+{
+	final private SeedFactory seedFactory;
+
+	public CustomerTransactionParametersSamplerBuilder(SeedFactory seedFactory)
+	{
+		this.seedFactory = seedFactory;
+	}
+	
+	public Sampler<CustomerTransactionParameters> build()
+	{
+		Sampler<Integer> nPetsSampler = new UniformIntSampler(Constants.MIN_PETS, Constants.MAX_PETS, seedFactory);
+		
+		Sampler<PetSpecies> petSpeciesSampler = RouletteWheelSampler.createUniform(Arrays.asList(PetSpecies.values()), seedFactory);
+		
+		Sampler<Double> transactionTriggerTimeSampler = new BoundedMultiModalGaussianSampler(Constants.TRANSACTION_TRIGGER_TIME_GAUSSIANS,
+					Constants.TRANSACTION_TRIGGER_TIME_MIN, Constants.TRANSACTION_TRIGGER_TIME_MAX,
+					seedFactory);
+		
+		Sampler<Double> purchaseTriggerTimeSampler = new BoundedMultiModalGaussianSampler(Constants.PURCHASE_TRIGGER_TIME_GAUSSIANS,
+				Constants.PURCHASE_TRIGGER_TIME_MIN, Constants.PURCHASE_TRIGGER_TIME_MAX,
+				seedFactory);
+		
+		return new CustomerTransactionParametersSampler(nPetsSampler, petSpeciesSampler,
+				transactionTriggerTimeSampler, purchaseTriggerTimeSampler);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryInventory.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryInventory.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryInventory.java
new file mode 100644
index 0000000..8d43b82
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryInventory.java
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import org.apache.bigtop.bigpetstore.datagenerator.Constants;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+
+public class ProductCategoryInventory
+{	
+	private ProductCategoryUsageTrajectory trajectory;
+	private ProductCategoryUsageSimulator simulator;
+	
+	public ProductCategoryInventory(ProductCategory productCategory, CustomerTransactionParameters parameters,
+			SeedFactory seedFactory)
+	{
+		
+		double amountUsedAverage = productCategory.getBaseAmountUsedAverage() * parameters.countPetsBySpecies(productCategory.getApplicableSpecies());
+		double amountUsedVariance = productCategory.getBaseAmountUsedVariance() * parameters.countPetsBySpecies(productCategory.getApplicableSpecies());		
+		
+		trajectory = new ProductCategoryUsageTrajectory(0.0, 0.0);
+		simulator = new ProductCategoryUsageSimulator(productCategory.getDailyUsageRate(),
+				amountUsedAverage, amountUsedVariance, seedFactory);
+	}
+	
+	public void simulatePurchase(double time, Product product) throws Exception
+	{
+		double amountPurchased = product.getFieldValueAsDouble(Constants.PRODUCT_QUANTITY);
+		
+		double amountRemainingBeforePurchase = trajectory.amountAtTime(time);
+		
+		trajectory = simulator.simulate(time, amountRemainingBeforePurchase + amountPurchased);
+	}
+	
+	public double findExhaustionTime()
+	{
+		return trajectory.getLastTime();
+	}
+	
+	public double findRemainingAmount(double time)
+	{
+		return trajectory.amountAtTime(time);
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageSimulator.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageSimulator.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageSimulator.java
new file mode 100644
index 0000000..b09d395
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageSimulator.java
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.ExponentialSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.GaussianSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+public class ProductCategoryUsageSimulator
+{
+	final private double amountUsedAverage;
+	final private double amountUsedVariance;
+	
+	final private Sampler<Double> timestepSampler;
+	final private Sampler<Double> R;
+	
+	public ProductCategoryUsageSimulator(double dailyUsageRate, double amountUsedAverage,
+			double amountUsedVariance, SeedFactory seedFactory)
+	{
+		this.amountUsedAverage = amountUsedAverage;
+		this.amountUsedVariance = amountUsedVariance;
+		
+		timestepSampler = new ExponentialSampler(dailyUsageRate, seedFactory);
+		R = new GaussianSampler(0.0, 1.0, seedFactory);
+	}
+	
+	private void step(ProductCategoryUsageTrajectory trajectory) throws Exception
+	{
+		// given in days since last usage
+		double timestep = timestepSampler.sample();
+		
+		double r = R.sample();
+		
+		// given in units per day
+		double usageAmount = this.amountUsedAverage * timestep + 
+				Math.sqrt(this.amountUsedVariance * timestep) * r;
+		
+		// can't use a negative amount
+		usageAmount = Math.max(usageAmount, 0.0);
+		
+		double remainingAmount = Math.max(0.0, trajectory.getLastAmount() - usageAmount);
+		double time = trajectory.getLastTime() + timestep;
+		
+		trajectory.append(time, remainingAmount);
+	}
+	
+	public ProductCategoryUsageTrajectory simulate(double initialTime, double initialAmount) throws Exception
+	{
+		ProductCategoryUsageTrajectory trajectory = new ProductCategoryUsageTrajectory(initialTime, initialAmount);
+		
+		while(trajectory.getLastAmount() > 0.0)
+		{
+			step(trajectory);
+		}
+		
+		return trajectory;
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageTrajectory.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageTrajectory.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageTrajectory.java
new file mode 100644
index 0000000..f3c20c7
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageTrajectory.java
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import java.util.List;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.google.common.collect.Lists;
+
+public class ProductCategoryUsageTrajectory
+{
+	final private List<Pair<Double, Double>> trajectory;
+	
+	public ProductCategoryUsageTrajectory(double initialTime, double initialAmount)
+	{
+		trajectory = Lists.newArrayList();
+		this.append(initialTime, initialAmount);
+	}
+	
+	public void append(double time, double amount)
+	{
+		trajectory.add(Pair.of(time, amount));
+	}
+	
+	public double getLastAmount()
+	{
+		return trajectory.get(trajectory.size() - 1).getValue();
+	}
+	
+	public double getLastTime()
+	{
+		return trajectory.get(trajectory.size() - 1).getKey();
+	}
+	
+	public double amountAtTime(double time)
+	{
+		Pair<Double, Double> previous = null;
+		for(Pair<Double, Double> entry : trajectory)
+		{
+			if(entry.getKey() > time)
+				break;
+			previous = entry;
+		}
+		
+		if(previous == null)
+			return 0.0;
+		
+		return previous.getValue();
+	}
+	
+	public Pair<Double, Double> getStep(int idx)
+	{
+		return trajectory.get(idx);
+	}
+	
+	public int size()
+	{
+		return trajectory.size();
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProposedPurchaseTimeSampler.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProposedPurchaseTimeSampler.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProposedPurchaseTimeSampler.java
new file mode 100644
index 0000000..3fa2ef9
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProposedPurchaseTimeSampler.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+public class ProposedPurchaseTimeSampler implements Sampler<Double>
+{
+	final CustomerInventory customerInventory;
+	final Sampler<Double> arrivalTimeSampler;
+	
+	public ProposedPurchaseTimeSampler(CustomerInventory customerInventory,
+			Sampler<Double> arrivalTimeSampler)
+	{
+		this.customerInventory = customerInventory;
+		this.arrivalTimeSampler = arrivalTimeSampler;
+	}
+	
+	protected double categoryProposedTime(double exhaustionTime) throws Exception
+	{
+		return Math.max(exhaustionTime - arrivalTimeSampler.sample(), 0.0);
+	}
+	
+	public Double sample() throws Exception
+	{
+		double minProposedTime = Double.MAX_VALUE;
+		for(Double exhaustionTime : this.customerInventory.getExhaustionTimes().values())
+		{
+			double proposedTime = this.categoryProposedTime(exhaustionTime);
+			minProposedTime = Math.min(proposedTime, minProposedTime);
+		}
+		
+		return minProposedTime;
+	}
+	
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java
new file mode 100644
index 0000000..83924e3
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.bigtop.bigpetstore.datagenerator.Constants;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.ConditionalSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.RouletteWheelSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.wfs.ConditionalWeightFunction;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+public class TransactionPurchasesHiddenMarkovModel implements ConditionalSampler<List<Product>, Double>
+{
+	
+	protected final static String STOP_STATE = "STOP";
+	
+	final ConditionalSampler<Product, String> purchasingProcesses;
+	final ConditionalWeightFunction<Double, Double> categoryWF;
+	final CustomerInventory inventory;
+	
+	final SeedFactory seedFactory;
+	
+	public TransactionPurchasesHiddenMarkovModel(ConditionalSampler<Product, String> purchasingProcesses,
+			ConditionalWeightFunction<Double, Double> categoryWF, CustomerInventory inventory,
+				SeedFactory seedFactory)
+	{
+		this.purchasingProcesses = purchasingProcesses;
+		this.inventory = inventory;
+		this.categoryWF = categoryWF;
+		
+		this.seedFactory = seedFactory;
+	}
+	
+	protected String chooseCategory(double transactionTime, int numPurchases) throws Exception
+	{
+		ImmutableMap<String, Double> exhaustionTimes = this.inventory.getExhaustionTimes();
+		Map<String, Double> weights = Maps.newHashMap();
+		
+		for(Map.Entry<String, Double> entry : exhaustionTimes.entrySet())
+		{
+			String category = entry.getKey();
+			double weight = this.categoryWF.weight(entry.getValue(), transactionTime);
+			weights.put(category, weight);
+		}
+		
+		if(numPurchases > 0)
+		{
+			weights.put(STOP_STATE, Constants.STOP_CATEGORY_WEIGHT);
+		}
+		
+		Sampler<String> sampler = RouletteWheelSampler.create(weights, seedFactory);
+		
+		return sampler.sample();
+	}
+	
+	protected Product chooseProduct(String category) throws Exception
+	{
+		return this.purchasingProcesses.sample(category);
+	}
+
+	public List<Product> sample(Double transactionTime) throws Exception
+	{
+		int numPurchases = 0;
+		
+		List<Product> purchasedProducts = Lists.newArrayList();
+		
+		String category;
+		while(true)
+		{
+			category = this.chooseCategory(transactionTime, numPurchases);
+			
+			if(category.equals(STOP_STATE))
+			{
+				break;
+			}
+			
+			Product product = this.chooseProduct(category);
+			
+			purchasedProducts.add(product);
+			
+			this.inventory.simulatePurchase(transactionTime, product);
+			numPurchases += 1;
+		}
+		
+		return purchasedProducts;
+	}
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/3bbbb557/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesSamplerBuilder.java
----------------------------------------------------------------------
diff --git a/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesSamplerBuilder.java b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesSamplerBuilder.java
new file mode 100644
index 0000000..4400151
--- /dev/null
+++ b/bigtop-data-generators/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesSamplerBuilder.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.bigtop.bigpetstore.datagenerator.generators.transaction;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.SeedFactory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.ConditionalSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.wfs.ConditionalWeightFunction;
+import org.apache.bigtop.bigpetstore.datagenerator.generators.purchase.PurchasingModel;
+import org.apache.bigtop.bigpetstore.datagenerator.generators.purchase.PurchasingProcesses;
+
+public class TransactionPurchasesSamplerBuilder
+{
+	final SeedFactory seedFactory;
+	final Collection<ProductCategory> productCategories;
+	final PurchasingModel purchasingProfile;
+	
+	protected CustomerTransactionParameters transactionParameters;
+	protected CustomerInventory inventory;
+	
+	public TransactionPurchasesSamplerBuilder(Collection<ProductCategory> productCategories,
+			PurchasingModel purchasingProfile,
+			SeedFactory seedFactory)
+	{
+		this.seedFactory = seedFactory;
+		this.productCategories = productCategories;
+		this.purchasingProfile = purchasingProfile;
+	}
+	
+	public void setTransactionParameters(
+			CustomerTransactionParameters transactionParameters)
+	{
+		this.transactionParameters = transactionParameters;
+	}
+
+	public void setInventory(CustomerInventory inventory)
+	{
+		this.inventory = inventory;
+	}
+
+	public ConditionalSampler<List<Product>, Double> build() throws Exception
+	{
+		PurchasingProcesses processes = purchasingProfile.buildProcesses(seedFactory);
+		
+		ConditionalWeightFunction<Double, Double> categoryWF =
+				new CategoryWeightFunction(transactionParameters.getAveragePurchaseTriggerTime());
+		
+		ConditionalSampler<List<Product>, Double> sampler = new TransactionPurchasesHiddenMarkovModel(processes,
+				categoryWF, inventory, this.seedFactory);
+		
+		return sampler;
+	}
+}


Mime
View raw message