Example 2: Build And Propagate
The second example describes how a Bayesian network can be constructed using the Hugin C#/.NET Core API. The Bayesian network constructed consists of three numbered nodes. Two of the nodes take on values 0, 1, and 2. The third node is the sum of the two other nodes. Once the Bayesian network is constructed, the network is saved to a NET specification file and an initial propagation is performed. Finally, the marginals of the nodes are printed on standard output.
# if X64
using size_t = System.UInt64;
using h_index_t = System.Int64;
# else
using size_t = System.UInt32;
using h_index_t = System.Int32;
# endif
# if H_DOUBLE
using h_number_t = System.Double;
# else
using h_number_t = System.Single;
# endif
using System;
using System.Drawing;
using HAPI;
namespace Example
{
public class BAP
{
protected Domain domain;
// Build a Bayesian network and propagate evidence.
public BAP()
{
domain = new Domain();
BuildNetwork();
domain.SaveAsNet("builddomain.net");
domain.Compile();
PropagateEvidenceInNetwork();
}
// Propagate evidence in domain.
protected void PropagateEvidenceInNetwork()
{
domain.Propagate(Domain.Equilibrium.H_EQUILIBRIUM_SUM,
Domain.EvidenceMode.H_EVIDENCE_MODE_NORMAL);
PrintNodeMarginals(domain);
}
// Print node marginals.
protected void PrintNodeMarginals(Domain d)
{
foreach (Node n in domain.GetNodes())
{
DiscreteChanceNode node = (DiscreteChanceNode)n;
size_t nStates = node.GetNumberOfStates();
Console.WriteLine(node.GetLabel());
for (size_t i = 0; i < nStates; i++)
Console.WriteLine("-" + node.GetStateLabel(i) + " "
+ node.GetBelief(i));
}
}
// Construct numbered discrete chance node.
protected NumberedDCNode ConstructNDC(String label, String name, size_t n)
{
NumberedDCNode node = new NumberedDCNode(domain);
node.SetNumberOfStates(n);
for (size_t i = 0; i < n; i++)
node.SetStateValue(i, i);
node.SetLabel(label);
node.SetName(name);
return node;
}
// Build the structure.
protected void BuildStructure
(NumberedDCNode A, NumberedDCNode B, NumberedDCNode C)
{
C.AddParent(A);
C.AddParent(B);
A.SetPosition(new Point(100, 200));
B.SetPosition(new Point(200, 200));
C.SetPosition(new Point(150, 50));
}
// Expression for C
protected void BuildExpressionForC
(NumberedDCNode A, NumberedDCNode B, NumberedDCNode C)
{
NodeList modelNodes = new NodeList();
Model model = new Model(C, modelNodes);
NodeExpression exprA = new NodeExpression(A);
NodeExpression exprB = new NodeExpression(B);
AddExpression exprC = new AddExpression(exprA, exprB);
model.SetExpression(0, exprC);
}
// Specify the prior distribution of A and B.
protected void SpecifyDistributions(NumberedDCNode A, NumberedDCNode B)
{
Table table = A.GetTable();
h_number_t[] data = table.GetData();
data[0] = (h_number_t)0.1;
data[1] = (h_number_t)0.2;
data[2] = (h_number_t)0.7;
table.SetData(data);
table = B.GetTable();
data = table.GetData();
data[0] = (h_number_t)0.2;
data[1] = (h_number_t)0.2;
data[2] = (h_number_t)0.6;
table.SetData(data);
}
// Build the Bayesian network.
public void BuildNetwork()
{
domain.SetNodeSize(new Size(50, 30));
NumberedDCNode A = ConstructNDC("A1234567890123", "A", 3);
NumberedDCNode B = ConstructNDC("B", "B", 3);
NumberedDCNode C = ConstructNDC("C", "C", 5);
BuildStructure(A, B, C);
BuildExpressionForC(A, B, C);
SpecifyDistributions(A, B);
}
// Build a Bayesian network and perform a propagation of evidence.
// Print the results.
public static int Main()
{
try
{
new BAP();
}
catch (ExceptionHugin e)
{
Console.WriteLine(e);
return -1;
}
return 0;
}
}
}