Skip to content

Commit

Permalink
Merge pull request #368 from andrea-cassioli-maersk/fix-single-soluti…
Browse files Browse the repository at this point in the history
…on-rcsp

Fix issue #368 in the single solution RCSP
  • Loading branch information
jeremy-murphy authored Apr 3, 2024
2 parents 46ddc51 + fa8caee commit 158eebd
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ kevin-bacon2.dat
random.dot
triangular-fr.dot
triangular-kk.dot
test/*.dot
example/routing-table.dat
example/figs/ospf-sptree.dot
CMakeFiles/
4 changes: 4 additions & 0 deletions include/boost/graph/r_c_shortest_paths.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ namespace detail
}
}
std::list< Splabel > dsplabels = get(vec_vertex_labels, t);
if(!b_all_pareto_optimal_solutions)
{
dsplabels.sort();
}
typename std::list< Splabel >::const_iterator csi = dsplabels.begin();
typename std::list< Splabel >::const_iterator csi_end = dsplabels.end();
// if d could be reached from o
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ alias graph_test_regular :
[ run named_vertices_test.cpp ]
[ run r_c_shortest_paths_test.cpp ]
[ run rcsp_custom_vertex_id.cpp ]
[ run rcsp_single_solution.cpp ]
[ run is_straight_line_draw_test.cpp ]
[ run metric_tsp_approx.cpp /boost/timer//boost_timer : metric_tsp_approx.graph : : ]
[ compile dimacs.cpp ]
Expand Down
118 changes: 118 additions & 0 deletions test/rcsp_single_solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//=======================================================================
// Copyright (c) 2024 Andrea Cassioli
// Author: Andrea Cassioli <[email protected]>
//
// 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 <boost/graph/adjacency_list.hpp>
#include <boost/graph/r_c_shortest_paths.hpp>

#include <boost/core/lightweight_test.hpp>

struct edge_prop {
edge_prop(int c, int t) : cost(c), time(t) {}

int cost;
int time;
};

using graph_type = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, std::string, edge_prop>;
using vertex_type = graph_type::vertex_descriptor;
using edge_type = graph_type::edge_descriptor;
using path_type = std::vector<edge_type>;

class dominance
{
public:
template<class C>
inline bool operator()(const C& res_cont_1, const C& res_cont_2) const {
return res_cont_1.cost <= res_cont_2.cost && res_cont_1.time <= res_cont_2.time;
}
};

struct resource_container
{
resource_container(int c, int t) : cost(c), time(t) {}

int cost; // minimise cost
int time; // a fake time constraints
};


bool operator==(
const resource_container& res_cont_1, const resource_container& res_cont_2)
{
return (res_cont_1.cost == res_cont_2.cost
&& res_cont_1.time == res_cont_2.time);
}

bool operator<(
const resource_container& res_cont_1, const resource_container& res_cont_2)
{
if (res_cont_1.cost > res_cont_2.cost)
return false;
if (res_cont_1.cost == res_cont_2.cost)
return res_cont_1.time < res_cont_2.time;
return true;
}

struct extension_function {
template <typename GraphType>
bool operator()(const GraphType& graph,
resource_container& new_cont,
const resource_container& old_cont,
const typename GraphType::edge_descriptor& edge) const {
new_cont = old_cont;
new_cont.cost = old_cont.cost + graph[edge].cost;
// here I could check tme constraint, but for this example does not matter
new_cont.time = old_cont.time + graph[edge].time;
return true;
}
};

resource_container run_rcsp(const graph_type& graph, vertex_type source, vertex_type target) {
const auto vertex_index_map = boost::get(boost::vertex_index, graph);
const auto edge_index_map = boost::get(boost::edge_all, graph);
boost::default_r_c_shortest_paths_allocator label_allocator{};

path_type single_solution;
resource_container single_resource(0, 0);
const resource_container start_resource(0, 0);
boost::r_c_shortest_paths(graph, vertex_index_map, edge_index_map, source, target, single_solution, single_resource,
start_resource, extension_function{}, dominance{}, label_allocator,
boost::default_r_c_shortest_paths_visitor());

return single_resource;
}

int main() {
graph_type graph;

/*
(1,0) (10, 1)
/-----> [A] ------\
[s] [t]
\-----> [B] ------/
(2, 1) (3,1)
The shortest path is s->B->t with cost 5.
*/

const auto s = boost::add_vertex("s", graph);
const auto A = boost::add_vertex("A", graph);
const auto B = boost::add_vertex("B", graph);
const auto t = boost::add_vertex("t", graph);

boost::add_edge(s, A, edge_prop(1, 0), graph);
boost::add_edge(s, B, edge_prop(2, 1), graph);
boost::add_edge(A, t, edge_prop(10, 0), graph);
boost::add_edge(B, t, edge_prop(3, 1), graph);

const auto solution_resource_container = run_rcsp(graph, s, t);

BOOST_TEST(solution_resource_container.cost == 5);
return boost::report_errors();
}

0 comments on commit 158eebd

Please sign in to comment.