diff --git a/data/short_recipebook.xml b/data/short_recipebook.xml
new file mode 100644
index 0000000..317b3d6
--- /dev/null
+++ b/data/short_recipebook.xml
@@ -0,0 +1,521 @@
+
+
+
+
+ Catalan Rice
+
+
+ Fish
+ Casserole
+ Main dish
+ Pork
+ Clams
+
+ 6servings
+
+
+
+
+
+
+
+
+ 2.5
+ cups
+
+ - Fish stock
+
+
+
+
+ 0.25
+ teaspoon
+
+ - Saffron Threads
+
+
+
+
+ 0.25
+ cup
+
+ - Dry white wine
+
+
+
+
+ 6
+ tablespoons
+
+ - Lard
+
+
+
+
+ 0.5
+ pound
+
+ - Chorizo
+ Sliced 1/4"
+
+
+
+ 1.5
+ pounds
+
+ - Pork Loin
+ 1" Cubes
+
+
+
+ 1
+
+
+ - onion
+ thinly sliced
+
+
+
+ 2
+
+
+ - Bell peppers
+ julienned
+
+
+
+ 2
+
+
+ - tomatoes
+ peeled,seeded
+
+
+
+ 3
+
+
+ - Large Squid
+
+
+
+
+ 2
+ cups
+
+ - Long-Grained Rice
+
+
+
+
+ 0.75
+ cup
+
+ - Blanched almonds
+
+
+
+
+ 0.333333
+ cup
+
+ - Pine Nuts
+
+
+
+
+ 3
+
+
+ - garlic cloves
+ minced
+
+
+
+ 1
+ cup
+
+ - Artichoke hearts
+ drained
+
+
+
+ 18
+
+
+ - Clams Or Mussels
+ scrubbed
+
+
+
+ 0.5
+ cup
+
+ - Peas
+
+
+
+
+ 0.25
+ cup
+
+ - Pimientos
+ julienned
+
+
+
+ 2
+ tablespoons
+
+ - Fresh parsley
+ minced
+
+
+
+ Clean squid and cut body sacs into rings. Cut tentacles in half. In
+a small saucepan, bring stock to a bare simmer. Crush saffron and
+combine it with wine in a small bowl. In a flameproof casserole or
+paella pan, heat the lard over moderately high heat. Saute the
+chorizo and pork, turning them until they are browned. Add the
+onion, bell peppers, tomatoes, and squid and cook the mixture over
+moderate heat, stirring, for 15 minutes. Stir in the rice and cook
+for 1 minute, stirring. Stir in almonds, pine nuts, garlic, saffron
+mixture, and artichoke hearts. Ladle in enough stock to just cover
+the rice mixture. Bring to a boil and simmer it, covered, for 20
+minutes. Arrange the clams in the rice, add the peas, and simmer for
+10-15 minutes, or until the rice is just tender and the clams open.
+Discard any clams that do not open. Garnish with pimientos and
+parsley. This is a recipe by Elizabeth David, appearing in an article
+in 1972 by James Beard. It originated on Spain's Costa Brava. "not a
+true paella, but it is quite good." A 1972 Gourmet Magazine Favorite.
+
+
+
+
+ Hamburger Steak
+
+
+ Beef
+ Penndutch
+
+ 1servings
+
+
+
+
+
+
+
+
+ 1
+ pound
+
+ - Beef
+ ground
+
+
+
+ 0.5
+ teaspoon
+
+ - salt
+
+
+
+
+ 1
+
+
+ - onion
+ minced
+
+
+
+ 1
+
+
+ - egg
+ well beaten
+
+
+
+ 1
+ dash
+
+ - pepper
+
+
+
+
+ 0.25
+ cup
+
+ - bread crumbs
+
+
+
+
+ Mix in order given and shape into round cakes. Fry in butter until
+nicely browned. Source: Pennsylvania Dutch Cook Book - Fine Old
+Recipes, Culinary Arts Press, 1936.
+
+
+
+
+ Potatoes in a Thick Sauce
+
+
+ Main dish
+ Potatoes
+ Indian
+ Vegetarian
+
+ 6servings
+
+
+
+
+
+
+
+
+ 5
+ medium
+
+ - potatoes
+ cubed & cooked
+
+
+
+ 1
+ slice
+
+ - ginger
+
+
+
+
+ 1
+ tablespoon
+
+ - Coriander
+
+
+
+
+ 1
+ teaspoon
+
+ - cumin
+
+
+
+
+ 6
+ tablespoons
+
+ - tomato sauce
+
+
+
+
+ 6
+ tablespoons
+
+ - vegetable oil
+
+
+
+
+ 1
+ teaspoon
+
+ - Fennel
+
+
+
+
+ 1
+ teaspoon
+
+ - Fenugreek
+
+
+
+
+ 0.5
+ teaspoon
+
+ - Black mustard seeds
+
+
+
+
+ 3
+
+
+ - Whole dried red chilies
+
+
+
+
+ 1
+ teaspoon
+
+ - salt
+
+
+
+
+ 1.5
+ teaspoons
+
+ - lemon juice
+
+
+
+
+ 1
+ teaspoon
+
+ - Garam masala
+
+
+
+
+ Place ginger, coriander, cumin, tomato sauce & 3 tb water in a
+blender & blend till smooth.
+
+Break potatoes into bite sized pieces.
+
+Heat oil (I use ghee) in a large pot. When hot, throw in fennel,
+fenugreek & mustard seeds. After 20 seconds, add red chilies. As
+they darken, put in paste from blender. Fry for 5 minutes, stirring
+frequently. Put in the potato pieces & fry for 3 to 5 minutes. Add 1
+1/2 c warm water. Bring to a boil. Add salt & lemon juice. Simmer
+for 20 minutes.
+
+Before serving, sprinkle with garam masala.
+
+Madhur Jaffrey, "An Invitation to Indian Cooking.
+
+
+
+
+ Tomato-Zucchini Casserole
+
+
+ Vegetarian
+ Casseroles
+
+ 4servings
+
+
+
+
+
+
+
+
+ 1.5
+ teaspoons
+
+ - chili powder
+
+
+
+
+ 1
+ tablespoon
+
+ - parsley flakes
+
+
+
+
+ 0.5
+ teaspoon
+
+ - garlic powder
+
+
+
+
+ 0.5
+ teaspoon
+
+ - onion powder
+
+
+
+
+ 0.125
+ teaspoon
+
+ - salt
+
+
+
+
+ 0.125
+ teaspoon
+
+ - black pepper
+ ground
+
+
+
+ 3
+ cups
+
+ - zucchini
+ thinly sliced,fresh
+
+
+
+ 1
+ pound
+
+ - tomatoes
+ fresh,sliced
+
+
+
+ 0.25
+ cup
+
+ - bread crumbs
+ white,fresh
+
+
+
+ 1
+ tablespoon
+
+ - vegetable oil
+
+
+
+
+ 1. Combine chili powder, 1 1/2 teaspooons parsley flakes, garlic and
+onion powders, salt and pepper in a small bowl.~ 2. Place half the
+zucchini in a lightly greased 6-cup casserole, or layer with half the
+tomatoes.~ 3. Sprinkle with half the seasoning mixture.~ 4. Repeat
+the layers.~ 5. Combine bread crumbs, oil and remaining parsley
+flakes; sprinkle over vegetables.~ 6. Bake, uncovered, in preheated
+375'F. oven, until vegetables are tender, about 40 minutes.~
+
+
+
\ No newline at end of file
diff --git a/data/short_survey.xml b/data/short_survey.xml
new file mode 100644
index 0000000..33805ec
--- /dev/null
+++ b/data/short_survey.xml
@@ -0,0 +1,109 @@
+
+
+
+
+ 0
+ Catalan Rice
+
+
+ 1
+ Hamburger Steak
+
+
+ 2
+ Potatoes in a Thick Sauce
+
+
+ 3
+ Tomato-Zucchini Casserole
+
+
+
+
+ 0
+
+ chocolate
+
+
+
+ 1
+
+ nuts
+
+
+
+ 2
+ shellfish
+
+
+
+ 0
+
+
+ 0
+ 10
+
+
+ 1
+ 2
+
+
+ 2
+ 5
+
+
+ 3
+ 5
+
+
+
+
+ 0
+ false
+
+
+ 1
+ false
+
+
+ 2
+ false
+
+
+
+
+ 1
+
+
+ 0
+ 10
+
+
+ 1
+ 2
+
+
+ 2
+ 5
+
+
+ 3
+ 5
+
+
+
+
+ 0
+ false
+
+
+ 1
+ false
+
+
+ 2
+ false
+
+
+
+
\ No newline at end of file
diff --git a/src/dkohl/bayes/builders/FoodNetBuilder.java b/src/dkohl/bayes/builders/FoodNetBuilder.java
new file mode 100644
index 0000000..677ea76
--- /dev/null
+++ b/src/dkohl/bayes/builders/FoodNetBuilder.java
@@ -0,0 +1,218 @@
+package dkohl.bayes.builders;
+
+import java.util.HashSet;
+
+import net.woodyfolsom.cs6601.p2.Diner;
+import net.woodyfolsom.cs6601.p2.Ingredient.TYPE;
+import net.woodyfolsom.cs6601.p2.Ingredients;
+import net.woodyfolsom.cs6601.p2.Recipe;
+import net.woodyfolsom.cs6601.p2.RecipeBook;
+import net.woodyfolsom.cs6601.p2.Survey;
+import dkohl.bayes.bayesnet.BayesNet;
+import dkohl.bayes.estimation.MaximumLikelihoodEstimation;
+import dkohl.bayes.example.builders.FoodExampleBuilder;
+import dkohl.bayes.probability.Assignment;
+import dkohl.bayes.probability.Probability;
+import dkohl.bayes.probability.Variable;
+import dkohl.bayes.probability.distribution.ContinousDistribution;
+import dkohl.bayes.probability.distribution.ProbabilityDistribution;
+import dkohl.bayes.probability.distribution.ProbabilityTable;
+import dkohl.bayes.statistic.DataPoint;
+import dkohl.bayes.statistic.DataSet;
+import dkohl.onthology.Ontology;
+
+public class FoodNetBuilder {
+ public static final String TASTE = "Taste";
+ public static final String SOMEONE_VEGETARIAN = "Vegetarian";
+ public static final String CONTAINS_MEAT = "Meat";
+ public static final String CONTAINS_VEGETABLE = "Vegetable";
+ public static final String CONTAINS_BEEF = TYPE.BEEF.toString();
+ public static final String CONTAINS_PORK = TYPE.PORK.toString();
+ public static final String CONTAINS_TOMATOS = TYPE.TOMATO.toString();
+ public static final String CONTAINS_POTATOS = TYPE.POTATO.toString();
+
+ public static final String TRUE_VALUE = "true";
+ public static final String FALSE_VALUE = "false";
+
+ public static final String DOMAIN[] = { TRUE_VALUE, FALSE_VALUE };
+
+ public static final String RATING_DOMAIN[] = { "1", "2", "3", "4", "5",
+ "6", "7", "8", "9", "10" };
+
+ private static final String[] VARIABLES = { SOMEONE_VEGETARIAN,
+ CONTAINS_BEEF, CONTAINS_MEAT, CONTAINS_PORK, CONTAINS_POTATOS,
+ CONTAINS_TOMATOS, CONTAINS_VEGETABLE, TASTE };
+
+ private static final String[] OBSERVED = { CONTAINS_BEEF, CONTAINS_PORK,
+ CONTAINS_POTATOS, CONTAINS_TOMATOS, };
+
+ public static Ontology createOntology() {
+ HashSet classes = new HashSet();
+
+ classes.add(CONTAINS_MEAT);
+ classes.add(CONTAINS_VEGETABLE);
+
+ Ontology onthology = new Ontology(classes);
+
+ onthology.define(CONTAINS_PORK, CONTAINS_MEAT);
+ onthology.define(CONTAINS_BEEF, CONTAINS_MEAT);
+
+ onthology.define(CONTAINS_TOMATOS, CONTAINS_VEGETABLE);
+ onthology.define(CONTAINS_POTATOS, CONTAINS_VEGETABLE);
+ return onthology;
+ }
+
+ private static Assignment build(String varible, String value) {
+ return new Assignment(new Variable(varible, DOMAIN), value);
+ }
+
+ public static DataPoint normalize(DataPoint point, Ontology onto) {
+ // resolve onthology
+ DataPoint normPoint = new DataPoint(point);
+ for (String key : point.keySet()) {
+ if (onto.getInheritance().containsKey(key)) {
+ normPoint
+ .add(build(onto.getInheritance().get(key), TRUE_VALUE));
+ }
+ }
+
+ // implement closed world assumption
+ // everything unknown is false
+ for (String variable : VARIABLES) {
+ if (!normPoint.containsKey(variable)) {
+ normPoint.add(build(variable, FALSE_VALUE));
+ }
+ }
+ return normPoint;
+ }
+
+ public static DataSet getSurveyDataSet(Survey survey, RecipeBook recipeBook) {
+ DataSet data = FoodExampleBuilder.examples();
+ Ontology onto = createOntology();
+
+ int nDishes = survey.getDishCount();
+ for (int dinerIndex = 0; dinerIndex < survey.getDinerCount(); dinerIndex++) {
+ Diner diner = survey.getDiner(dinerIndex);
+ for (int dishIndex = 0; dishIndex < nDishes; dishIndex++) {
+ data.add(normalize(createDataPoint(recipeBook, survey.getDish(dishIndex), diner.getRating(dishIndex)),onto));
+ }
+ }
+ return data;
+ }
+
+ public static DataPoint createDataPoint(RecipeBook recipeBook, String recipeName, int weight) {
+ DataPoint point = new DataPoint();
+
+ Recipe recipe = recipeBook.getRecipe(recipeName);
+ Ingredients ingredients = recipe.getIngredients();
+
+ if (ingredients.contains(TYPE.BEEF)) {
+ point.add(build(CONTAINS_BEEF, TRUE_VALUE));
+ }
+ if (ingredients.contains(TYPE.PORK)) {
+ point.add(build(CONTAINS_PORK, TRUE_VALUE));
+ }
+ if (ingredients.contains(TYPE.POTATO)) {
+ point.add(build(CONTAINS_POTATOS, TRUE_VALUE));
+ }
+ if (ingredients.contains(TYPE.TOMATO)) {
+ point.add(build(CONTAINS_TOMATOS, TRUE_VALUE));
+ }
+
+ point.add(build(TASTE, "" + weight));
+
+ return point;
+ }
+
+ public static ProbabilityDistribution vegi() {
+ String names[] = { SOMEONE_VEGETARIAN };
+ ProbabilityTable table = new ProbabilityTable(names);
+ table.setProbabilityForAssignment("true;", new Probability(0));
+ table.setProbabilityForAssignment("false;", new Probability(1));
+ return table;
+ }
+
+ public static ProbabilityDistribution beef() {
+ String names[] = { CONTAINS_MEAT, CONTAINS_BEEF };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
+ public static ProbabilityDistribution pork() {
+ String names[] = { CONTAINS_MEAT, CONTAINS_PORK };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
+ public static ProbabilityDistribution meet() {
+ String names[] = { SOMEONE_VEGETARIAN, CONTAINS_MEAT };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
+ public static ProbabilityDistribution tomatos() {
+ String names[] = { CONTAINS_VEGETABLE, CONTAINS_TOMATOS };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
+ public static ProbabilityDistribution potatos() {
+ String names[] = { CONTAINS_VEGETABLE, CONTAINS_POTATOS };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
+ public static ProbabilityDistribution vegetables() {
+ String names[] = { CONTAINS_VEGETABLE, SOMEONE_VEGETARIAN };
+ ProbabilityTable table = new ProbabilityTable(names);
+ return table;
+ }
+
+ public static ProbabilityDistribution taste() {
+ String names[] = { TASTE, CONTAINS_BEEF, CONTAINS_PORK,
+ CONTAINS_POTATOS, CONTAINS_TOMATOS };
+ ContinousDistribution distribution = new ContinousDistribution(names, 0);
+ return distribution;
+ }
+
+ public static BayesNet createDishNet(Survey survey, RecipeBook recipeBook) {
+ BayesNet net = new BayesNet(VARIABLES);
+
+ net.setDistribution(new Variable(SOMEONE_VEGETARIAN, DOMAIN), vegi());
+ net.setDistribution(new Variable(CONTAINS_MEAT, DOMAIN), meet());
+ net.setDistribution(new Variable(CONTAINS_VEGETABLE, DOMAIN),
+ vegetables());
+ net.setDistribution(new Variable(CONTAINS_BEEF, DOMAIN), beef());
+ net.setDistribution(new Variable(CONTAINS_PORK, DOMAIN), pork());
+ net.setDistribution(new Variable(CONTAINS_POTATOS, DOMAIN), potatos());
+ net.setDistribution(new Variable(CONTAINS_TOMATOS, DOMAIN), tomatos());
+ net.setDistribution(new Variable(TASTE, RATING_DOMAIN), taste());
+
+ Ontology ontology = createOntology();
+ for (String category : ontology.getClasses()) {
+ net.connect(category, SOMEONE_VEGETARIAN);
+ }
+
+ for (String thing : OBSERVED) {
+ net.connect(thing, ontology.getInheritance().get(thing));
+ net.connect(TASTE, thing);
+ }
+
+ DataSet dataSet = getSurveyDataSet(survey, recipeBook);
+
+ for (String category : ontology.getClasses()) {
+ MaximumLikelihoodEstimation.estimate(dataSet, net, category);
+ for (String thing : ontology.getClasses2thing().get(category)) {
+ MaximumLikelihoodEstimation.estimate(dataSet, net, thing);
+ }
+ }
+
+ MaximumLikelihoodEstimation.estimate(dataSet, net, TASTE);
+ ContinousDistribution distribturion = (ContinousDistribution) net
+ .getNodes().get(TASTE);
+
+ distribturion.estimate();
+
+ return net;
+ }
+}
\ No newline at end of file
diff --git a/src/dkohl/bayes/inference/EnumerateAll.java b/src/dkohl/bayes/inference/EnumerateAll.java
index 593061f..47bab52 100644
--- a/src/dkohl/bayes/inference/EnumerateAll.java
+++ b/src/dkohl/bayes/inference/EnumerateAll.java
@@ -27,8 +27,8 @@ public class EnumerateAll {
* a set of assignments in this net.
* @return
*/
- public static LinkedList enumerateAsk(
- Variable query, BayesNet net, LinkedList assignments) {
+ public static List enumerateAsk(
+ Variable query, BayesNet net, List assignments) {
LinkedList variables = net.getVariables();
LinkedList result = new LinkedList();
diff --git a/src/net/woodyfolsom/cs6601/p2/BayesChef.java b/src/net/woodyfolsom/cs6601/p2/BayesChef.java
index 466106a..ec5344e 100644
--- a/src/net/woodyfolsom/cs6601/p2/BayesChef.java
+++ b/src/net/woodyfolsom/cs6601/p2/BayesChef.java
@@ -1,61 +1,112 @@
package net.woodyfolsom.cs6601.p2;
import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
-import org.apache.commons.math3.stat.regression.SimpleRegression;
+import net.woodyfolsom.cs6601.p2.Ingredient.TYPE;
+import dkohl.bayes.bayesnet.BayesNet;
+import dkohl.bayes.builders.FoodNetBuilder;
+import dkohl.bayes.example.builders.FoodExampleBuilder;
+import dkohl.bayes.inference.EnumerateAll;
+import dkohl.bayes.probability.Assignment;
+import dkohl.bayes.probability.ProbabilityAssignment;
+import dkohl.bayes.probability.Variable;
public class BayesChef {
public static void main(String... args) {
System.out.println("Reading recipe book.");
- RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/survey_recipes.xml"));
-
- System.out.println("Read data for " + recipeBook.getSize() + " recipes.");
+ RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/short_recipebook.xml"));
System.out.println("Reading survey data.");
- Survey survey = SurveyReader.readSurvey(new File("data/survey.xml"));
+ Survey survey = SurveyReader.readSurvey(new File("data/short_survey.xml"));
- System.out.println("Read data for " + survey.getDinerCount() + " diner(s).");
+ new BayesChef().reportBestMeal(recipeBook,survey);
+ }
+
+ private void reportBestMeal(RecipeBook recipeBook, Survey survey) {
+ int numRecipes = recipeBook.getSize();
+ System.out.println("Read data for " + numRecipes + " recipes.");
+ int numDiners = survey.getDinerCount();
+ System.out.println("Read data for " + numDiners + " diner(s).");
+
+ /*
System.out.println("Setting evidence for first 11 recipes.");
System.out.println("Evaluating preference for remaining recipes.");
//read survey prefs from survey.xml
- double[][] surveyPrefs = new double[5][];
- for (int i = 0; i < 5; i++) {
- surveyPrefs[i] = new double[11];
- for (int j = 0; j < 11; j++) {
+ double[][] surveyPrefs = new double[numDiners][];
+ for (int i = 0; i < numDiners; i++) {
+ surveyPrefs[i] = new double[numRecipes/2];
+ for (int j = 0; j < numRecipes/2; j++) {
surveyPrefs[i][j] = survey.getDiner(i).getRating(j);
}
}
//generating stub evaluated preferences to test RMSE calculation
- double[][] calculatedPrefs = new double[5][];
- calculatedPrefs[0] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- calculatedPrefs[1] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- calculatedPrefs[2] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- calculatedPrefs[3] = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- calculatedPrefs[4] = new double[] { 10.0, 10.0, 0.0, 10.0, 10.0, 4.0, 10.0, 10.0, 10.0, 10.0, 10.0 };
+ double[][] calculatedPrefs = new double[numDiners][];
+ calculatedPrefs[0] = new double[numRecipes/2];
- System.out.println("RMSE for recipes #12-22 (calculated vs. surveyed preference):");
+ System.out.println("RMSE for recipes #" + numRecipes/2 + "-" + numRecipes +" (calculated vs. surveyed preference):");
for (int dinerIndex = 0; dinerIndex < survey.getDinerCount(); dinerIndex++) {
SimpleRegression simpleRegression = new SimpleRegression();
- for (int i = 0; i < 11; i++) {
+ for (int i = 0; i < numRecipes/2; i++) {
simpleRegression.addData(i,calculatedPrefs[dinerIndex][i]);
}
double calculatedMSE = simpleRegression.getMeanSquareError();
simpleRegression.clear();
- for (int i = 0; i < 11; i++) {
+ for (int i = 0; i < numRecipes/2; i++) {
simpleRegression.addData(i,surveyPrefs[dinerIndex][i]);
}
double surveyMSE = simpleRegression.getMeanSquareError();
System.out.println("Diner # " + (dinerIndex + 1) + ": " + calculatedMSE + " vs. "+ surveyMSE);
+ }*/
+
+ BayesNet net = FoodNetBuilder.createDishNet(survey, recipeBook);
+ //BayesNet net = FoodExampleBuilder.dishNet();
+
+ printPreference(net, TYPE.PORK);
+ printPreference(net, TYPE.BEEF);
+ printPreference(net, TYPE.POTATO);
+ printPreference(net, TYPE.TOMATO);
+ }
+
+ void printPreference(BayesNet net, TYPE type) {
+ List probs = EnumerateAll.enumerateAsk(new Variable(
+ FoodNetBuilder.TASTE, FoodNetBuilder.RATING_DOMAIN),
+ net, createQuery(type));
+ double max_val = 0.0;
+ String max_arg = "N/A";
+ for (ProbabilityAssignment p : probs) {
+ if (p.getProbability() > max_val) {
+ max_val = p.getProbability();
+ max_arg = p.getValue();
+ }
}
+
+ System.out.println("TASTE " + type + ": " + max_arg + " " + max_val);
+ }
+
+ List createQuery(TYPE type) {
+ List assignment = new LinkedList();
+ switch (type) {
+ case PORK:
+ case BEEF:
+ case POTATO:
+ case TOMATO:
+ assignment.add(new Assignment(new Variable(type.toString(), FoodNetBuilder.DOMAIN),
+ FoodNetBuilder.TRUE_VALUE));
+ break;
+ default:
+ }
+ return assignment;
}
}
diff --git a/src/net/woodyfolsom/cs6601/p2/Ingredient.java b/src/net/woodyfolsom/cs6601/p2/Ingredient.java
index b27da77..26bbfe4 100644
--- a/src/net/woodyfolsom/cs6601/p2/Ingredient.java
+++ b/src/net/woodyfolsom/cs6601/p2/Ingredient.java
@@ -4,7 +4,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("ing")
public class Ingredient {
- public enum TYPE { ALCOHOL, DAIRY, EGGS, FISH, GLUTEN, GRAIN, NUTS, PORK, POULTRY, RED_MEAT, SHELLFISH, SPICE, SUGAR}
+ public enum TYPE { ALCOHOL, BEEF, DAIRY, EGGS, FISH, GLUTEN, GRAIN, NUTS, PORK, POULTRY, POTATO, SHELLFISH, SPICE, SUGAR, TOMATO}
private String item;
@@ -14,20 +14,31 @@ public class Ingredient {
public boolean isType(TYPE type) {
switch (type) {
+ case BEEF :
+ return item.contains("beef");
case DAIRY :
return item.contains("margarine");
case EGGS :
return item.equals("egg") || item.equals("eggs");
case GLUTEN :
return item.contains("flour");
- case RED_MEAT :
- return item.contains("beef");
+ case PORK :
+ return item.contains("pork");
+ case POTATO :
+ return item.contains("potato");
case SPICE :
return item.endsWith("cinnamon") || item.endsWith("nutmeg") || item.endsWith("cloves");
case SUGAR :
return item.endsWith("sugar");
+ case TOMATO :
+ return item.contains("tomato");
default : //unknown ingredient, e.g. coffee, bananas, honey
return false;
}
}
+
+ public Object readResolve() {
+ item = item.toLowerCase();
+ return this;
+ }
}
diff --git a/src/net/woodyfolsom/cs6601/p2/RecipeBook.java b/src/net/woodyfolsom/cs6601/p2/RecipeBook.java
index 7f557ac..0dab8f9 100644
--- a/src/net/woodyfolsom/cs6601/p2/RecipeBook.java
+++ b/src/net/woodyfolsom/cs6601/p2/RecipeBook.java
@@ -15,6 +15,16 @@ public class RecipeBook {
return recipes.get(index);
}
+ //TODO build an index of recipes by name?
+ public Recipe getRecipe(String recipeName) {
+ for (Recipe recipe : recipes) {
+ if (recipeName.equalsIgnoreCase(recipe.getHead().getTitle())) {
+ return recipe;
+ }
+ }
+ return null;
+ }
+
public int getSize() {
return recipes.size();
}
diff --git a/test/dkohl/bayes/example/AlarmExampleTest.java b/test/dkohl/bayes/example/AlarmExampleTest.java
index 303c225..97aa174 100644
--- a/test/dkohl/bayes/example/AlarmExampleTest.java
+++ b/test/dkohl/bayes/example/AlarmExampleTest.java
@@ -4,7 +4,7 @@ import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import java.util.LinkedList;
+import java.util.List;
import org.junit.Test;
@@ -22,7 +22,7 @@ public class AlarmExampleTest {
BayesNet sprinkler = AlarmNetBuilderTable.alarm();
sprinkler = AlarmNetBuilderTree.sprinkler();
// P(B | j, m)
- LinkedList probs = EnumerateAll.enumerateAsk(
+ List probs = EnumerateAll.enumerateAsk(
new Variable(AlarmNetBuilderTable.BURGLARY,
AlarmNetBuilderTable.DOMAIN), sprinkler,
AlarmNetBuilderTable.completeQueryBulgary());
diff --git a/test/dkohl/bayes/example/FoodExampleTest.java b/test/dkohl/bayes/example/FoodExampleTest.java
index b75ac77..bbdc069 100644
--- a/test/dkohl/bayes/example/FoodExampleTest.java
+++ b/test/dkohl/bayes/example/FoodExampleTest.java
@@ -1,11 +1,11 @@
package dkohl.bayes.example;
-import java.util.LinkedList;
-
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import java.util.List;
+
import org.junit.Test;
import dkohl.bayes.bayesnet.BayesNet;
@@ -119,7 +119,7 @@ public class FoodExampleTest {
+ dist.getAssignments().get(assignment));
}
- LinkedList probs = EnumerateAll.enumerateAsk(
+ List probs = EnumerateAll.enumerateAsk(
new Variable(FoodExampleBuilder.TASTE,
FoodExampleBuilder.RATING_DOMAIN), net,
FoodExampleBuilder.completeQueryTasteBeef());
@@ -145,7 +145,7 @@ public class FoodExampleTest {
}
}
- System.out.println("TASE PORK: " + max_arg + " " + max_val);
+ System.out.println("TASTE PORK: " + max_arg + " " + max_val);
assertThat(max_arg, equalTo("10"));
assertTrue("Error: max_val for TASTE_PORK should be > 2.6%", max_val > 0.026);
}
diff --git a/test/dkohl/bayes/example/builders/FoodExampleBuilder.java b/test/dkohl/bayes/example/builders/FoodExampleBuilder.java
index b3b100f..3bcc9c8 100644
--- a/test/dkohl/bayes/example/builders/FoodExampleBuilder.java
+++ b/test/dkohl/bayes/example/builders/FoodExampleBuilder.java
@@ -3,6 +3,8 @@ package dkohl.bayes.example.builders;
import java.util.HashSet;
import java.util.LinkedList;
+import net.woodyfolsom.cs6601.p2.Ingredient.TYPE;
+
import dkohl.bayes.bayesnet.BayesNet;
import dkohl.bayes.estimation.MaximumLikelihoodEstimation;
import dkohl.bayes.probability.Assignment;
@@ -21,13 +23,13 @@ public class FoodExampleBuilder {
public static final String SOMEONE_VEGETARIAN = "Vegetarian";
public static final String CONTAINS_MEAT = "Meat";
public static final String CONTAINS_VEGETABLE = "Vegetable";
- public static final String CONTAINS_BEEF = "Beef";
- public static final String CONTAINS_PORK = "Pork";
- public static final String CONTAINS_TOMATOS = "Tomatos";
- public static final String CONTAINS_POTATOS = "Potatos";
+ public static final String CONTAINS_BEEF = TYPE.BEEF.toString();
+ public static final String CONTAINS_PORK = TYPE.PORK.toString();
+ public static final String CONTAINS_TOMATOS = TYPE.TOMATO.toString();
+ public static final String CONTAINS_POTATOS = TYPE.POTATO.toString();
- public static final String TRUE_VALUE = "true";
- public static final String FALSE_VALUE = "false";
+ public static final String TRUE_VALUE = Boolean.TRUE.toString();
+ public static final String FALSE_VALUE = Boolean.FALSE.toString();
public static final String DOMAIN[] = { TRUE_VALUE, FALSE_VALUE };
diff --git a/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java b/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java
index a5af10c..3871b76 100644
--- a/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java
+++ b/test/net/woodyfolsom/cs6601/p2/RecipeBookReaderTest.java
@@ -29,7 +29,7 @@ public class RecipeBookReaderTest {
assertTrue(recipe.getIngredients().contains(TYPE.EGGS));
assertTrue(recipe.getIngredients().contains(TYPE.GLUTEN));
assertTrue(recipe.getIngredients().contains(TYPE.SPICE));
- assertFalse(recipe.getIngredients().contains(TYPE.RED_MEAT));
+ assertFalse(recipe.getIngredients().contains(TYPE.BEEF));
assertFalse(recipe.getIngredients().contains(TYPE.POULTRY));
assertFalse(recipe.getIngredients().contains(TYPE.SHELLFISH));
@@ -37,4 +37,44 @@ public class RecipeBookReaderTest {
System.out.println(recipeBook.getRecipe(rIndex).getHead().getTitle());
}
}
+
+ @Test
+ public void testReadShortSurveyDataset() {
+ RecipeBook recipeBook = RecipeBookReader.readRecipeBook(new File("data/short_recipebook.xml"));
+ assertNotNull(recipeBook);
+ assertThat(recipeBook.getSize(), is(equalTo(4)));
+
+ for (int i = 0; i < 4; i++) {
+ Recipe recipe = recipeBook.getRecipe(i);
+ System.out.println(i + ": " +recipe.getHead().getTitle());
+ }
+
+ Recipe recipe = recipeBook.getRecipe(0);
+ assertThat(recipe.getHead().getTitle(), is(equalTo("Catalan Rice")));
+ assertTrue(recipe.getIngredients().contains(TYPE.PORK));
+ assertFalse(recipe.getIngredients().contains(TYPE.BEEF));
+ assertFalse(recipe.getIngredients().contains(TYPE.POTATO));
+ assertTrue(recipe.getIngredients().contains(TYPE.TOMATO));
+
+ recipe = recipeBook.getRecipe(1);
+ assertThat(recipe.getHead().getTitle(), is(equalTo("Hamburger Steak")));
+ assertFalse(recipe.getIngredients().contains(TYPE.PORK));
+ assertTrue(recipe.getIngredients().contains(TYPE.BEEF));
+ assertFalse(recipe.getIngredients().contains(TYPE.POTATO));
+ assertFalse(recipe.getIngredients().contains(TYPE.TOMATO));
+
+ recipe = recipeBook.getRecipe(2);
+ assertThat(recipe.getHead().getTitle(), is(equalTo("Potatoes in a Thick Sauce")));
+ assertFalse(recipe.getIngredients().contains(TYPE.PORK));
+ assertFalse(recipe.getIngredients().contains(TYPE.BEEF));
+ assertTrue(recipe.getIngredients().contains(TYPE.POTATO));
+ assertTrue(recipe.getIngredients().contains(TYPE.TOMATO));
+
+ recipe = recipeBook.getRecipe(3);
+ assertThat(recipe.getHead().getTitle(), is(equalTo("Tomato-Zucchini Casserole")));
+ assertFalse(recipe.getIngredients().contains(TYPE.PORK));
+ assertFalse(recipe.getIngredients().contains(TYPE.BEEF));
+ assertFalse(recipe.getIngredients().contains(TYPE.POTATO));
+ assertTrue(recipe.getIngredients().contains(TYPE.TOMATO));
+ }
}