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

Computing conflict groups in section graph

parent 1f0f32c4
......@@ -10,6 +10,9 @@
* It is a graph on sections, also groups together conflicting sections.
*/
#include <algorithm>
#include <numeric>
#include "section_graph.h"
void
......@@ -19,6 +22,7 @@ Loco::SectionGraph::Build(const InputData &data,
InitSectionInfo(data, logical_graph);
BuildConflicts();
BuildNeighbours();
BuildConflictGroups();
// Find conflicts:
// - for each node and point collect the sections it is in
// - points give incidence
......@@ -93,6 +97,23 @@ Loco::SectionGraph::PrintSectionInfo(std::ostream &os) const
{
mSections[i].Print(os, i);
}
os << "[[conflict groups]]" << std::endl;
for (unsigned i = 0; i < mConflictGroups.size(); ++i)
{
if (!mConflictGroups[i].empty())
{
os << kTabString << "[Group " << i << "]" << std::endl;
os << kTabString << kTabString << "sections = "
<< mSections[mConflictGroups[i].front()].mSection->Ident();
for (auto i_sect_id = mConflictGroups[i].begin() + 1;
i_sect_id != mConflictGroups[i].end(); ++i_sect_id)
{
os << " " << kArraySep << " "
<< mSections[*i_sect_id].mSection->Ident();
}
os << std::endl;
}
}
return os;
}
......@@ -113,6 +134,7 @@ Loco::SectionGraph::SectionInfo::Print(std::ostream &os, unsigned id) const
});
os << std::endl;
}
os << kTabString << "conflict-group = " << mConflictGroupId << std::endl;
return os;
}
......@@ -139,3 +161,75 @@ Loco::SectionGraph::BuildConflicts()
return sect.mConflicts;
});
}
void
Loco::SectionGraph::InitConflictGroups()
{
mConflictGroups.resize(mSections.size());
for (unsigned i = 0; i < mSections.size(); ++i)
{
mSections[i].mConflictGroupId = i;
mConflictGroups[i].push_back(i);
}
}
void
Loco::SectionGraph::BuildConflictGroups()
{
InitConflictGroups();
for (const auto &[node, sects] : mNodeSections)
{
UnifyConflictGroups(sects);
}
CompressConflictGroups();
}
void
Loco::SectionGraph::UnifyConflictGroups(const std::vector<unsigned> &sects)
{
// Find the conflict group with the biggest number of elements
auto cg_size = [this](unsigned sect_id) {
return mConflictGroups[mSections[sect_id].mConflictGroupId].size();
};
unsigned cg = std::reduce(sects.begin() + 1, sects.end(), sects.front(),
[cg_size](unsigned a, unsigned b) {
return cg_size(a) <= cg_size(b) ? a : b;
});
// Renumber the conflict groups whenever needed
for (auto sect_id : sects)
{
if (mSections[sect_id].mConflictGroupId != cg)
{
ChangeIdOfConflictGroup(mSections[sect_id].mConflictGroupId, cg);
}
}
}
void
Loco::SectionGraph::ChangeIdOfConflictGroup(unsigned old_id, unsigned new_id)
{
for (auto sect_id : mConflictGroups[old_id])
{
mSections[sect_id].mConflictGroupId = new_id;
mConflictGroups[new_id].push_back(sect_id);
}
mConflictGroups[old_id].clear();
}
void
Loco::SectionGraph::CompressConflictGroups()
{
unsigned last = 0;
for (unsigned i = 0; i < mConflictGroups.size(); ++i)
{
if (!mConflictGroups[i].empty())
{
if (last < i)
{
ChangeIdOfConflictGroup(i, last);
}
++last;
}
}
mConflictGroups.resize(last + 1);
}
......@@ -28,7 +28,7 @@ namespace Loco
SectionConstPtr mSection{};
std::vector<LogicalGraph::Vertex> mVertices{};
length_type mLength;
std::optional<unsigned> mConflictGroupId{};
unsigned mConflictGroupId{};
std::vector<unsigned> mNeighbours;
std::vector<unsigned> mConflicts;
......@@ -64,6 +64,11 @@ namespace Loco
F get_vector);
void BuildConflicts();
void BuildNeighbours();
void BuildConflictGroups();
void InitConflictGroups();
void UnifyConflictGroups(const std::vector<unsigned> &sects);
void ChangeIdOfConflictGroup(unsigned old_id, unsigned new_id);
void CompressConflictGroups();
std::ostream &PrintVertices(std::ostream &os) const;
public:
......
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