-
Notifications
You must be signed in to change notification settings - Fork 0
/
markov.cpp
56 lines (50 loc) · 1.49 KB
/
markov.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <functional>
#include <iostream>
#include <random>
#include <vector>
class MarkovChain {
private:
std::vector<std::discrete_distribution<int>> gen;
unsigned state;
public:
MarkovChain(const std::vector<std::vector<double>>& probabilities, unsigned state = 0) : state{state} {
checkSize(probabilities);
gen.reserve(probabilities.size());
for(size_t ii = 0; ii < probabilities.size(); ii++) {
const std::vector<double>& p = probabilities[ii];
gen[ii] = std::discrete_distribution<int>(p.begin(), p.end());
}
}
unsigned process(std::random_device& rd) {
state = gen[state](rd);
return state;
}
unsigned getState() const {
return state;
}
private:
// Check that the probability matrix has a square shape
// all rows are the same size : the number of rows
void checkSize(const std::vector<std::vector<double>>& probabilities) {
if (probabilities.size() < 1)
std::cerr << "Empty probability vector" << std::endl;
size_t s = probabilities.size();
for(const std::vector<double>& vp : probabilities) {
if (vp.size() != s) {
std::cerr << "Wrong probability vector size" << std::endl;
break;
}
}
}
};
// Example 4x4 Markov chain
// Deterministic example 0 -> 1 -> 2 -> 3 -> 0 -> etc.
// with probability 1
int main()
{
using namespace std;
random_device rd;
MarkovChain mc{{{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1},{1, 0, 0, 0}}, 0};
for(int ii = 0; ii < 100; ii++)
cout << mc.process(rd) << endl;
}