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
|
|
|
|
2013-02-08 21:12:46 +00:00
|
|
|
namespace Horus {
|
2013-02-07 23:53:13 +00:00
|
|
|
|
2013-02-13 14:26:47 +00:00
|
|
|
class ElimGraph {
|
2012-05-23 14:56:01 +01:00
|
|
|
public:
|
2013-03-09 15:39:39 +00:00
|
|
|
enum class ElimHeuristic {
|
2013-02-20 12:52:55 +00:00
|
|
|
sequentialEh,
|
|
|
|
minNeighborsEh,
|
|
|
|
minWeightEh,
|
|
|
|
minFillEh,
|
|
|
|
weightedMinFillEh
|
|
|
|
};
|
|
|
|
|
2012-05-29 17:12:57 +01:00
|
|
|
ElimGraph (const Factors&);
|
2012-05-23 14:56:01 +01:00
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
~ElimGraph();
|
2012-12-17 18:39:42 +00:00
|
|
|
|
2012-05-23 14:56:01 +01:00
|
|
|
VarIds getEliminatingOrder (const VarIds&);
|
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
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
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
static ElimHeuristic elimHeuristic() { return elimHeuristic_; }
|
2012-12-27 15:44:40 +00:00
|
|
|
|
|
|
|
static void setElimHeuristic (ElimHeuristic eh) { elimHeuristic_ = eh; }
|
2012-05-23 14:56:01 +01:00
|
|
|
|
|
|
|
private:
|
2013-02-20 13:49:01 +00:00
|
|
|
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); }
|
|
|
|
|
2013-02-28 19:45:37 +00:00
|
|
|
const EGNeighs& neighbors() const { return neighs_; }
|
2013-02-20 13:49:01 +00:00
|
|
|
|
|
|
|
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-06 00:24:02 +00:00
|
|
|
|
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
|
|
|
|
2013-02-28 19:45:37 +00: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_;
|
2012-12-27 15:44:40 +00:00
|
|
|
|
|
|
|
static ElimHeuristic elimHeuristic_;
|
2012-12-27 22:25:45 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN (ElimGraph);
|
2012-05-23 14:56:01 +01:00
|
|
|
};
|
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
|
|
|
|
|
2013-02-20 23:08:12 +00:00
|
|
|
/* Profiling shows that we should inline the following functions */
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-02-06 00:24:02 +00:00
|
|
|
inline void
|
2013-02-16 17:03:12 +00:00
|
|
|
ElimGraph::addEdge (EGNode* n1, EGNode* n2)
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
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
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
return n->neighbors().size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline unsigned
|
2013-02-16 17:03:12 +00:00
|
|
|
ElimGraph::getWeightCost (const EGNode* n) const
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
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
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
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
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
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
|
2013-02-06 00:24:02 +00:00
|
|
|
{
|
|
|
|
return n1->isNeighbor (n2);
|
|
|
|
}
|
|
|
|
|
2013-02-08 21:12:46 +00:00
|
|
|
} // 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
|
|
|
|