Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new planar_vertex_six_coloring() algorithm with examples, tests and doc #387

Open
wants to merge 20 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c481ecd
new protected remove_edge() that allows for O(1) edge removal
Hermann-SW Oct 2, 2024
585e4d7
New undirected_graph_constant_time_edge_add_and_remove class + example
Hermann-SW Oct 2, 2024
2853595
New undirected_graph_constant_time_edge_add_and_remove class + example
Hermann-SW Oct 2, 2024
383b835
new planar_vertex_six_coloring() + example
Hermann-SW Oct 2, 2024
136da69
new planar_vertex_six_coloring() tests and input graphs
Hermann-SW Oct 2, 2024
31eeb8b
planar_vertex_six_coloring doc
Hermann-SW Oct 2, 2024
d7ff091
missing toc entry
Hermann-SW Oct 2, 2024
a885319
missing Jamfile.v2 entry
Hermann-SW Oct 5, 2024
adf3c08
fix issues uncovered by CI
Hermann-SW Oct 7, 2024
c990f6f
fix CI reported issue not reportd by local b2 + fix another unused pa…
Hermann-SW Oct 7, 2024
0769bbb
Comment out C++11 runs as 1.86 requires C++14 minimum, fix clang7 ent…
Hermann-SW Oct 7, 2024
80dbad8
remove C++11 lines completely
Hermann-SW Oct 7, 2024
aff14b4
ge new .drone.star to resolve conflicts
Hermann-SW Oct 9, 2024
4c23ba1
Merge branch 'boostorg:develop' into develop
Hermann-SW Oct 9, 2024
253ddc3
inspect: fix C-style assert, *M* violation of Boost min/max guidelines
Hermann-SW Oct 11, 2024
ef76629
planar_vertex_six_coloring() calls "sequential coloring" with determi…
Hermann-SW Oct 19, 2024
21f3979
Add comments for three major parts of planar_vertex_six_coloring()
Hermann-SW Oct 19, 2024
bd1a227
remove now superfluous adj5 code
Hermann-SW Oct 19, 2024
08f7315
Merge branch 'boostorg:develop' into develop
Hermann-SW Oct 31, 2024
f063fdd
Merge branch 'boostorg:develop' into develop
Hermann-SW Nov 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added doc/figs/planar_vertex_coloring_with_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions doc/planar_vertex_six_coloring.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--
Copyright (c) Hermann Stamm-Wilbrandt 2024

Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<head>
<title>Boost Graph Library: Planar Vertex Six Coloring</title>
</head>

<body>
<IMG SRC="../../../boost.png"
ALT="C++ Boost" width="277" height="86">
<h1><tt>planar_vertex_six_coloring</tt></h1>

<p>
<pre>
template&lt;class VertexListGraph, class ColorMap&gt;
typename property_traits&lt;ColorMap&gt;::value_type
planar_vertex_six_coloring(const VertexListGraph&amp; g, ColorMap color);
</pre>

<p>Computes a <a href="graph_coloring.html">vertex coloring</a> for
the vertices in the planar graph in linear time, using at most 6 colors.<br>
Planar graphs can always be vertex colored with 4 colors, there
is a <a href="https://en.wikipedia.org/wiki/Four_color_theorem#Simplification_and_verification">quadratic time algorithm</a>.<br>
Boost <a href="sequential_vertex_coloring.html">sequential_vertex_coloring</a> can be forced to use any number <em>k</em> of colors for a crafted planar graph (first test graph).

<p>Here is the vertex coloring with 5 colors determined for icosahedron.

<p><img src="figs/planar_vertex_coloring_with_5.png">

<p>Planar graphs with <em>n</em> vertices have at most <em>3n-6</em> edges. Therefore always a vertex of degree &#x2264;5 exists. Algorithm removes such "small" vertices until the graph becomes empty. Then the vertices are colored in reverse order they were removed, with the smallest color different to its at most 5 neighbors when it was removed. Therefore at most 6 colors are needed.

<h3>Where Defined</h3>
<a href="../../../boost/graph/planar_vertex_six_coloring.hpp"><tt>boost/graph/planar_vertex_six_coloring.hpp</tt></a>

<h3>Parameters</h3>
IN: <tt>const Graph&amp; g</tt>
<blockquote>
The graph object on which the algorithm will be applied. The type
<tt>Graph</tt> must be a model of <a
href="VertexListGraph.html">Vertex List Graph</a> and <a
href="AdjacencyGraph.html">Adjacency Graph</a>.<br>
</blockquote>

OUT: <tt>ColorMap color</tt>
<blockquote>
This property map records the colors of each vertex. It must be a
model of
<a href="../../property_map/doc/WritablePropertyMap.html">Writeable
Property Map</a> whose key type is the same as the vertex descriptor
type of the graph and whose value type is an integral type that can
store all values of the graph's <tt>vertices_size_type</tt>.<br>
</blockquote>

