59 template <
typename GUM_SCALAR >
62 const std::string& domain) {
66 std::string ds = domain;
67 switch (*(node.begin())) {
77 default : isChanc =
true;
84 }
catch (gum::NotFound&) {
90 "No type (chance, decision or utility) for the node '" << node <<
"'.")
96 template <
typename GUM_SCALAR >
97 InfluenceDiagram< GUM_SCALAR >
99 return fastPrototype(dotlike,
"[" + std::to_string(domainSize) +
"]");
102 template <
typename GUM_SCALAR >
105 const std::string& domain) {
110 bool notfirst =
false;
111 for (
const auto& souschaine:
split(chaine,
"->")) {
113 for (
auto& node:
split(souschaine,
"<-")) {
117 infdiag.
addArc(lastId, idVar);
120 infdiag.
addArc(idVar, lastId);
131 for (
const auto n: infdiag.
nodes()) {
147 template <
typename GUM_SCALAR >
155 template <
typename GUM_SCALAR >
164 template <
typename GUM_SCALAR >
173 template <
typename GUM_SCALAR >
176 if (
this != &source) {
185 template <
typename GUM_SCALAR >
189 _variableMap_.clear();
192 _utilityMap_.clear();
198 template <
typename GUM_SCALAR >
200 for (
const auto node:
dag_.nodes()) {
209 template <
typename GUM_SCALAR >
212 for (
auto node: IDsource.
nodes()) {
219 for (
auto node: IDsource.
nodes()) {
223 addArc(IDsource.
cpt(node).variable(par).name(), s);
235 for (
auto node: IDsource.
nodes()) {
238 cpt(node).fillWith(IDsource.
cpt(s));
245 template <
typename GUM_SCALAR >
247 std::stringstream output;
248 std::stringstream decisionNode;
249 std::stringstream utilityNode;
250 std::stringstream chanceNode;
251 std::stringstream arcstream;
252 output <<
"digraph \"";
255 output << this->
property(
"name") <<
"\" {" << std::endl;
256 }
catch (
NotFound const&) { output <<
"no_name\" {" << std::endl; }
258 output <<
" node [bgcolor=\"#AAAAAA\", style=filled, height=0];" << std::endl;
260 decisionNode <<
"node [shape = box];" << std::endl;
262 utilityNode <<
"node [shape = hexagon, margin=0];" << std::endl;
263 chanceNode <<
"node [shape = ellipse];" << std::endl;
264 std::string tab =
" ";
266 for (
const auto node:
dag_.nodes()) {
268 chanceNode << tab <<
"\"" << node <<
"-" <<
variable(node).name() <<
"\""
271 utilityNode << tab <<
"\"" << node <<
"-" <<
variable(node).name() <<
"\""
274 decisionNode << tab <<
"\"" << node <<
"-" <<
variable(node).name() <<
"\""
277 if (
dag_.children(node).size() > 0)
278 for (
const auto chi:
dag_.children(node)) {
279 arcstream <<
"\"" << node <<
"-" <<
variable(node).name() <<
"\""
281 <<
"\"" << chi <<
"-" <<
variable(chi).name() <<
"\"";
282 if (
isDecisionNode(chi)) { arcstream <<
" [style=\"tapered, bold\"]"; }
283 arcstream <<
";" << std::endl;
287 output << decisionNode.str() << std::endl
288 << utilityNode.str() << std::endl
289 << chanceNode.str() << std::endl
291 << arcstream.str() << std::endl
297 template <
typename GUM_SCALAR >
299 std::stringstream output;
301 output <<
"Influence Diagram{" << std::endl;
305 output <<
" arcs: " <<
dag().sizeArcs() <<
"," << std::endl;
308 if (
double dSize =
log10DomainSize(); dSize > 6) output <<
" domainSize: 10^" << dSize;
309 else output <<
" domainSize: " << std::round(std::pow(10.0, dSize));
311 output << std::endl <<
"}";
323 template <
typename GUM_SCALAR >
331 template <
typename GUM_SCALAR >
339 template <
typename GUM_SCALAR >
347 template <
typename GUM_SCALAR >
359 template <
typename GUM_SCALAR >
367 template <
typename GUM_SCALAR >
375 template <
typename GUM_SCALAR >
383 template <
typename GUM_SCALAR >
392 template <
typename GUM_SCALAR >
400 template <
typename GUM_SCALAR >
408 template <
typename GUM_SCALAR >
414 template <
typename GUM_SCALAR >
420 template <
typename GUM_SCALAR >
430 template <
typename GUM_SCALAR >
440 template <
typename GUM_SCALAR >
448 if (newMultiDim !=
nullptr)
delete newMultiDim;
459 template <
typename GUM_SCALAR >
469 template <
typename GUM_SCALAR >
488 template <
typename GUM_SCALAR >
495 auto varcpt =
new Tensor< GUM_SCALAR >(aContent);
507 template <
typename GUM_SCALAR >
514 "Utility var have no state ( which implicates a "
515 "single label for data output reasons ).")
520 auto varut =
new Tensor< GUM_SCALAR >(aContent);
532 template <
typename GUM_SCALAR >
538 if (DesiredId == 0) proposedId =
dag_.nextNodeId();
539 else proposedId = DesiredId;
543 dag_.addNodeWithId(proposedId);
554 template <
typename GUM_SCALAR >
558 for (
const auto chi:
dag_.children(varId))
571 dag_.eraseNode(varId);
580 template <
typename GUM_SCALAR >
587 template <
typename GUM_SCALAR >
589 const std::string& new_name) {
599 template <
typename GUM_SCALAR >
603 dag_.addArc(tail, head);
619 template <
typename GUM_SCALAR >
621 if (
dag_.existsArc(arc)) {
640 template <
typename GUM_SCALAR >
652 template <
typename GUM_SCALAR >
654 for (
const auto node:
dag_.nodes())
657 for (
const auto node:
dag_.nodes()) {
659 for (
const auto par:
dag_.parents(node)) {
662 for (
const auto par2:
dag_.parents(node))
663 if (par != par2) graph.
addEdge(par, par2);
671 template <
typename GUM_SCALAR >
681 if (orderIter == order.
end())
return true;
683 NodeId parentDecision = (*orderIter);
687 while (orderIter != order.
end()) {
691 parentDecision = *orderIter;
703 template <
typename GUM_SCALAR >
711 mark[src] = (int)src;
714 while (!nodeFIFO.
empty()) {
715 current = nodeFIFO.
front();
718 for (
const auto new_one:
dag_.children(current)) {
719 if (mark[new_one] != -1)
continue;
721 mark[new_one] = (int)current;
723 if (new_one == dest)
break;
729 if (mark[dest] == -1)
return false;
737 template <
typename GUM_SCALAR >
739 auto temporalGraph =
new gum::DAG();
741 for (
const auto node:
dag_.nodes()) {
743 if (!temporalGraph->existsNode(node)) temporalGraph->addNodeWithId(node);
746 if (!temporalGraph->existsNode(chi)) temporalGraph->addNodeWithId(chi);
748 temporalGraph->addArc(node, chi);
753 return temporalGraph;
759 template <
typename GUM_SCALAR >
771 mark[parentDecision] =
true;
775 while (!nodeFIFO.
empty()) {
776 current = nodeFIFO.
front();
779 for (
const auto new_one:
dag_.children(current)) {
780 if (mark[new_one])
continue;
782 mark[new_one] =
true;
785 else childrenSeq.
insert(new_one);
796 template <
typename GUM_SCALAR >
800 std::vector< NodeId > decisionSequence;
805 return decisionSequence;
812 template <
typename GUM_SCALAR >
820 for (
auto i: order) {
823 for (
const auto par:
dag_.parents(i)) {
825 partialOrderedSet.
insert(par);
841 for (
const auto node: nodeList)
850 template <
typename GUM_SCALAR >
852 unsigned int default_nbrmod) {
858 template <
typename GUM_SCALAR >
861 if (v->domainSize() >= 2)
863 v->name() <<
" has a domain size >= 2 which is impossible for a utility node")
867 template <
typename GUM_SCALAR >
869 unsigned int default_nbrmod) {
875 template <
typename GUM_SCALAR >
877 unsigned int default_nbrmod) {
878 std::string node = fast_description;
879 switch (*(node.begin())) {
880 case '*' : node.erase(0, 1);
return addDecisionNode(node, default_nbrmod);
882 default :
return addChanceNode(fast_description, default_nbrmod);
887 template <
typename GUM_SCALAR >
889 for (
const auto node:
nodes())
895 template <
typename GUM_SCALAR >
897 for (
const auto node:
nodes())
902 template <
typename GUM_SCALAR >
904 if (
size() != from.
size()) {
return false; }
911 for (
auto node:
nodes()) {
915 if (v1 != v2) {
return false; }
930 if (p1.
nbrDim() != p2.nbrDim()) {
return false; }
932 if (p1.
domainSize() != p2.domainSize()) {
return false; }
938 for (
Idx indice = 0; indice < p1.
nbrDim(); ++indice) {
943 if (std::pow(p1.
get(i) - p2.get(j), (GUM_SCALAR)2) > (GUM_SCALAR)1e-6) {
return false; }
947 for (
auto node:
nodes()) {
950 if (!check_pot(
cpt(node), from.
cpt(fromnode))) {
return false; }
952 if (!check_pot(
utility(node), from.
utility(fromnode))) {
return false; }
The base class for all directed edges.
GUM_NODISCARD NodeId head() const
returns the head of the arc
GUM_NODISCARD NodeId tail() const
returns the tail of the arc
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
Set of pairs of elements with fast search for both elements.
const DAG & dag() const
Returns a constant reference to the dag of this Bayes Net.
DAG dag_
The DAG of this Directed Graphical Model.
DAGmodel()
Default constructor.
virtual Size size() const final
Returns the number of variables in this Directed Graphical Model.
Size sizeArcs() const
Returns the number of arcs in this Directed Graphical Model.
Sequence< NodeId > topologicalOrder() const
The topological order stays the same as long as no variable or arcs are added or erased src the topol...
const NodeSet & parents(const NodeId id) const
returns the set of nodes with arc ingoing to a given node
const NodeGraphPart & nodes() const final
Returns a constant reference to the dag of this Bayes Net.
Base class for discrete random variable.
virtual Size domainSize() const =0
Base class for all aGrUM's exceptions.
Exception : fatal (unknown ?) error.
void setProperty(const std::string &name, const std::string &value)
Add or change a property of this GraphicalModel.
const std::string & property(const std::string &name) const
Return the value of the property name of this GraphicalModel.
double log10DomainSize() const
Class representing an Influence Diagram.
void beginTopologyTransformation()
When inserting/removing arcs, node CPTs/utilities change their dimension with a cost in time.
List< NodeSet > _temporalOrder_
The temporal order.
gum::DAG * getDecisionGraph() const
Returns the temporal Graph.
const List< NodeSet > & getPartialTemporalOrder(bool clear=true) const
Returns partial temporal ordering.
bool isDecisionNode(NodeId varId) const
Returns true if node is a decision one.
VariableNodeMap _variableMap_
Mapping between id and variable.
virtual const Tensor< GUM_SCALAR > & cpt(NodeId varId) const
Returns the CPT of a tensor variable.
NodeId addChanceNode(const DiscreteVariable &variable, NodeId id=0)
Add a chance variable, it's associate node and it's CPT.
Size chanceNodeSize() const
Returns the number of chance nodes.
void endTopologyTransformation()
terminates a sequence of insertions/deletions of arcs by adjusting all CPTs/utilities dimensions.
void removeTables_()
Removing ancient table.
NodeProperty< Tensor< GUM_SCALAR > * > _tensorMap_
Mapping between tensor variable's id and their CPT.
const VariableNodeMap & variableNodeMap() const final
Returns a constant reference to the VariableNodeMap of this Influence Diagram.
void addArc(NodeId tail, NodeId head)
Add an arc in the ID, and update diagram's tensor nodes cpt if necessary.
virtual void moralGraph_(UndiGraph &graph) const
Returns the moral graph of this InfluenceDiagram.
NodeId addNode_(const DiscreteVariable &variableType, NodeId DesiredId)
Add a node.
std::string toDot() const
bool decisionOrderExists() const
True if a directed path exist with all decision nodes.
Size utilityNodeSize() const
Returns the number of utility nodes.
InfluenceDiagram< GUM_SCALAR > & operator=(const InfluenceDiagram< GUM_SCALAR > &source)
Copy Operator.
void changeVariableName(NodeId id, const std::string &new_name)
we allow the user to change the name of a variable
NodeId add(const DiscreteVariable &variable, NodeId id=0)
Add a chance variable, it's associate node and it's CPT.
static InfluenceDiagram< GUM_SCALAR > fastPrototype(const std::string &dotlike, Size domainSize)
Create an Influence Diagram with a dot-like syntax which specifies:
NodeId addUtilityNode(const DiscreteVariable &variable, NodeId id=0)
Add a utility variable, it's associate node and it's UT.
std::string toString() const
bool isUtilityNode(NodeId varId) const
Returns true if node is a utility one.
void copyStructureAndTables_(const InfluenceDiagram< GUM_SCALAR > &IDsource)
Copying tables from another influence diagram.
NodeId addDecisionNode(const DiscreteVariable &variable, NodeId id=0)
Add a decision variable.
bool isChanceNode(NodeId varId) const
Returns true if node is a chance one.
InfluenceDiagram()
Default constructor.
const DiscreteVariable & variable(NodeId id) const final
Returns a constant reference over a variable given it's node id.
bool operator==(const InfluenceDiagram< GUM_SCALAR > &other) const
void eraseArc(const Arc &arc)
Removes an arc in the ID, and update diagram's tensor nodes cpt if necessary.
NodeProperty< Tensor< GUM_SCALAR > * > _utilityMap_
Mapping between utility variable's id and their utility table.
NodeId nodeId(const DiscreteVariable &var) const final
Return id node from discrete var pointer.
Size decisionNodeSize() const
Returns the number of decision nodes.
Sequence< NodeId > getChildrenDecision_(NodeId parentDecision) const
Returns the list of children decision for a given nodeId.
const DiscreteVariable & variableFromName(const std::string &name) const final
Getter by name.
void erase(NodeId id)
Erase a Variable from the network and remove the variable from all his children.
virtual const Tensor< GUM_SCALAR > & utility(NodeId varId) const
Returns the utility table of a utility node.
std::vector< NodeId > decisionOrder() const
Returns the sequence of decision nodes in the directed path.
NodeId idFromName(const std::string &name) const final
Getter by name.
bool existsPathBetween(NodeId src, NodeId dest) const
Returns true if a path exists between two nodes.
~InfluenceDiagram() override
Destructor.
Class for assigning/browsing values to tuples of discrete variables.
Instantiation & chgVal(const DiscreteVariable &v, Idx newval)
Assign newval to variable v in the Instantiation.
bool end() const
Returns true if the Instantiation reached the end.
void inc()
Operator increment.
Idx val(Idx i) const
Returns the current value of the variable at position i.
void setFirst()
Assign the first values to the tuple of the Instantiation.
const DiscreteVariable & variable(Idx i) const final
Returns the variable at position i in the tuple.
Exception : there is something wrong with an arc.
Exception: at least one argument passed to a function is not what was expected.
Generic doubly linked lists.
Val & front() const
Returns a reference to first element of a list, if any.
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
void popFront()
Removes the first element of a List, if any.
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
Multidimensional matrix stored as an array in memory.
virtual Idx nbrDim() const final
Returns the number of vars in the multidimensional container.
virtual GUM_SCALAR get(const Instantiation &i) const final
Default implementation of MultiDimContainer::get().
virtual Size domainSize() const final
Returns the product of the variables domain size.
<agrum/base/multidim/multiDimImplementation.h>
virtual void addNodeWithId(const NodeId id)
try to insert a node with the given id
Exception : the element we looked for cannot be found.
Exception : operation not allowed.
const iterator & end() const noexcept
void insert(const Key &k)
SequenceIterator< Key > const_iterator
Types for STL compliance.
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
void insert(const Key &k)
Inserts a new element into the set.
bool empty() const noexcept
Indicates whether the set is the empty set.
void erase(const Key &k)
Erases an element from the set.
aGrUM's Tensor is a multi-dimensional array with tensor operators.
Base class for undirected graphs.
void addEdge(NodeId first, NodeId second) override
insert a new edge into the undirected graph
Container used to map discrete variables with nodes.
const std::string & name() const
returns the name of the variable
#define GUM_ERROR(type, msg)
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Size Idx
Type for indexes.
Size NodeId
Type for node ids.
HashTable< NodeId, VAL > NodeProperty
Property on graph elements.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
std::string remove_newline(const std::string &s)
remove all newlines in a string
std::vector< std::string > split(const std::string &str, const std::string &delim)
Split str using the delimiter.
Class representing Influence Diagrams.
gum is the global namespace for all aGrUM entities
std::unique_ptr< DiscreteVariable > fastVariable(std::string var_description, Size default_domain_size)
Create a pointer on a Discrete Variable from a "fast" syntax.
NodeId build_node_for_ID(gum::InfluenceDiagram< GUM_SCALAR > &infdiag, std::string node, const std::string &domain)