From c481ecd5b920e57d481613e8fcd95b0c8c70f5cb Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 2 Oct 2024 14:49:41 +0200 Subject: [PATCH 01/17] new protected remove_edge() that allows for O(1) edge removal --- include/boost/graph/detail/adjacency_list.hpp | 75 +++++++++++++++++++ include/boost/graph/undirected_graph.hpp | 8 ++ 2 files changed, 83 insertions(+) diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index ed5a1d483..dbf571f46 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -797,6 +797,32 @@ namespace detail } g.m_edges.erase(edge_iter_to_erase); } + + // O(1) + template < class OutEdgeList_iterator, class Config > + static void apply(OutEdgeList_iterator iter1, + OutEdgeList_iterator iter2, + undirected_graph_helper< Config >& g_, StoredProperty& p) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((is_same< EdgeListS, listS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::edge_descriptor e = *iter1; + typename Config::edge_descriptor f = *iter2; + BOOST_ASSERT(source(e, g) == target(f, g)); + BOOST_ASSERT(source(f, g) == target(e, g)); + + typename Config::OutEdgeList& out_el + = g.out_edge_list(source(e, g)); + typename Config::EdgeIter edge_iter_to_erase; + edge_iter_to_erase = (*iter1.base()).get_iter(); + out_el.erase(iter1.base()); + typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); + in_el.erase(iter2.base()); + g.m_edges.erase(edge_iter_to_erase); + } }; template <> struct remove_undirected_edge_dispatch< no_property > @@ -833,6 +859,33 @@ namespace detail } g.m_edges.erase(edge_iter_to_erase); } + + // O(1) + template < class OutEdgeList_iterator, class Config > + static void apply(OutEdgeList_iterator iter1, + OutEdgeList_iterator iter2, + undirected_graph_helper< Config >& g_, no_property&) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((is_same< EdgeListS, listS >::value)); + + typedef typename Config::graph_type graph_type; + graph_type& g = static_cast< graph_type& >(g_); + typename Config::edge_descriptor e = *iter1; + typename Config::edge_descriptor f = *iter2; + BOOST_ASSERT(source(e, g) == target(f, g)); + BOOST_ASSERT(source(f, g) == target(e, g)); + + no_property* p = (no_property*)e.get_property(); + typename Config::OutEdgeList& out_el + = g.out_edge_list(source(e, g)); + typename Config::EdgeIter edge_iter_to_erase; + edge_iter_to_erase = (*iter1.base()).get_iter(); + out_el.erase(iter1.base()); + typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g)); + in_el.erase(iter2.base()); + g.m_edges.erase(edge_iter_to_erase); + } }; // O(E/V) @@ -924,6 +977,17 @@ template < class Config > struct undirected_graph_helper { this->remove_edge(*iter); } + // O(1) + inline void remove_edge(typename Config::out_edge_iterator iter1, + typename Config::out_edge_iterator iter2) + { + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value)); + + typedef typename Config::OutEdgeList::value_type::property_type PType; + detail::remove_undirected_edge_dispatch< PType >::apply( + iter1, iter2, *this, *(PType*)((*iter1).get_property())); + } }; // Had to make these non-members to avoid accidental instantiation @@ -953,6 +1017,17 @@ inline void remove_edge(EdgeOrIter e, undirected_graph_helper< Config >& g_) g_.remove_edge(e); } +// O(1) +template < class OutEdgeIter, class Config > +inline void remove_edge(OutEdgeIter i1, OutEdgeIter i2, + undirected_graph_helper< Config >& g_) +{ + typedef typename Config::global_edgelist_selector EdgeListS; + BOOST_STATIC_ASSERT((is_same< EdgeListS, listS >::value)); + + g_.remove_edge(i1, i2); +} + // O(E/V) or O(log(E/V)) template < class Config > void remove_edge(typename Config::vertex_descriptor u, diff --git a/include/boost/graph/undirected_graph.hpp b/include/boost/graph/undirected_graph.hpp index ec1bbbba6..6ae82012b 100644 --- a/include/boost/graph/undirected_graph.hpp +++ b/include/boost/graph/undirected_graph.hpp @@ -340,6 +340,14 @@ class undirected_graph std::swap(m_max_edge_index, g.m_max_edge_index); } +protected: + void remove_edge(void *p) + { + auto *q = static_cast< std::pair< out_edge_iterator, out_edge_iterator > * >(p); + boost::remove_edge(q->first, q->second, m_graph); + --m_num_edges; + } + private: vertices_size_type renumber_vertex_indices( vertex_iterator i, vertex_iterator end, vertices_size_type n) From 585e4d76f5ff61e5ad6206995e954fe05658fcfc Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 2 Oct 2024 14:53:20 +0200 Subject: [PATCH 02/17] New undirected_graph_constant_time_edge_add_and_remove class + example --- ...raph_constant_time_edge_add_and_remove.cpp | 103 +++++++++++++++ ...raph_constant_time_edge_add_and_remove.hpp | 122 ++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 example/undirected_graph_constant_time_edge_add_and_remove.cpp create mode 100644 include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp diff --git a/example/undirected_graph_constant_time_edge_add_and_remove.cpp b/example/undirected_graph_constant_time_edge_add_and_remove.cpp new file mode 100644 index 000000000..1b93fb02f --- /dev/null +++ b/example/undirected_graph_constant_time_edge_add_and_remove.cpp @@ -0,0 +1,103 @@ +//======================================================================= +// 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 +#include +#include +#include +#include + +typedef boost::undirected_graph_constant_time_edge_add_and_remove< + boost::no_property, boost::no_property, boost::no_property > ugraph_o1; + +typedef boost::undirected_graph< + boost::no_property, boost::no_property, boost::no_property > ugraph; + + +/* + Wheel graphs W5 4 W7 6---1 + /|\ / \ / \ + / | \ 5---0---2 + 3--0--1 \ / \ / + \ | / 4---3 + \|/ + 2 +*/ +template< class Graph > void wheel(Graph& g, int n); + + +/* + Demo function removing the edges for all but central vertex of + wheel graph Wn, showing roughly linear time for ugraph_01 + [because of O(1) remove_edge()] and quadratic time for ugraph. + + Very simplified version of what planar_vertex_six_coloring() does. + Proof that boost::undirected_graph_constant_time_edge_add_and_remove + class is essential for linear runtime of that vertex coloring algorithm. +*/ +template< class Graph > float clear_vertices(Graph& g, int n) +{ + wheel(g, n); + + std::vector< typename Graph::vertex_descriptor > vec; + vec.reserve(num_vertices(g)); + + BGL_FORALL_VERTICES_T(v, g, Graph) { vec.push_back(v); } + + clock_t start = clock(); + + typename Graph::vertex_descriptor u; + BOOST_REVERSE_FOREACH(u, vec) { g.clear_vertex(u); } + + return (clock()-start)*1.0/CLOCKS_PER_SEC; +} + + +int main(int argc, char*argv[]) { + int n = argc < 2 ? 2000 : atoi(argv[1]); + ugraph_o1 UO1; + ugraph U; + + std::cout << "Wn ugraph_o1 ugraph runtimes [s]" << std::endl; + + for (int i=0; i <= 4; ++i, n*=2) + { + std::cout << n << " " + << clear_vertices(UO1, n) << " " + << clear_vertices(U, n) << std::endl; + } + + return 0; +} + + +template< class Graph > +void wheel(Graph& g, int n) +{ + typedef typename Graph::vertex_descriptor vertex_descriptor; + + BOOST_ASSERT(n > 3); + + g = Graph(); + + vertex_descriptor v = add_vertex(g); + vertex_descriptor w = add_vertex(g); + g.add_edge(v, w); + + vertex_descriptor x = w; + + for (int i=3; i <= n; ++i) + { + vertex_descriptor y = add_vertex(g); + g.add_edge(v, y); + g.add_edge(x, y); + x = y; + } + + g.add_edge(x, w); +} diff --git a/include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp b/include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp new file mode 100644 index 000000000..21ca745b4 --- /dev/null +++ b/include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp @@ -0,0 +1,122 @@ +//======================================================================= +// 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) +//======================================================================= + +#ifndef BOOST_GRAPH_UNDIRECTED_GRAPH_CONSTANT_TIME_EDGE_ADD_AND_REMOVE.HPP +#define BOOST_GRAPH_UNDIRECTED_GRAPH_CONSTANT_TIME_EDGE_ADD_AND_REMOVE.HPP + +#include +#include +#include +#include + +enum edge_oeip_t +{ + edge_oeip +}; + +namespace boost +{ +BOOST_INSTALL_PROPERTY(edge, oeip); + + +/** + * The undirected_graph_constant_time_edge_add_and_remove class + * extends undirected_graph class template of the BGL. + * Its only purpose over undirected_graph is to provide + * O(1) time remove_edge() (and add_edge()) functions. + */ +#define GRAPH_TYPE \ + undirected_graph< VP, property< edge_oeip_t, void*, EP >, GP > + +template< class VP, class EP, class GP> +class undirected_graph_constant_time_edge_add_and_remove + : public GRAPH_TYPE +{ + public: + typedef GRAPH_TYPE graph_type; + + typedef typename graph_type::vertices_size_type vertices_size_type; + typedef typename graph_type::vertex_descriptor vertex_descriptor; + typedef typename graph_type::edge_descriptor edge_descriptor; + typedef typename graph_type::out_edge_iterator out_edge_iterator; + typedef typename graph_type::edge_iterator edge_iterator; + + public: + inline undirected_graph_constant_time_edge_add_and_remove() + : graph_type() + , m_map(get(edge_oeip, *this)) + { + } + + // would miss necessary linkage between x and created graph + inline undirected_graph_constant_time_edge_add_and_remove( + graph_type const& x) = delete; + + // would miss necessary linkage between graphs + inline undirected_graph_constant_time_edge_add_and_remove( + vertices_size_type n, GP const& p = GP()) = delete; + + template < typename EdgeIterator > + inline undirected_graph_constant_time_edge_add_and_remove(EdgeIterator f, + EdgeIterator l, + typename GRAPH_TYPE::vertices_size_type n, + typename GRAPH_TYPE::edges_size_type m = 0, + GP const& p = GP()) = delete; + + // too slow + std::pair< edge_descriptor, bool > add_edge( + vertex_descriptor u, vertex_descriptor v, EP const& p) = delete; + + // O(1) + inline std::pair< edge_descriptor, bool > + add_edge(vertex_descriptor u, vertex_descriptor v) + { + std::pair< edge_descriptor, bool > et = graph_type::add_edge(u, v); + BOOST_ASSERT(et.second); + + storage.push_back(std::make_pair(--out_edges(u, *this).second, + --out_edges(v, *this).second)); + m_map[et.first] = reinterpret_cast(&storage.back()); + return et; + } + + // too slow + void remove_edge(vertex_descriptor u, vertex_descriptor v) = delete; + + // O(1) + void remove_edge(edge_iterator i) { remove_edge(*i); } + + // O(1) + inline void remove_edge(edge_descriptor e) + { + graph_type::remove_edge(m_map[e]); + } + + // O(degree(v)) + inline void clear_vertex(vertex_descriptor v) + { + while (true) + { + out_edge_iterator ei, ei_end; + boost::tie(ei, ei_end) = out_edges(v, *this); + if (ei == ei_end) + break; + this->remove_edge(*ei); + } + } + + private: + typename property_map< graph_type, edge_oeip_t >::type m_map; + std::list< std::pair< out_edge_iterator, out_edge_iterator > > storage; +}; + +} /* namespace boost */ + + +#endif From 2853595f001454ff4ef6148c966aae760fa91d8c Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 2 Oct 2024 14:56:00 +0200 Subject: [PATCH 03/17] New undirected_graph_constant_time_edge_add_and_remove class + example --- doc/table_of_contents.html | 3 + ...aph_constant_time_edge_add_and_remove.html | 91 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 doc/undirected_graph_constant_time_edge_add_and_remove.html diff --git a/doc/table_of_contents.html b/doc/table_of_contents.html index 5eb527ac1..a24be642a 100644 --- a/doc/table_of_contents.html +++ b/doc/table_of_contents.html @@ -104,6 +104,9 @@

