60 template < GUM_Numeric GUM_SCALAR >
63 std::string_view domain) {
67 std::string ds(domain);
68 switch (*(node.begin())) {
78 default : isChanc =
true;
83 if (infdiag.
exists(v->name())) {
91 "No type (chance, decision or utility) for the node '" << node <<
"'.")
97 template < GUM_Numeric GUM_SCALAR >
98 InfluenceDiagram< GUM_SCALAR >
100 return fastPrototype(dotlike,
"[" + std::to_string(domainSize) +
"]");
103 template < GUM_Numeric GUM_SCALAR >
106 std::string_view domain) {
111 bool notfirst =
false;
112 for (
const auto& souschaine:
split(chaine,
"->")) {
114 for (
auto& node:
split(souschaine,
"<-")) {
118 infdiag.
addArc(lastId, idVar);
121 infdiag.
addArc(idVar, lastId);
132 for (
const auto n: infdiag.
nodes()) {
148 template < GUM_Numeric GUM_SCALAR >
156 template < GUM_Numeric GUM_SCALAR >
162 template < GUM_Numeric GUM_SCALAR >
171 template < GUM_Numeric GUM_SCALAR >
174 if (
this != &source) {
188 template < GUM_Numeric GUM_SCALAR >
197 template < GUM_Numeric GUM_SCALAR >
200 if (
this != &source) {
209 template < GUM_Numeric GUM_SCALAR >
213 this->varMap_.clear();
216 _utilityMap_.clear();
222 template < GUM_Numeric GUM_SCALAR >
233 template < GUM_Numeric GUM_SCALAR >
236 for (
auto node: IDsource.
nodes()) {
243 for (
auto node: IDsource.
nodes()) {
247 addArc(IDsource.
cpt(node).variable(par).name(), s);
259 for (
auto node: IDsource.
nodes()) {
262 cpt(node).fillWith(IDsource.
cpt(s));
269 template < GUM_Numeric GUM_SCALAR >
271 std::stringstream output;
272 std::stringstream decisionNode;
273 std::stringstream utilityNode;
274 std::stringstream chanceNode;
275 std::stringstream arcstream;
277 output << std::format(
"digraph \"{}\" {{\n", this->
propertyWithDefault(
"name",
"no_name"));
279 output <<
" node [bgcolor=\"#AAAAAA\", style=filled, height=0];" << std::endl;
281 decisionNode <<
"node [shape = box];" << std::endl;
283 utilityNode <<
"node [shape = hexagon, margin=0];" << std::endl;
284 chanceNode <<
"node [shape = ellipse];" << std::endl;
285 std::string tab =
" ";
287 for (
const auto node:
dag_.nodes()) {
289 chanceNode << std::format(
" \"{}-{}\";", node,
variable(node).name());
291 utilityNode << std::format(
" \"{}-{}\";", node,
variable(node).name());
292 else decisionNode << std::format(
" \"{}-{}\";", node,
variable(node).name());
294 if (
dag_.children(node).size() > 0)
295 for (
const auto chi:
dag_.children(node)) {
296 arcstream << std::format(
"\"{}-{}\" -> \"{}-{}\"",
301 if (
isDecisionNode(chi)) { arcstream <<
" [style=\"tapered, bold\"]"; }
306 output << decisionNode.str() << std::endl
307 << utilityNode.str() << std::endl
308 << chanceNode.str() << std::endl
310 << arcstream.str() << std::endl
316 template < GUM_Numeric GUM_SCALAR >
318 std::stringstream output;
320 output <<
"Influence Diagram{" << std::endl;
324 output << std::format(
" arcs: {},\n",
dag().
sizeArcs());
327 output << std::format(
" domainSize: 10^{}", dSize);
328 else output << std::format(
" domainSize: {}", std::round(std::pow(10.0, dSize)));
330 output << std::endl <<
"}";
342 template < GUM_Numeric GUM_SCALAR >
350 template < GUM_Numeric GUM_SCALAR >
358 template < GUM_Numeric GUM_SCALAR >
366 template < GUM_Numeric GUM_SCALAR >
378 template < GUM_Numeric GUM_SCALAR >
386 template < GUM_Numeric GUM_SCALAR >
394 template < GUM_Numeric GUM_SCALAR >
402 template < GUM_Numeric GUM_SCALAR >
411 template < GUM_Numeric GUM_SCALAR >
421 template < GUM_Numeric GUM_SCALAR >
429 if (newMultiDim !=
nullptr)
delete newMultiDim;
440 template < GUM_Numeric GUM_SCALAR >
450 template < GUM_Numeric GUM_SCALAR >
469 template < GUM_Numeric GUM_SCALAR >
476 auto varcpt =
new Tensor< GUM_SCALAR >(aContent);
488 template < GUM_Numeric GUM_SCALAR >
495 "Utility var have no state ( which implicates a "
496 "single label for data output reasons ).")
501 auto varut =
new Tensor< GUM_SCALAR >(aContent);
513 template < GUM_Numeric GUM_SCALAR >
519 if (DesiredId == 0) proposedId =
dag_.nextNodeId();
520 else proposedId = DesiredId;
522 this->
varMap_.insert(proposedId, variableType);
524 dag_.addNodeWithId(proposedId);
535 template < GUM_Numeric GUM_SCALAR >
537 if (this->
varMap_.exists(varId)) {
539 for (
const auto chi:
dag_.children(varId))
552 dag_.eraseNode(varId);
561 template < GUM_Numeric GUM_SCALAR >
568 template < GUM_Numeric GUM_SCALAR >
570 this->
varMap_.changeName(
id, new_name);
579 template < GUM_Numeric GUM_SCALAR >
583 dag_.addArc(tail, head);
599 template < GUM_Numeric GUM_SCALAR >
601 if (
dag_.existsArc(arc)) {
620 template < GUM_Numeric GUM_SCALAR >
632 template < GUM_Numeric GUM_SCALAR >
634 for (
const auto node:
dag_.nodes())
637 for (
const auto node:
dag_.nodes()) {
639 for (
const auto par:
dag_.parents(node)) {
642 for (
const auto par2:
dag_.parents(node))
643 if (par != par2)
graph.addEdge(par, par2);
651 template < GUM_Numeric GUM_SCALAR >
661 if (orderIter == order.
end())
return true;
663 NodeId parentDecision = (*orderIter);
667 while (orderIter != order.
end()) {
671 parentDecision = *orderIter;
683 template < GUM_Numeric GUM_SCALAR >
691 mark[src] = (int)src;
694 while (!nodeFIFO.
empty()) {
695 current = nodeFIFO.
front();
698 for (
const auto new_one:
dag_.children(current)) {
699 if (mark[new_one] != -1)
continue;
701 mark[new_one] = (int)current;
703 if (new_one == dest)
break;
709 if (mark[dest] == -1)
return false;
717 template < GUM_Numeric GUM_SCALAR >
721 for (
const auto node:
dag_.nodes()) {
728 temporalGraph.
addArc(node, chi);
733 return temporalGraph;
739 template < GUM_Numeric GUM_SCALAR >
751 mark[parentDecision] =
true;
755 while (!nodeFIFO.
empty()) {
756 current = nodeFIFO.
front();
759 for (
const auto new_one:
dag_.children(current)) {
760 if (mark[new_one])
continue;
762 mark[new_one] =
true;
765 else childrenSeq.
insert(new_one);
776 template < GUM_Numeric GUM_SCALAR >
780 std::vector< NodeId > decisionSequence;
785 return decisionSequence;
792 template < GUM_Numeric GUM_SCALAR >
800 for (
auto i: order) {
803 for (
const auto par:
dag_.parents(i)) {
805 partialOrderedSet.
insert(par);
821 for (
const auto node: nodeList)
830 template < GUM_Numeric GUM_SCALAR >
832 unsigned int default_nbrmod) {
838 template < GUM_Numeric GUM_SCALAR >
841 if (v->domainSize() >= 2)
843 v->name() <<
" has a domain size >= 2 which is impossible for a utility node")
847 template < GUM_Numeric GUM_SCALAR >
849 unsigned int default_nbrmod) {
855 template < GUM_Numeric GUM_SCALAR >
857 unsigned int default_nbrmod) {
858 std::string node(fast_description);
859 switch (*(node.begin())) {
860 case '*' : node.erase(0, 1);
return addDecisionNode(node, default_nbrmod);
862 default :
return addChanceNode(fast_description, default_nbrmod);
867 template < GUM_Numeric GUM_SCALAR >
869 for (
const auto node:
nodes())
875 template < GUM_Numeric GUM_SCALAR >
877 for (
const auto node:
nodes())
882 template < GUM_Numeric GUM_SCALAR >
884 if (
size() != from.
size()) {
return false; }
891 for (
auto node:
nodes()) {
893 if (!from.
exists(v1.name()))
return false;
895 if (v1 != v2) {
return false; }
906 if (p1.
nbrDim() != p2.nbrDim()) {
return false; }
908 if (p1.
domainSize() != p2.domainSize()) {
return false; }
914 for (
Idx indice = 0; indice < p1.
nbrDim(); ++indice) {
919 if (std::pow(p1.
get(i) - p2.get(j), (GUM_SCALAR)2) > (GUM_SCALAR)1e-6) {
return false; }
923 for (
auto node:
nodes()) {
926 if (!check_pot(
cpt(node), from.
cpt(fromnode))) {
return false; }
928 if (!check_pot(
utility(node), from.
utility(fromnode))) {
return false; }
935 template < GUM_Numeric GUM_SCALAR >
940 template < GUM_Numeric GUM_SCALAR >
945 template < GUM_Numeric GUM_SCALAR >
950 template < GUM_Numeric GUM_SCALAR >
955 template < GUM_Numeric GUM_SCALAR >
960 template < GUM_Numeric GUM_SCALAR >
965 template < GUM_Numeric GUM_SCALAR >
970 template < GUM_Numeric GUM_SCALAR >
972 std::string_view new_name) {
976 template < GUM_Numeric GUM_SCALAR >
981 template < GUM_Numeric GUM_SCALAR >
986 template < GUM_Numeric GUM_SCALAR >
988 std::string_view dest)
const {
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
const T2 & second(const T1 &first) const
Returns the second value of a pair given its first value.
void insert(const T1 &first, const T2 &second)
Inserts a new association in the gum::Bijection.
Set of pairs of elements with fast search for both elements.
void addArc(NodeId tail, NodeId head) final
insert a new arc into the directed graph
DAG dag_
The DAG of this Directed Graphical Model.
DAGmodel()
Default constructor.
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...
DAG dag() const
Returns a named copy of the internal DAG: each node id is assigned the name of the corresponding vari...
DAGmodel & operator=(const DAGmodel &source)
Private copy operator.
bool exists(NodeId node) const final
Return true if this node exists in this graphical model.
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 named copy of the internal DAG: each node id is assigned the name of the corresponding vari...
VariableNodeMap varMap_
Mapping between NodeIds and discrete variables.
Base class for discrete random variable.
virtual Size domainSize() const =0
Base class for all aGrUM's exceptions.
Exception : fatal (unknown ?) error.
void setProperty(std::string_view name, std::string_view value)
Add or change a property of this GraphicalModel.
double log10DomainSize() const
const std::string & propertyWithDefault(std::string_view name, const std::string &byDefault) const
Return the value of the property name of this GraphicalModel.
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.
NodeId idFromName(std::string_view name) const override
Returns the NodeId of a variable given its name.
Size chanceNodeSize() const
Returns the number of chance nodes.
InfluenceDiagram()
Default constructor.
const List< NodeSet > & getPartialTemporalOrder(bool clear=true) const
Returns partial temporal ordering.
NodeId addChanceNode(const DiscreteVariable &variable, NodeId id=0)
Add a chance variable, it's associate node and it's CPT.
void addArc(NodeId tail, NodeId head)
Add an arc in the ID, and update diagram's tensor nodes cpt if necessary.
void endTopologyTransformation()
terminates a sequence of insertions/deletions of arcs by adjusting all CPTs/utilities dimensions.
static InfluenceDiagram< GUM_SCALAR > fastPrototype(std::string_view dotlike, Size domainSize)
Create an Influence Diagram with a dot-like syntax which specifies:
void removeTables_()
Removing ancient table.
void eraseArc(const Arc &arc)
Removes an arc in the ID, and update diagram's tensor nodes cpt if necessary.
NodeProperty< Tensor< GUM_SCALAR > * > _tensorMap_
Mapping between tensor variable's id and their CPT.
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.
bool isChanceNode(NodeId varId) const
Returns true if node is a chance one.
InfluenceDiagram< GUM_SCALAR > & operator=(const InfluenceDiagram< GUM_SCALAR > &source)
Copy Operator.
NodeId add(const DiscreteVariable &variable, NodeId id=0)
Add a chance variable, it's associate node and it's CPT.
NodeId addUtilityNode(const DiscreteVariable &variable, NodeId id=0)
Add a utility variable, it's associate node and it's UT.
std::string toString() const
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.
const DiscreteVariable & variableFromName(std::string_view name) const override
Returns a constant reference over a variable given its name.
bool isUtilityNode(NodeId varId) const
Returns true if node is a utility one.
bool operator==(const InfluenceDiagram< GUM_SCALAR > &other) const
Size utilityNodeSize() const
Returns the number of utility nodes.
NodeProperty< Tensor< GUM_SCALAR > * > _utilityMap_
Mapping between utility variable's id and their utility table.
gum::DAG getDecisionGraph() const
Returns the temporal Graph.
void changeVariableName(NodeId id, std::string_view new_name)
we allow the user to change the name of a variable
bool isDecisionNode(NodeId varId) const
Returns true if node is a decision one.
const DiscreteVariable & variable(std::string_view name) const
Returns the CPT of a tensor variable.
Sequence< NodeId > getChildrenDecision_(NodeId parentDecision) const
Returns the list of children decision for a given nodeId.
Size decisionNodeSize() const
Returns the number of decision nodes.
void erase(NodeId id)
Erase a Variable from the network and remove the variable from all his children.
virtual const Tensor< GUM_SCALAR > & cpt(NodeId varId) const
Returns the CPT of a tensor variable.
std::vector< NodeId > decisionOrder() const
Returns the sequence of decision nodes in the directed path.
virtual const Tensor< GUM_SCALAR > & utility(NodeId varId) const
Returns the utility table of a utility node.
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.
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
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.
Multidimensional matrix stored as an array in memory.
Idx nbrDim() const final
Returns the number of vars in the multidimensional container.
Size domainSize() const final
Returns the product of the variables domain size.
GUM_ELEMENT get(const Instantiation &i) const final
Default implementation of MultiDimContainer::get().
bool existsNode(const NodeId id) const
returns true iff the NodeGraphPart contains the given nodeId
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.
bool empty() const noexcept
Indicates whether the set is the empty set.
void insert(const Key &k)
Inserts a new element into the 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.
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(std::string_view s)
remove all newlines in a string
std::vector< std::string > split(std::string_view str, std::string_view delim)
Split str using the delimiter.
Class representing Influence Diagrams.
gum is the global namespace for all aGrUM entities
NodeId build_node_for_ID(gum::InfluenceDiagram< GUM_SCALAR > &infdiag, std::string node, std::string_view domain)
std::unique_ptr< DiscreteVariable > fastVariable(std::string var_description, Size default_domain_size)
Create a pointer on a Discrete Variable from a "fast" syntax.