From 5bb73cd8993ef97b201d95f644790d77f2d80d06 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 29 May 2021 20:34:01 +0300 Subject: [PATCH 1/5] Add CMakeLists.txt --- CMakeLists.txt | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..2300cb340 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,81 @@ +# Generated by `boostdep --cmake graph` +# Copyright 2020 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5...3.16) + +project(boost_graph VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX) + +add_library(boost_graph + src/graphml.cpp + src/read_graphviz_new.cpp +) + +add_library(Boost::graph ALIAS boost_graph) + +target_include_directories(boost_graph PUBLIC include) + +target_link_libraries(boost_graph + PUBLIC + Boost::algorithm + Boost::any + Boost::array + Boost::assert + Boost::bimap + Boost::bind + Boost::concept_check + Boost::config + Boost::container_hash + Boost::conversion + Boost::core + Boost::detail + Boost::foreach + Boost::function + Boost::integer + Boost::iterator + Boost::lexical_cast + Boost::math + Boost::move + Boost::mpl + Boost::multi_index + Boost::optional + Boost::parameter + Boost::preprocessor + Boost::property_map + Boost::property_tree + Boost::random + Boost::range + Boost::serialization + Boost::smart_ptr + Boost::spirit + Boost::static_assert + Boost::throw_exception + Boost::tti + Boost::tuple + Boost::type_traits + Boost::typeof + Boost::unordered + Boost::utility + Boost::xpressive + PRIVATE + Boost::regex +) + +target_compile_definitions(boost_graph + PUBLIC BOOST_GRAPH_NO_LIB + PRIVATE BOOST_GRAPH_SOURCE +) + +if(BUILD_SHARED_LIBS) + target_compile_definitions(boost_graph PUBLIC BOOST_GRAPH_DYN_LINK) +else() + target_compile_definitions(boost_graph PUBLIC BOOST_GRAPH_STATIC_LINK) +endif() + +if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") + + add_subdirectory(test) + +endif() + From 2bc8d0490e3b2b8fdeb37519084a316c4834d572 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 9 Jun 2021 18:45:39 +0300 Subject: [PATCH 2/5] Do not define BOOST_GRAPH_SOURCE in CMakeLists.txt --- CMakeLists.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2300cb340..0e294eb5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,4 @@ -# Generated by `boostdep --cmake graph` -# Copyright 2020 Peter Dimov +# Copyright 2020, 2021 Peter Dimov # Distributed under the Boost Software License, Version 1.0. # https://www.boost.org/LICENSE_1_0.txt @@ -64,7 +63,8 @@ target_link_libraries(boost_graph target_compile_definitions(boost_graph PUBLIC BOOST_GRAPH_NO_LIB - PRIVATE BOOST_GRAPH_SOURCE + # Source files already define BOOST_GRAPH_SOURCE + # PRIVATE BOOST_GRAPH_SOURCE ) if(BUILD_SHARED_LIBS) @@ -78,4 +78,3 @@ if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") add_subdirectory(test) endif() - From 4f4b4e04ada42852a923e1298341aab1a7c2a9c5 Mon Sep 17 00:00:00 2001 From: G Yuvan Shankar Date: Sun, 19 Dec 2021 13:38:10 +0530 Subject: [PATCH 3/5] Added karp_minimum_mean_cycle.hpp --- .../boost/graph/karp_minimum_mean_cycle.hpp | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 include/boost/graph/karp_minimum_mean_cycle.hpp diff --git a/include/boost/graph/karp_minimum_mean_cycle.hpp b/include/boost/graph/karp_minimum_mean_cycle.hpp new file mode 100644 index 000000000..a0f82df10 --- /dev/null +++ b/include/boost/graph/karp_minimum_mean_cycle.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_GRAPH_KARP_MINIMUM_MEAN_CYCLE_HPP +#define BOOST_GRAPH_KARP_MINIMUM_MEAN_CYCLE_HPP + +#include +#include +#include + +namespace boost +{ + template + double karp_minimum_mean_cycle(Graph g) + { + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typename property_map::type weight = get(edge_weight,g); + typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; + BOOST_CONCEPT_ASSERT((GraphConcept< Graph >)); + + int n = num_vertices(g); + double distance_matrix[n+1][n]; + std::fill(distance_matrix[0],distance_matrix[0]+(n+1)*(n), -1.0); + distance_matrix[0][0] = 0; + + std::pair vertex_iterator_pair= vertices(g); + std::vector vertices_vector; + for(vertex_iterator a=vertex_iterator_pair.first; a!=vertex_iterator_pair.second;a++) + { + vertices_vector.push_back(*a);; + } + + for (int i=1; i<=n; i++) + { + for (int j=0; j edge_iterator_pair= boost::out_edges(vertices_vector[j],g); + std::vector::edge_descriptor> incident_edges; + for(out_edge_iterator b=edge_iterator_pair.first;b!=edge_iterator_pair.second;b++) + { + incident_edges.push_back(*b); + } + for (int k=0; k< out_degree(vertices_vector[j],g); k++) + { + vertex_descriptor t=target(incident_edges[k],g); + auto it = find(vertices_vector.begin(), vertices_vector.end(), t); + int index = it - vertices_vector.begin(); + if (distance_matrix[i-1][index] != -1) + { + double curr_wt = distance_matrix[i-1][index] + + get(weight,incident_edges[k]); + if (distance_matrix[i][j] == -1) + distance_matrix[i][j] = curr_wt; + else + distance_matrix[i][j] = std::min(distance_matrix[i][j], curr_wt); + } + } + } + } + double avg[n]; + std::fill(avg,avg+n,-1.0); + + for (int i=0; i Date: Tue, 4 Jan 2022 20:00:38 +0530 Subject: [PATCH 4/5] Added documentation, example. Changed name. --- doc/figs/mcm.jpg | Bin 0 -> 3409 bytes doc/karp_minimum_cycle_mean.html | 87 ++++++++++++++++++ example/minimum_cycle_mean_example.cpp | 28 ++++++ ..._cycle.hpp => karp_minimum_cycle_mean.hpp} | 6 +- 4 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 doc/figs/mcm.jpg create mode 100644 doc/karp_minimum_cycle_mean.html create mode 100644 example/minimum_cycle_mean_example.cpp rename include/boost/graph/{karp_minimum_mean_cycle.hpp => karp_minimum_cycle_mean.hpp} (95%) diff --git a/doc/figs/mcm.jpg b/doc/figs/mcm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2a225b6049a4e27e61184663ce8a40840507f41a GIT binary patch literal 3409 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 + + + + Boost Graph Library: Karps Minimum Cycle Mean + + + + + + + + + +

