http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModelSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/MarkovPurchasingModelSampler.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryMarkovModelSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryMarkovModelSampler.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryMarkovModelSampler.java
new file mode 100644
index 0000000..1cc35bf
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryMarkovModelSampler.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 ProductCategoryMarkovModelSampler 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 ProductCategoryMarkovModelSampler(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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryPDFSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryPDFSampler.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryPDFSampler.java
new file mode 100644
index 0000000..b1d40d6
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/ProductCategoryPDFSampler.java
@@ -0,0 +1,117 @@
+/**
+ * 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 java.util.Set;
+
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import 
org.apache.bigtop.bigpetstore.datagenerator.datamodels.inputs.ProductCategory;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.pdfs.DiscretePDF;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+public class ProductCategoryPDFSampler implements Sampler<DiscretePDF<Product>>
+{
+       private final ProductCategory productCategory;
+       private final Sampler<Double> fieldValueWeightSampler;
+       private final Map<String, Double> fieldWeights;
+       
+       public ProductCategoryPDFSampler(ProductCategory productCategory,
+                       Map<String, Double> fieldWeights,
+                       Sampler<Double> fieldValueWeightSampler)
+       {
+               this.productCategory = productCategory;
+               this.fieldWeights = fieldWeights;
+               this.fieldValueWeightSampler = fieldValueWeightSampler;
+       }
+       
+       protected <T> Map<T, Double> normalize(Map<T, Double> weights)
+       {
+               double weightSum = 0.0;
+               for(double w : weights.values())
+               {
+                       weightSum += w;
+               }
+               
+               Map<T, Double> normalized = Maps.newHashMap();
+               for(Map.Entry<T, Double> entry : weights.entrySet())
+               {
+                       normalized.put(entry.getKey(), entry.getValue() / 
weightSum);
+               }
+               
+               return normalized;
+       }
+       
+       protected Map<String, Map<Object, Double>> generateFieldValueWeights() 
throws Exception
+       {
+               Map<String, Set<Object>> allFieldValues = Maps.newHashMap();
+               for(String fieldName : productCategory.getFieldNames())
+               {
+                       Set<Object> fieldValues = Sets.newHashSet();
+                       for(Product p : productCategory.getProducts())
+                       {
+                               Object fieldValue = p.getFieldValue(fieldName); 
+                               fieldValues.add(fieldValue);
+                       }
+                       allFieldValues.put(fieldName, fieldValues);
+               }
+               
+               Map<String, Map<Object, Double>> allFieldValueWeights = 
Maps.newHashMap();
+               for(String fieldName : productCategory.getFieldNames())
+               {
+                       Map<Object, Double> fieldValueWeights = 
Maps.newHashMap();
+                       for(Object fieldValue : allFieldValues.get(fieldName))
+                       {
+                               double fieldValueWeight = 
fieldValueWeightSampler.sample();
+                               fieldValueWeights.put(fieldValue, 
fieldValueWeight);
+                       }
+
+                       allFieldValueWeights.put(fieldName, fieldValueWeights);
+               }
+               
+               return allFieldValueWeights;
+       }
+       
+       protected Map<Product, Double> generateProductWeights() throws Exception
+       {
+               Map<String, Map<Object, Double>> allFieldValueWeights = 
generateFieldValueWeights();
+               
+               Map<Product, Double> productWeights = Maps.newHashMap();
+               for(Product p : productCategory.getProducts())
+               {
+                       double weight = 0.0;
+                       for(String fieldName : productCategory.getFieldNames())
+                       {
+                               Object fieldValue = p.getFieldValue(fieldName);
+                               weight += fieldWeights.get(fieldName) * 
allFieldValueWeights.get(fieldName).get(fieldValue);
+                       }
+                       productWeights.put(p, weight);
+               }
+               productWeights = normalize(productWeights);
+               
+               return productWeights;
+       }
+       
+       public DiscretePDF<Product> sample() throws Exception
+       {
+               Map<Product, Double> probs = generateProductWeights();
+               return new DiscretePDF<Product>(probs);
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java
new file mode 100644
index 0000000..d54ae98
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModel.java
@@ -0,0 +1,29 @@
+/**
+ * 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 extends Serializable
+{
+       public ImmutableSet<String> getProductCategories();
+       
+       public PurchasingProcesses buildProcesses(SeedFactory seedFactory);
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java
new file mode 100644
index 0000000..a88636a
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingModelSamplerBuilder.java
@@ -0,0 +1,152 @@
+/**
+ * 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.pdfs.DiscretePDF;
+import 
org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.BoundedMultiModalGaussianSampler;
+import 
org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.ExponentialSampler;
+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<StaticPurchasingModel> buildStaticPurchasingModel() 
throws Exception
+       {
+               Sampler<Double> fieldWeightSampler;
+               Sampler<Double> fieldValueWeightSampler;
+               
+               
if(Constants.STATIC_PURCHASING_MODEL_FIELD_WEIGHT_DISTRIBUTION_TYPE.equals(Constants.DistributionType.BOUNDED_MULTIMODAL_GAUSSIAN))
+               {
+                       fieldWeightSampler = new 
BoundedMultiModalGaussianSampler(Constants.STATIC_FIELD_WEIGHT_GAUSSIANS, 
+                                       
Constants.STATIC_FIELD_WEIGHT_LOWERBOUND, 
+                                       
Constants.STATIC_FIELD_WEIGHT_UPPERBOUND,
+                                       seedFactory);
+               }
+               else
+               {
+                       fieldWeightSampler = new 
ExponentialSampler(Constants.STATIC_FIELD_WEIGHT_EXPONENTIAL, seedFactory);
+               }
+               
+               
if(Constants.STATIC_PURCHASING_MODEL_FIELD_VALUE_WEIGHT_DISTRIBUTION_TYPE.equals(Constants.DistributionType.BOUNDED_MULTIMODAL_GAUSSIAN))
+               {
+                       fieldValueWeightSampler = new 
BoundedMultiModalGaussianSampler(Constants.STATIC_FIELD_VALUE_WEIGHT_GAUSSIANS, 
+                                       
Constants.STATIC_FIELD_VALUE_WEIGHT_LOWERBOUND, 
+                                       
Constants.STATIC_FIELD_VALUE_WEIGHT_UPPERBOUND,
+                                       seedFactory);
+               }
+               else
+               {
+                       fieldValueWeightSampler = new 
ExponentialSampler(Constants.STATIC_FIELD_VALUE_WEIGHT_EXPONENTIAL, 
seedFactory);
+               }
+               
+               Map<String, Double> fieldWeights = 
generateFieldWeights(fieldWeightSampler);
+               
+               Map<ProductCategory, Sampler<DiscretePDF<Product>>> 
categorySamplers = Maps.newHashMap();
+               for(ProductCategory productCategory : productCategories)
+               {
+                       Sampler<DiscretePDF<Product>> sampler = new 
ProductCategoryPDFSampler(productCategory,
+                                       fieldWeights, fieldValueWeightSampler);
+                       categorySamplers.put(productCategory, sampler);
+               }
+               
+               return new StaticPurchasingModelSampler(categorySamplers);
+       }
+       
+       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)
+               {
+                       ProductCategoryMarkovModelSampler sampler = new 
ProductCategoryMarkovModelSampler(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.DYNAMIC))
+               {
+                       return buildMarkovPurchasingModel();
+               }
+               else
+               {
+                       return buildStaticPurchasingModel();
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.java
new file mode 100644
index 0000000..746026b
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/PurchasingProcesses.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.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();
+       }
+       
+       public Sampler<Product> fixConditional(String productCategory) throws 
Exception
+       {
+               return this.processes.get(productCategory);
+       }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModel.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModel.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModel.java
new file mode 100644
index 0000000..e7234ab
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModel.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.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.DiscretePDF;
+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 StaticPurchasingModel implements PurchasingModel
+{
+
+       private static final long serialVersionUID = 5863830733003282570L;
+       
+       private final ImmutableMap<String, DiscretePDF<Product>> productPDFs;
+       
+       public StaticPurchasingModel(Map<String, DiscretePDF<Product>> 
productPDFs)
+       {
+               this.productPDFs = ImmutableMap.copyOf(productPDFs);
+       }
+
+       @Override
+       public ImmutableSet<String> getProductCategories()
+       {
+               return productPDFs.keySet();
+       }
+
+       @Override
+       public PurchasingProcesses buildProcesses(SeedFactory seedFactory)
+       {
+               Map<String, Sampler<Product>> processes = Maps.newHashMap();
+               for(String category : getProductCategories())
+               {
+                       DiscretePDF<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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModelSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModelSampler.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModelSampler.java
new file mode 100644
index 0000000..0647720
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/purchase/StaticPurchasingModelSampler.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.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.pdfs.DiscretePDF;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+public class StaticPurchasingModelSampler implements 
Sampler<StaticPurchasingModel>
+{
+       final ImmutableMap<ProductCategory, Sampler<DiscretePDF<Product>>> 
categorySamplers;
+       
+       public StaticPurchasingModelSampler(Map<ProductCategory, 
Sampler<DiscretePDF<Product>>> categorySamplers)
+       {
+               this.categorySamplers = ImmutableMap.copyOf(categorySamplers);
+       }
+       
+       public StaticPurchasingModel sample() throws Exception
+       {
+               Map<String, DiscretePDF<Product>> pdfs = Maps.newHashMap();
+               for(ProductCategory productCategory : categorySamplers.keySet())
+               {
+                       Sampler<DiscretePDF<Product>> sampler = 
categorySamplers.get(productCategory);
+                       pdfs.put(productCategory.getCategoryLabel(), 
sampler.sample());
+               }
+               
+               return new StaticPurchasingModel(pdfs);
+       }
+}
+

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationIncomePDF.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationIncomePDF.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationPopulationPDF.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreLocationPopulationPDF.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSampler.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSamplerBuilder.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/store/StoreSamplerBuilder.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java
new file mode 100644
index 0000000..10f195e
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CategoryWeightFunction.java
@@ -0,0 +1,51 @@
+/**
+ * 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)
+       {
+               return fixConditional(transactionTime).weight(exhaustionTime);
+       }
+       
+       @Override
+       public WeightFunction<Double> fixConditional(final Double 
transactionTime)
+       {
+               return new WeightFunction<Double>()
+                       {
+                               public double weight(Double exhaustionTime)
+                               {
+                                       double remainingTime = Math.max(0.0, 
exhaustionTime - transactionTime);
+                                       return pdf.probability(remainingTime);
+                               }
+                       };
+       }
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventory.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventory.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventoryBuilder.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerInventoryBuilder.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParameters.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParameters.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersBuilder.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersBuilder.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSampler.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSamplerBuilder.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/CustomerTransactionParametersSamplerBuilder.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryInventory.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryInventory.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageSimulator.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageSimulator.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageTrajectory.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageTrajectory.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProductCategoryUsageTrajectory.java
new file mode 100644
index 0000000..665d524
--- /dev/null
+++ 
b/bigtop-bigpetstore/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.bigtop.bigpetstore.datagenerator.datamodels.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.create(time, amount));
+       }
+       
+       public double getLastAmount()
+       {
+               return trajectory.get(trajectory.size() - 1).getSecond();
+       }
+       
+       public double getLastTime()
+       {
+               return trajectory.get(trajectory.size() - 1).getFirst();
+       }
+       
+       public double amountAtTime(double time)
+       {
+               Pair<Double, Double> previous = null;
+               for(Pair<Double, Double> entry : trajectory)
+               {
+                       if(entry.getFirst() > time)
+                               break;
+                       previous = entry;
+               }
+               
+               if(previous == null)
+                       return 0.0;
+               
+               return previous.getSecond();
+       }
+       
+       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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProposedPurchaseTimeSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/ProposedPurchaseTimeSampler.java
 
b/bigtop-bigpetstore/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-bigpetstore/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/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java
new file mode 100644
index 0000000..8e6bd78
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesHiddenMarkovModel.java
@@ -0,0 +1,121 @@
+/**
+ * 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;
+       }
+       
+       public Sampler<List<Product>> fixConditional(final Double 
transactionTime)
+       {
+               final ConditionalSampler<List<Product>, Double> sampler = this;
+               return new Sampler<List<Product>>()
+               {
+                       public List<Product> sample() throws Exception
+                       {
+                               return sampler.sample(transactionTime);
+                       }
+               };
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesSamplerBuilder.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionPurchasesSamplerBuilder.java
 
b/bigtop-bigpetstore/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-bigpetstore/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;
+       }
+}

http://git-wip-us.apache.org/repos/asf/bigtop/blob/5646c87d/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionSampler.java
----------------------------------------------------------------------
diff --git 
a/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionSampler.java
 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionSampler.java
new file mode 100644
index 0000000..b19ae38
--- /dev/null
+++ 
b/bigtop-bigpetstore/bigpetstore-data-generator/src/main/java/org/apache/bigtop/bigpetstore/datagenerator/generators/transaction/TransactionSampler.java
@@ -0,0 +1,56 @@
+/**
+ * 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.bigtop.bigpetstore.datagenerator.datamodels.Customer;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Product;
+import org.apache.bigtop.bigpetstore.datagenerator.datamodels.Transaction;
+import 
org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.ConditionalSampler;
+import org.apache.bigtop.bigpetstore.datagenerator.framework.samplers.Sampler;
+
+public class TransactionSampler implements Sampler<Transaction>
+{
+       private final Sampler<Double> timeSampler;
+       private final ConditionalSampler<List<Product>, Double> 
purchasesSampler;
+       private final Sampler<Integer> idSampler;
+       private final Customer customer;
+       
+       public TransactionSampler(Customer customer, Sampler<Double> 
timeSampler,
+                       ConditionalSampler<List<Product>, Double> 
purchasesSampler,
+                       Sampler<Integer> idSampler)
+       {
+               this.timeSampler = timeSampler;
+               this.customer = customer;
+               this.purchasesSampler = purchasesSampler;
+               this.idSampler = idSampler;
+       }
+       
+       
+       public Transaction sample() throws Exception
+       {       
+               Double transactionTime = timeSampler.sample();
+               List<Product> purchase = 
purchasesSampler.sample(transactionTime);
+               Integer id = idSampler.sample();
+                       
+               Transaction transaction = new Transaction(id, customer, 
customer.getStore(),
+                               transactionTime, purchase);
+               
+               return transaction;
+       }
+
+}

Reply via email to