<h3>Complexity</h3>

The time complexity is <em>O(V)</em>, where <em>V</em> is the
number of vertices of the planar graph.<br>
This runtime is only possible using <a href="undirected_graph_constant_time_edge_add_and_remove.html">undirected_graph_constant_time_edge_add_and_remove</a> providing <em>O(1)</em> remove_edge().

<h3>Example</h3>
<a href="../example/planar_vertex_six_coloring.cpp"><tt>boost/graph/example/planar_vertex_six_coloring.cpp</tt></a>

<pre>
template< class graph > void simple_maximal_planar_random_graph(graph& g, int n); // see example
typedef adjacency_list< listS, vecS, undirectedS > Graph;
typedef graph_traits< Graph >::vertices_size_type vertices_size_type;

Graph g;
simple_maximal_planar_random_graph(g, 1000000);

std::vector< vertices_size_type > color_vec(num_vertices(g));
auto color = make_container_vertex_map(color_vec, g);
<b>vertices_size_type num_colors = planar_vertex_six_coloring(g, color);</b>
</pre>

<h3>Test</h3>
<a href="../test/planar_vertex_six_coloring.cpp"><tt>boost/graph/test/planar_vertex_six_coloring.cpp</tt></a> test determines vertex coloring for three planar graphs:
<ol>
<li>"Fibonacci graph" (for k=15), with <em>fib(k+1)</em> vertices and <em>fib(k+2)-2</em> edges
<li> <a href="../test/planar_input_graphs/pentakis_dodecahedron.leda"><tt>boost/graph/test/planar_input_graphs/pentakis_dodecahedron.leda</tt></a>
<li> <a href="../test/planar_input_graphs/maximal_planar_1000.leda"><tt>boost/graph/test/planar_input_graphs/maximal_planar_1000.leda</tt></a>
</ol>
With 15/5/6 colors used by sequential_vertex_coloring() and 6/4/6 colors used by planar_vertex_six_coloring().

<hr>

<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy; 2024</TD><TD>
<A HREF="https://github.com/Hermann-SW/">Hermann Stamm-Wilbrandt</A> (<A
HREF="mailto:hermann@stamm-wilbrandt.de">hermann@stamm-wilbrandt.de</A>)
</TD></TR></TABLE>

</BODY>
</HTML>
5 changes: 5 additions & 0 deletions doc/table_of_contents.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ <h1>Table of Contents: the Boost Graph Library
<OL>
<LI><A href="./directed_graph.html"><tt>directed_graph</tt></a></li>
<LI><A href="./undirected_graph.html"><tt>undirected_graph</tt></a></li>
<OL>
<LI><A href="./undirected_graph_constant_time_edge_add_and_remove.html"><tt>undirected_graph_constant_time_edge_add_and_remove</tt></a></li>
</OL>
</OL>
<LI><A href="./adjacency_matrix.html"><tt>adjacency_matrix</tt></a></li>
<li><a href="compressed_sparse_row.html"><tt>compressed_sparse_row_graph</tt></a></li>
Expand Down Expand Up @@ -286,6 +289,8 @@ <h1>Table of Contents: the Boost Graph Library
<tt>make_biconnected_planar</tt></a>
<li><a href="make_maximal_planar.html">
<tt>make_maximal_planar</tt></a>
<li><a href="planar_vertex_six_coloring.html">
<tt>planar_vertex_six_coloring</tt></a>
</ol>

<li>Miscellaneous Algorithms
Expand Down
91 changes: 91 additions & 0 deletions doc/undirected_graph_constant_time_edge_add_and_remove.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<HTML>
<!--
Copyright (c) Hermann Stamm-Wilbrandt 2024

Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<Head>
<Title>Boost Graph Library: Undirected Graph with constant time edge add and remove</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../../boost.png"
ALT="C++ Boost" width="277" height="86">

<BR Clear>

<H1><A NAME="sec:undirected-graph-class"></A>
<pre>
undirected_graph_constant_time_edge_add_and_remove&lt;VertexProp, EdgeProp, GraphProp&gt;
</pre>
</H1>


<P>
The <tt>undirected_graph_constant_time_edge_add_and_remove</tt> class template is derived from BGL undirected graph. This class is provided only for constant time edge remove, in case that is not needed use undirected graph instead.

<H3>Example</H3>

An example of using an undirected_graph_constant_time_edge_add_and_remove is available here <a href="../../../libs/graph/example/undirected_graph_constant_time_edge_add_and_remove.cpp"><tt>libs/graph/example/undirected_graph_constant_time_edge_add and_remove.cpp</tt></a>. It demonstrates that undirected_graph takes quadratic time while undirected_graph_constant_time_edge_and_remove takes only linear time for clearing all outer vertices of wheel graph W<sub>n</sub>.
<P>


