1 /**
2  *
3  *   Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_AMU)
4  *   info_at_agrum_dot_org
5  *
6  *  This library is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU Lesser General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public License
17  *  along with this library.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief The K2 algorithm
24  *
25  * @author Christophe GONZALES(_at_AMU) and Pierre-Henri WUILLEMIN(_at_LIP6)
26  */
27 
28 #include <type_traits>
29 
30 #include <agrum/BN/learning/paramUtils/DAG2BNLearner.h>
31 #include <agrum/BN/learning/structureUtils/graphChange.h>
32 #include <agrum/BN/learning/structureUtils/graphChangesGenerator4K2.h>
33 
34 namespace gum {
35 
36   namespace learning {
37 
38     /// learns the structure of a Bayes net
39     template < typename GRAPH_CHANGES_SELECTOR >
learnStructure(GRAPH_CHANGES_SELECTOR & selector,DAG initial_dag)40     DAG K2::learnStructure(GRAPH_CHANGES_SELECTOR& selector, DAG initial_dag) {
41       // check that we used a selector compatible with the K2 algorithm
42       static_assert(std::is_base_of< _GraphChangesGenerator4K2_,
43                                      typename GRAPH_CHANGES_SELECTOR::GeneratorType >::value,
44                     "K2 must be called with a K2-compliant Graph Change Generator");
45 
46       // check that the order passed in argument concerns all the nodes
47       // __checkOrder(modal);
48 
49       // get the generator and assign the order
50       auto& generator = selector.graphChangeGenerator();
51       generator.setOrder(_order_);
52 
53       // use the greedy hill climbing algorithm to perform the search
54       return GreedyHillClimbing::learnStructure(selector, initial_dag);
55     }
56 
57     /// learns the structure and the parameters of a BN
58     template < typename GUM_SCALAR, typename GRAPH_CHANGES_SELECTOR, typename PARAM_ESTIMATOR >
59     BayesNet< GUM_SCALAR >
learnBN(GRAPH_CHANGES_SELECTOR & selector,PARAM_ESTIMATOR & estimator,DAG initial_dag)60        K2::learnBN(GRAPH_CHANGES_SELECTOR& selector, PARAM_ESTIMATOR& estimator, DAG initial_dag) {
61       // check that we used a selector compatible with the K2 algorithm
62       static_assert(std::is_base_of< _GraphChangesGenerator4K2_,
63                                      typename GRAPH_CHANGES_SELECTOR::GeneratorType >::value,
64                     "K2 must be called with a K2-compliant Graph Change Generator");
65 
66       // check that the order passed in argument concerns all the nodes
67       // __checkOrder(modal);
68 
69       // get the generator and assign the order
70       auto& generator = selector.graphChangeGenerator();
71       generator.setOrder(_order_);
72 
73       // use the greedy hill climbing algorithm to perform the search
74       return GreedyHillClimbing::learnBN< GUM_SCALAR >(selector, estimator, initial_dag);
75     }
76 
77   } /* namespace learning */
78 
79 } /* namespace gum */
80