Table of Contents: the Boost Graph Library
  1. directed_graph
  2. undirected_graph
  3. +
      +
    1. undirected_graph_constant_time_edge_add_and_remove
    2. +
  • adjacency_matrix
  • compressed_sparse_row_graph
  • diff --git a/doc/undirected_graph_constant_time_edge_add_and_remove.html b/doc/undirected_graph_constant_time_edge_add_and_remove.html new file mode 100644 index 000000000..332651f95 --- /dev/null +++ b/doc/undirected_graph_constant_time_edge_add_and_remove.html @@ -0,0 +1,91 @@ + + + +Boost Graph Library: Undirected Graph with constant time edge add and remove + +C++ Boost + +
    + +

    +
    +undirected_graph_constant_time_edge_add_and_remove<VertexProp, EdgeProp, GraphProp>
    +
    +

    + + +

    +The undirected_graph_constant_time_edge_add_and_remove 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. + +

    Example

    + +An example of using an undirected_graph_constant_time_edge_add_and_remove is available here libs/graph/example/undirected_graph_constant_time_edge_add and_remove.cpp. 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 Wn. +

    + + +

    +  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);
    +
    + +

    Template Parameters

    + +

    + + + + + + + + + + + + + + + + + + + + + +
    ParameterDescriptionDefault
    VertexPropA property map for the graph vertices. 
    EdgePropA property map for the graph edges. 
    GraphPropA property map for the graph itself.
    +

    + +

    Where Defined

    + +

    +boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp + +

    + +
    +


    + + +
    Copyright © 2024 +Hermann Stamm-Wilbrandt (hermann@stamm-wilbrandt.de) +
    + + + From 383b835ec21c13a5b2b23e98a677dc0f47680bcc Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 2 Oct 2024 15:00:20 +0200 Subject: [PATCH 04/17] new planar_vertex_six_coloring() + example --- example/planar_vertex_six_coloring.cpp | 90 ++++++++++++ .../graph/planar_vertex_six_coloring.hpp | 129 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 example/planar_vertex_six_coloring.cpp create mode 100644 include/boost/graph/planar_vertex_six_coloring.hpp diff --git a/example/planar_vertex_six_coloring.cpp b/example/planar_vertex_six_coloring.cpp new file mode 100644 index 000000000..3f7deb514 --- /dev/null +++ b/example/planar_vertex_six_coloring.cpp @@ -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 +#include +#include + +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> 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; + } +} diff --git a/include/boost/graph/planar_vertex_six_coloring.hpp b/include/boost/graph/planar_vertex_six_coloring.hpp new file mode 100644 index 000000000..14b117463 --- /dev/null +++ b/include/boost/graph/planar_vertex_six_coloring.hpp @@ -0,0 +1,129 @@ +//======================================================================= +// 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) +//======================================================================= +// +#ifndef BOOST_GRAPH_PLANAR_VERTEX_SIX_COLORING_HPP +#define BOOST_GRAPH_PLANAR_VERTEX_SIX_COLORING_HPP + +#include +#include +#include +#include +#include + +/* This algorithm is to find a vertex six coloring of a planar graph + + Algorithm: + Let G = (V,E) be a planar graph with n vertices. + Planar graphs always have a vertex of degree 5 or less. + Remember its (at most 5) adjacent vertices and remove its edges. + Repeat until all vertices have been processed. + Now color the vertices in reverse order they were removed. + Assign smallest color different to all <=5 remembered vertices to vertex. + Repeat until done. + + The color of the vertex v will be stored in color[v]. + i.e., vertex v belongs to coloring color[v] */ + +namespace boost +{ + enum vertex_back_t { vertex_back }; + BOOST_INSTALL_PROPERTY(vertex, back); + + enum vertex_adj5_t { vertex_adj5 }; + BOOST_INSTALL_PROPERTY(vertex, adj5); + +template < class VertexListGraph, class ColorMap > +typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( + const VertexListGraph& G, ColorMap color) +{ + typedef typename VertexListGraph::vertex_descriptor vertex_descriptor; + + typedef typename property_traits< ColorMap >::value_type size_type; + + typedef undirected_graph_constant_time_edge_add_and_remove< + property< vertex_back_t, vertex_descriptor, + property< vertex_adj5_t, std::vector< vertex_descriptor > > >, + no_property, no_property > ugraph_o1; + + + std::vector< typename ugraph_o1::vertex_descriptor > + vertex_u(num_vertices(G)); + auto vmap = make_container_vertex_map(vertex_u, G); +// +// get(vmap, _) +// {v,w} in V(G)---------------> +// <---------------V(U) <= {u,t} +// back[_] | +// | +// std::vector <--------------+ +// adj5[_] +// + ugraph_o1 U; + + auto adj5 = get(vertex_adj5, U); + auto back = get(vertex_back, U); + + + BGL_FORALL_VERTICES_T(v, G, VertexListGraph) + { put(vmap, v, U.add_vertex(v)); } + + BGL_FORALL_EDGES_T(e, G, VertexListGraph) + { U.add_edge(get(vmap, source(e, G)), get(vmap, target(e, G))); } + + + std::vector< typename ugraph_o1::vertex_descriptor > small, visited; + small.reserve(num_vertices(U)); + visited.reserve(num_vertices(U)); + + BGL_FORALL_VERTICES_T(u, U, ugraph_o1) + { adj5[u].reserve(5); if (degree(u, U) <= 5) { small.push_back(u); } } + + + while (!small.empty()) + { + typename ugraph_o1::vertex_descriptor u = small.back(); + small.pop_back(); + + BGL_FORALL_ADJ_T(u, t, U, ugraph_o1) + { + adj5[u].push_back(back[t]); + if (degree(t, U) == 6) small.push_back(t); + } + U.clear_vertex(u); + + visited.push_back(u); + } + + BOOST_ASSERT(num_vertices(U) == visited.size()); + + + // highest possisble index with <=5 neighbors is 0x3E (= 0b111110) + const size_type smallest_possible_color[1+0x3E] + = {0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, + 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; + + size_type colmax = 0; + typename ugraph_o1::vertex_descriptor u; + BOOST_REVERSE_FOREACH(u, visited) + { + size_type bs = 0; + vertex_descriptor w; + BOOST_FOREACH(w, adj5[u]) { bs |= (1 << get(color, w)); } + put(color, back[u], smallest_possible_color[bs]); + colmax = std::max(colmax, smallest_possible_color[bs]); + } + + return colmax+1; +} + +} // namespace boost + +#endif // BOOST_GRAPH_PLANAR_VERTEX_SIX_COLORING_HPP From 136da697a0a54493ed9e42baef6912615834edb1 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 2 Oct 2024 15:05:12 +0200 Subject: [PATCH 05/17] new planar_vertex_six_coloring() tests and input graphs --- .../maximal_planar_1000.leda | 3999 +++++++++++++++++ .../pentakis_dodecahedron.leda | 127 + test/planar_vertex_six_coloring.cpp | 216 + 3 files changed, 4342 insertions(+) create mode 100644 test/planar_input_graphs/maximal_planar_1000.leda create mode 100644 test/planar_input_graphs/pentakis_dodecahedron.leda create mode 100644 test/planar_vertex_six_coloring.cpp diff --git a/test/planar_input_graphs/maximal_planar_1000.leda b/test/planar_input_graphs/maximal_planar_1000.leda new file mode 100644 index 000000000..b0e046119 --- /dev/null +++ b/test/planar_input_graphs/maximal_planar_1000.leda @@ -0,0 +1,3999 @@ +LEDA.GRAPH // randomgraph 1000 -t maximal_planar -o maximal_planar_1000.leda +point +int +1000 +(50.00,90.00) +(50.25,90.00) +(50.50,90.00) +(50.75,89.99) +(51.01,89.99) +(51.26,89.98) +(51.51,89.97) +(51.76,89.96) +(52.01,89.95) +(52.26,89.94) +(52.51,89.92) +(52.76,89.90) +(53.01,89.89) +(53.27,89.87) +(53.52,89.85) +(53.77,89.82) +(54.02,89.80) +(54.27,89.77) +(54.52,89.74) +(54.77,89.72) +(55.02,89.68) +(55.26,89.65) +(55.51,89.62) +(55.76,89.58) +(56.01,89.55) +(56.26,89.51) +(56.51,89.47) +(56.76,89.43) +(57.00,89.38) +(57.25,89.34) +(57.50,89.29) +(57.75,89.24) +(57.99,89.19) +(58.24,89.14) +(58.48,89.09) +(58.73,89.04) +(58.97,88.98) +(59.22,88.92) +(59.46,88.86) +(59.71,88.80) +(59.95,88.74) +(60.20,88.68) +(60.44,88.61) +(60.68,88.55) +(60.92,88.48) +(61.16,88.41) +(61.41,88.34) +(61.65,88.27) +(61.89,88.19) +(62.13,88.12) +(62.37,88.04) +(62.60,87.96) +(62.84,87.88) +(63.08,87.80) +(63.32,87.72) +(63.56,87.63) +(63.79,87.55) +(64.03,87.46) +(64.26,87.37) +(64.50,87.28) +(64.73,87.19) +(64.96,87.10) +(65.20,87.00) +(65.43,86.90) +(65.66,86.81) +(65.89,86.71) +(66.12,86.61) +(66.35,86.50) +(66.58,86.40) +(66.81,86.30) +(67.04,86.19) +(67.27,86.08) +(67.49,85.97) +(67.72,85.86) +(67.94,85.75) +(68.17,85.64) +(68.39,85.52) +(68.61,85.41) +(68.84,85.29) +(69.06,85.17) +(69.28,85.05) +(69.50,84.93) +(69.72,84.80) +(69.94,84.68) +(70.15,84.55) +(70.37,84.42) +(70.59,84.30) +(70.80,84.17) +(71.02,84.03) +(71.23,83.90) +(71.44,83.77) +(71.65,83.63) +(71.86,83.50) +(72.07,83.36) +(72.28,83.22) +(72.49,83.08) +(72.70,82.94) +(72.91,82.79) +(73.11,82.65) +(73.32,82.50) +(73.52,82.35) +(73.72,82.21) +(73.93,82.06) +(74.13,81.90) +(74.33,81.75) +(74.53,81.60) +(74.72,81.44) +(74.92,81.29) +(75.12,81.13) +(75.31,80.97) +(75.51,80.81) +(75.70,80.65) +(75.89,80.49) +(76.08,80.33) +(76.27,80.16) +(76.46,80.00) +(76.65,79.83) +(76.84,79.66) +(77.02,79.49) +(77.21,79.32) +(77.39,79.15) +(77.57,78.98) +(77.76,78.80) +(77.94,78.63) +(78.12,78.45) +(78.29,78.27) +(78.47,78.10) +(78.65,77.92) +(78.82,77.74) +(79.00,77.55) +(79.17,77.37) +(79.34,77.19) +(79.51,77.00) +(79.68,76.82) +(79.85,76.63) +(80.01,76.44) +(80.18,76.25) +(80.34,76.06) +(80.51,75.87) +(80.67,75.68) +(80.83,75.48) +(80.99,75.29) +(81.15,75.10) +(81.31,74.90) +(81.46,74.70) +(81.62,74.50) +(81.77,74.30) +(81.92,74.10) +(82.07,73.90) +(82.22,73.70) +(82.37,73.50) +(82.52,73.29) +(82.66,73.09) +(82.81,72.88) +(82.95,72.68) +(83.09,72.47) +(83.23,72.26) +(83.37,72.05) +(83.51,71.84) +(83.65,71.63) +(83.78,71.42) +(83.92,71.21) +(84.05,70.99) +(84.18,70.78) +(84.31,70.56) +(84.44,70.35) +(84.57,70.13) +(84.69,69.91) +(84.82,69.69) +(84.94,69.47) +(85.06,69.25) +(85.18,69.03) +(85.30,68.81) +(85.42,68.59) +(85.53,68.37) +(85.65,68.14) +(85.76,67.92) +(85.87,67.69) +(85.98,67.47) +(86.09,67.24) +(86.20,67.01) +(86.31,66.78) +(86.41,66.56) +(86.52,66.33) +(86.62,66.10) +(86.72,65.87) +(86.82,65.64) +(86.92,65.40) +(87.01,65.17) +(87.11,64.94) +(87.20,64.71) +(87.29,64.47) +(87.38,64.24) +(87.47,64.00) +(87.56,63.77) +(87.64,63.53) +(87.73,63.29) +(87.81,63.05) +(87.89,62.82) +(87.97,62.58) +(88.05,62.34) +(88.13,62.10) +(88.20,61.86) +(88.28,61.62) +(88.35,61.38) +(88.42,61.14) +(88.49,60.90) +(88.56,60.65) +(88.62,60.41) +(88.69,60.17) +(88.75,59.92) +(88.81,59.68) +(88.87,59.44) +(88.93,59.19) +(88.99,58.95) +(89.04,58.70) +(89.10,58.46) +(89.15,58.21) +(89.20,57.96) +(89.25,57.72) +(89.30,57.47) +(89.34,57.22) +(89.39,56.98) +(89.43,56.73) +(89.47,56.48) +(89.51,56.23) +(89.55,55.98) +(89.59,55.74) +(89.62,55.49) +(89.66,55.24) +(89.69,54.99) +(89.72,54.74) +(89.75,54.49) +(89.77,54.24) +(89.80,53.99) +(89.82,53.74) +(89.85,53.49) +(89.87,53.24) +(89.89,52.99) +(89.91,52.74) +(89.92,52.48) +(89.94,52.23) +(89.95,51.98) +(89.96,51.73) +(89.97,51.48) +(89.98,51.23) +(89.99,50.98) +(89.99,50.73) +(90.00,50.47) +(90.00,50.22) +(90.00,49.97) +(90.00,49.72) +(90.00,49.47) +(89.99,49.22) +(89.99,48.97) +(89.98,48.71) +(89.97,48.46) +(89.96,48.21) +(89.95,47.96) +(89.93,47.71) +(89.92,47.46) +(89.90,47.21) +(89.88,46.96) +(89.86,46.71) +(89.84,46.46) +(89.82,46.21) +(89.80,45.96) +(89.77,45.71) +(89.74,45.46) +(89.71,45.21) +(89.68,44.96) +(89.65,44.71) +(89.61,44.46) +(89.58,44.21) +(89.54,43.96) +(89.50,43.71) +(89.46,43.46) +(89.42,43.22) +(89.38,42.97) +(89.33,42.72) +(89.29,42.47) +(89.24,42.23) +(89.19,41.98) +(89.14,41.73) +(89.08,41.49) +(89.03,41.24) +(88.97,41.00) +(88.92,40.75) +(88.86,40.51) +(88.80,40.26) +(88.74,40.02) +(88.67,39.78) +(88.61,39.53) +(88.54,39.29) +(88.47,39.05) +(88.40,38.81) +(88.33,38.57) +(88.26,38.33) +(88.18,38.09) +(88.11,37.85) +(88.03,37.61) +(87.95,37.37) +(87.87,37.13) +(87.79,36.89) +(87.71,36.65) +(87.62,36.42) +(87.54,36.18) +(87.45,35.95) +(87.36,35.71) +(87.27,35.48) +(87.18,35.24) +(87.08,35.01) +(86.99,34.78) +(86.89,34.54) +(86.80,34.31) +(86.70,34.08) +(86.60,33.85) +(86.49,33.62) +(86.39,33.39) +(86.28,33.16) +(86.18,32.94) +(86.07,32.71) +(85.96,32.48) +(85.85,32.26) +(85.74,32.03) +(85.62,31.81) +(85.51,31.58) +(85.39,31.36) +(85.27,31.14) +(85.15,30.92) +(85.03,30.70) +(84.91,30.48) +(84.79,30.26) +(84.66,30.04) +(84.54,29.82) +(84.41,29.61) +(84.28,29.39) +(84.15,29.17) +(84.02,28.96) +(83.89,28.75) +(83.75,28.53) +(83.62,28.32) +(83.48,28.11) +(83.34,27.90) +(83.20,27.69) +(83.06,27.48) +(82.92,27.28) +(82.78,27.07) +(82.63,26.87) +(82.48,26.66) +(82.34,26.46) +(82.19,26.25) +(82.04,26.05) +(81.89,25.85) +(81.74,25.65) +(81.58,25.45) +(81.43,25.25) +(81.27,25.06) +(81.11,24.86) +(80.95,24.67) +(80.79,24.47) +(80.63,24.28) +(80.47,24.09) +(80.31,23.90) +(80.14,23.71) +(79.98,23.52) +(79.81,23.33) +(79.64,23.14) +(79.47,22.96) +(79.30,22.77) +(79.13,22.59) +(78.96,22.41) +(78.78,22.22) +(78.61,22.04) +(78.43,21.86) +(78.25,21.69) +(78.08,21.51) +(77.90,21.33) +(77.72,21.16) +(77.53,20.98) +(77.35,20.81) +(77.17,20.64) +(76.98,20.47) +(76.80,20.30) +(76.61,20.13) +(76.42,19.97) +(76.23,19.80) +(76.04,19.64) +(75.85,19.47) +(75.66,19.31) +(75.46,19.15) +(75.27,18.99) +(75.07,18.83) +(74.88,18.68) +(74.68,18.52) +(74.48,18.37) +(74.28,18.21) +(74.08,18.06) +(73.88,17.91) +(73.68,17.76) +(73.47,17.61) +(73.27,17.47) +(73.07,17.32) +(72.86,17.18) +(72.65,17.03) +(72.45,16.89) +(72.24,16.75) +(72.03,16.61) +(71.82,16.47) +(71.61,16.34) +(71.39,16.20) +(71.18,16.07) +(70.97,15.94) +(70.75,15.80) +(70.54,15.67) +(70.32,15.55) +(70.10,15.42) +(69.89,15.29) +(69.67,15.17) +(69.45,15.05) +(69.23,14.92) +(69.01,14.80) +(68.79,14.69) +(68.56,14.57) +(68.34,14.45) +(68.12,14.34) +(67.89,14.22) +(67.67,14.11) +(67.44,14.00) +(67.21,13.89) +(66.99,13.79) +(66.76,13.68) +(66.53,13.58) +(66.30,13.47) +(66.07,13.37) +(65.84,13.27) +(65.61,13.17) +(65.38,13.07) +(65.15,12.98) +(64.91,12.88) +(64.68,12.79) +(64.44,12.70) +(64.21,12.61) +(63.97,12.52) +(63.74,12.43) +(63.50,12.35) +(63.27,12.26) +(63.03,12.18) +(62.79,12.10) +(62.55,12.02) +(62.31,11.94) +(62.07,11.87) +(61.83,11.79) +(61.59,11.72) +(61.35,11.64) +(61.11,11.57) +(60.87,11.50) +(60.63,11.44) +(60.38,11.37) +(60.14,11.31) +(59.90,11.24) +(59.65,11.18) +(59.41,11.12) +(59.16,11.06) +(58.92,11.01) +(58.67,10.95) +(58.43,10.90) +(58.18,10.85) +(57.94,10.80) +(57.69,10.75) +(57.44,10.70) +(57.20,10.65) +(56.95,10.61) +(56.70,10.57) +(56.45,10.52) +(56.20,10.48) +(55.96,10.45) +(55.71,10.41) +(55.46,10.37) +(55.21,10.34) +(54.96,10.31) +(54.71,10.28) +(54.46,10.25) +(54.21,10.22) +(53.96,10.20) +(53.71,10.17) +(53.46,10.15) +(53.21,10.13) +(52.96,10.11) +(52.71,10.09) +(52.46,10.08) +(52.21,10.06) +(51.95,10.05) +(51.70,10.04) +(51.45,10.03) +(51.20,10.02) +(50.95,10.01) +(50.70,10.01) +(50.45,10.00) +(50.20,10.00) +(49.94,10.00) +(49.69,10.00) +(49.44,10.00) +(49.19,10.01) +(48.94,10.01) +(48.69,10.02) +(48.44,10.03) +(48.18,10.04) +(47.93,10.05) +(47.68,10.07) +(47.43,10.08) +(47.18,10.10) +(46.93,10.12) +(46.68,10.14) +(46.43,10.16) +(46.18,10.18) +(45.93,10.21) +(45.68,10.23) +(45.43,10.26) +(45.18,10.29) +(44.93,10.32) +(44.68,10.36) +(44.43,10.39) +(44.18,10.43) +(43.93,10.46) +(43.68,10.50) +(43.44,10.54) +(43.19,10.58) +(42.94,10.63) +(42.69,10.67) +(42.45,10.72) +(42.20,10.77) +(41.95,10.82) +(41.71,10.87) +(41.46,10.92) +(41.22,10.98) +(40.97,11.03) +(40.73,11.09) +(40.48,11.15) +(40.24,11.21) +(39.99,11.27) +(39.75,11.34) +(39.51,11.40) +(39.27,11.47) +(39.02,11.54) +(38.78,11.61) +(38.54,11.68) +(38.30,11.75) +(38.06,11.82) +(37.82,11.90) +(37.58,11.98) +(37.34,12.06) +(37.10,12.14) +(36.87,12.22) +(36.63,12.30) +(36.39,12.39) +(36.16,12.47) +(35.92,12.56) +(35.68,12.65) +(35.45,12.74) +(35.22,12.83) +(34.98,12.93) +(34.75,13.02) +(34.52,13.12) +(34.29,13.22) +(34.06,13.32) +(33.83,13.42) +(33.60,13.52) +(33.37,13.62) +(33.14,13.73) +(32.91,13.83) +(32.68,13.94) +(32.46,14.05) +(32.23,14.16) +(32.01,14.28) +(31.78,14.39) +(31.56,14.50) +(31.34,14.62) +(31.11,14.74) +(30.89,14.86) +(30.67,14.98) +(30.45,15.10) +(30.23,15.22) +(30.02,15.35) +(29.80,15.48) +(29.58,15.60) +(29.37,15.73) +(29.15,15.86) +(28.94,16.00) +(28.72,16.13) +(28.51,16.26) +(28.30,16.40) +(28.09,16.54) +(27.88,16.67) +(27.67,16.81) +(27.46,16.95) +(27.25,17.10) +(27.05,17.24) +(26.84,17.39) +(26.64,17.53) +(26.43,17.68) +(26.23,17.83) +(26.03,17.98) +(25.83,18.13) +(25.63,18.28) +(25.43,18.44) +(25.23,18.59) +(25.04,18.75) +(24.84,18.90) +(24.64,19.06) +(24.45,19.22) +(24.26,19.38) +(24.07,19.55) +(23.87,19.71) +(23.68,19.88) +(23.50,20.04) +(23.31,20.21) +(23.12,20.38) +(22.94,20.55) +(22.75,20.72) +(22.57,20.89) +(22.38,21.06) +(22.20,21.24) +(22.02,21.41) +(21.84,21.59) +(21.67,21.77) +(21.49,21.94) +(21.31,22.12) +(21.14,22.30) +(20.97,22.49) +(20.79,22.67) +(20.62,22.85) +(20.45,23.04) +(20.28,23.23) +(20.11,23.41) +(19.95,23.60) +(19.78,23.79) +(19.62,23.98) +(19.46,24.17) +(19.29,24.37) +(19.13,24.56) +(18.97,24.75) +(18.82,24.95) +(18.66,25.15) +(18.50,25.34) +(18.35,25.54) +(18.20,25.74) +(18.04,25.94) +(17.89,26.14) +(17.74,26.34) +(17.60,26.55) +(17.45,26.75) +(17.30,26.96) +(17.16,27.16) +(17.02,27.37) +(16.88,27.58) +(16.74,27.79) +(16.60,28.00) +(16.46,28.21) +(16.32,28.42) +(16.19,28.63) +(16.05,28.84) +(15.92,29.06) +(15.79,29.27) +(15.66,29.49) +(15.53,29.70) +(15.41,29.92) +(15.28,30.14) +(15.16,30.36) +(15.03,30.58) +(14.91,30.80) +(14.79,31.02) +(14.67,31.24) +(14.56,31.46) +(14.44,31.68) +(14.33,31.91) +(14.21,32.13) +(14.10,32.36) +(13.99,32.58) +(13.88,32.81) +(13.77,33.04) +(13.67,33.27) +(13.56,33.49) +(13.46,33.72) +(13.36,33.95) +(13.26,34.18) +(13.16,34.42) +(13.06,34.65) +(12.97,34.88) +(12.87,35.11) +(12.78,35.35) +(12.69,35.58) +(12.60,35.82) +(12.51,36.05) +(12.42,36.29) +(12.34,36.52) +(12.25,36.76) +(12.17,37.00) +(12.09,37.24) +(12.01,37.48) +(11.93,37.71) +(11.86,37.95) +(11.78,38.19) +(11.71,38.43) +(11.64,38.68) +(11.57,38.92) +(11.50,39.16) +(11.43,39.40) +(11.36,39.64) +(11.30,39.89) +(11.24,40.13) +(11.18,40.37) +(11.12,40.62) +(11.06,40.86) +(11.00,41.11) +(10.95,41.35) +(10.89,41.60) +(10.84,41.84) +(10.79,42.09) +(10.74,42.34) +(10.69,42.58) +(10.65,42.83) +(10.60,43.08) +(10.56,43.33) +(10.52,43.57) +(10.48,43.82) +(10.44,44.07) +(10.41,44.32) +(10.37,44.57) +(10.34,44.82) +(10.31,45.07) +(10.27,45.32) +(10.25,45.57) +(10.22,45.82) +(10.19,46.07) +(10.17,46.32) +(10.15,46.57) +(10.13,46.82) +(10.11,47.07) +(10.09,47.32) +(10.07,47.57) +(10.06,47.82) +(10.05,48.07) +(10.04,48.32) +(10.03,48.58) +(10.02,48.83) +(10.01,49.08) +(10.01,49.33) +(10.00,49.58) +(10.00,49.83) +(10.00,50.08) +(10.00,50.34) +(10.00,50.59) +(10.01,50.84) +(10.01,51.09) +(10.02,51.34) +(10.03,51.59) +(10.04,51.84) +(10.05,52.10) +(10.07,52.35) +(10.08,52.60) +(10.10,52.85) +(10.12,53.10) +(10.14,53.35) +(10.16,53.60) +(10.19,53.85) +(10.21,54.10) +(10.24,54.35) +(10.27,54.60) +(10.30,54.85) +(10.33,55.10) +(10.36,55.35) +(10.39,55.60) +(10.43,55.85) +(10.47,56.10) +(10.51,56.34) +(10.55,56.59) +(10.59,56.84) +(10.63,57.09) +(10.68,57.33) +(10.73,57.58) +(10.77,57.83) +(10.82,58.07) +(10.88,58.32) +(10.93,58.57) +(10.98,58.81) +(11.04,59.06) +(11.10,59.30) +(11.16,59.55) +(11.22,59.79) +(11.28,60.03) +(11.34,60.28) +(11.41,60.52) +(11.47,60.76) +(11.54,61.00) +(11.61,61.25) +(11.68,61.49) +(11.76,61.73) +(11.83,61.97) +(11.91,62.21) +(11.99,62.45) +(12.06,62.69) +(12.15,62.92) +(12.23,63.16) +(12.31,63.40) +(12.40,63.63) +(12.48,63.87) +(12.57,64.11) +(12.66,64.34) +(12.75,64.58) +(12.84,64.81) +(12.94,65.04) +(13.03,65.28) +(13.13,65.51) +(13.23,65.74) +(13.33,65.97) +(13.43,66.20) +(13.53,66.43) +(13.63,66.66) +(13.74,66.89) +(13.85,67.11) +(13.95,67.34) +(14.06,67.57) +(14.18,67.79) +(14.29,68.02) +(14.40,68.24) +(14.52,68.47) +(14.63,68.69) +(14.75,68.91) +(14.87,69.13) +(14.99,69.35) +(15.12,69.57) +(15.24,69.79) +(15.36,70.01) +(15.49,70.23) +(15.62,70.44) +(15.75,70.66) +(15.88,70.87) +(16.01,71.09) +(16.14,71.30) +(16.28,71.51) +(16.41,71.72) +(16.55,71.94) +(16.69,72.14) +(16.83,72.35) +(16.97,72.56) +(17.11,72.77) +(17.26,72.98) +(17.40,73.18) +(17.55,73.39) +(17.70,73.59) +(17.84,73.79) +(17.99,73.99) +(18.15,74.19) +(18.30,74.39) +(18.45,74.59) +(18.61,74.79) +(18.76,74.99) +(18.92,75.18) +(19.08,75.38) +(19.24,75.57) +(19.40,75.76) +(19.57,75.96) +(19.73,76.15) +(19.89,76.34) +(20.06,76.53) +(20.23,76.71) +(20.40,76.90) +(20.57,77.09) +(20.74,77.27) +(20.91,77.45) +(21.08,77.64) +(21.26,77.82) +(21.43,78.00) +(21.61,78.18) +(21.79,78.35) +(21.96,78.53) +(22.14,78.71) +(22.33,78.88) +(22.51,79.05) +(22.69,79.23) +(22.87,79.40) +(23.06,79.57) +(23.25,79.74) +(23.43,79.90) +(23.62,80.07) +(23.81,80.24) +(24.00,80.40) +(24.19,80.56) +(24.39,80.72) +(24.58,80.88) +(24.77,81.04) +(24.97,81.20) +(25.17,81.36) +(25.36,81.51) +(25.56,81.67) +(25.76,81.82) +(25.96,81.97) +(26.16,82.12) +(26.37,82.27) +(26.57,82.42) +(26.77,82.57) +(26.98,82.71) +(27.19,82.86) +(27.39,83.00) +(27.60,83.14) +(27.81,83.28) +(28.02,83.42) +(28.23,83.56) +(28.44,83.69) +(28.65,83.83) +(28.87,83.96) +(29.08,84.09) +(29.30,84.22) +(29.51,84.35) +(29.73,84.48) +(29.94,84.61) +(30.16,84.73) +(30.38,84.86) +(30.60,84.98) +(30.82,85.10) +(31.04,85.22) +(31.26,85.34) +(31.49,85.46) +(31.71,85.57) +(31.93,85.69) +(32.16,85.80) +(32.38,85.91) +(32.61,86.02) +(32.84,86.13) +(33.06,86.24) +(33.29,86.34) +(33.52,86.45) +(33.75,86.55) +(33.98,86.65) +(34.21,86.75) +(34.44,86.85) +(34.67,86.95) +(34.91,87.04) +(35.14,87.14) +(35.37,87.23) +(35.61,87.32) +(35.84,87.41) +(36.08,87.50) +(36.31,87.59) +(36.55,87.67) +(36.79,87.75) +(37.03,87.84) +(37.26,87.92) +(37.50,88.00) +(37.74,88.08) +(37.98,88.15) +(38.22,88.23) +(38.46,88.30) +(38.70,88.37) +(38.94,88.44) +(39.19,88.51) +(39.43,88.58) +(39.67,88.64) +(39.91,88.71) +(40.16,88.77) +(40.40,88.83) +(40.65,88.89) +(40.89,88.95) +(41.13,89.01) +(41.38,89.06) +(41.63,89.11) +(41.87,89.17) +(42.12,89.22) +(42.37,89.26) +(42.61,89.31) +(42.86,89.36) +(43.11,89.40) +(43.35,89.44) +(43.60,89.49) +(43.85,89.52) +(44.10,89.56) +(44.35,89.60) +(44.60,89.63) +(44.85,89.67) +(45.10,89.70) +(45.35,89.73) +(45.60,89.76) +(45.85,89.78) +(46.10,89.81) +(46.35,89.83) +(46.60,89.85) +(46.85,89.88) +(47.10,89.89) +(47.35,89.91) +(47.60,89.93) +(47.85,89.94) +(48.10,89.95) +(48.35,89.97) +(48.60,89.98) +(48.86,89.98) +(49.11,89.99) +(49.36,89.99) +(49.61,90.00) +(49.86,90.00) +2994 +8 3 0 +9 8 0 +10 6 0 +13 3 0 +15 6 0 +15 7 0 +15 5 0 +16 1 0 +17 7 0 +19 8 0 +19 18 0 +20 4 0 +20 2 0 +21 5 0 +22 5 0 +25 10 0 +25 24 0 +27 10 0 +27 20 0 +27 25 0 +28 12 0 +29 11 0 +29 23 0 +30 4 0 +30 20 0 +33 13 0 +33 32 0 +34 2 0 +36 17 0 +37 13 0 +39 19 0 +39 18 0 +40 33 0 +40 29 0 +41 36 0 +42 8 0 +42 5 0 +44 21 0 +45 18 0 +45 11 0 +46 34 0 +46 20 0 +47 19 0 +48 28 0 +49 5 0 +49 17 0 +50 23 0 +50 18 0 +51 43 0 +52 17 0 +52 38 0 +53 20 0 +53 27 0 +55 3 0 +55 47 0 +57 20 0 +58 3 0 +59 30 0 +59 54 0 +59 56 0 +60 26 0 +60 15 0 +60 7 0 +60 5 0 +61 59 0 +62 12 0 +63 16 0 +63 8 0 +64 29 0 +64 42 0 +65 33 0 +67 7 0 +68 17 0 +68 49 0 +69 7 0 +69 62 0 +69 12 0 +69 28 0 +70 44 0 +71 51 0 +71 9 0 +73 66 0 +73 42 0 +73 64 0 +74 55 0 +75 16 0 +75 1 0 +75 51 0 +76 29 0 +76 41 0 +77 12 0 +77 62 0 +78 59 0 +79 52 0 +79 60 0 +80 50 0 +80 23 0 +80 29 0 +80 11 0 +81 18 0 +81 19 0 +82 57 0 +83 39 0 +83 28 0 +84 7 0 +84 17 0 +85 78 0 +85 59 0 +86 52 0 +87 30 0 +88 35 0 +88 7 0 +88 6 0 +89 47 0 +89 74 0 +89 37 0 +90 29 0 +90 64 0 +90 42 0 +91 8 0 +92 57 0 +93 69 0 +93 88 0 +94 7 0 +96 82 0 +96 22 0 +96 5 0 +97 88 0 +97 6 0 +97 35 0 +98 39 0 +98 83 0 +99 19 0 +100 29 0 +101 41 0 +101 36 0 +101 7 0 +102 72 0 +103 99 0 +103 12 0 +103 19 0 +104 24 0 +104 25 0 +106 35 0 +107 15 0 +108 13 0 +108 32 0 +110 34 0 +110 6 0 +110 10 0 +111 47 0 +111 19 0 +111 8 0 +111 3 0 +112 5 0 +112 52 0 +112 49 0 +113 8 0 +114 31 0 +114 12 0 +115 18 0 +116 34 0 +116 35 0 +118 14 0 +118 39 0 +118 98 0 +119 11 0 +119 7 0 +120 42 0 +120 73 0 +121 37 0 +121 89 0 +121 74 0 +121 109 0 +122 117 0 +123 56 0 +123 59 0 +124 11 0 +124 101 0 +126 8 0 +127 49 0 +127 29 0 +128 101 0 +128 7 0 +129 16 0 +129 114 0 +129 12 0 +130 25 0 +130 24 0 +131 119 0 +132 73 0 +132 66 0 +134 23 0 +134 13 0 +135 11 0 +135 119 0 +136 52 0 +136 84 0 +137 55 0 +137 74 0 +137 89 0 +138 18 0 +139 54 0 +139 10 0 +139 133 0 +139 61 0 +140 73 0 +140 66 0 +141 8 0 +141 63 0 +141 75 0 +142 98 0 +142 39 0 +143 101 0 +143 124 0 +143 11 0 +143 41 0 +144 58 0 +145 40 0 +145 65 0 +145 33 0 +147 11 0 +147 29 0 +147 41 0 +148 5 0 +148 60 0 +148 79 0 +149 32 0 +149 146 0 +149 29 0 +150 29 0 +150 3 0 +151 45 0 +152 9 0 +152 44 0 +153 35 0 +153 116 0 +153 34 0 +154 43 0 +155 112 0 +155 52 0 +157 69 0 +157 28 0 +158 17 0 +158 36 0 +160 1 0 +160 43 0 +161 90 0 +161 5 0 +161 29 0 +162 1 0 +162 16 0 +162 2 0 +162 92 0 +162 160 0 +163 147 0 +163 41 0 +163 143 0 +164 51 0 +165 113 0 +165 91 0 +166 8 0 +166 42 0 +166 120 0 +166 132 0 +167 122 0 +167 72 0 +167 102 0 +167 95 0 +168 17 0 +168 7 0 +168 101 0 +169 117 0 +169 156 0 +169 56 0 +169 102 0 +169 72 0 +170 82 0 +170 4 0 +171 158 0 +171 29 0 +173 130 0 +174 162 0 +174 92 0 +175 11 0 +175 135 0 +175 45 0 +176 69 0 +177 105 0 +178 125 0 +179 55 0 +179 3 0 +180 137 0 +180 89 0 +180 47 0 +181 106 0 +181 97 0 +182 35 0 +182 62 0 +183 4 0 +183 22 0 +183 170 0 +184 2 0 +184 16 0 +184 12 0 +185 139 0 +186 12 0 +187 35 0 +187 182 0 +187 62 0 +188 184 0 +188 129 0 +189 182 0 +189 2 0 +190 170 0 +190 82 0 +190 57 0 +191 59 0 +191 139 0 +191 185 0 +191 61 0 +192 103 0 +192 12 0 +192 114 0 +192 91 0 +193 140 0 +193 66 0 +193 132 0 +193 73 0 +194 30 0 +194 87 0 +195 117 0 +195 122 0 +196 35 0 +196 116 0 +196 153 0 +197 21 0 +197 44 0 +198 10 0 +198 6 0 +199 29 0 +200 71 0 +200 164 0 +200 51 0 +201 18 0 +201 19 0 +201 81 0 +202 5 0 +202 42 0 +203 137 0 +204 110 0 +204 173 0 +204 34 0 +205 16 0 +205 63 0 +206 47 0 +206 111 0 +206 3 0 +206 58 0 +206 55 0 +207 29 0 +208 65 0 +209 54 0 +209 59 0 +210 12 0 +211 29 0 +211 127 0 +212 5 0 +212 148 0 +212 86 0 +212 52 0 +213 96 0 +214 163 0 +214 147 0 +215 80 0 +216 183 0 +216 22 0 +216 170 0 +217 125 0 +218 79 0 +218 52 0 +219 217 0 +219 167 0 +220 133 0 +220 139 0 +220 10 0 +220 4 0 +221 110 0 +221 10 0 +222 207 0 +222 127 0 +222 29 0 +223 173 0 +223 25 0 +223 130 0 +224 59 0 +224 78 0 +224 178 0 +224 123 0 +225 3 0 +225 150 0 +226 100 0 +226 23 0 +226 134 0 +226 145 0 +227 142 0 +227 39 0 +227 177 0 +228 54 0 +228 209 0 +229 114 0 +229 31 0 +230 114 0 +231 3 0 +231 37 0 +231 121 0 +231 109 0 +231 179 0 +232 39 0 +232 118 0 +232 159 0 +233 106 0 +233 35 0 +233 97 0 +233 181 0 +234 8 0 +234 230 0 +235 1 0 +235 160 0 +235 75 0 +236 13 0 +236 23 0 +236 50 0 +236 37 0 +237 95 0 +238 235 0 +239 43 0 +239 51 0 +240 19 0 +240 83 0 +240 28 0 +241 72 0 +241 117 0 +242 70 0 +243 7 0 +244 68 0 +244 17 0 +245 208 0 +245 13 0 +245 65 0 +246 33 0 +246 65 0 +246 245 0 +247 169 0 +247 78 0 +248 68 0 +248 17 0 +249 157 0 +249 28 0 +250 65 0 +250 226 0 +251 133 0 +251 87 0 +251 30 0 +251 61 0 +251 139 0 +252 131 0 +252 48 0 +252 151 0 +253 52 0 +253 38 0 +253 155 0 +254 242 0 +254 152 0 +255 214 0 +256 28 0 +256 119 0 +256 7 0 +256 249 0 +257 88 0 +257 7 0 +258 31 0 +258 16 0 +258 205 0 +258 230 0 +258 114 0 +259 59 0 +259 78 0 +260 29 0 +260 64 0 +261 94 0 +261 7 0 +261 243 0 +262 76 0 +262 41 0 +263 91 0 +263 192 0 +263 114 0 +263 8 0 +264 236 0 +264 37 0 +264 13 0 +265 12 0 +265 77 0 +265 2 0 +265 184 0 +266 2 0 +267 46 0 +267 20 0 +268 6 0 +268 110 0 +269 52 0 +269 136 0 +270 200 0 +271 254 0 +272 22 0 +272 96 0 +272 170 0 +273 19 0 +273 111 0 +273 47 0 +274 56 0 +274 219 0 +274 167 0 +275 210 0 +275 19 0 +276 18 0 +276 227 0 +276 39 0 +277 19 0 +277 39 0 +278 91 0 +279 80 0 +279 11 0 +279 215 0 +280 3 0 +280 13 0 +280 37 0 +280 231 0 +281 231 0 +281 109 0 +281 179 0 +282 97 0 +282 6 0 +282 268 0 +283 62 0 +283 182 0 +284 43 0 +284 51 0 +284 75 0 +284 160 0 +285 236 0 +285 50 0 +285 115 0 +286 161 0 +286 90 0 +287 49 0 +288 13 0 +288 108 0 +289 47 0 +289 180 0 +290 56 0 +290 54 0 +291 8 0 +292 114 0 +292 230 0 +292 234 0 +293 249 0 +293 7 0 +293 69 0 +293 157 0 +294 7 0 +294 128 0 +294 101 0 +295 34 0 +295 204 0 +296 25 0 +296 24 0 +297 139 0 +297 191 0 +297 54 0 +298 27 0 +298 104 0 +298 25 0 +299 8 0 +299 263 0 +299 114 0 +299 292 0 +300 103 0 +300 192 0 +301 205 0 +301 230 0 +301 258 0 +302 109 0 +302 74 0 +302 55 0 +302 179 0 +302 281 0 +303 230 0 +303 301 0 +304 263 0 +304 299 0 +305 221 0 +305 10 0 +305 25 0 +305 223 0 +307 7 0 +307 176 0 +307 69 0 +308 114 0 +308 31 0 +309 44 0 +309 51 0 +309 239 0 +309 43 0 +310 57 0 +310 92 0 +310 162 0 +310 2 0 +310 20 0 +311 263 0 +311 114 0 +311 299 0 +312 130 0 +312 20 0 +312 46 0 +312 173 0 +313 219 0 +313 274 0 +314 59 0 +314 27 0 +314 209 0 +315 147 0 +315 255 0 +316 5 0 +316 207 0 +316 29 0 +316 161 0 +317 54 0 +317 156 0 +317 59 0 +318 167 0 +318 195 0 +318 122 0 +319 183 0 +319 4 0 +320 153 0 +320 34 0 +320 35 0 +321 88 0 +321 93 0 +321 69 0 +321 67 0 +321 7 0 +322 70 0 +322 242 0 +322 254 0 +322 271 0 +323 98 0 +323 39 0 +324 66 0 +324 73 0 +324 260 0 +324 29 0 +325 31 0 +325 229 0 +326 119 0 +326 131 0 +326 252 0 +326 151 0 +327 290 0 +327 54 0 +328 150 0 +328 3 0 +328 29 0 +329 38 0 +329 253 0 +329 52 0 +330 184 0 +330 16 0 +332 326 0 +332 151 0 +332 45 0 +333 11 0 +333 143 0 +333 124 0 +334 274 0 +335 138 0 +335 50 0 +335 18 0 +336 238 0 +336 235 0 +337 19 0 +337 165 0 +337 8 0 +338 225 0 +338 149 0 +338 146 0 +338 3 0 +339 45 0 +339 335 0 +340 29 0 +340 150 0 +340 328 0 +341 326 0 +341 45 0 +342 29 0 +342 149 0 +342 338 0 +342 150 0 +343 318 0 +343 167 0 +343 306 0 +344 245 0 +344 33 0 +344 246 0 +345 125 0 +345 178 0 +345 224 0 +345 78 0 +345 237 0 +346 3 0 +346 58 0 +347 15 0 +347 88 0 +347 257 0 +348 52 0 +348 218 0 +348 84 0 +348 136 0 +349 17 0 +349 52 0 +349 269 0 +350 245 0 +350 13 0 +350 33 0 +350 344 0 +351 177 0 +351 105 0 +351 227 0 +352 24 0 +353 9 0 +353 8 0 +354 151 0 +354 18 0 +354 45 0 +355 165 0 +355 337 0 +356 299 0 +356 292 0 +356 234 0 +356 8 0 +357 287 0 +357 49 0 +357 127 0 +357 222 0 +357 207 0 +358 266 0 +358 35 0 +358 34 0 +358 2 0 +359 270 0 +359 164 0 +360 203 0 +360 55 0 +360 137 0 +361 17 0 +361 168 0 +361 101 0 +361 36 0 +362 303 0 +362 301 0 +362 205 0 +362 234 0 +362 230 0 +363 156 0 +363 327 0 +364 89 0 +364 37 0 +364 81 0 +365 52 0 +365 17 0 +365 49 0 +365 112 0 +366 141 0 +366 16 0 +366 75 0 +367 360 0 +367 180 0 +367 55 0 +368 286 0 +368 202 0 +368 5 0 +368 161 0 +369 91 0 +369 263 0 +369 126 0 +369 8 0 +370 71 0 +370 51 0 +370 309 0 +370 44 0 +370 70 0 +371 360 0 +371 137 0 +371 180 0 +371 367 0 +372 286 0 +372 90 0 +372 202 0 +372 368 0 +373 225 0 +373 150 0 +374 166 0 +375 306 0 +376 6 0 +376 110 0 +376 268 0 +377 213 0 +377 96 0 +377 170 0 +378 367 0 +378 180 0 +379 375 0 +379 343 0 +379 306 0 +380 169 0 +380 334 0 +380 274 0 +381 10 0 +381 54 0 +381 209 0 +382 45 0 +382 80 0 +382 215 0 +383 35 0 +384 216 0 +384 170 0 +385 10 0 +385 221 0 +385 110 0 +386 62 0 +386 182 0 +386 189 0 +386 77 0 +387 347 0 +387 7 0 +388 296 0 +388 130 0 +388 25 0 +389 100 0 +389 199 0 +389 29 0 +389 23 0 +389 226 0 +390 387 0 +390 347 0 +391 134 0 +391 13 0 +391 250 0 +391 226 0 +392 55 0 +392 144 0 +392 58 0 +392 3 0 +393 14 0 +394 130 0 +394 388 0 +395 73 0 +395 64 0 +395 260 0 +395 324 0 +396 11 0 +396 45 0 +396 382 0 +397 55 0 +397 47 0 +398 371 0 +399 188 0 +399 12 0 +399 184 0 +400 237 0 +400 95 0 +401 234 0 +401 362 0 +402 21 0 +402 197 0 +402 44 0 +402 154 0 +402 43 0 +403 367 0 +403 360 0 +403 371 0 +404 277 0 +404 39 0 +404 83 0 +404 240 0 +405 154 0 +405 43 0 +405 402 0 +406 176 0 +406 67 0 +406 321 0 +407 336 0 +407 238 0 +408 5 0 +408 21 0 +409 241 0 +409 122 0 +409 117 0 +410 207 0 +410 316 0 +410 5 0 +410 49 0 +411 317 0 +411 156 0 +411 247 0 +411 85 0 +412 162 0 +412 174 0 +412 92 0 +413 141 0 +413 75 0 +413 51 0 +413 291 0 +414 8 0 +414 113 0 +414 165 0 +414 91 0 +415 98 0 +415 142 0 +415 227 0 +415 28 0 +415 83 0 +416 337 0 +416 19 0 +416 103 0 +416 165 0 +417 355 0 +417 165 0 +417 113 0 +417 337 0 +418 210 0 +418 275 0 +418 19 0 +418 12 0 +419 196 0 +419 153 0 +420 100 0 +420 199 0 +421 345 0 +421 78 0 +421 237 0 +422 8 0 +422 132 0 +423 87 0 +424 28 0 +424 12 0 +424 186 0 +424 240 0 +425 127 0 +425 248 0 +425 17 0 +426 380 0 +426 334 0 +426 274 0 +427 29 0 +427 172 0 +427 324 0 +428 298 0 +428 20 0 +428 24 0 +429 331 0 +429 308 0 +429 114 0 +430 202 0 +430 368 0 +430 372 0 +431 219 0 +431 217 0 +431 95 0 +431 167 0 +432 35 0 +432 187 0 +432 93 0 +433 129 0 +433 184 0 +433 330 0 +433 16 0 +434 363 0 +434 156 0 +435 137 0 +435 203 0 +435 360 0 +436 16 0 +436 184 0 +437 374 0 +437 132 0 +438 243 0 +438 7 0 +439 272 0 +439 96 0 +440 342 0 +440 225 0 +441 18 0 +441 45 0 +442 309 0 +442 51 0 +442 239 0 +443 382 0 +443 50 0 +443 80 0 +444 56 0 +444 123 0 +444 178 0 +444 125 0 +444 313 0 +445 112 0 +445 155 0 +445 38 0 +445 365 0 +446 139 0 +446 61 0 +447 100 0 +447 226 0 +447 145 0 +447 40 0 +447 29 0 +448 342 0 +448 225 0 +448 373 0 +448 150 0 +449 1 0 +449 160 0 +449 407 0 +449 336 0 +450 307 0 +450 7 0 +450 94 0 +451 375 0 +451 237 0 +451 78 0 +451 379 0 +452 50 0 +452 138 0 +452 18 0 +453 272 0 +453 439 0 +453 213 0 +453 377 0 +453 170 0 +454 69 0 +454 176 0 +454 406 0 +454 321 0 +455 316 0 +455 207 0 +455 29 0 +456 141 0 +456 413 0 +456 291 0 +457 61 0 +457 59 0 +457 191 0 +458 421 0 +458 78 0 +458 451 0 +458 237 0 +459 8 0 +459 9 0 +459 152 0 +459 5 0 +459 42 0 +460 85 0 +460 59 0 +460 317 0 +460 411 0 +461 194 0 +461 87 0 +461 220 0 +461 4 0 +461 30 0 +462 347 0 +462 15 0 +462 107 0 +463 74 0 +463 302 0 +464 8 0 +464 166 0 +464 374 0 +465 94 0 +465 261 0 +465 307 0 +466 18 0 +466 81 0 +466 364 0 +466 37 0 +466 115 0 +467 30 0 +467 20 0 +467 27 0 +467 314 0 +467 59 0 +468 70 0 +468 370 0 +468 44 0 +469 110 0 +469 221 0 +469 305 0 +469 223 0 +470 56 0 +470 297 0 +470 59 0 +471 181 0 +471 34 0 +471 116 0 +472 411 0 +473 164 0 +473 200 0 +474 403 0 +474 360 0 +474 398 0 +474 371 0 +475 227 0 +475 276 0 +475 18 0 +476 45 0 +476 441 0 +476 18 0 +476 335 0 +477 132 0 +477 66 0 +477 324 0 +477 427 0 +478 357 0 +478 127 0 +479 41 0 +479 163 0 +480 67 0 +480 406 0 +480 176 0 +480 307 0 +481 429 0 +481 114 0 +481 129 0 +482 227 0 +482 351 0 +482 28 0 +483 251 0 +483 133 0 +483 87 0 +484 328 0 +484 3 0 +484 8 0 +485 84 0 +485 218 0 +485 79 0 +485 60 0 +485 7 0 +486 78 0 +486 117 0 +486 195 0 +486 318 0 +487 19 0 +487 89 0 +487 364 0 +487 81 0 +488 296 0 +488 394 0 +488 388 0 +489 72 0 +489 241 0 +489 117 0 +489 169 0 +490 241 0 +490 72 0 +490 167 0 +491 438 0 +491 480 0 +491 261 0 +491 243 0 +492 211 0 +492 171 0 +493 448 0 +493 373 0 +493 150 0 +494 65 0 +494 208 0 +494 245 0 +495 202 0 +495 90 0 +495 42 0 +496 126 0 +496 369 0 +496 263 0 +497 354 0 +497 151 0 +497 252 0 +497 48 0 +497 105 0 +498 283 0 +498 182 0 +499 254 0 +499 152 0 +499 9 0 +499 322 0 +500 115 0 +500 50 0 +500 18 0 +501 283 0 +501 498 0 +501 182 0 +501 386 0 +501 62 0 +502 420 0 +502 199 0 +502 389 0 +502 100 0 +503 3 0 +503 179 0 +503 55 0 +504 59 0 +504 56 0 +505 184 0 +505 433 0 +505 129 0 +505 188 0 +507 265 0 +507 77 0 +507 386 0 +507 189 0 +508 428 0 +508 24 0 +509 183 0 +509 216 0 +509 384 0 +509 170 0 +510 15 0 +510 7 0 +510 60 0 +511 78 0 +511 247 0 +511 169 0 +511 117 0 +511 486 0 +512 490 0 +512 167 0 +512 122 0 +512 409 0 +512 241 0 +513 257 0 +513 7 0 +513 387 0 +513 347 0 +514 466 0 +514 364 0 +514 37 0 +515 110 0 +515 97 0 +515 282 0 +515 268 0 +516 327 0 +517 89 0 +517 487 0 +517 19 0 +517 47 0 +518 169 0 +518 380 0 +519 2 0 +519 46 0 +519 267 0 +519 20 0 +520 3 0 +520 338 0 +520 146 0 +520 13 0 +521 79 0 +521 60 0 +522 377 0 +522 96 0 +522 82 0 +522 170 0 +523 145 0 +523 226 0 +523 250 0 +524 10 0 +524 198 0 +524 6 0 +524 5 0 +525 428 0 +525 20 0 +525 130 0 +525 352 0 +525 24 0 +526 73 0 +526 66 0 +527 476 0 +527 45 0 +527 441 0 +528 130 0 +528 488 0 +528 296 0 +528 24 0 +529 471 0 +529 181 0 +529 110 0 +529 34 0 +530 498 0 +530 283 0 +530 182 0 +531 342 0 +531 225 0 +531 448 0 +532 446 0 +532 139 0 +532 251 0 +533 394 0 +533 488 0 +533 528 0 +533 130 0 +534 236 0 +534 115 0 +534 466 0 +535 52 0 +535 112 0 +535 506 0 +536 506 0 +536 535 0 +536 5 0 +537 46 0 +537 34 0 +537 295 0 +537 204 0 +538 186 0 +538 418 0 +539 228 0 +539 381 0 +539 54 0 +540 211 0 +540 492 0 +540 171 0 +541 365 0 +541 445 0 +541 38 0 +541 52 0 +542 83 0 +542 14 0 +542 118 0 +543 76 0 +543 262 0 +543 41 0 +543 147 0 +543 29 0 +544 159 0 +545 306 0 +545 343 0 +545 167 0 +545 237 0 +546 146 0 +546 149 0 +546 13 0 +547 347 0 +547 462 0 +547 107 0 +548 62 0 +548 501 0 +548 386 0 +549 155 0 +550 218 0 +550 485 0 +550 348 0 +551 85 0 +551 78 0 +551 259 0 +552 165 0 +553 13 0 +553 245 0 +553 208 0 +553 65 0 +554 34 0 +554 110 0 +554 204 0 +555 427 0 +555 29 0 +555 8 0 +556 466 0 +556 37 0 +557 159 0 +557 232 0 +558 481 0 +558 129 0 +558 308 0 +558 429 0 +559 516 0 +559 56 0 +559 169 0 +559 156 0 +559 434 0 +560 134 0 +560 391 0 +560 226 0 +561 480 0 +561 307 0 +561 465 0 +561 261 0 +561 491 0 +562 70 0 +562 9 0 +562 71 0 +562 370 0 +563 81 0 +563 487 0 +564 110 0 +564 469 0 +564 223 0 +565 5 0 +565 459 0 +565 152 0 +566 19 0 +566 418 0 +566 275 0 +567 108 0 +567 13 0 +567 32 0 +568 557 0 +568 83 0 +568 39 0 +568 232 0 +569 6 0 +569 376 0 +570 27 0 +570 10 0 +570 209 0 +570 314 0 +571 172 0 +571 427 0 +572 507 0 +572 77 0 +572 386 0 +573 20 0 +573 298 0 +574 133 0 +574 483 0 +575 470 0 +575 191 0 +575 59 0 +576 51 0 +576 164 0 +576 8 0 +576 291 0 +576 413 0 +577 45 0 +577 50 0 +577 443 0 +577 382 0 +578 139 0 +578 220 0 +578 133 0 +579 210 0 +579 275 0 +580 572 0 +580 77 0 +580 386 0 +581 28 0 +581 424 0 +581 240 0 +582 144 0 +582 392 0 +582 55 0 +583 96 0 +583 213 0 +583 439 0 +584 28 0 +584 48 0 +584 131 0 +584 119 0 +584 256 0 +585 228 0 +585 209 0 +585 381 0 +585 539 0 +586 325 0 +586 229 0 +586 114 0 +586 308 0 +586 31 0 +587 471 0 +587 34 0 +588 582 0 +588 55 0 +588 144 0 +589 244 0 +589 17 0 +589 248 0 +589 68 0 +590 301 0 +590 205 0 +590 362 0 +591 52 0 +591 535 0 +591 5 0 +591 212 0 +592 383 0 +592 35 0 +592 196 0 +592 419 0 +593 521 0 +593 60 0 +593 485 0 +593 79 0 +594 587 0 +594 34 0 +594 116 0 +594 471 0 +595 388 0 +595 296 0 +595 488 0 +596 291 0 +596 8 0 +597 430 0 +597 368 0 +598 278 0 +598 91 0 +599 308 0 +599 586 0 +599 114 0 +600 158 0 +600 171 0 +600 492 0 +600 17 0 +601 422 0 +601 8 0 +601 464 0 +602 28 0 +602 415 0 +603 165 0 +603 552 0 +603 278 0 +604 235 0 +604 75 0 +604 1 0 +605 125 0 +605 345 0 +605 217 0 +606 508 0 +606 104 0 +606 298 0 +606 428 0 +607 46 0 +607 537 0 +607 204 0 +607 173 0 +607 312 0 +608 159 0 +608 544 0 +608 118 0 +608 14 0 +608 393 0 +609 323 0 +609 39 0 +609 142 0 +609 98 0 +610 52 0 +610 535 0 +610 591 0 +611 286 0 +611 161 0 +611 90 0 +612 487 0 +612 563 0 +612 81 0 +613 118 0 +613 544 0 +613 232 0 +614 555 0 +614 172 0 +614 427 0 +615 127 0 +615 222 0 +615 357 0 +616 207 0 +616 410 0 +616 49 0 +616 287 0 +616 357 0 +617 347 0 +617 390 0 +617 387 0 +618 471 0 +618 116 0 +618 35 0 +618 106 0 +618 181 0 +619 513 0 +619 387 0 +619 390 0 +619 347 0 +620 70 0 +620 322 0 +620 499 0 +620 9 0 +620 562 0 +621 445 0 +621 38 0 +621 541 0 +622 339 0 +622 577 0 +622 45 0 +623 398 0 +623 474 0 +623 360 0 +623 371 0 +624 133 0 +625 431 0 +625 605 0 +625 237 0 +625 95 0 +626 164 0 +626 473 0 +626 200 0 +626 270 0 +626 359 0 +627 380 0 +627 274 0 +628 411 0 +628 472 0 +628 156 0 +628 169 0 +629 452 0 +629 138 0 +629 18 0 +630 156 0 +630 628 0 +630 472 0 +630 411 0 +631 425 0 +631 127 0 +631 49 0 +631 68 0 +631 248 0 +632 605 0 +633 505 0 +633 184 0 +633 433 0 +634 422 0 +634 601 0 +634 464 0 +634 374 0 +634 437 0 +635 569 0 +635 6 0 +635 110 0 +635 376 0 +636 516 0 +636 434 0 +637 391 0 +637 65 0 +637 250 0 +638 464 0 +639 499 0 +639 322 0 +639 271 0 +639 254 0 +640 5 0 +640 319 0 +640 524 0 +641 184 0 +641 16 0 +641 330 0 +642 577 0 +642 622 0 +642 339 0 +643 492 0 +643 425 0 +643 17 0 +643 600 0 +644 146 0 +644 546 0 +644 13 0 +644 520 0 +645 21 0 +645 57 0 +645 82 0 +645 96 0 +646 319 0 +646 640 0 +646 5 0 +647 408 0 +647 21 0 +647 645 0 +647 96 0 +647 5 0 +648 7 0 +648 101 0 +648 168 0 +649 604 0 +649 1 0 +649 235 0 +650 237 0 +650 451 0 +650 375 0 +650 306 0 +651 22 0 +651 183 0 +651 319 0 +651 646 0 +651 5 0 +652 11 0 +652 124 0 +653 6 0 +653 10 0 +653 110 0 +654 485 0 +654 84 0 +654 550 0 +655 130 0 +655 24 0 +655 352 0 +655 525 0 +656 170 0 +656 190 0 +657 500 0 +657 115 0 +657 285 0 +658 128 0 +658 7 0 +658 119 0 +658 11 0 +658 652 0 +659 518 0 +659 380 0 +659 627 0 +659 102 0 +659 169 0 +660 483 0 +660 574 0 +660 87 0 +661 118 0 +661 98 0 +661 83 0 +661 542 0 +662 164 0 +662 8 0 +662 576 0 +663 135 0 +663 119 0 +663 326 0 +664 342 0 +664 149 0 +664 338 0 +665 438 0 +665 7 0 +665 67 0 +666 548 0 +666 386 0 +666 62 0 +667 253 0 +667 38 0 +667 549 0 +667 155 0 +668 242 0 +668 70 0 +668 44 0 +668 152 0 +668 254 0 +669 332 0 +669 341 0 +669 326 0 +670 482 0 +670 351 0 +670 105 0 +670 48 0 +670 28 0 +671 270 0 +671 353 0 +671 8 0 +672 15 0 +672 6 0 +672 88 0 +673 176 0 +673 454 0 +673 69 0 +674 588 0 +674 58 0 +674 144 0 +675 18 0 +675 354 0 +675 497 0 +675 105 0 +675 177 0 +676 110 0 +676 564 0 +677 528 0 +677 296 0 +677 24 0 +678 150 0 +678 29 0 +678 342 0 +679 555 0 +679 8 0 +679 422 0 +679 172 0 +679 614 0 +680 284 0 +680 75 0 +681 239 0 +681 442 0 +682 163 0 +682 143 0 +682 11 0 +682 147 0 +683 638 0 +683 464 0 +683 601 0 +684 19 0 +684 81 0 +684 201 0 +685 29 0 +685 40 0 +685 33 0 +685 32 0 +685 149 0 +686 538 0 +686 418 0 +687 78 0 +687 85 0 +687 247 0 +688 322 0 +688 242 0 +688 254 0 +689 337 0 +689 417 0 +690 65 0 +690 637 0 +690 391 0 +690 13 0 +690 553 0 +691 682 0 +691 163 0 +691 143 0 +692 275 0 +692 579 0 +692 210 0 +692 99 0 +692 19 0 +693 446 0 +693 532 0 +694 137 0 +694 203 0 +695 146 0 +695 520 0 +695 338 0 +696 624 0 +696 423 0 +696 660 0 +696 574 0 +696 133 0 +697 169 0 +697 56 0 +697 274 0 +698 381 0 +698 10 0 +698 139 0 +698 54 0 +699 172 0 +699 132 0 +699 477 0 +700 515 0 +700 110 0 +700 529 0 +700 181 0 +700 97 0 +701 66 0 +701 324 0 +701 477 0 +702 2 0 +702 34 0 +702 46 0 +702 519 0 +703 630 0 +703 156 0 +703 628 0 +704 90 0 +704 495 0 +705 43 0 +705 21 0 +705 402 0 +706 422 0 +706 634 0 +706 437 0 +706 132 0 +707 2 0 +707 162 0 +707 436 0 +707 184 0 +708 147 0 +708 315 0 +708 255 0 +708 214 0 +709 683 0 +709 464 0 +709 601 0 +710 406 0 +710 454 0 +710 176 0 +711 173 0 +711 204 0 +711 110 0 +712 171 0 +712 158 0 +712 41 0 +713 452 0 +713 50 0 +713 335 0 +713 138 0 +714 476 0 +714 335 0 +714 339 0 +714 45 0 +715 538 0 +715 686 0 +715 418 0 +715 19 0 +715 240 0 +716 170 0 +716 57 0 +716 20 0 +716 4 0 +717 48 0 +717 497 0 +717 252 0 +718 615 0 +718 127 0 +718 222 0 +719 305 0 +719 10 0 +719 25 0 +720 394 0 +720 130 0 +721 663 0 +721 119 0 +722 404 0 +722 240 0 +722 19 0 +722 277 0 +723 105 0 +723 351 0 +723 177 0 +724 588 0 +724 55 0 +725 551 0 +725 259 0 +725 59 0 +725 85 0 +726 43 0 +726 57 0 +726 645 0 +726 21 0 +727 674 0 +727 588 0 +728 56 0 +728 444 0 +728 313 0 +728 274 0 +729 422 0 +729 679 0 +729 8 0 +730 420 0 +730 502 0 +730 100 0 +731 44 0 +731 70 0 +731 468 0 +732 428 0 +732 298 0 +732 573 0 +732 20 0 +733 663 0 +733 326 0 +733 341 0 +733 135 0 +734 367 0 +734 180 0 +734 289 0 +734 55 0 +735 374 0 +735 132 0 +735 437 0 +736 55 0 +736 206 0 +736 58 0 +736 588 0 +737 217 0 +737 605 0 +737 625 0 +738 575 0 +738 470 0 +738 191 0 +739 224 0 +739 178 0 +739 444 0 +740 15 0 +740 60 0 +740 26 0 +741 464 0 +741 8 0 +741 166 0 +742 627 0 +742 274 0 +742 167 0 +742 102 0 +742 659 0 +743 422 0 +743 132 0 +743 699 0 +743 172 0 +743 679 0 +744 414 0 +744 278 0 +744 598 0 +744 91 0 +745 326 0 +745 131 0 +745 252 0 +746 636 0 +746 327 0 +746 516 0 +747 31 0 +747 308 0 +747 558 0 +747 129 0 +747 16 0 +748 380 0 +748 169 0 +748 697 0 +748 334 0 +749 431 0 +749 737 0 +749 625 0 +750 619 0 +750 513 0 +750 387 0 +751 614 0 +751 172 0 +751 571 0 +751 427 0 +752 105 0 +752 497 0 +752 48 0 +752 670 0 +753 726 0 +753 21 0 +753 705 0 +753 43 0 +754 358 0 +754 35 0 +754 320 0 +754 34 0 +755 738 0 +755 575 0 +755 470 0 +756 552 0 +756 165 0 +756 91 0 +756 278 0 +756 603 0 +757 16 0 +757 258 0 +757 31 0 +757 747 0 +758 430 0 +758 597 0 +758 372 0 +759 15 0 +759 347 0 +759 387 0 +760 412 0 +760 92 0 +760 43 0 +760 160 0 +760 162 0 +761 526 0 +761 66 0 +761 73 0 +762 432 0 +762 187 0 +762 62 0 +762 69 0 +762 93 0 +763 676 0 +763 110 0 +763 469 0 +763 564 0 +764 720 0 +764 394 0 +764 533 0 +764 130 0 +765 88 0 +765 35 0 +765 432 0 +765 93 0 +766 215 0 +766 279 0 +766 11 0 +766 396 0 +766 382 0 +767 687 0 +767 78 0 +767 85 0 +768 298 0 +768 27 0 +768 573 0 +769 149 0 +769 32 0 +769 567 0 +769 13 0 +769 546 0 +770 70 0 +770 370 0 +770 468 0 +771 737 0 +771 749 0 +771 431 0 +771 217 0 +772 565 0 +772 152 0 +772 44 0 +772 21 0 +772 5 0 +773 1 0 +773 16 0 +774 596 0 +774 8 0 +774 141 0 +774 456 0 +774 291 0 +775 100 0 +775 29 0 +775 199 0 +775 420 0 +776 710 0 +776 454 0 +776 176 0 +777 112 0 +777 5 0 +777 536 0 +777 535 0 +778 316 0 +778 5 0 +778 410 0 +779 657 0 +779 285 0 +779 50 0 +779 500 0 +780 247 0 +780 687 0 +780 85 0 +780 411 0 +781 92 0 +781 57 0 +781 726 0 +781 43 0 +781 760 0 +782 524 0 +782 6 0 +782 15 0 +782 5 0 +783 84 0 +783 348 0 +783 550 0 +783 654 0 +784 423 0 +784 87 0 +784 660 0 +785 247 0 +785 687 0 +785 780 0 +786 13 0 +786 134 0 +786 23 0 +786 236 0 +787 638 0 +787 683 0 +787 601 0 +787 8 0 +788 520 0 +788 644 0 +789 662 0 +789 270 0 +790 213 0 +790 583 0 +790 96 0 +791 237 0 +791 306 0 +791 545 0 +792 615 0 +792 357 0 +792 127 0 +793 400 0 +793 237 0 +793 545 0 +793 167 0 +793 95 0 +794 234 0 +794 205 0 +794 63 0 +794 8 0 +795 632 0 +795 605 0 +795 345 0 +795 237 0 +796 561 0 +796 465 0 +796 261 0 +797 443 0 +797 382 0 +798 434 0 +798 636 0 +798 516 0 +798 559 0 +799 504 0 +799 56 0 +799 470 0 +799 59 0 +800 788 0 +800 520 0 +800 146 0 +800 644 0 +801 73 0 +801 132 0 +801 166 0 +802 347 0 +802 88 0 +802 257 0 +803 603 0 +803 414 0 +803 165 0 +804 311 0 +804 299 0 +804 304 0 +804 263 0 +805 13 0 +805 134 0 +805 786 0 +806 419 0 +806 153 0 +806 35 0 +806 383 0 +806 592 0 +807 214 0 +807 255 0 +807 315 0 +807 479 0 +808 104 0 +808 606 0 +808 508 0 +808 24 0 +809 235 0 +809 1 0 +810 261 0 +810 7 0 +810 243 0 +811 366 0 +811 141 0 +811 63 0 +811 16 0 +812 120 0 +812 73 0 +812 801 0 +812 166 0 +813 300 0 +813 192 0 +813 91 0 +813 165 0 +813 103 0 +814 539 0 +814 54 0 +814 228 0 +815 697 0 +815 274 0 +815 334 0 +815 748 0 +816 262 0 +816 41 0 +816 543 0 +817 203 0 +817 371 0 +817 360 0 +818 341 0 +818 669 0 +818 332 0 +818 45 0 +819 736 0 +819 58 0 +819 674 0 +819 727 0 +819 588 0 +820 171 0 +820 712 0 +820 41 0 +820 29 0 +821 18 0 +821 675 0 +821 177 0 +821 227 0 +822 562 0 +822 71 0 +822 370 0 +823 613 0 +823 118 0 +824 387 0 +824 390 0 +824 619 0 +825 135 0 +825 733 0 +825 341 0 +825 45 0 +825 175 0 +826 665 0 +826 67 0 +826 480 0 +827 640 0 +827 220 0 +827 10 0 +827 524 0 +828 710 0 +828 406 0 +829 789 0 +829 662 0 +829 164 0 +829 359 0 +829 270 0 +830 80 0 +830 797 0 +830 443 0 +831 186 0 +831 538 0 +831 715 0 +831 240 0 +831 424 0 +832 133 0 +832 220 0 +832 461 0 +832 87 0 +832 423 0 +833 640 0 +833 646 0 +833 319 0 +834 173 0 +834 711 0 +834 110 0 +834 564 0 +834 223 0 +835 52 0 +835 86 0 +835 212 0 +835 148 0 +835 79 0 +836 236 0 +836 285 0 +836 115 0 +836 534 0 +837 792 0 +837 357 0 +837 478 0 +837 127 0 +838 182 0 +838 35 0 +838 266 0 +838 189 0 +839 482 0 +840 524 0 +840 640 0 +840 827 0 +841 544 0 +841 608 0 +842 582 0 +842 55 0 +842 724 0 +842 588 0 +843 76 0 +843 262 0 +843 543 0 +844 105 0 +844 670 0 +844 351 0 +845 516 0 +845 327 0 +845 290 0 +845 56 0 +846 832 0 +846 423 0 +846 133 0 +847 787 0 +847 8 0 +847 464 0 +847 638 0 +848 29 0 +848 328 0 +848 484 0 +848 8 0 +848 555 0 +849 331 0 +849 429 0 +849 558 0 +850 162 0 +850 1 0 +850 773 0 +850 16 0 +851 54 0 +851 297 0 +851 470 0 +851 56 0 +851 290 0 +852 166 0 +852 741 0 +852 8 0 +853 735 0 +853 374 0 +853 166 0 +853 132 0 +854 179 0 +854 503 0 +854 3 0 +855 234 0 +855 401 0 +855 362 0 +855 205 0 +855 794 0 +856 83 0 +856 568 0 +857 250 0 +857 65 0 +858 807 0 +858 479 0 +858 163 0 +858 214 0 +859 44 0 +859 309 0 +859 43 0 +859 154 0 +859 402 0 +860 203 0 +860 694 0 +860 137 0 +860 371 0 +860 817 0 +861 427 0 +861 172 0 +861 699 0 +861 477 0 +862 557 0 +862 159 0 +862 608 0 +862 856 0 +863 605 0 +863 632 0 +863 795 0 +863 237 0 +863 625 0 +864 343 0 +864 379 0 +864 451 0 +864 78 0 +864 318 0 +865 802 0 +865 347 0 +865 88 0 +866 387 0 +866 15 0 +866 759 0 +867 17 0 +867 349 0 +867 269 0 +867 136 0 +867 84 0 +868 423 0 +868 624 0 +868 133 0 +868 846 0 +869 8 0 +869 126 0 +870 597 0 +870 368 0 +870 372 0 +870 758 0 +871 115 0 +871 18 0 +871 466 0 +872 387 0 +872 7 0 +872 15 0 +872 866 0 +873 170 0 +873 216 0 +873 22 0 +873 272 0 +874 256 0 +874 249 0 +874 28 0 +875 55 0 +875 179 0 +875 302 0 +876 235 0 +876 809 0 +876 1 0 +876 449 0 +876 336 0 +877 176 0 +877 406 0 +877 828 0 +877 710 0 +878 704 0 +878 495 0 +878 202 0 +879 789 0 +879 662 0 +879 829 0 +880 360 0 +880 137 0 +880 435 0 +881 797 0 +881 830 0 +881 80 0 +881 382 0 +882 544 0 +882 159 0 +882 232 0 +882 613 0 +883 191 0 +883 738 0 +883 470 0 +883 297 0 +884 31 0 +884 114 0 +884 229 0 +885 803 0 +885 603 0 +885 278 0 +885 744 0 +885 414 0 +886 299 0 +886 804 0 +886 311 0 +887 235 0 +887 160 0 +887 284 0 +887 680 0 +887 75 0 +888 227 0 +888 39 0 +889 547 0 +889 107 0 +889 88 0 +889 347 0 +890 20 0 +890 312 0 +890 130 0 +890 525 0 +891 109 0 +891 121 0 +891 74 0 +891 463 0 +891 302 0 +892 353 0 +892 671 0 +892 71 0 +892 9 0 +893 189 0 +893 838 0 +893 266 0 +893 2 0 +894 200 0 +894 71 0 +894 892 0 +894 671 0 +894 270 0 +895 393 0 +895 14 0 +895 542 0 +896 823 0 +896 118 0 +896 608 0 +896 544 0 +896 613 0 +897 357 0 +897 49 0 +897 127 0 +898 784 0 +898 660 0 +898 696 0 +898 423 0 +899 337 0 +899 689 0 +899 417 0 +899 113 0 +899 8 0 +900 440 0 +900 342 0 +900 338 0 +900 225 0 +901 739 0 +901 444 0 +901 123 0 +901 224 0 +902 251 0 +902 61 0 +902 446 0 +902 693 0 +902 532 0 +903 51 0 +903 239 0 +903 681 0 +903 442 0 +904 90 0 +904 611 0 +904 161 0 +905 237 0 +905 650 0 +905 306 0 +905 791 0 +906 318 0 +906 864 0 +906 78 0 +906 486 0 +907 690 0 +907 13 0 +907 553 0 +908 573 0 +908 768 0 +908 27 0 +908 53 0 +908 20 0 +909 640 0 +909 319 0 +909 827 0 +910 734 0 +910 289 0 +910 47 0 +910 397 0 +910 55 0 +911 145 0 +911 523 0 +911 65 0 +912 412 0 +912 174 0 +912 92 0 +913 5 0 +913 15 0 +913 740 0 +913 26 0 +913 60 0 +914 61 0 +914 251 0 +914 30 0 +914 59 0 +915 694 0 +915 137 0 +915 860 0 +916 288 0 +916 108 0 +916 32 0 +916 33 0 +916 13 0 +917 61 0 +917 191 0 +917 185 0 +917 139 0 +918 306 0 +918 545 0 +918 791 0 +919 602 0 +919 415 0 +919 227 0 +919 482 0 +919 839 0 +920 331 0 +920 849 0 +920 558 0 +920 308 0 +920 429 0 +921 56 0 +921 799 0 +922 448 0 +922 493 0 +922 150 0 +923 707 0 +923 162 0 +923 16 0 +923 436 0 +924 838 0 +924 266 0 +925 487 0 +925 89 0 +925 364 0 +926 238 0 +926 407 0 +926 449 0 +926 160 0 +926 235 0 +927 131 0 +927 584 0 +927 48 0 +927 252 0 +928 542 0 +928 83 0 +928 856 0 +928 393 0 +928 895 0 +929 266 0 +929 924 0 +929 35 0 +929 358 0 +930 795 0 +930 237 0 +930 863 0 +931 2 0 +931 893 0 +931 266 0 +932 636 0 +932 434 0 +932 363 0 +932 327 0 +932 746 0 +933 823 0 +933 613 0 +933 118 0 +934 363 0 +934 156 0 +934 317 0 +934 54 0 +934 327 0 +935 41 0 +935 479 0 +935 807 0 +935 315 0 +935 147 0 +936 450 0 +936 94 0 +936 307 0 +937 231 0 +937 121 0 +938 685 0 +938 40 0 +938 33 0 +939 856 0 +939 568 0 +939 557 0 +939 862 0 +940 820 0 +940 41 0 +940 76 0 +940 29 0 +941 531 0 +941 342 0 +942 29 0 +942 211 0 +942 540 0 +942 171 0 +943 936 0 +943 94 0 +943 465 0 +943 307 0 +944 378 0 +944 367 0 +944 371 0 +944 180 0 +945 712 0 +945 158 0 +945 36 0 +945 41 0 +946 583 0 +946 213 0 +947 665 0 +947 826 0 +947 480 0 +947 491 0 +947 438 0 +948 141 0 +948 8 0 +948 63 0 +949 559 0 +949 516 0 +949 845 0 +949 56 0 +950 549 0 +950 667 0 +950 38 0 +950 445 0 +950 155 0 +951 5 0 +951 591 0 +951 535 0 +951 506 0 +951 536 0 +952 453 0 +952 439 0 +952 583 0 +952 946 0 +952 213 0 +953 28 0 +953 602 0 +953 919 0 +953 839 0 +953 482 0 +954 643 0 +954 492 0 +954 211 0 +954 127 0 +954 425 0 +955 725 0 +955 59 0 +955 85 0 +956 628 0 +956 169 0 +956 247 0 +956 411 0 +957 27 0 +957 467 0 +957 20 0 +958 289 0 +958 180 0 +958 47 0 +959 941 0 +959 342 0 +959 440 0 +959 225 0 +959 531 0 +960 12 0 +960 418 0 +960 538 0 +960 186 0 +961 165 0 +961 416 0 +961 103 0 +961 813 0 +962 2 0 +962 265 0 +963 176 0 +963 710 0 +963 776 0 +964 125 0 +964 217 0 +964 219 0 +964 313 0 +964 444 0 +965 210 0 +965 12 0 +965 103 0 +965 99 0 +965 692 0 +966 761 0 +966 66 0 +966 140 0 +967 911 0 +967 523 0 +967 250 0 +967 857 0 +967 65 0 +968 652 0 +968 124 0 +968 101 0 +968 128 0 +968 658 0 +969 335 0 +969 50 0 +969 577 0 +969 642 0 +969 339 0 +970 775 0 +970 100 0 +970 29 0 +971 129 0 +971 12 0 +972 470 0 +972 799 0 +972 921 0 +972 56 0 +973 624 0 +973 868 0 +973 423 0 +973 696 0 +974 612 0 +974 81 0 +974 19 0 +974 487 0 +975 556 0 +975 37 0 +975 236 0 +975 534 0 +975 466 0 +976 663 0 +976 135 0 +977 827 0 +977 909 0 +977 319 0 +977 4 0 +977 220 0 +978 10 0 +978 381 0 +978 209 0 +978 570 0 +979 13 0 +979 644 0 +979 546 0 +980 7 0 +980 293 0 +980 249 0 +980 256 0 +981 109 0 +981 231 0 +981 937 0 +981 121 0 +982 929 0 +982 924 0 +982 838 0 +982 35 0 +983 966 0 +983 140 0 +983 73 0 +983 761 0 +984 671 0 +984 8 0 +984 662 0 +984 789 0 +984 270 0 +985 878 0 +985 202 0 +985 372 0 +985 90 0 +985 704 0 +986 18 0 +986 821 0 +986 227 0 +986 475 0 +987 57 0 +987 716 0 +987 170 0 +987 656 0 +987 190 0 +988 856 0 +988 862 0 +988 608 0 +988 393 0 +988 928 0 +989 77 0 +989 12 0 +989 62 0 +990 888 0 +990 227 0 +990 142 0 +990 39 0 +991 841 0 +991 608 0 +991 159 0 +991 544 0 +992 399 0 +992 188 0 +992 129 0 +992 971 0 +992 12 0 +993 618 0 +993 35 0 +993 106 0 +994 672 0 +994 88 0 +994 889 0 +994 107 0 +994 15 0 +995 976 0 +995 135 0 +995 119 0 +995 721 0 +995 663 0 +996 485 0 +996 7 0 +996 84 0 +997 507 0 +997 189 0 +997 2 0 +997 962 0 +997 265 0 +998 496 0 +998 263 0 +998 8 0 +998 869 0 +998 126 0 +999 392 0 +999 58 0 +999 346 0 +999 3 0 +1000 154 0 +1000 405 0 +1000 402 0 diff --git a/test/planar_input_graphs/pentakis_dodecahedron.leda b/test/planar_input_graphs/pentakis_dodecahedron.leda new file mode 100644 index 000000000..eba98dc50 --- /dev/null +++ b/test/planar_input_graphs/pentakis_dodecahedron.leda @@ -0,0 +1,127 @@ +LEDA.GRAPH // dual graph of truncated icosahedron (known from football) +int +int +32 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +90 +1 2 0 +2 3 0 +3 4 0 +4 5 0 +5 1 0 +6 7 0 +7 8 0 +8 9 0 +9 10 0 +10 6 0 +11 12 0 +12 13 0 +13 14 0 +14 15 0 +15 16 0 +16 17 0 +17 18 0 +18 19 0 +19 20 0 +20 11 0 +1 11 0 +2 13 0 +3 15 0 +4 17 0 +5 19 0 +6 12 0 +7 14 0 +8 16 0 +9 18 0 +10 20 0 +21 1 0 +21 2 0 +21 3 0 +21 4 0 +21 5 0 +22 6 0 +22 7 0 +22 8 0 +22 9 0 +22 10 0 +23 1 0 +23 2 0 +23 11 0 +23 12 0 +23 13 0 +24 6 0 +24 7 0 +24 12 0 +24 13 0 +24 14 0 +25 2 0 +25 3 0 +25 13 0 +25 14 0 +25 15 0 +26 7 0 +26 8 0 +26 14 0 +26 15 0 +26 16 0 +27 3 0 +27 4 0 +27 15 0 +27 16 0 +27 17 0 +28 8 0 +28 9 0 +28 16 0 +28 17 0 +28 18 0 +29 4 0 +29 5 0 +29 17 0 +29 18 0 +29 19 0 +30 9 0 +30 10 0 +30 18 0 +30 19 0 +30 20 0 +31 1 0 +31 5 0 +31 11 0 +31 19 0 +31 20 0 +32 6 0 +32 10 0 +32 11 0 +32 12 0 +32 20 0 diff --git a/test/planar_vertex_six_coloring.cpp b/test/planar_vertex_six_coloring.cpp new file mode 100644 index 000000000..4507c86e6 --- /dev/null +++ b/test/planar_vertex_six_coloring.cpp @@ -0,0 +1,216 @@ +//======================================================================= +// Copyright 2024 +// Authors: Hermann Stamm-Wilbrandt +// +// Use, modification and distribution is subject to 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) +//======================================================================= +// +// Demonstrates sequential_vertex_coloring() forced to take 15 colors +// on graph built with "create(15, g)", and planar_vertex_six_coloring() +// taking 6 colors only (both linear time algorithms). +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace boost; + +typedef adjacency_list< listS, vecS, undirectedS > Graph; +typedef graph_traits< Graph >::vertices_size_type vertices_size_type; +typedef graph_traits< Graph >::vertex_descriptor vertex_descriptor; +typedef graph_traits< Graph >::edge_descriptor edge_descriptor; + + +edge_descriptor create(Graph& g, int k); +void read_leda_graph(Graph& g, const char* gname); + +// time measurements +clock_t start_; +#define __(blk) if (output) std::cerr << #blk << " "; start_ = clock(); blk \ + if (output) std::cerr << (clock()-start_)*1.0/CLOCKS_PER_SEC << std::endl; + + +int main(int argc, char*argv[]) +{ + unsigned int k = (argc < 2) ? 15 : atoi(argv[1]); + bool output = argc > 2; + + Graph g; + edge_descriptor e; + + __(create(g, k);) + + BOOST_TEST(num_vertices(g) == 987); // fib(k+1) + BOOST_TEST(num_edges(g) == 1595); // fib(k+2)-2 + + std::vector< vertices_size_type > color_vec(num_vertices(g)); + auto color = make_container_vertex_map(color_vec, g); + + __(vertices_size_type num_colors = sequential_vertex_coloring(g, color);) + + BOOST_TEST(num_colors == k); + BGL_FORALL_EDGES(e, g, Graph) + { BOOST_ASSERT(get(color, source(e, g)) != get(color, target(e, g))); } + + __(vertices_size_type num_color6 = planar_vertex_six_coloring(g, color);) + + BOOST_TEST(num_color6 == 6); + BGL_FORALL_EDGES(e, g, Graph) + { BOOST_ASSERT(get(color, source(e, g)) != get(color, target(e, g))); } + + if (output) + { + std::cerr << num_vertices(g) << "/" << num_edges(g) + << " vertices/edges" << std::endl; + std::cerr << num_colors << "/" << num_color6 + << " colors used" << std::endl; + } + + + __(read_leda_graph(g, "planar_input_graphs/pentakis_dodecahedron.leda");) + + color_vec.resize(num_vertices(g)); + color = make_container_vertex_map(color_vec, g); + + BOOST_TEST(num_vertices(g) == 32); + BOOST_TEST(num_edges(g) == 3*32-6); + + __(num_colors = sequential_vertex_coloring(g, color);) + + BOOST_TEST(num_colors == 5); + BGL_FORALL_EDGES(e, g, Graph) + { BOOST_ASSERT(get(color, source(e, g)) != get(color, target(e, g))); } + + __(num_color6 = planar_vertex_six_coloring(g, color);) + + BOOST_TEST(num_color6 == 4); + BGL_FORALL_EDGES(e, g, Graph) + { BOOST_ASSERT(get(color, source(e, g)) != get(color, target(e, g))); } + + if (output) + { + std::cerr << num_vertices(g) << "/" << num_edges(g) + << " vertices/edges" << std::endl; + std::cerr << num_colors << "/" << num_color6 + << " colors used" << std::endl; + } + + + __(read_leda_graph(g, "planar_input_graphs/maximal_planar_1000.leda");) + + color_vec.resize(num_vertices(g)); + color = make_container_vertex_map(color_vec, g); + + BOOST_TEST(num_vertices(g) == 1000); + BOOST_TEST(num_edges(g) == 3*1000-6); + + __(num_colors = sequential_vertex_coloring(g, color);) + + BOOST_TEST(num_colors == 6); + BGL_FORALL_EDGES(e, g, Graph) + { BOOST_ASSERT(get(color, source(e, g)) != get(color, target(e, g))); } + + __(num_color6 = planar_vertex_six_coloring(g, color);) + + BOOST_TEST(num_color6 == 6); + BGL_FORALL_EDGES(e, g, Graph) + { BOOST_ASSERT(get(color, source(e, g)) != get(color, target(e, g))); } + + if (output) + { + std::cerr << num_vertices(g) << "/" << num_edges(g) + << " vertices/edges" << std::endl; + std::cerr << num_colors << "/" << num_color6 + << " colors used" << std::endl; + } + + + return boost::report_errors(); +} + + +/* + creating C6 + + -5- + /|\ +... + from C5 + / + ---4 + / /|\ / + plus C3 / / | 3 + / / / |/|\ + plus C1 2 / / 2 | \ + / / \ / / / / \| \ + 0 0---1 0--1 0---1 0 +*/ +edge_descriptor create(Graph& g, int k) +{ + if (k < 4) + { + BOOST_ASSERT(k > 1); + + vertex_descriptor v = add_vertex(g); + vertex_descriptor w = add_vertex(g); + auto e = add_edge(v, w, g); + if (k == 2) return e.first; + + vertex_descriptor x = add_vertex(g); + add_edge(v, x, g); + return add_edge(w, x, g).first; + } + + std::vector es; + while (--k > 1) { es.push_back(create(g, k--)); } + + vertex_descriptor v = add_vertex(g); + if (k == 1) + { + vertex_descriptor w = add_vertex(g); + add_edge(v, w, g); + v = w; + } + + edge_descriptor e; + for (auto ei = es.rbegin(); ei != es.rend(); ++ei) + { + add_edge(source(*ei, g), v, g); + e = add_edge(target(*ei, g), v, g).first; + } + return e; +} + + +void read_leda_graph(Graph& g, const char* gname) +{ + int n, m; + std::string line; + + std::ifstream in(gname); + assert(in); + + std::getline(in, line); + in >> line >> line >> n; + + g = Graph(n); + + for (int i=1; i <= n; ++i) { + in >> line; + } + + in >> m; + for (int i=1; i <= m; ++i) { + int s, t, v; + in >> s >> t >> v; + add_edge(s-1, t-1, g); + } +} From 31eeb8b926c38829f1f1f2ac68da4bcedd36b16e Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 2 Oct 2024 15:08:16 +0200 Subject: [PATCH 06/17] planar_vertex_six_coloring doc --- doc/figs/planar_vertex_coloring_with_5.png | Bin 0 -> 24916 bytes doc/planar_vertex_six_coloring.html | 101 +++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 doc/figs/planar_vertex_coloring_with_5.png create mode 100644 doc/planar_vertex_six_coloring.html diff --git a/doc/figs/planar_vertex_coloring_with_5.png b/doc/figs/planar_vertex_coloring_with_5.png new file mode 100644 index 0000000000000000000000000000000000000000..729083cf1cd7bee0f9930c9ce62863d94276b7d8 GIT binary patch literal 24916 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 literal 0 HcmV?d00001 diff --git a/doc/planar_vertex_six_coloring.html b/doc/planar_vertex_six_coloring.html new file mode 100644 index 000000000..15465b1ef --- /dev/null +++ b/doc/planar_vertex_six_coloring.html @@ -0,0 +1,101 @@ + + + + + Boost Graph Library: Planar Vertex Six Coloring + + + + C++ Boost +

    planar_vertex_six_coloring

    + +

    +

    +template<class VertexListGraph, class ColorMap>
    +typename property_traits<ColorMap>::value_type
    +planar_vertex_six_coloring(const VertexListGraph& g, ColorMap color);
    +    
    + +

    Here is the vertex coloring with 5 colors determined for icosahedron. + +

    + +

    Planar graphs with n vertices have at most 3n-6 edges. Therefore always a vertex of degree ≤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. + +

    Where Defined

    +boost/graph/planar_vertex_six_coloring.hpp + +

    Parameters

    +IN: const Graph& g +
    + The graph object on which the algorithm will be applied. The type + Graph must be a model of Vertex List Graph and Adjacency Graph.
    +
    + +OUT: ColorMap color +
    + This property map records the colors of each vertex. It must be a + model of + Writeable + Property Map 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 vertices_size_type.
    +
    + +

    Complexity

    + +The time complexity is O(V), where V is the +number of vertices of the planar graph.
    +This runtime is only possible using undirected_graph_constant_time_edge_add_and_remove providing O(1) remove_edge(). + +

    Example

    +boost/graph/example/planar_vertex_six_coloring.cpp + +
    +  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);
    +  vertices_size_type num_colors = planar_vertex_six_coloring(g, color);
    +
    + +

    Test

    +boost/graph/test/planar_vertex_six_coloring.cpp test determines vertex coloring for three planar graphs: +
      +
    1. "Fibonacci graph" (for k=15), with fib(k+1) vertices and fib(k+2)-2 edges +
    2. boost/graph/test/planar_input_graphs/pentakis_dodecahedron.leda +
    3. boost/graph/test/planar_input_graphs/maximal_planar_1000.leda +
    +With 15/5/6 colors used by sequential_vertex_coloring() and 6/4/6 colors used by planar_vertex_six_coloring(). + +
    + + + +
    Copyright © 2024 +Hermann Stamm-Wilbrandt (hermann@stamm-wilbrandt.de) +
    + + + From d7ff09170ca568e9b5005b571c0bc25a247ae110 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 2 Oct 2024 15:10:06 +0200 Subject: [PATCH 07/17] missing toc entry --- doc/table_of_contents.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/table_of_contents.html b/doc/table_of_contents.html index a24be642a..8fe5d98e2 100644 --- a/doc/table_of_contents.html +++ b/doc/table_of_contents.html @@ -289,6 +289,8 @@

    Table of Contents: the Boost Graph Library make_biconnected_planar
  • make_maximal_planar +
  • + planar_vertex_six_coloring
  • Miscellaneous Algorithms From a885319f014329e4ddcf6ba1fd67443e29fbe856 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Sat, 5 Oct 2024 16:58:20 +0200 Subject: [PATCH 08/17] missing Jamfile.v2 entry --- test/Jamfile.v2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b2656eb07..0e065d677 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -84,7 +84,8 @@ alias graph_test_regular : [ compile reverse_graph_cc.cpp ] [ run sequential_vertex_coloring.cpp ] - + [ run planar_vertex_six_coloring.cpp ] + # TODO: Merge these into a single test framework. [ run subgraph.cpp ] [ run subgraph_bundled.cpp ] From adf3c0807d8fa05ba563482c45c93d883d9bd9b0 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Mon, 7 Oct 2024 11:36:28 +0200 Subject: [PATCH 09/17] fix issues uncovered by CI --- include/boost/graph/detail/adjacency_list.hpp | 2 +- include/boost/graph/undirected_graph.hpp | 4 ++-- .../undirected_graph_constant_time_edge_add_and_remove.hpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index dbf571f46..f1f0ac297 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -1019,7 +1019,7 @@ inline void remove_edge(EdgeOrIter e, undirected_graph_helper< Config >& g_) // O(1) template < class OutEdgeIter, class Config > -inline void remove_edge(OutEdgeIter i1, OutEdgeIter i2, +inline void remove_edge_(OutEdgeIter i1, OutEdgeIter i2, undirected_graph_helper< Config >& g_) { typedef typename Config::global_edgelist_selector EdgeListS; diff --git a/include/boost/graph/undirected_graph.hpp b/include/boost/graph/undirected_graph.hpp index 6ae82012b..3ec353ef3 100644 --- a/include/boost/graph/undirected_graph.hpp +++ b/include/boost/graph/undirected_graph.hpp @@ -341,10 +341,10 @@ class undirected_graph } protected: - void remove_edge(void *p) + void remove_edge_(void *p) { auto *q = static_cast< std::pair< out_edge_iterator, out_edge_iterator > * >(p); - boost::remove_edge(q->first, q->second, m_graph); + boost::remove_edge_(q->first, q->second, m_graph); --m_num_edges; } diff --git a/include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp b/include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp index 21ca745b4..0c32e3a02 100644 --- a/include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp +++ b/include/boost/graph/undirected_graph_constant_time_edge_add_and_remove.hpp @@ -7,8 +7,8 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -#ifndef BOOST_GRAPH_UNDIRECTED_GRAPH_CONSTANT_TIME_EDGE_ADD_AND_REMOVE.HPP -#define BOOST_GRAPH_UNDIRECTED_GRAPH_CONSTANT_TIME_EDGE_ADD_AND_REMOVE.HPP +#ifndef BOOST_GRAPH_UNDIRECTED_GRAPH_CONSTANT_TIME_EDGE_ADD_AND_REMOVE_HPP +#define BOOST_GRAPH_UNDIRECTED_GRAPH_CONSTANT_TIME_EDGE_ADD_AND_REMOVE_HPP #include #include @@ -95,7 +95,7 @@ class undirected_graph_constant_time_edge_add_and_remove // O(1) inline void remove_edge(edge_descriptor e) { - graph_type::remove_edge(m_map[e]); + graph_type::remove_edge_(m_map[e]); } // O(degree(v)) From c990f6f3ee34b6452b8f2c5fb37d0f0454c2edb0 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Mon, 7 Oct 2024 13:03:30 +0200 Subject: [PATCH 10/17] fix CI reported issue not reportd by local b2 + fix another unused parameter warning --- include/boost/graph/detail/adjacency_list.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index f1f0ac297..f80ed8fba 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -802,7 +802,7 @@ namespace detail template < class OutEdgeList_iterator, class Config > static void apply(OutEdgeList_iterator iter1, OutEdgeList_iterator iter2, - undirected_graph_helper< Config >& g_, StoredProperty& p) + undirected_graph_helper< Config >& g_, StoredProperty&) { typedef typename Config::global_edgelist_selector EdgeListS; BOOST_STATIC_ASSERT((is_same< EdgeListS, listS >::value)); @@ -876,7 +876,6 @@ namespace detail BOOST_ASSERT(source(e, g) == target(f, g)); BOOST_ASSERT(source(f, g) == target(e, g)); - no_property* p = (no_property*)e.get_property(); typename Config::OutEdgeList& out_el = g.out_edge_list(source(e, g)); typename Config::EdgeIter edge_iter_to_erase; From 0769bbb1fb055a8f5da1b612770b49d7f55b082e Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Mon, 7 Oct 2024 21:56:34 +0200 Subject: [PATCH 11/17] Comment out C++11 runs as 1.86 requires C++14 minimum, fix clang7 entries --- .drone.star | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.drone.star b/.drone.star index f49c164ec..9bcbfe9db 100644 --- a/.drone.star +++ b/.drone.star @@ -14,64 +14,64 @@ windowsglobalimage="cppalliance/dronevs2019" def main(ctx): return [ - linux_cxx("g++-5 11", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("g++-5 11", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-5 14", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-5 1z", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '1z', }, globalenv=globalenv), - linux_cxx("g++-6 11", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("g++-6 11", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-6 14", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-6 1z", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '1z', }, globalenv=globalenv), - linux_cxx("g++-7 11", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("g++-7 11", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-7 14", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-7 17", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '17', }, globalenv=globalenv), - linux_cxx("g++-8 11", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("g++-8 11", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-8 14", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-8 17", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '17', }, globalenv=globalenv), - linux_cxx("g++-9 11", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("g++-9 11", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-9 14", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-9 17", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("g++-9 2a", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '2a', }, globalenv=globalenv), - linux_cxx("g++-10 11", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("g++-10 11", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-10 14", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-10 17", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("g++-10 20", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '20', }, globalenv=globalenv), - linux_cxx("clang++-4.0 11", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("clang++-4.0 11", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-4.0 14", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-4.0 1z", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '1z', }, globalenv=globalenv), - linux_cxx("clang++-5.0 11", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("clang++-5.0 11", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-5.0 14", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-5.0 1z", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '1z', }, globalenv=globalenv), - linux_cxx("clang++-6.0 11", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("clang++-6.0 11", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-6.0 14", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-6.0 1z", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '1z', }, globalenv=globalenv), - linux_cxx("clang++-7 14", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '11', }, globalenv=globalenv), - linux_cxx("clang++-7 17", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '14', }, globalenv=globalenv), + linux_cxx("clang++-7 14", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '14', }, globalenv=globalenv), + linux_cxx("clang++-7 17", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-7 1z", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '1z', }, globalenv=globalenv), - linux_cxx("clang++-8 11", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("clang++-8 11", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-8 14", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-8 17", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-8 2a", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '2a', }, globalenv=globalenv), - linux_cxx("clang++-9 11", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("clang++-9 11", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-9 14", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-9 17", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-9 2a", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '2a', }, globalenv=globalenv), - linux_cxx("clang++-10 11", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '11', }, globalenv=globalenv), +// linux_cxx("clang++-10 11", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-10 14", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-10 17", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-10 20", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '20', }, globalenv=globalenv), - osx_cxx("XCode-11.7 11", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11', }, globalenv=globalenv), +// osx_cxx("XCode-11.7 11", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11', }, globalenv=globalenv), osx_cxx("XCode-11.7 14", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '14', }, globalenv=globalenv), osx_cxx("XCode-11.7 17", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '17', }, globalenv=globalenv), osx_cxx("XCode-11.7 2a", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '2a', }, globalenv=globalenv), From 80dbad8a79e9d381f5a5102a442fb39de159ae28 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Mon, 7 Oct 2024 22:16:10 +0200 Subject: [PATCH 12/17] remove C++11 lines completely --- .drone.star | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.drone.star b/.drone.star index 9bcbfe9db..ac979e3cf 100644 --- a/.drone.star +++ b/.drone.star @@ -14,41 +14,32 @@ windowsglobalimage="cppalliance/dronevs2019" def main(ctx): return [ -// linux_cxx("g++-5 11", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-5 14", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-5 1z", "g++-5", packages="g++-5", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-5', 'CXXSTD': '1z', }, globalenv=globalenv), -// linux_cxx("g++-6 11", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-6 14", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-6 1z", "g++-6", packages="g++-6", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-6', 'CXXSTD': '1z', }, globalenv=globalenv), -// linux_cxx("g++-7 11", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-7 14", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-7 17", "g++-7", packages="g++-7", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-7', 'CXXSTD': '17', }, globalenv=globalenv), -// linux_cxx("g++-8 11", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-8 14", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-8 17", "g++-8", packages="g++-8", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-8', 'CXXSTD': '17', }, globalenv=globalenv), -// linux_cxx("g++-9 11", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-9 14", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-9 17", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("g++-9 2a", "g++-9", packages="g++-9", buildtype="boost", image="cppalliance/droneubuntu1404:1", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-9', 'CXXSTD': '2a', }, globalenv=globalenv), -// linux_cxx("g++-10 11", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("g++-10 14", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("g++-10 17", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("g++-10 20", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '20', }, globalenv=globalenv), -// linux_cxx("clang++-4.0 11", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-4.0 14", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-4.0 1z", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '1z', }, globalenv=globalenv), -// linux_cxx("clang++-5.0 11", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-5.0 14", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-5.0 1z", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '1z', }, globalenv=globalenv), -// linux_cxx("clang++-6.0 11", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-6.0 14", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-6.0 1z", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '1z', }, globalenv=globalenv), @@ -56,22 +47,18 @@ def main(ctx): linux_cxx("clang++-7 17", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-7 1z", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '1z', }, globalenv=globalenv), -// linux_cxx("clang++-8 11", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-8 14", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-8 17", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-8 2a", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '2a', }, globalenv=globalenv), -// linux_cxx("clang++-9 11", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-9 14", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-9 17", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-9 2a", "clang++-9", packages="clang-9", llvm_os="xenial", llvm_ver="9", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-9', 'CXXSTD': '2a', }, globalenv=globalenv), -// linux_cxx("clang++-10 11", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '11', }, globalenv=globalenv), linux_cxx("clang++-10 14", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-10 17", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-10 20", "clang++-10", packages="clang-10", llvm_os="xenial", llvm_ver="10", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-10', 'CXXSTD': '20', }, globalenv=globalenv), -// osx_cxx("XCode-11.7 11", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '11', }, globalenv=globalenv), osx_cxx("XCode-11.7 14", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '14', }, globalenv=globalenv), osx_cxx("XCode-11.7 17", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '17', }, globalenv=globalenv), osx_cxx("XCode-11.7 2a", "clang++", packages="", buildtype="boost", xcode_version="11.7", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++', 'CXXSTD': '2a', }, globalenv=globalenv), From aff14b42679c63b63511ac4b9a644f6fff7294d0 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Wed, 9 Oct 2024 10:50:12 +0200 Subject: [PATCH 13/17] ge new .drone.star to resolve conflicts --- .drone.star | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.drone.star b/.drone.star index ac979e3cf..f96e29474 100644 --- a/.drone.star +++ b/.drone.star @@ -35,18 +35,14 @@ def main(ctx): linux_cxx("g++-10 20", "g++-10", packages="g++-10", image="cppalliance/droneubuntu2004:1", buildtype="boost", environment={'TOOLSET': 'gcc', 'COMPILER': 'g++-10', 'CXXSTD': '20', }, globalenv=globalenv), linux_cxx("clang++-4.0 14", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '14', }, globalenv=globalenv), - linux_cxx("clang++-4.0 1z", "clang++-4.0", packages="clang-4.0", llvm_os="xenial", llvm_ver="4.0", buildtype="boost", image=linuxglobalimage, environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-4.0', 'CXXSTD': '1z', }, globalenv=globalenv), linux_cxx("clang++-5.0 14", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '14', }, globalenv=globalenv), - linux_cxx("clang++-5.0 1z", "clang++-5.0", packages="clang-5.0", llvm_os="xenial", llvm_ver="5.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-5.0', 'CXXSTD': '1z', }, globalenv=globalenv), - + linux_cxx("clang++-6.0 14", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '14', }, globalenv=globalenv), - linux_cxx("clang++-6.0 1z", "clang++-6.0", packages="clang-6.0", llvm_os="xenial", llvm_ver="6.0", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-6.0', 'CXXSTD': '1z', }, globalenv=globalenv), - + linux_cxx("clang++-7 14", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-7 17", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '17', }, globalenv=globalenv), - linux_cxx("clang++-7 1z", "clang++-7", packages="clang-7", llvm_os="xenial", llvm_ver="7", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-7', 'CXXSTD': '1z', }, globalenv=globalenv), - + linux_cxx("clang++-8 14", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '14', }, globalenv=globalenv), linux_cxx("clang++-8 17", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '17', }, globalenv=globalenv), linux_cxx("clang++-8 2a", "clang++-8", packages="clang-8", llvm_os="xenial", llvm_ver="8", buildtype="boost", image="cppalliance/droneubuntu1804:1", environment={'TOOLSET': 'clang', 'COMPILER': 'clang++-8', 'CXXSTD': '2a', }, globalenv=globalenv), From 253ddc3e6ab0e25f5cb6aedba284f58edb03a400 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Fri, 11 Oct 2024 16:50:42 +0200 Subject: [PATCH 14/17] inspect: fix C-style assert, *M* violation of Boost min/max guidelines --- include/boost/graph/planar_vertex_six_coloring.hpp | 3 ++- test/planar_vertex_six_coloring.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boost/graph/planar_vertex_six_coloring.hpp b/include/boost/graph/planar_vertex_six_coloring.hpp index 14b117463..5ab5ffdaf 100644 --- a/include/boost/graph/planar_vertex_six_coloring.hpp +++ b/include/boost/graph/planar_vertex_six_coloring.hpp @@ -118,7 +118,8 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( vertex_descriptor w; BOOST_FOREACH(w, adj5[u]) { bs |= (1 << get(color, w)); } put(color, back[u], smallest_possible_color[bs]); - colmax = std::max(colmax, smallest_possible_color[bs]); + colmax = std::max BOOST_PREVENT_MACRO_SUBSTITUTION( + colmax, smallest_possible_color[bs]); } return colmax+1; diff --git a/test/planar_vertex_six_coloring.cpp b/test/planar_vertex_six_coloring.cpp index 4507c86e6..9b11a7087 100644 --- a/test/planar_vertex_six_coloring.cpp +++ b/test/planar_vertex_six_coloring.cpp @@ -196,7 +196,7 @@ void read_leda_graph(Graph& g, const char* gname) std::string line; std::ifstream in(gname); - assert(in); + BOOST_ASSERT(in); std::getline(in, line); in >> line >> line >> n; From ef766291a8adfa947f51694b8c49dce4d9fad835 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Sun, 20 Oct 2024 00:11:22 +0200 Subject: [PATCH 15/17] planar_vertex_six_coloring() calls "sequential coloring" with determined order --- .../graph/planar_vertex_six_coloring.hpp | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/include/boost/graph/planar_vertex_six_coloring.hpp b/include/boost/graph/planar_vertex_six_coloring.hpp index 5ab5ffdaf..c13e0aeef 100644 --- a/include/boost/graph/planar_vertex_six_coloring.hpp +++ b/include/boost/graph/planar_vertex_six_coloring.hpp @@ -15,6 +15,7 @@ #include #include #include +#include /* This algorithm is to find a vertex six coloring of a planar graph @@ -78,8 +79,10 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( std::vector< typename ugraph_o1::vertex_descriptor > small, visited; + std::vector< vertex_descriptor > rev; small.reserve(num_vertices(U)); visited.reserve(num_vertices(U)); + rev.reserve(num_vertices(U)); BGL_FORALL_VERTICES_T(u, U, ugraph_o1) { adj5[u].reserve(5); if (degree(u, U) <= 5) { small.push_back(u); } } @@ -103,26 +106,11 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( BOOST_ASSERT(num_vertices(U) == visited.size()); - // highest possisble index with <=5 neighbors is 0x3E (= 0b111110) - const size_type smallest_possible_color[1+0x3E] - = {0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, - 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, - 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, - 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; + BOOST_REVERSE_FOREACH(typename ugraph_o1::vertex_descriptor u, visited) + rev.push_back(back[u]); - size_type colmax = 0; - typename ugraph_o1::vertex_descriptor u; - BOOST_REVERSE_FOREACH(u, visited) - { - size_type bs = 0; - vertex_descriptor w; - BOOST_FOREACH(w, adj5[u]) { bs |= (1 << get(color, w)); } - put(color, back[u], smallest_possible_color[bs]); - colmax = std::max BOOST_PREVENT_MACRO_SUBSTITUTION( - colmax, smallest_possible_color[bs]); - } - - return colmax+1; + return sequential_vertex_coloring( + G, make_container_vertex_map(rev, G), color); } } // namespace boost From 21f39791634c3251f08bfc68f415abe5b7f9c77b Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Sun, 20 Oct 2024 00:26:31 +0200 Subject: [PATCH 16/17] Add comments for three major parts of planar_vertex_six_coloring() --- include/boost/graph/planar_vertex_six_coloring.hpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/boost/graph/planar_vertex_six_coloring.hpp b/include/boost/graph/planar_vertex_six_coloring.hpp index c13e0aeef..98b7d7a73 100644 --- a/include/boost/graph/planar_vertex_six_coloring.hpp +++ b/include/boost/graph/planar_vertex_six_coloring.hpp @@ -64,6 +64,8 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( // | // std::vector <--------------+ // adj5[_] +// +// Determine copy U of G with linkage // ugraph_o1 U; @@ -77,7 +79,14 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( BGL_FORALL_EDGES_T(e, G, VertexListGraph) { U.add_edge(get(vmap, source(e, G)), get(vmap, target(e, G))); } +/* + Determine 5-bounded acyclic orientation + Marek Chrobak, David Eppstein + "Planar orientations with low out-degree and compaction of adjacency matrices" + Theoretical Computer Science 1991 + https://dl.acm.org/doi/10.1016/0304-3975%2891%2990020-3 +*/ std::vector< typename ugraph_o1::vertex_descriptor > small, visited; std::vector< vertex_descriptor > rev; small.reserve(num_vertices(U)); @@ -105,7 +114,9 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( BOOST_ASSERT(num_vertices(U) == visited.size()); - +// call sequential_vertex_coloring() +// with reverse order of 5-bounded acyclic orientation determination +// BOOST_REVERSE_FOREACH(typename ugraph_o1::vertex_descriptor u, visited) rev.push_back(back[u]); From bd1a22798b52a0ec4b47b0dec689a4c300817cf9 Mon Sep 17 00:00:00 2001 From: Hermann-SW Date: Sun, 20 Oct 2024 01:08:58 +0200 Subject: [PATCH 17/17] remove now superfluous adj5 code --- .../boost/graph/planar_vertex_six_coloring.hpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/include/boost/graph/planar_vertex_six_coloring.hpp b/include/boost/graph/planar_vertex_six_coloring.hpp index 98b7d7a73..17a374306 100644 --- a/include/boost/graph/planar_vertex_six_coloring.hpp +++ b/include/boost/graph/planar_vertex_six_coloring.hpp @@ -36,9 +36,6 @@ namespace boost enum vertex_back_t { vertex_back }; BOOST_INSTALL_PROPERTY(vertex, back); - enum vertex_adj5_t { vertex_adj5 }; - BOOST_INSTALL_PROPERTY(vertex, adj5); - template < class VertexListGraph, class ColorMap > typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( const VertexListGraph& G, ColorMap color) @@ -48,8 +45,7 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( typedef typename property_traits< ColorMap >::value_type size_type; typedef undirected_graph_constant_time_edge_add_and_remove< - property< vertex_back_t, vertex_descriptor, - property< vertex_adj5_t, std::vector< vertex_descriptor > > >, + property< vertex_back_t, vertex_descriptor >, no_property, no_property > ugraph_o1; @@ -60,16 +56,12 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( // get(vmap, _) // {v,w} in V(G)---------------> // <---------------V(U) <= {u,t} -// back[_] | -// | -// std::vector <--------------+ -// adj5[_] +// back[_] // // Determine copy U of G with linkage // ugraph_o1 U; - auto adj5 = get(vertex_adj5, U); auto back = get(vertex_back, U); @@ -94,7 +86,7 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( rev.reserve(num_vertices(U)); BGL_FORALL_VERTICES_T(u, U, ugraph_o1) - { adj5[u].reserve(5); if (degree(u, U) <= 5) { small.push_back(u); } } + { if (degree(u, U) <= 5) { small.push_back(u); } } while (!small.empty()) @@ -104,7 +96,6 @@ typename property_traits< ColorMap >::value_type planar_vertex_six_coloring( BGL_FORALL_ADJ_T(u, t, U, ugraph_o1) { - adj5[u].push_back(back[t]); if (degree(t, U) == 6) small.push_back(t); } U.clear_vertex(u);
  • Computes a vertex coloring for +the vertices in the planar graph in linear time, using at most 6 colors.
    +Planar graphs can always be vertex colored with 4 colors, there +is a quadratic time algorithm.
    +Boost sequential_vertex_coloring can be forced to use any number k of colors for a crafted planar graph (first test graph). + +