Commit 2ef6be01 authored by Kučera Petr RNDr. Ph.D.'s avatar Kučera Petr RNDr. Ph.D.
Browse files

Update used activities before printing model data

parent c9a9fb4c
......@@ -146,8 +146,9 @@ main([[maybe_unused]] int argc, char *argv[])
sg->PrintSubgraph(f, subg_kopanky_petrov, "subg_kopanky_petrov");
}
Loco::TrainRoutes routes(input_data, sg);
routes.UpdateActivities(input_data.mTrainList);
{
std::ofstream f(cfg.output.model_data);
routes.PrintActivities(f, "");
routes.PrintActivities(f, "", true);
}
}
......@@ -87,13 +87,5 @@ std::ostream &
Loco::InputData::PrintTrainList(std::ostream &os,
const std::string &prefix) const
{
for (const auto &[id, tl] : mTrainList)
{
os << prefix << kLabelDelimLeft << id << kLabelDelimRight << std::endl;
for (const auto &tp : tl)
{
os << prefix << kTabString << tp->Ident() << std::endl;
}
}
return os;
return mTrainList.Print(os, prefix);
}
......@@ -57,6 +57,15 @@ namespace Loco
TimeSpec parse_time_spec(const std::string &ts);
enum class SEARCH_STATE
{
UNVISITED,
OPEN,
CLOSED,
TERMINAL,
ADDED
};
std::ostream &operator<<(std::ostream &os, const TimeSpec &ts);
} // namespace Loco
......
......@@ -112,6 +112,12 @@ namespace Loco
{
return mPoints;
}
unsigned
TrainListId() const
{
return mData.buf_offset;
}
};
using SectionCPtr = std::shared_ptr<const Section>;
......
......@@ -18,15 +18,6 @@
namespace Loco
{
enum class SEARCH_STATE
{
UNVISITED,
OPEN,
CLOSED,
TERMINAL,
ADDED
};
// Like PhysicalGraph, but subdivided with points
// Physical nodes are in the graph as well
class LogicalGraph
......
......@@ -363,6 +363,12 @@ Loco::SectionGraph::SectionIds(const std::vector<SectionCPtr> &sections) const
return sect_id;
}
unsigned
Loco::SectionGraph::SectionId(const SectionCPtr &section) const
{
return mSectionId.at(section);
}
auto
Loco::SectionGraph::NewSubgraphWithIds(std::vector<unsigned> sources,
std::vector<unsigned> targets) const
......
......@@ -131,6 +131,8 @@ namespace Loco
std::ostream &PrintSubgraph(std::ostream &os, const SGSubgraphCPtr &subg,
const std::string &label) const;
unsigned SectionId(const SectionCPtr &section) const;
};
using SectionGraphCPtr = std::shared_ptr<const SectionGraph>;
......
......@@ -38,4 +38,5 @@ Loco::SectionParser::AddDataElementFromSection(InputData &data,
"Section with identifier " + sect.mIdent
+ " already exists in the region " + reg.mIdent);
}
data.mTrainList.AddSection(sect_ptr);
}
......@@ -25,7 +25,6 @@ Loco::TrainListParser::AddSectionTrainList(InputData &data,
const INISection &sect) const
{
auto id = std::stoul(sect.mIdent);
auto &tl = data.mTrainList[id];
for (const auto &train_ident : sect.mSimpleStrings)
{
auto train_ptr = data.mTrains.Find(train_ident);
......@@ -43,6 +42,6 @@ Loco::TrainListParser::AddSectionTrainList(InputData &data,
}
train_ptr = tp;
}
tl.push_back(std::move(train_ptr));
data.mTrainList.AddTrain(id, std::move(train_ptr));
}
}
......@@ -106,13 +106,15 @@ Loco::TrainRouteGraph::AddElementActivities(unsigned element_id)
if (element_id > 0
&& node_info.mNodeType == SGSubgraph::NODE_TYPE::SOURCE)
{
element.mPlaceActivities[place] =
mElements[element_id - 1].mPlaceActivities[place];
auto place_activity = mElements[element_id - 1].mSectActivities[sect];
element.mPlaceActivities[place] = place_activity;
element.mSectActivities[sect] = place_activity;
continue;
}
if (element.mPlaceActivities.find(place)
!= element.mPlaceActivities.end())
auto i_place = element.mPlaceActivities.find(place);
if (i_place != element.mPlaceActivities.end())
{
element.mSectActivities[sect] = i_place->second;
continue;
}
std::string name =
......@@ -123,34 +125,49 @@ Loco::TrainRouteGraph::AddElementActivities(unsigned element_id)
? element_id + 1
: element_id);
element.mPlaceActivities[place] = mActList.size();
element.mSectActivities[sect] = mActList.size();
mActList.emplace_back(name, std::move(place), false);
}
}
std::ostream &
Loco::TrainRoutes::PrintActivities(std::ostream &os,
const std::string &prefix) const
Loco::TrainRoutes::PrintActivities(std::ostream &os, const std::string &prefix,
bool only_used) const
{
os << "activities = #[" << std::endl;
for (const auto &[train, g] : mRouteGraphs)
{
g.PrintActivities(os, prefix + kTabString);
g.PrintActivities(os, prefix + kTabString, only_used);
}
return os << "]#" << std::endl;
}
std::ostream &
Loco::TrainRouteGraph::PrintActivities(std::ostream &os,
const std::string &prefix) const
const std::string &prefix,
bool only_used) const
{
os << prefix << "Train" << mTrainId << ":" << std::endl;
os << prefix << "{" << std::endl;
bool has_used = false;
for (const auto &act : mActList)
{
if (only_used && !act.mUse)
{
continue;
}
if (!has_used)
{
has_used = true;
os << prefix << "Train" << mTrainId << ":" << std::endl;
os << prefix << "{" << std::endl;
}
os << prefix << kTabString;
PrintActivity(os, act) << "," << std::endl;
}
return os << prefix << "}" << std::endl;
if (has_used)
{
os << prefix << "}" << std::endl;
}
return os;
}
std::ostream &
......@@ -173,10 +190,22 @@ Loco::TrainRouteGraph::PrintActNamesList(
os << "{";
if (!act_ids.empty())
{
os << mActList[act_ids.front()].mName;
std::for_each(
act_ids.begin() + 1, act_ids.end(),
[this, &os](const auto &i) { os << ", " << mActList[i].mName; });
bool print_comma = false;
for (const auto &id : act_ids)
{
if (mActList[id].mUse)
{
if (print_comma)
{
os << ", ";
}
else
{
print_comma = true;
}
os << mActList[act_ids.front()].mName;
}
}
}
return os << "}";
}
......@@ -202,8 +231,7 @@ Loco::TrainRouteGraph::ConnectEnterActivity()
{
for (auto src : mElements.front().mSubgraph->mSources)
{
auto i = mElements.front().mPlaceActivities.at(
mSectionGraph->PlaceOfSection(src));
auto i = mElements.front().mSectActivities.at(src);
if (mActList[i].mPred.empty())
{
mActList[i].mPred.push_back(0);
......@@ -217,8 +245,7 @@ Loco::TrainRouteGraph::ConnectLeaveActivity()
auto &pred = mActList.back().mPred;
for (auto leaf : mElements.back().mSubgraph->mTargets)
{
auto i = mElements.back().mPlaceActivities.at(
mSectionGraph->PlaceOfSection(leaf));
auto i = mElements.back().mSectActivities.at(leaf);
pred.push_back(i);
}
}
......@@ -229,18 +256,148 @@ Loco::TrainRouteGraph::ConnectElementActivities(unsigned element_id)
auto &element = mElements[element_id];
for (const auto &[sect, node_info] : element.mSubgraph->mSections)
{
auto i = element.mPlaceActivities.at(mSectionGraph->PlaceOfSection(sect));
auto i = element.mSectActivities.at(sect);
for (const auto &succ : node_info.mSucc)
{
auto j =
element.mPlaceActivities.at(mSectionGraph->PlaceOfSection(succ));
auto j = element.mSectActivities.at(succ);
mActList[i].mSucc.push_back(j);
}
for (const auto &pred : node_info.mPred)
{
auto j =
element.mPlaceActivities.at(mSectionGraph->PlaceOfSection(pred));
auto j = element.mSectActivities.at(pred);
mActList[i].mPred.push_back(j);
}
}
}
void
Loco::TrainRouteGraph::UpdateActivities(const SectionCPtr &initial_section)
{
if (!initial_section)
{
ClearActivities(true);
mActList.front().mForced = true;
mActList.back().mForced = true;
return;
}
UpdateWithInitialSection(mSectionGraph->SectionId(initial_section));
}
void
Loco::TrainRouteGraph::UpdateWithInitialSection(unsigned sect_id)
{
ClearActivities(false);
unsigned elem_id = ElementWithSection(sect_id);
if (elem_id == mElements.size())
{
std::cerr << "[TrainRouteGraph::UpdateWithInitialSection] Train is not "
"on the route"
<< std::endl;
return;
}
UpdateInitialActivity(elem_id, sect_id);
std::vector<unsigned> sources;
sources.push_back(sect_id);
for (unsigned el = elem_id; el < mElements.size(); ++el)
{
const auto &element = mElements[el];
UpdateSubgraph(element, sources);
sources.clear();
AddUsedLeaves(element, sources);
}
UpdateLastActivity(sources);
}
void
Loco::TrainRouteGraph::ClearActivities(bool use_flag)
{
for (auto &act : mActList)
{
act.mUse = use_flag;
}
}
unsigned
Loco::TrainRouteGraph::ElementWithSection(unsigned sect_id) const
{
for (unsigned i = 0; i < mElements.size(); ++i)
{
const auto &sections = mElements[i].mSubgraph->mSections;
auto ni = sections.find(sect_id);
if (ni == sections.end())
{
continue;
}
if (i + 1 < mElements.size()
&& ni->second.mNodeType == SGSubgraph::NODE_TYPE::LEAF)
{
return i + 1;
}
return i;
}
return mElements.size();
}
void
Loco::TrainRoutes::UpdateActivities(const TrainList &train_list
[[maybe_unused]])
{
for (const auto &[train, sect] : train_list.TrainSections())
{
mRouteGraphs.at(train).UpdateActivities(sect);
}
}
void
Loco::TrainRouteGraph::UpdateSubgraph(const Element &el,
const std::vector<unsigned> &sources)
{
for (const auto &src : sources)
{
UpdateSubgraphNode(el, src);
}
}
void
Loco::TrainRouteGraph::UpdateSubgraphNode(const Element &el, unsigned node)
{
mActList[el.mSectActivities.at(node)].mUse = true;
for (const auto &succ : el.mSubgraph->mSections.at(node).mSucc)
{
if (!mActList[el.mSectActivities.at(succ)].mUse)
{
UpdateSubgraphNode(el, succ);
}
}
}
void
Loco::TrainRouteGraph::AddUsedLeaves(const Element &el,
std::vector<unsigned> &leaves)
{
for (unsigned leaf : el.mSubgraph->mTargets)
{
if (mActList[el.mSectActivities.at(leaf)].mUse)
{
leaves.push_back(leaf);
}
}
}
void
Loco::TrainRouteGraph::UpdateInitialActivity(unsigned elem_id, unsigned sect_id)
{
const auto act_id = mElements[elem_id].mSectActivities[sect_id];
auto &act = mActList[act_id];
act.mUse = true;
}
void
Loco::TrainRouteGraph::UpdateLastActivity(const std::vector<unsigned> &sources)
{
if (!sources.empty())
{
mActList.back().mUse = true;
}
}
......@@ -54,6 +54,7 @@ namespace Loco
// activities activities associated with the targets of the subgraph
// in the previous stop.
std::unordered_map<SGPlaceCPtr, unsigned> mPlaceActivities;
std::unordered_map<unsigned, unsigned> mSectActivities;
Element(unsigned start_stop, SGSubgraphCPtr subgraph)
: mStartStop(start_stop), mSubgraph(std::move(subgraph))
......@@ -88,12 +89,25 @@ namespace Loco
const std::vector<unsigned> &act_ids) const;
std::ostream &PrintActivity(std::ostream &os, const Activity &act) const;
void ClearActivities(bool use_flag);
void UpdateWithInitialSection(unsigned sect_id);
unsigned ElementWithSection(unsigned sect_id) const;
void UpdateSubgraph(const Element &el,
const std::vector<unsigned> &sources);
void AddUsedLeaves(const Element &el, std::vector<unsigned> &leaves);
void UpdateSubgraphNode(const Element &el, unsigned node);
void UpdateInitialActivity(unsigned elem_id, unsigned sect_id);
void UpdateLastActivity(const std::vector<unsigned> &sources);
public:
TrainRouteGraph(TrainCPtr train, unsigned train_id,
SectionGraphCPtr section_graph);
std::ostream &PrintActivities(std::ostream &os,
const std::string &prefix) const;
std::ostream &PrintActivities(std::ostream &os, const std::string &prefix,
bool only_used) const;
void UpdateActivities(const SectionCPtr &initial_section);
void ResetActivities();
};
// Manages train route graphs for all trains
......@@ -110,8 +124,9 @@ namespace Loco
TrainRoutes(const InputData &input_data,
const SectionGraphCPtr &section_graph);
std::ostream &PrintActivities(std::ostream &os,
const std::string &prefix) const;
std::ostream &PrintActivities(std::ostream &os, const std::string &prefix,
bool only_used) const;
void UpdateActivities(const TrainList &train_list);
};
} // namespace Loco
......
......@@ -110,3 +110,57 @@ Loco::TrainStopSpec::Print(std::ostream &os, const std::string &prefix) const
}
return os;
}
void
Loco::TrainList::AddSection(SectionCPtr sect)
{
mListIdToSection.insert({sect->TrainListId(), {sect, {}}});
}
void
Loco::TrainList::ClearTrains()
{
mTrainSections.clear();
for (auto &[id, lc] : mListIdToSection)
{
lc.mTrains.clear();
}
}
void
Loco::TrainList::AddTrain(unsigned list_id, TrainCPtr train)
{
auto i_list = mListIdToSection.find(list_id);
if (i_list == mListIdToSection.end())
{
throw InconsistentDataException("TrainList::AddTrain",
"List with a given id not found");
}
mTrainSections.insert({train, i_list->second.mSection});
i_list->second.mTrains.push_back(std::move(train));
}
auto
Loco::TrainList::TrainSection(const TrainCPtr &train) const -> SectionCPtr
{
auto i_sect = mTrainSections.find(train);
return (i_sect == mTrainSections.end() ? nullptr : i_sect->second);
}
std::ostream &
Loco::TrainList::Print(std::ostream &os, const std::string &prefix) const
{
for (const auto &[id, lc] : mListIdToSection)
{
if (lc.mTrains.empty())
{
continue;
}
os << prefix << kLabelDelimLeft << id << kLabelDelimRight << std::endl;
for (const auto &train : lc.mTrains)
{
os << prefix << kTabString << train->Ident() << std::endl;
}
}
return os;
}
......@@ -171,8 +171,40 @@ namespace Loco
};
using TrainCPtr = std::shared_ptr<const Train>;
using SectionTrainList = std::vector<TrainCPtr>;
using TrainList = std::map<unsigned, SectionTrainList>;
class TrainList
{
public:
struct ListContent
{
SectionCPtr mSection;
std::vector<TrainCPtr> mTrains;
};
using TrainSectionsMap = std::unordered_map<TrainCPtr, SectionCPtr>;
private:
std::map<unsigned, ListContent> mListIdToSection{};
TrainSectionsMap mTrainSections{};
public:
TrainList() = default;
void AddSection(SectionCPtr sect);
void ClearTrains();
void AddTrain(unsigned list_id, TrainCPtr train);
SectionCPtr TrainSection(const TrainCPtr &train) const;
std::ostream &Print(std::ostream &os, const std::string &prefix) const;
const TrainSectionsMap &
TrainSections() const
{
return mTrainSections;
}
};
// using SectionTrainList = std::vector<TrainCPtr>;
// using TrainList = std::map<SectionCPtr, SectionTrainList>;
} // namespace Loco
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment