#include "TransitionSet.hpp" #include <limits> TransitionSet::TransitionSet(const std::string & filename) { addTransitionsFromFile(filename); } TransitionSet::TransitionSet(const std::vector<std::string> & filenames) { for (auto & filename : filenames) addTransitionsFromFile(filename); } void TransitionSet::addTransitionsFromFile(const std::string & filename) { FILE * file = std::fopen(filename.c_str(), "r"); if (!file) util::myThrow(fmt::format("cannot open file '{}'", filename)); char readBuffer[1024]; while (!std::feof(file)) { if (readBuffer != std::fgets(readBuffer, 1024, file)) break; std::string transitionName = readBuffer; if (transitionName.back() == '\n') transitionName.pop_back(); transitions.emplace_back(transitionName); } std::fclose(file); } std::vector<std::pair<Transition*, int>> TransitionSet::getAppliableTransitionsCosts(const Config & c, bool dynamic) { using Pair = std::pair<Transition*, int>; std::vector<Pair> appliableTransitions; for (unsigned int i = 0; i < transitions.size(); i++) if (transitions[i].appliable(c)) appliableTransitions.emplace_back(&transitions[i], dynamic ? transitions[i].getCostDynamic(c) : transitions[i].getCostStatic(c)); std::sort(appliableTransitions.begin(), appliableTransitions.end(), [](const Pair & a, const Pair & b) { return a.second < b.second; }); return appliableTransitions; } std::vector<Transition *> TransitionSet::getNAppliableTransitions(const Config & c, int n) { std::vector<Transition *> result; for (unsigned int i = 0; i < transitions.size(); i++) if (transitions[i].appliable(c)) result.emplace_back(&transitions[i]); if ((int)result.size() > n) util::myThrow(fmt::format("there are {} appliable transitions n = {}\n", result.size(), n)); return result; } std::vector<int> TransitionSet::getAppliableTransitions(const Config & c) { std::vector<int> result; for (unsigned int i = 0; i < transitions.size(); i++) if (transitions[i].appliable(c)) result.emplace_back(1); else result.emplace_back(0); return result; } std::vector<Transition *> TransitionSet::getBestAppliableTransitions(const Config & c, const std::vector<int> & appliableTransitions, bool dynamic) { int bestCost = std::numeric_limits<int>::max(); std::vector<Transition *> result; std::vector<int> costs(transitions.size()); for (unsigned int i = 0; i < transitions.size(); i++) { if (!appliableTransitions[i]) { costs[i] = std::numeric_limits<int>::max(); continue; } int cost = dynamic ? transitions[i].getCostDynamic(c) : transitions[i].getCostStatic(c); costs[i] = cost; if (cost < bestCost) bestCost = cost; } for (unsigned int i = 0; i < transitions.size(); i++) if (costs[i] == bestCost) result.emplace_back(&transitions[i]); return result; } std::size_t TransitionSet::size() const { return transitions.size(); } std::size_t TransitionSet::getTransitionIndex(const Transition * transition) const { if (!transition) util::myThrow("transition is null"); int index = transition - &transitions[0]; if (index < 0 or index >= (int)transitions.size()) util::myThrow(fmt::format("transition index '{}' out of bounds [0;{}[", index, transitions.size())); return index; } Transition * TransitionSet::getTransition(std::size_t index) { return &transitions[index]; } Transition * TransitionSet::getTransition(const std::string & name) { for (auto & transition : transitions) if (transition.getName() == name) return &transition; return nullptr; }