8 #ifndef HOG2_GENERIC_PUZZLE_ENTROPY_H
9 #define HOG2_GENERIC_PUZZLE_ENTROPY_H
23 template<
class State,
class Action>
33 static void Softmin(
const std::vector<double> &vars, std::vector<double> &ret)
35 double sum = std::accumulate(vars.begin(), vars.end(), 0.0, [](
double r,
double i) {
36 return r + std::exp(-i);
38 ret.reserve(vars.size());
39 std::transform(vars.begin(), vars.end(), std::back_inserter(ret), [&](
double i) {
40 return std::exp(-i) / sum;
44 static double KlDivergence(
const std::vector<double> &p,
const std::vector<double> &q)
46 if (p.size() != q.size())
47 throw std::invalid_argument(
"Input vectors must be of the same size.");
48 double divergence = 0.0;
49 for (
size_t i = 0; i < p.size(); ++i)
51 if (p[i] != 0.0 && q[i] != 0.0)
52 divergence += p[i] * std::log2(p[i] / q[i]);
58 const std::vector<double> &childEntropy)
60 auto size =
static_cast<double>(actions.size());
62 return std::log2(size);
66 uniform.resize(actions.size());
67 std::generate(uniform.begin(), uniform.end(), [&]() { return 1 / size; });
79 this->isRelative = val;
89 ruleSet.FilterActions(env, state, allActions);
90 if (allActions.empty())
96 for (
auto &action: allActions)
99 childEntropyInfo.emplace_back(
Calculate(env, state, (lookahead > 0) ? lookahead - 1 : 0));
102 for (
auto it = childEntropyInfo.begin(); it != childEntropyInfo.end(); )
105 if (info.value == 0 && info.depth < lookahead)
106 return { 0.0, info.depth + 1 };
107 if (info.value ==
inf && info.depth < lookahead)
108 it = childEntropyInfo.erase(it);
113 if (std::all_of(childEntropyInfo.begin(), childEntropyInfo.end(), [](
EntropyInfo &info) {
114 return info.value == 0;
116 entropyInfo = { 0.0, childEntropyInfo[0].
depth + 1 };
117 else if (std::all_of(childEntropyInfo.begin(), childEntropyInfo.end(), [](
EntropyInfo &info) {
118 return info.value == inf;
120 entropyInfo = {
inf, childEntropyInfo[0].depth + 1 };
123 auto &min_childEntropyInfo = *std::min_element(childEntropyInfo.begin(), childEntropyInfo.end(),
125 return info1.value < info2.value;
127 auto childEntropy = std::vector<double>();
128 childEntropy.reserve(childEntropyInfo.size());
129 std::transform(childEntropyInfo.begin(), childEntropyInfo.end(), std::back_inserter(childEntropy),
132 min_childEntropyInfo.depth + 1 };