209 lines
4.0 KiB
C++
209 lines
4.0 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
|
|
#include "BayesianNetwork.h"
|
|
#include "BayesianNode.h"
|
|
|
|
BayesianNetwork::BayesianNetwork (void)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
BayesianNetwork::~BayesianNetwork (void)
|
|
{
|
|
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
|
delete nodes_[i];
|
|
}
|
|
for (unsigned int i = 0; i < dists_.size(); i++) {
|
|
delete dists_[i];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void
|
|
BayesianNetwork::addNode (string varName,
|
|
vector<BayesianNode*> parents,
|
|
int evidence,
|
|
int distId)
|
|
{
|
|
for (unsigned int i = 0; i < dists_.size(); i++) {
|
|
if (dists_[i]->id == distId) {
|
|
BayesianNode* node = new BayesianNode (varName, parents,
|
|
dists_[i], evidence);
|
|
nodes_.push_back (node);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
BayesianNetwork::addNode (string varName,
|
|
vector<BayesianNode*> parents,
|
|
double* params,
|
|
int nParams,
|
|
vector<string> domain)
|
|
{
|
|
Distribution* dist = new Distribution (params, nParams, domain);
|
|
BayesianNode* node = new BayesianNode (varName, parents, dist);
|
|
dists_.push_back (dist);
|
|
nodes_.push_back (node);
|
|
}
|
|
|
|
|
|
|
|
BayesianNode*
|
|
BayesianNetwork::getNode (string varName) const
|
|
{
|
|
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
|
if (nodes_[i]->getVariableName() == varName) {
|
|
return nodes_[i];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
void
|
|
BayesianNetwork::addDistribution (int distId,
|
|
double* params,
|
|
int nParams,
|
|
vector<string> domain)
|
|
{
|
|
dists_.push_back (new Distribution (distId, params, nParams, domain));
|
|
}
|
|
|
|
|
|
|
|
vector<BayesianNode*>
|
|
BayesianNetwork::getNodes (void) const
|
|
{
|
|
return nodes_;
|
|
}
|
|
|
|
|
|
|
|
vector<BayesianNode*>
|
|
BayesianNetwork::getRootNodes (void) const
|
|
{
|
|
vector<BayesianNode*> roots;
|
|
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
|
if (nodes_[i]->isRoot()) {
|
|
roots.push_back (nodes_[i]);
|
|
}
|
|
}
|
|
return roots;
|
|
}
|
|
|
|
|
|
|
|
vector<BayesianNode*>
|
|
BayesianNetwork::getLeafNodes (void) const
|
|
{
|
|
vector<BayesianNode*> leafs;
|
|
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
|
if (nodes_[i]->isLeaf()) {
|
|
leafs.push_back (nodes_[i]);
|
|
}
|
|
}
|
|
return leafs;
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
BayesianNetwork::isPolyTree (void) const
|
|
{
|
|
return !containsCycle();
|
|
}
|
|
|
|
|
|
|
|
void
|
|
BayesianNetwork::printNetwork (void) const
|
|
{
|
|
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
|
cout << *nodes_[i];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
BayesianNetwork::containsCycle (void) const
|
|
{
|
|
vector<bool> visited (nodes_.size());
|
|
for (unsigned int v = 0; v < nodes_.size(); v++) {
|
|
visited[v] = false;
|
|
}
|
|
|
|
for (unsigned int v = 0; v < nodes_.size(); v++) {
|
|
if (!visited[v]) {
|
|
if (containsCycle (v, -1, visited)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
BayesianNetwork::containsCycle (int v,
|
|
int predecessor,
|
|
vector<bool>& visited) const
|
|
{
|
|
visited[v] = true;
|
|
vector<int> adjs = getAdjacentVertexes (v);
|
|
for (unsigned int i = 0; i < adjs.size(); i++) {
|
|
int w = adjs[i];
|
|
if (!visited[w]) {
|
|
if (containsCycle (w, v, visited)) {
|
|
return true;
|
|
}
|
|
}
|
|
else if (visited[w] && w != predecessor) {
|
|
return true;
|
|
}
|
|
}
|
|
return false; // no cycle detected in this component
|
|
}
|
|
|
|
|
|
|
|
int
|
|
BayesianNetwork::getIndexOf (const BayesianNode* node) const
|
|
{
|
|
for (unsigned int i = 0; i < nodes_.size(); i++) {
|
|
if (node == nodes_[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
vector<int>
|
|
BayesianNetwork::getAdjacentVertexes (int v) const
|
|
{
|
|
vector<int> adjs;
|
|
vector<BayesianNode*> parents = nodes_[v]->getParents();
|
|
vector<BayesianNode*> childs = nodes_[v]->getChilds();
|
|
for (unsigned int i = 0; i < parents.size(); i++) {
|
|
adjs.push_back (getIndexOf (parents[i]));
|
|
}
|
|
for (unsigned int i = 0; i < childs.size(); i++) {
|
|
adjs.push_back (getIndexOf (childs[i]));
|
|
}
|
|
return adjs;
|
|
}
|
|
|