GraphColoring.hpp: cosmetics

This commit is contained in:
Tobias Meyer Andersen 2023-11-20 12:21:06 +01:00 committed by Arne Morten Kvarving
parent 9309f96d8f
commit 54b7f9c44f

View File

@ -29,29 +29,24 @@
#include <tuple> #include <tuple>
#include <vector> #include <vector>
namespace Opm namespace Opm {
{ namespace Detail {
template <class Graph>
namespace Detail
{
template<class Graph>
std::size_t colorGraphWelshPowell(const Graph& graph, std::size_t colorGraphWelshPowell(const Graph& graph,
std::deque<typename Graph::VertexDescriptor>& orderedVertices, std::deque<typename Graph::VertexDescriptor>& orderedVertices,
std::vector<int>& colors, std::vector<int>& colors,
int color, int noVertices) int color,
int noVertices)
{ {
std::vector<int> forbidden(noVertices, false); std::vector<int> forbidden(noVertices, false);
std::size_t noColored = 0; std::size_t noColored = 0;
for(auto vertex = orderedVertices.begin(), for (auto vertex = orderedVertices.begin(),
vertexEnd = orderedVertices.end(); vertexEnd = orderedVertices.end(); vertex != vertexEnd; ++vertex) {
vertex != vertexEnd; ++vertex)
{
// Skip forbidden vertices // Skip forbidden vertices
while(vertex != vertexEnd && forbidden[*vertex]) while (vertex != vertexEnd && forbidden[*vertex])
++vertex; ++vertex;
if ( vertex == vertexEnd ) if (vertex == vertexEnd) {
{
break; break;
} }
@ -59,24 +54,23 @@ std::size_t colorGraphWelshPowell(const Graph& graph,
colors[*vertex] = color; colors[*vertex] = color;
++noColored; ++noColored;
// Forbid neighors // Forbid neighors
for(auto edge = graph.beginEdges(*vertex), endEdge = graph.endEdges(*vertex); for (auto edge = graph.beginEdges(*vertex),
edge != endEdge; ++edge) endEdge = graph.endEdges(*vertex); edge != endEdge; ++edge) {
{
forbidden[edge.target()] = true; forbidden[edge.target()] = true;
} }
} }
// forbidden vertices will be colored next for coloring // forbidden vertices will be colored next for coloring
using Vertex = typename Graph::VertexDescriptor; using Vertex = typename Graph::VertexDescriptor;
auto newEnd = std::remove_if(orderedVertices.begin(), orderedVertices.end(), auto newEnd = std::remove_if(orderedVertices.begin(),
[&forbidden](const Vertex& vertex) orderedVertices.end(),
{ [&forbidden](const Vertex& vertex) { return !forbidden[vertex]; });
return !forbidden[vertex]; orderedVertices.resize(newEnd - orderedVertices.begin());
});
orderedVertices.resize(newEnd-orderedVertices.begin());
return noColored; return noColored;
} }
template<class Graph, class Functor>
std::size_t breadthFirstSearch(const Graph& graph, typename Graph::VertexDescriptor root, template <class Graph, class Functor>
std::size_t breadthFirstSearch(const Graph& graph,
typename Graph::VertexDescriptor root,
Functor functor) Functor functor)
{ {
std::vector<int> visited(graph.maxVertex() + 1, false); std::vector<int> visited(graph.maxVertex() + 1, false);
@ -86,15 +80,11 @@ std::size_t breadthFirstSearch(const Graph& graph, typename Graph::VertexDescrip
nextVertices.push(root); nextVertices.push(root);
visited[root] = true; // We do not visit root. visited[root] = true; // We do not visit root.
while( !nextVertices.empty() ) while (!nextVertices.empty()) {
{
auto current = nextVertices.front(); auto current = nextVertices.front();
for(auto edge = graph.beginEdges(current), for (auto edge = graph.beginEdges(current),
endEdge = graph.endEdges(current); endEdge = graph.endEdges(current); edge != endEdge; ++edge) {
edge != endEdge; ++edge) if (!visited[edge.target()]) {
{
if ( ! visited[edge.target()] )
{
visited[edge.target()] = true; visited[edge.target()] = true;
nextVertices.push(edge.target()); nextVertices.push(edge.target());
functor(edge.target()); functor(edge.target());
@ -114,44 +104,36 @@ std::size_t breadthFirstSearch(const Graph& graph, typename Graph::VertexDescrip
/// \param graph The graph to color. Must adhere to the graph interface of dune-istl. /// \param graph The graph to color. Must adhere to the graph interface of dune-istl.
/// \return A pair of a vector with the colors of the vertices and the number of colors /// \return A pair of a vector with the colors of the vertices and the number of colors
/// assigned /// assigned
template<class Graph> template <class Graph>
std::tuple<std::vector<int>, int, std::vector<std::size_t> > std::tuple<std::vector<int>, int, std::vector<std::size_t>>
colorVerticesWelshPowell(const Graph& graph) colorVerticesWelshPowell(const Graph& graph)
{ {
using Vertex = typename Graph::VertexDescriptor; using Vertex = typename Graph::VertexDescriptor;
std::deque<Vertex> orderedVertices; std::deque<Vertex> orderedVertices;
auto noVertices = graph.maxVertex()+1; auto noVertices = graph.maxVertex() + 1;
std::vector<int> degrees(noVertices, 0); std::vector<int> degrees(noVertices, 0);
int maxDegree = 0; int maxDegree = 0;
std::ptrdiff_t firstDegreeChange = 0; std::ptrdiff_t firstDegreeChange = 0;
// populate deque // populate deque
for( auto vertex = graph.begin(), endVertex = graph.end(); for (auto vertex = graph.begin(),
vertex != endVertex; ++vertex) endVertex = graph.end(); vertex != endVertex; ++vertex) {
{
auto currentVertex = *vertex; auto currentVertex = *vertex;
auto& degree = degrees[currentVertex]; auto& degree = degrees[currentVertex];
for(auto edge = graph.beginEdges(currentVertex), for (auto edge = graph.beginEdges(currentVertex),
endEdge = graph.endEdges(currentVertex); endEdge = graph.endEdges(currentVertex); edge != endEdge; ++edge) {
edge != endEdge; ++edge)
{
++degree; ++degree;
} }
if (degree >= maxDegree) {
if( degree >= maxDegree )
{
orderedVertices.emplace_front(currentVertex); orderedVertices.emplace_front(currentVertex);
++firstDegreeChange; ++firstDegreeChange;
if(degree > maxDegree) if (degree > maxDegree) {
{
firstDegreeChange = 1; firstDegreeChange = 1;
maxDegree = degree; maxDegree = degree;
} }
} } else {
else
{
orderedVertices.emplace_back(currentVertex); orderedVertices.emplace_back(currentVertex);
} }
} }
@ -160,9 +142,7 @@ colorVerticesWelshPowell(const Graph& graph)
std::stable_sort(orderedVertices.begin() + firstDegreeChange, std::stable_sort(orderedVertices.begin() + firstDegreeChange,
orderedVertices.end(), orderedVertices.end(),
[&degrees](const Vertex& v1, const Vertex& v2) [&degrees](const Vertex& v1, const Vertex& v2)
{ { return degrees[v1] > degrees[v2]; });
return degrees[v1] > degrees[v2];
});
// Overwrite degree with color // Overwrite degree with color
auto& colors = degrees; auto& colors = degrees;
@ -172,39 +152,38 @@ colorVerticesWelshPowell(const Graph& graph)
std::vector<std::size_t> verticesPerColor; std::vector<std::size_t> verticesPerColor;
verticesPerColor.reserve(10); verticesPerColor.reserve(10);
while(!orderedVertices.empty()) while (!orderedVertices.empty()) {
{ verticesPerColor.push_back(Detail::colorGraphWelshPowell(graph, orderedVertices,
verticesPerColor colors, color++, noVertices));
.push_back(Detail::colorGraphWelshPowell(graph, orderedVertices, colors,
color++, noVertices));
} }
return std::make_tuple(colors, color, verticesPerColor); return std::make_tuple(colors, color, verticesPerColor);
} }
/// \! Reorder colored graph preserving order of vertices with the same color. /// \! Reorder colored graph preserving order of vertices with the same color.
template<class Graph> template <class Graph>
std::vector<std::size_t> std::vector<std::size_t>
reorderVerticesPreserving(const std::vector<int>& colors, int noColors, reorderVerticesPreserving(const std::vector<int>& colors,
int noColors,
const std::vector<std::size_t>& verticesPerColor, const std::vector<std::size_t>& verticesPerColor,
const Graph& graph) const Graph& graph)
{ {
std::vector<std::size_t> colorIndex(noColors, 0); std::vector<std::size_t> colorIndex(noColors, 0);
std::vector<std::size_t> indices(graph.maxVertex() + 1); std::vector<std::size_t> indices(graph.maxVertex() + 1);
std::partial_sum(verticesPerColor.begin(), std::partial_sum(verticesPerColor.begin(),
verticesPerColor.begin()+verticesPerColor.size() - 1, verticesPerColor.begin() + verticesPerColor.size() - 1,
colorIndex.begin() + 1); colorIndex.begin() + 1);
for(const auto& vertex: graph) for (const auto& vertex : graph) {
{
indices[vertex] = colorIndex[colors[vertex]]++; indices[vertex] = colorIndex[colors[vertex]]++;
} }
return indices; return indices;
} }
/// \! Reorder Vetrices in spheres /// \! Reorder Vetrices in spheres
template<class Graph> template <class Graph>
std::vector<std::size_t> std::vector<std::size_t>
reorderVerticesSpheres(const std::vector<int>& colors, int noColors, reorderVerticesSpheres(const std::vector<int>& colors,
int noColors,
const std::vector<std::size_t>& verticesPerColor, const std::vector<std::size_t>& verticesPerColor,
const Graph& graph, const Graph& graph,
typename Graph::VertexDescriptor root) typename Graph::VertexDescriptor root)
@ -214,7 +193,7 @@ reorderVerticesSpheres(const std::vector<int>& colors, int noColors,
std::vector<std::size_t> indices(graph.maxVertex() + 1, notVisitedTag); std::vector<std::size_t> indices(graph.maxVertex() + 1, notVisitedTag);
using Vertex = typename Graph::VertexDescriptor; using Vertex = typename Graph::VertexDescriptor;
std::partial_sum(verticesPerColor.begin(), std::partial_sum(verticesPerColor.begin(),
verticesPerColor.begin()+verticesPerColor.size() - 1, verticesPerColor.begin() + verticesPerColor.size() - 1,
colorIndex.begin() + 1); colorIndex.begin() + 1);
std::size_t noVisited = 0; std::size_t noVisited = 0;
auto numberer = [&colorIndex, &colors, &indices](Vertex vertex) auto numberer = [&colorIndex, &colors, &indices](Vertex vertex)
@ -222,18 +201,14 @@ reorderVerticesSpheres(const std::vector<int>& colors, int noColors,
indices[vertex] = colorIndex[colors[vertex]]++; indices[vertex] = colorIndex[colors[vertex]]++;
}; };
while ( noVisited < graph.maxVertex() + 1 ) while (noVisited < graph.maxVertex() + 1) {
{
numberer(root); numberer(root);
++noVisited; //root node already visited and not visited in BFS ++noVisited; // root node already visited and not visited in BFS
noVisited += Detail::breadthFirstSearch(graph, root, numberer); noVisited += Detail::breadthFirstSearch(graph, root, numberer);
if ( noVisited < graph.maxVertex() + 1 ) if (noVisited < graph.maxVertex() + 1) {
{
// Graph is disconnected search for not yet visited node // Graph is disconnected search for not yet visited node
for(auto vertex: graph) for (auto vertex : graph) {
{ if (indices[vertex] == notVisitedTag) {
if ( indices[vertex] == notVisitedTag )
{
// \todo make sure that this is a peripheral node! // \todo make sure that this is a peripheral node!
root = vertex; root = vertex;
break; break;