/******************************************************************************* * Copyright 2014 Felipe Takiyama * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package br.usp.poli.takiyama.samples; import java.math.BigDecimal; import java.util.Arrays; import java.util.HashSet; import java.util.List; import br.usp.poli.takiyama.cfove.StdParfactor.StdParfactorBuilder; import br.usp.poli.takiyama.common.Constraint; import br.usp.poli.takiyama.common.Factor; import br.usp.poli.takiyama.common.Marginal; import br.usp.poli.takiyama.common.Parfactor; import br.usp.poli.takiyama.common.StdMarginal.StdMarginalBuilder; import br.usp.poli.takiyama.prv.Binding; import br.usp.poli.takiyama.prv.LogicalVariable; import br.usp.poli.takiyama.prv.Prv; import br.usp.poli.takiyama.prv.RandomVariableSet; import br.usp.poli.takiyama.prv.StdLogicalVariable; import br.usp.poli.takiyama.prv.StdPrv; import br.usp.poli.takiyama.prv.Substitution; import br.usp.poli.takiyama.prv.Term; import br.usp.poli.takiyama.utils.Sets; import br.usp.poli.takiyama.utils.TestUtils; /** * Water sprinkler network proposed by Kevin Murphy. The network was * adapted to a lifted version: sprinkler and wet_grass are random * variables parameterized on a logical variable Lot. * <p> * The original network is shown * <a href='http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html'>here</a> * </p> * <p> * The number of nodes in this network is 2 * (domainSize + 1) * </p> * * @author Felipe Takiyama */ public final class WaterSprinklerNetwork { public final int domainSize; public final LogicalVariable lot; public final Prv cloudy; public final Prv rain; public final Prv sprinkler; public final Prv wetGrass; public final Parfactor cloudyParfactor; public final Parfactor rainParfactor; public final Parfactor sprinklerParfactor; public final Parfactor wetGrassParfactor; public Parfactor evidenceParfactor; public RandomVariableSet query; public WaterSprinklerNetwork(int domainSize) { // initializing domain size this.domainSize = domainSize; // initializing the logical variable this.lot = StdLogicalVariable.getInstance("Lot", "lot", domainSize); // initializing PRVs this.cloudy = StdPrv.getBooleanInstance("cloudy"); this.rain = StdPrv.getBooleanInstance("rain"); this.sprinkler = StdPrv.getBooleanInstance("sprinkler", lot); this.wetGrass = StdPrv.getBooleanInstance("wet_grass", lot); // initializing value arrays used in factors List<BigDecimal> fCloudy = TestUtils.toBigDecimalList(0.5, 0.5); List<BigDecimal> fRain = TestUtils.toBigDecimalList(0.8, 0.2, 0.2, 0.8); List<BigDecimal> fSprinkler = TestUtils.toBigDecimalList(0.5, 0.5, 0.9, 0.1); List<BigDecimal> fWetGrass = TestUtils.toBigDecimalList(1.0, 0.0, 0.1, 0.9, 0.1, 0.9, 0.01, 0.99); // initializing parfactors this.cloudyParfactor = new StdParfactorBuilder().variables(cloudy).values(fCloudy).build(); this.rainParfactor = new StdParfactorBuilder().variables(cloudy, rain).values(fRain).build(); this.sprinklerParfactor = new StdParfactorBuilder().variables(cloudy, sprinkler).values(fSprinkler).build(); this.wetGrassParfactor = new StdParfactorBuilder().variables(sprinkler, rain, wetGrass).values(fWetGrass).build(); } public void setEvidence(Prv evidence, int index) { if (evidence.parameters().size() > 0) { Substitution lot_i = getLot(index); Prv evidenceVariable = evidence.apply(lot_i); evidenceParfactor = new StdParfactorBuilder().variables(evidenceVariable).values(0.0, 1.0).build(); } else { evidenceParfactor = new StdParfactorBuilder().variables(evidence).values(0.0, 1.0).build(); } } public void setQuery(Prv query, Constraint ... constraints) { this.query = RandomVariableSet.getInstance(query, new HashSet<Constraint>(Arrays.asList(constraints))); } public Marginal getMarginal() { Marginal marginal; if (evidenceParfactor == null) { marginal = new StdMarginalBuilder(4).parfactors(cloudyParfactor, rainParfactor, sprinklerParfactor, wetGrassParfactor) .preservable(query).build(); } else { marginal = new StdMarginalBuilder(5).parfactors(cloudyParfactor, rainParfactor, sprinklerParfactor, wetGrassParfactor, evidenceParfactor).preservable(query).build(); } return marginal; } public Substitution getLot(int index) { Term individual = lot.population().individualAt(index); Substitution lot_i = Substitution.getInstance(Binding.getInstance(lot, individual)); return lot_i; } }