2008-05-02 22:19:38 +08:00
|
|
|
/*
|
|
|
|
This is an example illustrating the use of the Bayesian Network
|
|
|
|
inference utilities found in the dlib C++ library. In this example
|
|
|
|
we load a saved Bayesian Network from disk.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "dlib/bayes_utils.h"
|
|
|
|
#include "dlib/graph_utils.h"
|
|
|
|
#include "dlib/graph.h"
|
|
|
|
#include "dlib/directed_graph.h"
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
|
|
using namespace dlib;
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// This statement declares a bayesian network called bn. Note that a bayesian network
|
|
|
|
// in the dlib world is just a directed_graph object that contains a special kind
|
|
|
|
// of node called a bayes_node.
|
|
|
|
directed_graph<bayes_node>::kernel_1a_c bn;
|
|
|
|
|
|
|
|
if (argc != 2)
|
|
|
|
{
|
|
|
|
cout << "You must supply a file name on the command line. The file should "
|
|
|
|
<< "contain a serialized Bayesian Network" << endl;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ifstream fin(argv[1],ios::binary);
|
|
|
|
|
|
|
|
// Note that the saved networks produced by the bayes_net_gui_ex.cpp example can be deserialized
|
|
|
|
// into a network. So you can make your networks using that GUI if you like.
|
|
|
|
cout << "Loading the network from disk..." << endl;
|
|
|
|
deserialize(bn, fin);
|
|
|
|
|
|
|
|
cout << "Number of nodes in the network: " << bn.number_of_nodes() << endl;
|
|
|
|
|
|
|
|
// Lets compute some probability values using the loaded network using the join tree (aka. Junction
|
|
|
|
// Tree) algorithm.
|
|
|
|
|
|
|
|
// First we need to create an undirected graph which contains set objects at each node and
|
|
|
|
// edge. This long declaration does the trick.
|
|
|
|
typedef graph<set<unsigned long>::compare_1b_c, set<unsigned long>::compare_1b_c>::kernel_1a_c join_tree_type;
|
|
|
|
join_tree_type join_tree;
|
|
|
|
|
2008-07-15 10:31:58 +08:00
|
|
|
// Now we need to populate the join_tree with data from our bayesian network. The next two
|
2008-05-02 22:19:38 +08:00
|
|
|
// function calls do this. Explaining exactly what they do is outside the scope of this
|
|
|
|
// example. Just think of them as filling join_tree with information that is useful
|
|
|
|
// later on for dealing with our bayesian network.
|
|
|
|
create_moral_graph(bn, join_tree);
|
|
|
|
create_join_tree(join_tree, join_tree);
|
|
|
|
|
|
|
|
// Now we have a proper join_tree we can use it to obtain a solution to our
|
|
|
|
// bayesian network. Doing this is as simple as declaring an instance of
|
|
|
|
// the bayesian_network_join_tree object as follows:
|
|
|
|
bayesian_network_join_tree solution(bn, join_tree);
|
|
|
|
|
|
|
|
|
|
|
|
// now print out the probabilities for each node
|
|
|
|
cout << "Using the join tree algorithm:\n";
|
|
|
|
for (unsigned long i = 0; i < bn.number_of_nodes(); ++i)
|
|
|
|
{
|
|
|
|
// print out the probability distribution for node i.
|
|
|
|
cout << "p(node " << i <<") = " << solution.probability(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (exception& e)
|
|
|
|
{
|
|
|
|
cout << "exception thrown: " << e.what() << endl;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|