C++ Boost +

+

karp_minimum_cycle_mean

+

+

+template <typename Graph>
+double karp_minimum_cycle_mean(Graph g);
+
+

+ + +The karp_minimum_cycle_mean() function calculates minimum cycle mean of a +weighted directed graph G=(V,E,W), where V is a vertex set, +E is an edge set, W: E -> R is an edge weight function . +

+ +

We define the mean weight of a cycle C=<e1,e1,e2..,ek> of edges in E to be

+

+mean weight of cycle +

+ +The minimum cycle mean is the minimum cycle mean +of all cycles of the graph. The karp_minimum_cycle_mean() returns the +calculated minimum cycle mean. Returns -1 if the graph has no cycles. + +

+

+This algorithm was described by Richard M. Karp in his paper +A characterization of the minimum cycle mean in a digraph

+ + +

Where Defined

+

boost/graph/karp_minimum_cycle_mean.hpp +

+

Parameters

+ +

IN: const Graph g +

+
A weighted directed graph. +
+ +

+OUT: double minimum_mean_weight +

+ +

Complexity

+

The implemented algorithm runs in O(|V||E|) time. Where V and E are vertex set and edge set respectively. +

+ +

Example

+

The program in libs/graph/example/minimum_cycle_mean_example.cpp +finds the minimum cycle mean of the defined graph. +

+ diff --git a/example/minimum_cycle_mean_example.cpp b/example/minimum_cycle_mean_example.cpp new file mode 100644 index 000000000..d6928aaf3 --- /dev/null +++ b/example/minimum_cycle_mean_example.cpp @@ -0,0 +1,28 @@ +#include +#include +typedef boost::property EdgeWeight; +typedef boost::adjacency_list DirectedGraph; +int main() { + + DirectedGraph g; + /** + * Create the graph drawn below. + * + * + * 10 + * ________ + * / 1 3 \ + * 1-->2--->3 + ^ ^ / + * 8\0| /2 + * \|/ + * 4 + **/ + boost::add_edge(0, 1, 1, g); + boost::add_edge(1, 2, 3, g); + boost::add_edge(2, 3, 2, g); + boost::add_edge(3, 1, 0, g); + boost::add_edge(3, 0, 8, g); + boost::add_edge(0, 2, 10, g); + std::cout< #include @@ -8,7 +8,7 @@ namespace boost { template - double karp_minimum_mean_cycle(Graph g) + double karp_minimum_cycle_mean(Graph g) { typedef typename boost::graph_traits::vertex_iterator vertex_iterator; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; From b508420f2fbe8b9ef176286d4f819325b88ad48e Mon Sep 17 00:00:00 2001 From: G Yuvan Shankar Date: Thu, 6 Jan 2022 13:58:06 +0530 Subject: [PATCH 5/5] Added test file, minor changes to doc --- doc/karp_minimum_cycle_mean.html | 8 ++---- test/minimum_cycle_mean_test.cpp | 48 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 test/minimum_cycle_mean_test.cpp diff --git a/doc/karp_minimum_cycle_mean.html b/doc/karp_minimum_cycle_mean.html index f688871bb..16c73443e 100644 --- a/doc/karp_minimum_cycle_mean.html +++ b/doc/karp_minimum_cycle_mean.html @@ -3,14 +3,10 @@ Boost Graph Library: Karps Minimum Cycle Mean - - - + - 2--->3 + ^ ^ / + * 8\0| /2 + * \|/ + * 4 + **/ + boost::add_edge(0, 1, 1, g1); + boost::add_edge(1, 2, 3, g1); + boost::add_edge(2, 3, 2, g1); + boost::add_edge(3, 1, 0, g1); + boost::add_edge(3, 0, 8, g1); + boost::add_edge(0, 2, 10, g1); + double min_cycle_mean = boost::karp_minimum_cycle_mean(g1); + std::cout << min_cycle_mean << std::endl; + BOOST_TEST(std::abs(min_cycle_mean - 1.666666666) < epsilon); + } + { + DirectedGraph g2; + /** + * Create the graph drawn below. + * 1 + * 1-->2 + * + **/ + boost::add_edge(0, 1, 1, g2); + double min_cycle_mean = boost::karp_minimum_cycle_mean(g2); + std::cout << min_cycle_mean << std::endl; + BOOST_TEST(std::abs(min_cycle_mean +1) < epsilon); + } + + return boost::report_errors(); +}