110 lines
2.5 KiB
C++
110 lines
2.5 KiB
C++
#include <cmath>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <args.hxx>
|
|
|
|
#include "common.hh"
|
|
|
|
|
|
namespace param {
|
|
using namespace ::args;
|
|
|
|
ArgumentParser parser {
|
|
"converter: feature probability matrix -> feature series"
|
|
};
|
|
HelpFlag help {
|
|
parser, "help", "display this menu", {'h', "help"},
|
|
};
|
|
|
|
ValueFlag<std::string> smap {
|
|
parser, "path", "step map file path", {"smap"},
|
|
};
|
|
|
|
Flag output_prob {
|
|
parser, "output-prob", "prints path probability at last", {"output-prob", "prob"},
|
|
};
|
|
|
|
} // namespace param
|
|
|
|
|
|
static void Exec() {
|
|
const auto fprobs = ReadMatrix<double>(std::cin);
|
|
Enforce(fprobs.size() > 0 && fprobs[0].size() > 0, "empty matrix");
|
|
|
|
const auto dur = fprobs.size();
|
|
const auto n = fprobs[0].size();
|
|
|
|
std::ifstream smap_st {args::get(param::smap)};
|
|
Enforce(!!smap_st, "smap path is invalid");
|
|
const auto smap = ReadMatrix<uint32_t>(smap_st);
|
|
Enforce(smap.size() >= dur*n, "smap row shortage");
|
|
|
|
struct Step {
|
|
double prob = -1;
|
|
size_t from = 0;
|
|
};
|
|
std::vector<Step> steps((dur+1)*n);
|
|
for (size_t i = 0; i < n; ++i) {
|
|
steps[i].prob = fprobs[0][i];
|
|
}
|
|
for (size_t t = 1; t < dur; ++t) {
|
|
Enforce(fprobs[t].size() == n, "ill-formed matrix");
|
|
for (size_t i = 0; i < n; ++i) {
|
|
const auto& cur = steps[(t-1)*n + i];
|
|
for (auto j : smap[(t-1)*n+i]) {
|
|
auto& next = steps[t*n + j];
|
|
|
|
const auto sum = cur.prob + fprobs[t][j];
|
|
if (next.prob < sum) {
|
|
next.prob = sum;
|
|
next.from = i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
double max_prob = -1;
|
|
size_t max_idx = 0;
|
|
for (size_t i = 0; i < n; ++i) {
|
|
const auto& step = steps[(dur-1)*n + i];
|
|
if (max_prob < step.prob) {
|
|
max_prob = step.prob;
|
|
max_idx = i;
|
|
}
|
|
}
|
|
|
|
std::vector<size_t> path = {max_idx};
|
|
path.reserve(dur);
|
|
for (size_t t = dur-1; t > 0; --t) {
|
|
path.push_back(steps[t*n + path.back()].from);
|
|
}
|
|
for (auto itr = path.rbegin(); itr < path.rend(); ++itr) {
|
|
std::cout << *itr << '\n';
|
|
}
|
|
if (param::output_prob) {
|
|
std::cout << max_prob/static_cast<double>(path.size())*100 << "%" << std::endl;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
try {
|
|
param::parser.ParseCLI(argc, argv);
|
|
Exec();
|
|
return EXIT_SUCCESS;
|
|
} catch (const args::Help&) {
|
|
std::cout << param::parser << std::endl;
|
|
return EXIT_SUCCESS;
|
|
} catch (const std::exception& e) {
|
|
std::cerr << e.what() << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
|