-
Franck Dary authoredFranck Dary authored
TransitionSet.cpp 3.58 KiB
#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;
}