This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/CLPBN/horus/ElimGraph.h

178 lines
3.5 KiB
C
Raw Normal View History

2013-02-07 17:50:02 +00:00
#ifndef YAP_PACKAGES_CLPBN_HORUS_ELIMGRAPH_H_
#define YAP_PACKAGES_CLPBN_HORUS_ELIMGRAPH_H_
2012-05-23 14:56:01 +01:00
2013-02-07 20:09:10 +00:00
#include <cassert>
#include <vector>
#include <unordered_map>
2012-05-23 14:56:01 +01:00
#include "FactorGraph.h"
#include "TinySet.h"
#include "Horus.h"
2013-02-07 13:37:15 +00:00
namespace Horus {
2013-02-07 23:53:13 +00:00
class ElimGraph {
2012-05-23 14:56:01 +01:00
public:
enum class ElimHeuristic {
sequentialEh,
minNeighborsEh,
minWeightEh,
minFillEh,
weightedMinFillEh
};
2012-05-29 17:12:57 +01:00
ElimGraph (const Factors&);
2012-05-23 14:56:01 +01:00
~ElimGraph();
2012-12-17 18:39:42 +00:00
2012-05-23 14:56:01 +01:00
VarIds getEliminatingOrder (const VarIds&);
void print() const;
2012-05-23 14:56:01 +01:00
void exportToGraphViz (const char*, bool = true,
const VarIds& = VarIds()) const;
2012-05-29 17:12:57 +01:00
static VarIds getEliminationOrder (const Factors&, VarIds);
2012-05-23 14:56:01 +01:00
static ElimHeuristic elimHeuristic() { return elimHeuristic_; }
static void setElimHeuristic (ElimHeuristic eh) { elimHeuristic_ = eh; }
2012-05-23 14:56:01 +01:00
private:
class EGNode;
typedef TinySet<EGNode*> EGNeighs;
class EGNode : public Var {
public:
EGNode (VarId vid, unsigned range) : Var (vid, range) { }
void addNeighbor (EGNode* n) { neighs_.insert (n); }
void removeNeighbor (EGNode* n) { neighs_.remove (n); }
bool isNeighbor (EGNode* n) const { return neighs_.contains (n); }
const EGNeighs& neighbors() const { return neighs_; }
private:
EGNeighs neighs_;
};
2013-02-16 17:03:12 +00:00
void addEdge (EGNode* n1, EGNode* n2);
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
unsigned getNeighborsCost (const EGNode* n) const;
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
unsigned getWeightCost (const EGNode* n) const;
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
unsigned getFillCost (const EGNode* n) const;
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
unsigned getWeightedFillCost (const EGNode* n) const;
2013-02-16 17:03:12 +00:00
bool neighbors (EGNode* n1, EGNode* n2) const;
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
void addNode (EGNode*);
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
EGNode* getEGNode (VarId) const;
2012-05-23 14:56:01 +01:00
EGNode* getLowestCostNode() const;
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
void connectAllNeighbors (const EGNode*);
2012-05-23 14:56:01 +01:00
2013-02-16 17:03:12 +00:00
std::vector<EGNode*> nodes_;
EGNeighs unmarked_;
std::unordered_map<VarId, EGNode*> varMap_;
static ElimHeuristic elimHeuristic_;
2012-12-27 22:25:45 +00:00
DISALLOW_COPY_AND_ASSIGN (ElimGraph);
2012-05-23 14:56:01 +01:00
};
/* Profiling shows that we should inline the following functions */
inline void
2013-02-16 17:03:12 +00:00
ElimGraph::addEdge (EGNode* n1, EGNode* n2)
{
assert (n1 != n2);
n1->addNeighbor (n2);
n2->addNeighbor (n1);
}
inline unsigned
2013-02-16 17:03:12 +00:00
ElimGraph::getNeighborsCost (const EGNode* n) const
{
return n->neighbors().size();
}
inline unsigned
2013-02-16 17:03:12 +00:00
ElimGraph::getWeightCost (const EGNode* n) const
{
unsigned cost = 1;
const EGNeighs& neighs = n->neighbors();
for (size_t i = 0; i < neighs.size(); i++) {
cost *= neighs[i]->range();
}
return cost;
}
inline unsigned
2013-02-16 17:03:12 +00:00
ElimGraph::getFillCost (const EGNode* n) const
{
unsigned cost = 0;
const EGNeighs& neighs = n->neighbors();
if (neighs.size() > 0) {
for (size_t i = 0; i < neighs.size() - 1; i++) {
for (size_t j = i + 1; j < neighs.size(); j++) {
if ( ! neighbors (neighs[i], neighs[j])) {
cost ++;
}
}
}
}
return cost;
}
inline unsigned
2013-02-16 17:03:12 +00:00
ElimGraph::getWeightedFillCost (const EGNode* n) const
{
unsigned cost = 0;
const EGNeighs& neighs = n->neighbors();
if (neighs.size() > 0) {
for (size_t i = 0; i < neighs.size() - 1; i++) {
for (size_t j = i + 1; j < neighs.size(); j++) {
if ( ! neighbors (neighs[i], neighs[j])) {
cost += neighs[i]->range() * neighs[j]->range();
}
}
}
}
return cost;
}
inline bool
2013-02-16 17:03:12 +00:00
ElimGraph::neighbors (EGNode* n1, EGNode* n2) const
{
return n1->isNeighbor (n2);
}
} // namespace Horus
2013-02-07 23:53:13 +00:00
2013-02-08 00:20:01 +00:00
#endif // YAP_PACKAGES_CLPBN_HORUS_ELIMGRAPH_H_
2012-05-23 14:56:01 +01:00