<PRE>
typedef boost::undirected_graph_constant_time_edge_add_and_remove<
boost::no_property, boost::no_property, boost::no_property > Graph;
Graph g;
typedef typename Graph::vertex_descriptor vertex_descriptor;
typedef typename Graph::edge_descriptor edge_descriptor;

vertex_descriptor v0 = g.add_vertex();
vertex_descriptor v1 = g.add_vertex();
edge_descriptor e = g.add_edge(v0, v1).first;
g.remove_edge(e);
</PRE>

<H3>Template Parameters</H3>

<P>
<TABLE border>
<TR>
<th>Parameter</th><th>Description</th><th>Default</th>
</tr>

<TR><TD><TT>VertexProp</TT></TD>
<TD>A property map for the graph vertices.</TD>
<TD>&nbsp;</TD>
</TR>

<TR>
<TD><TT>EdgeProp</TT></TD>
<TD>A property map for the graph edges.</TD>
<TD>&nbsp;</TD>
</TR>

<TR>
<TD><TT>GraphProp</TT></TD>
<TD>A property map for the graph itself.</TD>
</TR>

</TABLE>
<P>

<H3>Where Defined</H3>

<P>
<a href="../../../boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp"><TT>boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp</TT></a>

<P>

<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy; 2024</TD><TD>
<A HREF="https://github.com/Hermann-SW/">Hermann Stamm-Wilbrandt</A> (<A
HREF="mailto:hermann@stamm-wilbrandt.de">hermann@stamm-wilbrandt.de</A>)
</TD></TR></TABLE>

</BODY>
</HTML>
90 changes: 90 additions & 0 deletions example/planar_vertex_six_coloring.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//=======================================================================
// Copyright 2024
// Author: Hermann Stamm-Wilbrandt
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/planar_vertex_six_coloring.hpp>

using namespace boost;

// => ../test/planar_vertex_six_coloring.cpp for application to other planar graphs
//
template< class graph > void simple_maximal_planar_random_graph(graph& g, int n);


// time measurements
clock_t start_;
#define _(blk) std::cerr << #blk << " "; start_ = clock(); blk \
std::cerr << (clock()-start_)*1.0/CLOCKS_PER_SEC << "s" << std::endl;


int main(int argc, char *argv[]) {
typedef adjacency_list< listS, vecS, undirectedS > Graph;
typedef graph_traits< Graph >::vertices_size_type vertices_size_type;
Graph g;

_(simple_maximal_planar_random_graph(g, argc < 2 ? 333335 : atoi(argv[1]));)

std::vector< vertices_size_type > color_vec(num_vertices(g));
auto color = make_container_vertex_map(color_vec, g);

std::cout << num_vertices(g) << " vertices" << std::endl;
std::cout << num_edges(g) << " egdes" << std::endl;

_(vertices_size_type num_colors = planar_vertex_six_coloring(g, color);)
std::cout << num_colors << " colors" << std::endl;

BGL_FORALL_EDGES(e, g, Graph)
{ BOOST_ASSERT(get(color, source(e, g)) != get(color, target(e, g))); }

std::cout << "vertex coloring verified" << std::endl;

return 0;
}


/*
https://www.researchgate.net/publication/360912158_A_simple_linear_time_algorithm_for_embedding_maximal_planar_graphs_1

"simple_maximal_planar_random_graph()" implements only type==3 of chapter 8.
With type==4 and type==5 added it would be full blown "maximal_planar_random_graph()".


triangular face T[t] transformation, t chosen randomly:

T[t][0] T[t][0]
+--#--+ +--#--+
| | | | |
| | | | |
| | ==> | i |
| | | / \ |
| | |/ \|
#-----# #-----#
T[t][1] T[t][2] T[t][1] T[t][2]
*/
template< class graph > void simple_maximal_planar_random_graph(graph& g, int n)
{
BOOST_ASSERT(n > 2);
g.clear();
std::vector< typename graph::vertex_descriptor> V; V.reserve(n);
V[0] = add_vertex(g); V[1] = add_vertex(g); V[2] = add_vertex(g);
add_edge(V[0], V[1], g); add_edge(V[0], V[2], g); add_edge(V[1], V[2], g);
std::vector<std::vector<unsigned>> T;
// start with inside and outside face of complete graph on 3 vertices
T.reserve(2*n-4); T.push_back({0, 1, 2}); T.push_back({0, 1, 2});
for (int i=3; i < n; ++i)
{
unsigned t = random() % T.size();
V[i] = add_vertex(g);
unsigned v;
BOOST_FOREACH(v, T[t]) { add_edge(V[v], V[i], g); }
T.push_back(T[t]); T.back()[0] = i;
T.push_back(T[t]); T.back()[1] = i;
T[t][2] = i;
}
}
Loading
Loading