1+ #include < algorithm>
2+
3+ #include " OptimalBST.h"
4+
5+
6+ OptimalBST::Node::Node ():
7+ m_left(),
8+ m_right(),
9+ m_idx(0 )
10+ {}
11+
12+ OptimalBST::Node::~Node ()
13+ {
14+ m_left.reset ();
15+ m_right.reset ();
16+ }
17+
18+ OptimalBST::MatrixEntity::MatrixEntity () :
19+ m_val(0 ),
20+ m_rootPos(0 )
21+ {}
22+
23+ OptimalBST::MatrixEntity::MatrixEntity (MatrixEntity&& matrixEntity)
24+ {
25+ m_val = matrixEntity.m_val ;
26+ m_rootPos = matrixEntity.m_rootPos ;
27+ matrixEntity.m_val = 0 ;
28+ matrixEntity.m_rootPos = 0 ;
29+ }
30+
31+ std::ostream& operator << (std::ostream& out, OptimalBST::MatrixEntity& matrixEntity)
32+ {
33+ out << " [rootPos : " << matrixEntity.m_rootPos << " ; val : " << matrixEntity.m_val << ' ]' ;
34+ return out;
35+ }
36+
37+ OptimalBST::OptimalBST ():
38+ m_probabilities()
39+ {
40+ }
41+
42+ OptimalBST::~OptimalBST ()
43+ {
44+ }
45+
46+ void OptimalBST::clear ()
47+ {
48+ m_probabilities.clear ();
49+ }
50+
51+ bool OptimalBST::read (std::istream& in)
52+ {
53+ clear ();
54+
55+ uint32_t numElements = 0 ;
56+ in >> numElements;
57+ m_probabilities.resize (numElements);
58+
59+ for (auto & probability : m_probabilities)
60+ {
61+ in >> probability;
62+ }
63+
64+ return true ;
65+ }
66+
67+ bool OptimalBST::run (double &c)
68+ {
69+
70+ uint32_t numProbabilities = static_cast <uint32_t >(m_probabilities.size ());
71+ m_matrix.resize (numProbabilities, numProbabilities);
72+
73+ // utility structures
74+ MatrixEntity minVal;
75+ double tmpVal = 0 ;
76+ for (uint32_t s = 0 ; s < numProbabilities; ++s)
77+ {
78+ for (uint32_t i = 0 ; i < numProbabilities - s; ++i)
79+ {
80+ double probSum = 0 ;
81+ for (uint32_t k = i; k <= i + s; ++k)
82+ {
83+ probSum += m_probabilities[k];
84+ }
85+
86+ // r = i
87+ minVal.m_rootPos = i;
88+ minVal.m_val = ((i + 1 ) > (i + s)) ? 0 : m_matrix[i + 1 ][i + s].m_val ;
89+ for (uint32_t r = i + 1 ; r <= i + s; ++r)
90+ {
91+ tmpVal = ((i + 1 > r) ? 0 : m_matrix[i][r - 1 ].m_val ) +
92+ (((r + 1 ) > (i + s)) ? 0 : m_matrix[r + 1 ][i + s].m_val );
93+ if (tmpVal < minVal.m_val )
94+ {
95+ minVal.m_val = tmpVal;
96+ minVal.m_rootPos = r;
97+ }
98+ }
99+ minVal.m_val += probSum;
100+ m_matrix[i][i + s] = std::move (minVal);
101+ }
102+ }
103+
104+ c = m_matrix[0 ][numProbabilities - 1 ].m_val ;
105+
106+ formTree (m_tree, m_matrix, 0 , numProbabilities - 1 );
107+
108+ return true ;
109+ }
110+
111+ void OptimalBST::formTree (
112+ std::unique_ptr<Node>& tree,
113+ Matrix<MatrixEntity>& matrix,
114+ const uint32_t begin,
115+ const uint32_t end)
116+ {
117+ if (begin > end)
118+ {
119+ return ;
120+ }
121+ else if (begin == end)
122+ {
123+ tree.reset (new Node);
124+ tree->m_idx = begin;
125+ return ;
126+ }
127+ tree.reset (new Node);
128+ tree->m_idx = matrix[begin][end].m_rootPos ;
129+ formTree (tree->m_left , matrix, begin, (matrix[begin][end].m_rootPos >= 1 ) ? (matrix[begin][end].m_rootPos - 1 ) : 0 );
130+ formTree (tree->m_right , matrix, matrix[begin][end].m_rootPos + 1 , end);
131+ }
132+
133+ void OptimalBST::writeTree (
134+ const std::unique_ptr<Node>& tree,
135+ std::ostream& out,
136+ const std::string& indent)
137+ {
138+ if (!tree)
139+ {
140+ return ;
141+ }
142+ writeTree (tree->m_right , out, indent + " " );
143+ out << indent << tree->m_idx << " : " << m_probabilities[tree->m_idx ] << std::endl;
144+ writeTree (tree->m_left , out, indent + " " );
145+ }
146+
147+ bool OptimalBST::write (std::ostream& out)
148+ {
149+ out << m_matrix;
150+
151+ uint32_t numProbabilities = static_cast <uint32_t > (m_probabilities.size ());
152+ for (uint32_t i = 0 ; i < numProbabilities; ++i)
153+ {
154+ out << i << " : " << m_probabilities[i] << std::endl;
155+ }
156+
157+ // write tree
158+ writeTree (m_tree, out);
159+ return true ;
160+ }
0 commit comments