Initialization of Auxillary Property Maps in Boost Graph Library - c++

Objective
Generate a random spanning tree on a randomly generated graph.
Why: because I don't know yet if I can directly generate random trees with specific number of nodes or leaves in BGL.
My problem
I think it boils down to struggling initializing the Auxillary Property Maps to a sensical default.
As you will see I've tried a number of combination of solutions, in the current state the code fails to compile with a cannot form a reference to 'void'.
What I tried
template<class Graph, class Generator>
auto generate_random_spanning_tree(int n_vertices, int n_edges, Generator& rng)
{
// create empty graph
Graph g;
using vertex_t = typename Graph::vertex_descriptor;
using edge_t = typename Graph::edge_descriptor;
// The key and value types of the map must both be the graph's vertex type.
using predecessor_map_t = boost::static_property_map<vertex_t, vertex_t>;
predecessor_map_t predecessor_map = boost::make_static_property_map<vertex_t,vertex_t>(vertex_t());
// unweighted version selected by passing an object of type static_property_map<double> as the weight map, so let's go
using weight_map_t = boost::static_property_map< double >;
// weight_map_t weight_map = boost::make_transform_value_property_map([](edge_t& e) { return 1.0; }, get(boost::edge_bundle, g)); // nope
//weight_map_t weight_map = boost::make_static_property_map<double>(1.0); // yes but complicated
// weight_map_t weight_map; // nope: why isn't it default constructible?
double my_constant_weight = 1.0;
weight_map_t weight_map(my_constant_weight);
using color_map_t = typename boost::property_map<Graph, boost::vertex_color_t>::type;
color_map_t color_map ; // i suspect this is faulty
// mutate graph
boost::generate_random_graph(g, n_vertices, n_edges, rng);
// pick root, I guess we could as well pick 1st vertex
auto root = boost::random_vertex(g, rng);
boost::random_spanning_tree(g, rng, root, predecessor_map, weight_map, color_map);
return g;
}

First: Your own suspect
using color_map_t = typename boost::property_map<Graph, boost::vertex_color_t>::type;
color_map_t color_map; // i suspect this is faulty
Yes. PropertyMaps map properties. They are like references. Here, color_map
is essentially an unitialized reference. You need something like
color_map_t color_map = get(boost::vertex_color, g);
This, of course, assumes that a vertex_color_t property map has been
associated with the graph by traits. In other words, this assumes that the
property is an iternal property of the graph. Internal properties are often
used by default.
Second: A constant cannot be modified
You use a static property map:
auto predecessor_map =
boost::make_static_property_map<vertex_t, vertex_t>(vertex_t());
That just creates a "virtual" property map (without a backing data structure)
that returns the construction parameter on every key. Logically, the return
value is constant. However, predecessor map is an output parameter:
You will need an LValuePropertyMap there. E.g.
std::map<vertex_t, vertex_t> predecessors;
auto predecessor_map =boost::make_assoc_property_map(predecessors);
Or even
auto vindex = get(boost::vertex_index, g);
auto predecessors = std::vector<vertex_t>(num_vertices(g));
auto predecessor_map = boost::make_safe_iterator_property_map(
predecessors.begin(), predecessors.size(), vindex);
Which uses a vertex index to (optionally) translate descriptors into vector
indices. Note that the second is fixed-size, so initialize it after creating
all vertices.
Other Points Of Interest
// weight_map_t weight_map; // nope: why isn't it default constructible?
What would it do? Surely it won't default to what you think is a good default
(1.0). So I'd just write
auto weight_map = boost::static_property_map(1.0);
Simplified
I'd write the entire function as:
template <class Graph, class Generator>
auto generate_random_spanning_tree(int n_vertices, int n_edges, Generator& rng) {
using vertex_t = typename Graph::vertex_descriptor;
Graph g;
generate_random_graph(g, n_vertices, n_edges, rng);
std::map<vertex_t, vertex_t> predecessors;
random_spanning_tree(g, rng, random_vertex(g, rng),
boost::make_assoc_property_map(predecessors),
boost::static_property_map(1.0), // unweighted
get(boost::vertex_color, g));
return g;
}
Functional Problems
You're asking some good questions yourself. But let me start with some observations.
You have Unspecified/Undefined
Behaviour because your
input graph doesn't conform to the requirements:
There must be a path from every non-root vertex of the graph to the
root; the algorithm typically enters an infinite loop when given a
graph that does not satisfy this property, but may also throw the
exception loop_erased_random_walk_stuck if the search reaches a vertex
with no outgoing edges
Indeed, running your code only completes for a few random seeds, and fails
or runs infinitely for others (this is even increasing the chance of
satisfying the requirements by using undirectedS):
Listing
while true; do (set -x; time ./build/sotest& sleep 3; kill %1); done
You are creating the random spanning tree only to completely forget about
it. Did you intend to return the predecessor map as well (or a derived path
representation)?
Your own questions:
"cannot form a reference to 'void'"
Usually indicates an associated property map could not be found (e.g.
what happens if you fail to supply the vertex_color interior
property. In
this case the remedy is simply to use the default color
map:
random_spanning_tree(
g, rng,
boost::root_vertex(random_vertex(g, rng))
.predecessor_map(boost::make_assoc_property_map(predecessors))
.weight_map(boost::static_property_map(1.0)) // unweighted
);
"I don't know yet if I can directly generate random trees with specific
number of nodes or leaves in BGL."
You can generate random graphs with specific number of nodes and leaves -
as you already demonstrate.
trees.
You can also find random spanning trees (given a graph satisfying the preconditions).
To adhere to the preconditions the simplest way would be to generate
undirected graphs, whilst additionally making sure that the result is
connected. A simple, possible inefficient(?) way to ensure it would be to
explicitly connect components:
if (int n = boost::connected_components(ug, cmap); n > 1) {
std::cout << "Connecting " << n << " components:\n";
for (int c = 1; c < n; ++c)
std::cout << "Added " << add_edge(from(c - 1), from(c), ug).first << "\n";
}
It might be more effective to write your own generating algorithm.
BONUS EXAMPLE
Showing the use of connected_components to make sure the graph is fully
connected, and even building a directed tree from undirected source graph. Also
writing graphviz representations of the "raw" (undirected) source and "tree"
(directed spanning tree), it seems to work pretty well.
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/random.hpp>
#include <boost/graph/random_spanning_tree.hpp>
#include <boost/property_map/function_property_map.hpp>
#include <iomanip>
#include <random>
namespace detail {
template <typename T> struct make_undirected { using type = void; };
template <typename A, typename B, typename C, typename D, typename E, typename F>
struct make_undirected<boost::adjacency_list<A, B, C, D, E, F>> {
using type = boost::adjacency_list<A, B, boost::undirectedS, D, E, F>;
};
} // namespace detail
template <typename T> using Undirect = typename detail::make_undirected<T>::type;
template <class Graph, class Generator>
auto generate_random_spanning_tree(int n_vertices, int n_edges, Generator& rng) {
using UG = Undirect<Graph>;
using vertex_t = typename UG::vertex_descriptor;
// assuming integral vertex index for simplicity
static_assert(std::is_same_v<vertex_t, size_t>);
static_assert(std::is_same_v<typename UG::vertex_descriptor,
typename Graph::vertex_descriptor>);
UG ug;
generate_random_graph(ug, n_vertices, n_edges, rng);
vertex_t const root = random_vertex(ug, rng);
print_graph(ug, std::cout << "Raw root: " << root << ", graph:\n");
{ // make connected
std::map<vertex_t, int> components;
auto from = [&](int component) { // just picking the first...
for (auto& [v, c] : components) if (c == component) return v;
throw std::range_error("component");
};
auto cmap = boost::make_assoc_property_map(components);
if (int n = connected_components(ug, cmap); n > 1) {
std::cout << "Connecting " << n << " components:\n";
for (int c = 1; c < n; ++c)
std::cout << "Added " << add_edge(from(c - 1), from(c), ug).first << "\n";
}
}
std::map<vertex_t, vertex_t> predecessors;
random_spanning_tree(
ug, rng,
boost::root_vertex(root) //
.predecessor_map(boost::make_assoc_property_map(predecessors)));
Graph tree(num_vertices(ug)); // build a tree copy
for (auto v : boost::make_iterator_range(vertices(ug)))
if (predecessors.contains(v))
if (auto pred = predecessors.at(v); ug.null_vertex() != pred)
add_edge(predecessors.at(v), v, tree);
auto save = [&predecessors](auto& g, auto name) {
using edge_t = typename std::decay_t<decltype(g)>::edge_descriptor;
auto tree_edge = [&predecessors](auto s, auto t) {
auto it = predecessors.find(s);
return it != end(predecessors) && it->second == t;
};
boost::dynamic_properties dp;
dp.property("node_id", get(boost::vertex_index, g));
dp.property("color",
boost::make_function_property_map<edge_t>([tree_edge, &g](edge_t e) {
auto s = source(e, g), t = target(e, g);
return tree_edge(s, t) || tree_edge(t, s) ? "red" : "gray";
}));
std::ofstream os(name);
write_graphviz_dp(os, g, dp);
};
save(ug, "raw.dot");
save(tree, "tree.dot");
return std::pair(std::move(tree), root);
}
int main(int argc, char** argv) {
using G = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
auto const seed = argc > 1 ? std::stoull(argv[1]) : std::random_device{}();
std::cout << "seed: " << seed << std::endl;
std::mt19937 prng(seed);
auto [tree, root] = generate_random_spanning_tree<G>(10, 20, prng);
print_graph(tree, std::cout << "From root: " << root << ", tree:\n");
}
Prints the sample seed: 1577455792
Raw root: 7, graph:
0 <--> 7 2 3 7 5 2 8
1 <-->
2 <--> 8 0 4 0 4 9
3 <--> 9 5 0 8
4 <--> 7 7 2 2 5
5 <--> 8 3 0 4
6 <-->
7 <--> 4 4 0 8 0
8 <--> 2 5 7 9 0 3
9 <--> 3 8 2
Connecting 3 components:
Added (0,1)
Added (1,6)
From root: 7, tree:
0 --> 1 3
1 --> 6
2 --> 9
3 --> 5
4 --> 2
5 --> 4 8
6 -->
7 --> 0
8 -->
9 -->
Running locally with:
watch './build/sotest; for a in raw tree; do (set -x ; dot -Tpng -o $a.png $a.dot); done'
Shows random solutions like:

Related

How to get vertex from boost graph in constant time?

I'm trying to create a graph where lanes represent vertices and edges connections between. The idea is to later on use a_star algorithm to traverse the graph and find the best route.
My question is how can I get vertex (descriptor?) by using just (town_id, road_id, lane_id)?
I tryied battling with the examples that are shipped with boost and basically lost. In them they always traverse thru all the vertices and then get the vertex_descriptor, but I want to do that in constant time.
What is need is something like boost::get_vertex(std::tuple(1, 2, 3), graph).
My situation is marked as PROBLEM bellow in the code. The code bellow compiles because there is 12 that I guess corresponds to the index in boost::vecS, but I want to use a tuple (or something else that can hold the triplet) that could get me the vertex descriptor as my starting location.
using TRL = std::tuple<int, int, int>;
struct TRL_VProp {
/// For some reason this object has to be default constructable
/// use invalid data to flag it as invalid
TRL_VProp()
: trl(-1, -1, 0) {}
TRL_VProp(TRL trl)
: trl(trl) {}
TRL_VProp(int town_id, int road_id, int lane_id)
: trl(town_id, road_id, lane_id) {}
TRL trl;
};
using DirectedGraph = boost::adjacency_list<boost::listS,
boost::vecS,
boost::directedS,
RSL_VProp>;
using Vertex = boost::graph_traits<DirectedGraph>::vertex_descriptor;
using VertexI = boost::graph_traits<DirectedGraph>::vertex_iterator;
using EdgeI = boost::graph_traits<DirectedGraph>::edge_iterator;
using Edge = boost::graph_traits<DirectedGraph>::edge_descriptor;
using AdjI = boost::graph_traits<DirectedGraph>::adjacency_iterator;
using Route = std:vector<TRL>;
Route BuildRoute(Map & map) {
Route result;
DirectedGraph graph;
const boost::property_map<DirectedGraph, RSL RSL_VProp:: *>::type trl =
boost::get(&TRL_VProp::rsl, graph);
bool is_inserted;
Edge e_desc;
for (auto & town: map.GetTowns()) {
for (auto & road: town.GetRoads()) {
for (auto & lane: road.GetLanes()) {
auto vtx_1 = boost::add_vertex(
RSL_VProp(town.GetId(), road.GetId(), lane.GetId()),
graph);
const auto next_lanes = map.GetNextLanes(town.GetId(), road.GetId(), lane.GetId());
for(const auto & next_lane : next_lanes) {
auto vtx_2 = boost::add_vertex(
TRL_VProp(lane.GetTown().GetId(), lane.GetRoad().GetId(), lane.GetId()),
graph);
std::tie(e_desc, is_inserted) = boost::add_edge(vtx_1, vtx_2, graph);
assert(is_inserted);
}
}
}
}
// debug part
TRL temp_trl;
std::pair<AdjI, AdjI> adj_i = boost::adjacent_vertices(12, graph); // <--- PROBLEM
for( auto i = adj_i.first; i != adj_i.second; i++) {
temp_trl = trl[*i]; // trl prop map
std:: cout << "\Town id: " << std::get<0>(temp_trl)
<< "\nRoad id: " << std::get<1>(temp_trl)
<< "\nLane id: " << std::get<2>(temp_trl);
result.push_back(
std::make_tuple(
std::get<0>(temp_trl),
std::get<1>(temp_trl),
std::get<2>(temp_trl)));
}
return result;
}
For completeness, I don't plan to change data inside the property or the graph itself. Once thing is created it will probably stay that way. Maybe lateron I'll probably have to add the weight or whatever is necessary to get the traversing algorithm to work.
Edit: I forgot to mention that there is a bug in the code because I'm adding vertices before checking was vertex with identical (town, road, lane) already been created. I wonder is there a builtin boost::graph way to not insert duplicated so I won't have to use a std::unordered_map or something.

Using two objects as hash key for an unordered_map or alternatives

Having defined my objects myType, I need to store relations between these objects. These relations are stored on a matrix.
The number of elements is not known in advance, not all elements have a relation (element1 can have a relation with element3, but may not have one with 5) and memory is an issue. For example it could look like:
element45 is connected with:
element3 with characteristic [3,1;1,4]
element12 with characteristic [1,1;1,1]
element1780 with characteristic [8,1;1,4]
element1661 is connected with:
element3 with characteristic [3,1;6,4]
element1 with characteristic [1,1;1,9]
element1780 with characteristic [8,1;1,1]
Having:
myType* element1;
myType* element2;
I would like to have something like (properly pointed the elements):
my_table[element1][element2][1][2]=7;
I have thought on creating a nested hash table using boost library:
boost::unordered_map<myType*, boost::unordered_map<myType*,
std::vector<std::vector <unsigned short int> > > > my_table;
However, even if the code compiles, it crashes (Segmentation fault, it points to a line calculating the hash key) running a simple line like:
my_table[element1][element2].resize(2);
for(int t=0; t<2; ++t)
my_table[element1][element2][t].resize(2);
Anyone can give me some light about this? Is this practically or conceptually wrong?
Any other approach to this problem is welcome.
Thank you
Right off the bat it seems obvious to me that your datastructure represent a graph (with attributed vertices and edges connecting them).
Furthermore when you say "These relations are stored on a matrix." you apparently mean "I visualize this as a matrix", since a true matrix representation¹ would become horrifically space-inefficient for larger number of vertices and sparse edge coverage.
Boost has a library for that: Boost Graph Library (BGL)
If we assume you want to be able to read a graph like²
graph X {
element1; element12; element166; element1780; element3; element4;
element45 -- element3 [ label="[3,1;1,4]" ];
element45 -- element12 [ label="[1,1;1,1]" ];
element45 -- element1780 [ label="[8,1;1,4]" ];
element1661 -- element1 [ label="[1,1;1,9]" ];
element1661 -- element3 [ label="[3,1;6,4]" ];
element1661 -- element1780 [ label="[8,1;1,1]" ];
}
Into a BGL compatible model, use typedefs like e.g.:
struct Vertex {
std::string node_id;
};
struct Edge {
Box box;
};
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge>;
Now you leverage the full facilities of the BGL:
Reading the graph from a file
Reading from a graphviz file is a feature³:
std::ifstream ifs("input.txt");
Graph result;
boost::dynamic_properties dp;
dp.property("node_id", boost::get(&Vertex::node_id, result));
dp.property("label", boost::get(&Edge::box, result));
read_graphviz(ifs, result, dp);
Manipulating the graph
The many algorithms (dijkstra, flow, spanning trees, connected components, etc.) are at your disposal. Or you can mix and match. For example let's filter the nodes that have no connections out:
struct Filter {
Graph const* _g;
bool operator()(Graph::vertex_descriptor v) const {
return boost::size(boost::adjacent_vertices(v, *_g))>0;
}
template <typename T>
bool operator()(T&&) const { return true; /*catch-all*/ }
};
using Filtered = filtered_graph<Graph, Filter, Filter>;
Filter filter { &graph };
Filtered filtered(graph, filter, filter);
Let's write it to graphviz again:
boost::dynamic_properties dp;
dp.property("node_id", boost::get(&Vertex::node_id, filtered));
dp.property("label", boost::get(&Edge::box, filtered));
write_graphviz_dp(std::cout, filtered, dp);
DEMO TIME
The full demo takes your input graph:
And filters it into:
Full Code
Live On Coliru
// http://stackoverflow.com/questions/32279268/using-two-objects-as-hash-key-for-an-unordered-map-or-alternatives
#include <cassert>
#include <iostream>
template <typename T> struct BasicBox {
struct Point { T x, y; };
Point tl, br;
friend std::ostream& operator<<(std::ostream& os, Point const& p) { return os << p.x << ',' << p.y; }
friend std::ostream& operator<<(std::ostream& os, BasicBox const& b) { return os << '[' << b.tl << ';' << b.br << ']'; }
friend std::istream& operator>>(std::istream& is, Point& p) {
char comma;
if (!(is >> p.x >> comma >> p.y) && (comma == ',')) {
is.setstate(std::ios::failbit | is.rdstate());
}
return is;
}
friend std::istream& operator>>(std::istream& is, BasicBox& b) {
char lbrace, semi, rbrace;
if (!(
(is >> lbrace >> b.tl >> semi >> b.br >> rbrace) &&
(lbrace == '[' && semi == ';' && rbrace == ']')
)) {
is.setstate(std::ios::failbit | is.rdstate());
}
return is;
}
};
using Box = BasicBox<int>;
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <libs/graph/src/read_graphviz_new.cpp>
struct Vertex {
std::string node_id;
};
struct Edge {
Box box;
};
using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Vertex, Edge>;
#include <fstream>
#include <boost/graph/filtered_graph.hpp>
struct Filter {
Graph const* _g;
bool operator()(Graph::vertex_descriptor v) const {
return boost::size(boost::adjacent_vertices(v, *_g))>0;
}
template <typename T>
bool operator()(T&&) const { return true; /*catch-all*/ }
};
int main() {
using namespace boost;
Graph const graph = []{
std::ifstream ifs("input.txt");
Graph result;
boost::dynamic_properties dp;
dp.property("node_id", boost::get(&Vertex::node_id, result));
dp.property("label", boost::get(&Edge::box, result));
read_graphviz(ifs, result, dp);
return result;
}();
// let's do some random task. Like. You know. Like... Filter out the unconnected nodes
using Filtered = filtered_graph<Graph, Filter, Filter>;
Filter filter { &graph };
Filtered filtered(graph, filter, filter);
boost::dynamic_properties dp;
dp.property("node_id", boost::get(&Vertex::node_id, filtered));
dp.property("label", boost::get(&Edge::box, filtered));
write_graphviz_dp(std::cout, filtered, dp);
}
¹ like e.g. BGL's AdjacencyMatrix
² the format chosen being Graphviz' DOT format: http://www.graphviz.org/
³ Of course you can also use Boost Serialization with BGL models, so you can opt for a more compact binary representation e.g.
You could use a boost::unordered_map with key std::pair<myType*, myType*> in combine with boost::hash. You could declare it as:
boost::unordered_map<std::pair<myType*, myType*>,
std::vector<std::vector<char>>,
boost::hash<std::pair<myType*, myType*>>> dictionary;
Then you could load the characteristics of each pair in the dictionary like in the example below:
dictionary[std::make_pair(&a, &b)] = std::vector<std::vector<char>>(1, {1, 2, 3, 4, 5});
And access them as:
dictionary[std::make_pair(&a, &b)][0][0];
LIVE DEMO

Boost-graph,accessing un-bundled vertex/edge properties [duplicate]

I have my custom vertex and edge properties
namespace boost {
enum vertex_diagonal_t{vertex_diagonal = 999};
BOOST_INSTALL_PROPERTY(vertex, diagonal);
}
namespace boost {
enum edge_dominance_t{edge_dominance = 998};
BOOST_INSTALL_PROPERTY(edge, dominance);
}
I create my adjacency list with boost::property
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
boost::property<boost::vertex_diagonal_t, const khut::diagonal*>,
boost::property<boost::edge_dominance_t, float>
> diagonal_dominance_graph;
typedef boost::property_map<diagonal_dominance_graph, boost::vertex_diagonal_t>::type diagonal_map_type;
typedef boost::property_map<diagonal_dominance_graph, boost::edge_dominance_t>::type dominance_map_type;
Now I want to loop through my own containers and add vertex
diagonal_dominance_graph graph;
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i){
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
//>> ?? HOW CAN I write Properties to dia_vertex HERE ?
//boost::property<boost::vertex_diagonal_t, const khut::diagonal*> p;
//boost::put(p, dia_vertex);
}
What I am not getting is How can I set properties of a vertex through vertex_descriptor. may be I am missing a simple function.
Please I don't need anything that makes BGL even more complex, or something that cleans and restructures the types in my example. I just need to know how to read/write properties through a vertex_descriptor or edge_descriptor
You're using property lists: they're documented here.
So in your example, you'd use
diagonal_map_type vp = get(boost::vertex_diagonal, graph);
using storage_type = std::vector<int>;
storage_type repo_begining(10);
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i) {
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
khut::diagonal* v = nullptr;
boost::put(vp, dia_vertex, v);
}
// likewise for edges
dominance_map_type ep = get(boost::edge_dominance, graph);
See it Live On Coliru
Bundled Properties
The very same documentation page says:
NOTE: The Boost Graph Library supports two interchangeable methods for specifying interior properties: bundled properties and property lists. The former is easier to use and requires less effort, whereas the latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to 1.32.0. If you absolutely require these compatibility features, read on to learn about property lists. Otherwise, we strongly suggest that you read about the bundled properties mechanism.
Boost 1.32 dates over 10 years ago! So, I'd suggest bundled properties:
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
namespace khut {
struct diagonal { };
struct MyVertexProperties {
diagonal const* diag_ptr;
};
struct MyEdgeProperties {
float dominance;
};
}
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
khut::MyVertexProperties,
khut::MyEdgeProperties
> diagonal_dominance_graph;
#include <iostream>
int main() {
using namespace boost;
diagonal_dominance_graph g;
khut::diagonal d1, d2;
{
auto v1 = add_vertex(khut::MyVertexProperties { &d1 }, g);
auto v2 = add_vertex(khut::MyVertexProperties { &d2 }, g);
/*auto e1 = */add_edge(v1, v2, khut::MyEdgeProperties { 42.31415926 }, g);
}
for(diagonal_dominance_graph::vertex_descriptor vd : make_iterator_range(vertices(g)))
std::cout << "Is diagonal d1? " << std::boolalpha << (&d1 == g[vd].diag_ptr) << "\n";
for(diagonal_dominance_graph::edge_descriptor ed : make_iterator_range(edges(g)))
std::cout << "Edge dominance: " << g[ed].dominance << "\n";
}
Prints
Is diagonal d1? true
Is diagonal d1? false
Edge dominance: 42.3142

Boost Graph accessing properties through vertex_descriptor

I have my custom vertex and edge properties
namespace boost {
enum vertex_diagonal_t{vertex_diagonal = 999};
BOOST_INSTALL_PROPERTY(vertex, diagonal);
}
namespace boost {
enum edge_dominance_t{edge_dominance = 998};
BOOST_INSTALL_PROPERTY(edge, dominance);
}
I create my adjacency list with boost::property
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
boost::property<boost::vertex_diagonal_t, const khut::diagonal*>,
boost::property<boost::edge_dominance_t, float>
> diagonal_dominance_graph;
typedef boost::property_map<diagonal_dominance_graph, boost::vertex_diagonal_t>::type diagonal_map_type;
typedef boost::property_map<diagonal_dominance_graph, boost::edge_dominance_t>::type dominance_map_type;
Now I want to loop through my own containers and add vertex
diagonal_dominance_graph graph;
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i){
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
//>> ?? HOW CAN I write Properties to dia_vertex HERE ?
//boost::property<boost::vertex_diagonal_t, const khut::diagonal*> p;
//boost::put(p, dia_vertex);
}
What I am not getting is How can I set properties of a vertex through vertex_descriptor. may be I am missing a simple function.
Please I don't need anything that makes BGL even more complex, or something that cleans and restructures the types in my example. I just need to know how to read/write properties through a vertex_descriptor or edge_descriptor
You're using property lists: they're documented here.
So in your example, you'd use
diagonal_map_type vp = get(boost::vertex_diagonal, graph);
using storage_type = std::vector<int>;
storage_type repo_begining(10);
for(storage_type::const_iterator i = repo_begining.begin(); i != repo_begining.end(); ++i) {
diagonal_dominance_graph::vertex_descriptor dia_vertex = boost::add_vertex(graph);
khut::diagonal* v = nullptr;
boost::put(vp, dia_vertex, v);
}
// likewise for edges
dominance_map_type ep = get(boost::edge_dominance, graph);
See it Live On Coliru
Bundled Properties
The very same documentation page says:
NOTE: The Boost Graph Library supports two interchangeable methods for specifying interior properties: bundled properties and property lists. The former is easier to use and requires less effort, whereas the latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to 1.32.0. If you absolutely require these compatibility features, read on to learn about property lists. Otherwise, we strongly suggest that you read about the bundled properties mechanism.
Boost 1.32 dates over 10 years ago! So, I'd suggest bundled properties:
Live On Coliru
#include <boost/graph/adjacency_list.hpp>
namespace khut {
struct diagonal { };
struct MyVertexProperties {
diagonal const* diag_ptr;
};
struct MyEdgeProperties {
float dominance;
};
}
typedef boost::adjacency_list<
boost::listS,
boost::vecS,
boost::bidirectionalS,
khut::MyVertexProperties,
khut::MyEdgeProperties
> diagonal_dominance_graph;
#include <iostream>
int main() {
using namespace boost;
diagonal_dominance_graph g;
khut::diagonal d1, d2;
{
auto v1 = add_vertex(khut::MyVertexProperties { &d1 }, g);
auto v2 = add_vertex(khut::MyVertexProperties { &d2 }, g);
/*auto e1 = */add_edge(v1, v2, khut::MyEdgeProperties { 42.31415926 }, g);
}
for(diagonal_dominance_graph::vertex_descriptor vd : make_iterator_range(vertices(g)))
std::cout << "Is diagonal d1? " << std::boolalpha << (&d1 == g[vd].diag_ptr) << "\n";
for(diagonal_dominance_graph::edge_descriptor ed : make_iterator_range(edges(g)))
std::cout << "Edge dominance: " << g[ed].dominance << "\n";
}
Prints
Is diagonal d1? true
Is diagonal d1? false
Edge dominance: 42.3142

CGAL::Delaunay_d C++ on UCI Seeds dataset: “EXC_BAD_ACCESS”

For my PhD work, I need to construct the Delaunay triangulation (DT) of a given point set in any (low) dimension. So far, I have been using the C++ CGAL library with data up to 4D without any noticeable problem.
However, as I used the same class CGAL::Delaunay_d as I previously used on an 7D data set (namely UCI repository Seeds data set ), it seems like something is going wrong and I don't know how to trace my problem.
Here is a copy-pastable code to reproduce the execution:
// CGAL includes
#include <CGAL/Cartesian_d.h>
#include <CGAL/Delaunay_d.h>
#include <CGAL/Gmpq.h>
// STANDARD includes
#include <iostream>
#include <string>
#include <map>
// TYPEDEFS
typedef CGAL::Gmpq EXACT_RT;
typedef CGAL::Cartesian_d<EXACT_RT> EXACT_Kernel;
typedef EXACT_Kernel::Point_d EXACT_Point;
typedef EXACT_Kernel::Vector_d EXACT_Vector;
typedef CGAL::Delaunay_d<EXACT_Kernel> EXACT_Delaunay_any_d;
typedef EXACT_Delaunay_any_d::Vertex_handle EXACT_Vertex_handle;
// NAMESPACES
using namespace std;
using namespace CGAL;
// FUNCTIONS
int main(int argc, char *argv[]);
void delaunay_d(EXACT_Delaunay_any_d &DT, const map <unsigned, vector<EXACT_RT> > &data);
map <unsigned, vector<EXACT_RT> > data_parse(const string &data_set);
// DATASET
char seeds_data_char[] = "15,26 14,84 0,871 5,763 3,312 2,221 5,22\n\
14,88 14,57 0,8811 5,554 3,333 1,018 4,956\n\
14,29 14,09 0,905 5,291 3,337 2,699 4,825\n\
13,84 13,94 0,8955 5,324 3,379 2,259 4,805\n\
16,14 14,99 0,9034 5,658 3,562 1,355 5,175\n\
14,38 14,21 0,8951 5,386 3,312 2,462 4,956\n\
14,69 14,49 0,8799 5,563 3,259 3,586 5,219\n\
14,11 14,1 0,8911 5,42 3,302 2,7 5\n\
16,63 15,46 0,8747 6,053 3,465 2,04 5,877\n\
16,44 15,25 0,888 5,884 3,505 1,969 5,533\n\
15,26 14,85 0,8696 5,714 3,242 4,543 5,314\n\
14,03 14,16 0,8796 5,438 3,201 1,717 5,001\n\
13,89 14,02 0,888 5,439 3,199 3,986 4,738\n\
13,78 14,06 0,8759 5,479 3,156 3,136 4,872\n\
13,74 14,05 0,8744 5,482 3,114 2,932 4,825\n\
14,59 14,28 0,8993 5,351 3,333 4,185 4,781\n\
13,99 13,83 0,9183 5,119 3,383 5,234 4,781\n\
15,69 14,75 0,9058 5,527 3,514 1,599 5,046\n\
14,7 14,21 0,9153 5,205 3,466 1,767 4,649\n\
12,72 13,57 0,8686 5,226 3,049 4,102 4,914\n\
14,16 14,4 0,8584 5,658 3,129 3,072 5,176\n\
14,11 14,26 0,8722 5,52 3,168 2,688 5,219\n\
15,88 14,9 0,8988 5,618 3,507 0,7651 5,091\n\
12,08 13,23 0,8664 5,099 2,936 1,415 4,961\n\
15,01 14,76 0,8657 5,789 3,245 1,791 5,001\n\
16,19 15,16 0,8849 5,833 3,421 0,903 5,307\n\
13,02 13,76 0,8641 5,395 3,026 3,373 4,825\n\
12,74 13,67 0,8564 5,395 2,956 2,504 4,869\n\
14,11 14,18 0,882 5,541 3,221 2,754 5,038\n\
13,45 14,02 0,8604 5,516 3,065 3,531 5,097\n\
13,16 13,82 0,8662 5,454 2,975 0,8551 5,056\n\
15,49 14,94 0,8724 5,757 3,371 3,412 5,228\n\
14,09 14,41 0,8529 5,717 3,186 3,92 5,299\n\
13,94 14,17 0,8728 5,585 3,15 2,124 5,012\n\
15,05 14,68 0,8779 5,712 3,328 2,129 5,36\n\
16,12 15 0,9 5,709 3,485 2,27 5,443\n\
16,2 15,27 0,8734 5,826 3,464 2,823 5,527\n\
17,08 15,38 0,9079 5,832 3,683 2,956 5,484\n\
14,8 14,52 0,8823 5,656 3,288 3,112 5,309\n\
14,28 14,17 0,8944 5,397 3,298 6,685 5,001\n\
13,54 13,85 0,8871 5,348 3,156 2,587 5,178\n\
13,5 13,85 0,8852 5,351 3,158 2,249 5,176\n\
13,16 13,55 0,9009 5,138 3,201 2,461 4,783\n\
15,5 14,86 0,882 5,877 3,396 4,711 5,528\n\
15,11 14,54 0,8986 5,579 3,462 3,128 5,18\n\
13,8 14,04 0,8794 5,376 3,155 1,56 4,961\n\
15,36 14,76 0,8861 5,701 3,393 1,367 5,132\n\
14,99 14,56 0,8883 5,57 3,377 2,958 5,175\n\
14,79 14,52 0,8819 5,545 3,291 2,704 5,111\n\
14,86 14,67 0,8676 5,678 3,258 2,129 5,351\n\
14,43 14,4 0,8751 5,585 3,272 3,975 5,144\n\
15,78 14,91 0,8923 5,674 3,434 5,593 5,136\n\
14,49 14,61 0,8538 5,715 3,113 4,116 5,396\n\
14,33 14,28 0,8831 5,504 3,199 3,328 5,224\n\
14,52 14,6 0,8557 5,741 3,113 1,481 5,487\n\
15,03 14,77 0,8658 5,702 3,212 1,933 5,439\n\
14,46 14,35 0,8818 5,388 3,377 2,802 5,044\n\
14,92 14,43 0,9006 5,384 3,412 1,142 5,088\n\
15,38 14,77 0,8857 5,662 3,419 1,999 5,222\n\
12,11 13,47 0,8392 5,159 3,032 1,502 4,519\n\
11,42 12,86 0,8683 5,008 2,85 2,7 4,607\n\
11,23 12,63 0,884 4,902 2,879 2,269 4,703\n\
12,36 13,19 0,8923 5,076 3,042 3,22 4,605\n\
13,22 13,84 0,868 5,395 3,07 4,157 5,088\n\
12,78 13,57 0,8716 5,262 3,026 1,176 4,782\n\
12,88 13,5 0,8879 5,139 3,119 2,352 4,607\n\
14,34 14,37 0,8726 5,63 3,19 1,313 5,15\n\
14,01 14,29 0,8625 5,609 3,158 2,217 5,132\n\
14,37 14,39 0,8726 5,569 3,153 1,464 5,3\n\
12,73 13,75 0,8458 5,412 2,882 3,533 5,067\n\
17,63 15,98 0,8673 6,191 3,561 4,076 6,06\n\
16,84 15,67 0,8623 5,998 3,484 4,675 5,877\n\
17,26 15,73 0,8763 5,978 3,594 4,539 5,791\n\
19,11 16,26 0,9081 6,154 3,93 2,936 6,079\n\
16,82 15,51 0,8786 6,017 3,486 4,004 5,841\n\
16,77 15,62 0,8638 5,927 3,438 4,92 5,795\n\
17,32 15,91 0,8599 6,064 3,403 3,824 5,922\n\
20,71 17,23 0,8763 6,579 3,814 4,451 6,451\n\
18,94 16,49 0,875 6,445 3,639 5,064 6,362\n\
17,12 15,55 0,8892 5,85 3,566 2,858 5,746\n\
16,53 15,34 0,8823 5,875 3,467 5,532 5,88\n\
18,72 16,19 0,8977 6,006 3,857 5,324 5,879\n\
20,2 16,89 0,8894 6,285 3,864 5,173 6,187\n\
19,57 16,74 0,8779 6,384 3,772 1,472 6,273\n\
19,51 16,71 0,878 6,366 3,801 2,962 6,185\n\
18,27 16,09 0,887 6,173 3,651 2,443 6,197\n\
18,88 16,26 0,8969 6,084 3,764 1,649 6,109\n\
18,98 16,66 0,859 6,549 3,67 3,691 6,498\n\
21,18 17,21 0,8989 6,573 4,033 5,78 6,231\n\
20,88 17,05 0,9031 6,45 4,032 5,016 6,321\n\
20,1 16,99 0,8746 6,581 3,785 1,955 6,449\n\
18,76 16,2 0,8984 6,172 3,796 3,12 6,053\n\
18,81 16,29 0,8906 6,272 3,693 3,237 6,053\n\
18,59 16,05 0,9066 6,037 3,86 6,001 5,877\n\
18,36 16,52 0,8452 6,666 3,485 4,933 6,448\n\
16,87 15,65 0,8648 6,139 3,463 3,696 5,967\n\
19,31 16,59 0,8815 6,341 3,81 3,477 6,238\n\
18,98 16,57 0,8687 6,449 3,552 2,144 6,453\n\
18,17 16,26 0,8637 6,271 3,512 2,853 6,273\n\
18,72 16,34 0,881 6,219 3,684 2,188 6,097\n\
16,41 15,25 0,8866 5,718 3,525 4,217 5,618\n\
17,99 15,86 0,8992 5,89 3,694 2,068 5,837\n\
19,46 16,5 0,8985 6,113 3,892 4,308 6,009\n\
19,18 16,63 0,8717 6,369 3,681 3,357 6,229\n\
18,95 16,42 0,8829 6,248 3,755 3,368 6,148\n\
18,83 16,29 0,8917 6,037 3,786 2,553 5,879\n\
18,85 16,17 0,9056 6,152 3,806 2,843 6,2\n\
17,63 15,86 0,88 6,033 3,573 3,747 5,929\n\
19,94 16,92 0,8752 6,675 3,763 3,252 6,55\n\
18,55 16,22 0,8865 6,153 3,674 1,738 5,894\n\
18,45 16,12 0,8921 6,107 3,769 2,235 5,794\n\
19,38 16,72 0,8716 6,303 3,791 3,678 5,965\n\
19,13 16,31 0,9035 6,183 3,902 2,109 5,924\n\
19,14 16,61 0,8722 6,259 3,737 6,682 6,053\n\
20,97 17,25 0,8859 6,563 3,991 4,677 6,316\n\
19,06 16,45 0,8854 6,416 3,719 2,248 6,163\n\
18,96 16,2 0,9077 6,051 3,897 4,334 5,75\n\
19,15 16,45 0,889 6,245 3,815 3,084 6,185\n\
18,89 16,23 0,9008 6,227 3,769 3,639 5,966\n\
20,03 16,9 0,8811 6,493 3,857 3,063 6,32\n\
20,24 16,91 0,8897 6,315 3,962 5,901 6,188\n\
18,14 16,12 0,8772 6,059 3,563 3,619 6,011\n\
16,17 15,38 0,8588 5,762 3,387 4,286 5,703\n\
18,43 15,97 0,9077 5,98 3,771 2,984 5,905\n\
15,99 14,89 0,9064 5,363 3,582 3,336 5,144\n\
18,75 16,18 0,8999 6,111 3,869 4,188 5,992\n\
18,65 16,41 0,8698 6,285 3,594 4,391 6,102\n\
17,98 15,85 0,8993 5,979 3,687 2,257 5,919\n\
20,16 17,03 0,8735 6,513 3,773 1,91 6,185\n\
17,55 15,66 0,8991 5,791 3,69 5,366 5,661\n\
18,3 15,89 0,9108 5,979 3,755 2,837 5,962\n\
18,94 16,32 0,8942 6,144 3,825 2,908 5,949\n\
15,38 14,9 0,8706 5,884 3,268 4,462 5,795\n\
16,16 15,33 0,8644 5,845 3,395 4,266 5,795\n\
15,56 14,89 0,8823 5,776 3,408 4,972 5,847\n\
15,38 14,66 0,899 5,477 3,465 3,6 5,439\n\
17,36 15,76 0,8785 6,145 3,574 3,526 5,971\n\
15,57 15,15 0,8527 5,92 3,231 2,64 5,879\n\
15,6 15,11 0,858 5,832 3,286 2,725 5,752\n\
16,23 15,18 0,885 5,872 3,472 3,769 5,922\n\
13,07 13,92 0,848 5,472 2,994 5,304 5,395\n\
13,32 13,94 0,8613 5,541 3,073 7,035 5,44\n\
13,34 13,95 0,862 5,389 3,074 5,995 5,307\n\
12,22 13,32 0,8652 5,224 2,967 5,469 5,221\n\
11,82 13,4 0,8274 5,314 2,777 4,471 5,178\n\
11,21 13,13 0,8167 5,279 2,687 6,169 5,275\n\
11,43 13,13 0,8335 5,176 2,719 2,221 5,132\n\
12,49 13,46 0,8658 5,267 2,967 4,421 5,002\n\
12,7 13,71 0,8491 5,386 2,911 3,26 5,316\n\
10,79 12,93 0,8107 5,317 2,648 5,462 5,194\n\
11,83 13,23 0,8496 5,263 2,84 5,195 5,307\n\
12,01 13,52 0,8249 5,405 2,776 6,992 5,27\n\
12,26 13,6 0,8333 5,408 2,833 4,756 5,36\n\
11,18 13,04 0,8266 5,22 2,693 3,332 5,001\n\
11,36 13,05 0,8382 5,175 2,755 4,048 5,263\n\
11,19 13,05 0,8253 5,25 2,675 5,813 5,219\n\
11,34 12,87 0,8596 5,053 2,849 3,347 5,003\n\
12,13 13,73 0,8081 5,394 2,745 4,825 5,22\n\
11,75 13,52 0,8082 5,444 2,678 4,378 5,31\n\
11,49 13,22 0,8263 5,304 2,695 5,388 5,31\n\
12,54 13,67 0,8425 5,451 2,879 3,082 5,491\n\
12,02 13,33 0,8503 5,35 2,81 4,271 5,308\n\
12,05 13,41 0,8416 5,267 2,847 4,988 5,046\n\
12,55 13,57 0,8558 5,333 2,968 4,419 5,176\n\
11,14 12,79 0,8558 5,011 2,794 6,388 5,049\n\
12,1 13,15 0,8793 5,105 2,941 2,201 5,056\n\
12,44 13,59 0,8462 5,319 2,897 4,924 5,27\n\
12,15 13,45 0,8443 5,417 2,837 3,638 5,338\n\
11,35 13,12 0,8291 5,176 2,668 4,337 5,132\n\
11,24 13 0,8359 5,09 2,715 3,521 5,088\n\
11,02 13 0,8189 5,325 2,701 6,735 5,163\n\
11,55 13,1 0,8455 5,167 2,845 6,715 4,956\n\
11,27 12,97 0,8419 5,088 2,763 4,309 5\n\
11,4 13,08 0,8375 5,136 2,763 5,588 5,089\n\
10,83 12,96 0,8099 5,278 2,641 5,182 5,185\n\
10,8 12,57 0,859 4,981 2,821 4,773 5,063\n\
11,26 13,01 0,8355 5,186 2,71 5,335 5,092\n\
10,74 12,73 0,8329 5,145 2,642 4,702 4,963\n\
11,48 13,05 0,8473 5,18 2,758 5,876 5,002\n\
12,21 13,47 0,8453 5,357 2,893 1,661 5,178\n\
11,41 12,95 0,856 5,09 2,775 4,957 4,825\n\
12,46 13,41 0,8706 5,236 3,017 4,987 5,147\n\
12,19 13,36 0,8579 5,24 2,909 4,857 5,158\n\
11,65 13,07 0,8575 5,108 2,85 5,209 5,135\n\
12,89 13,77 0,8541 5,495 3,026 6,185 5,316\n\
11,56 13,31 0,8198 5,363 2,683 4,062 5,182\n\
11,81 13,45 0,8198 5,413 2,716 4,898 5,352\n\
10,91 12,8 0,8372 5,088 2,675 4,179 4,956\n\
11,23 12,82 0,8594 5,089 2,821 7,524 4,957\n\
10,59 12,41 0,8648 4,899 2,787 4,975 4,794\n\
10,93 12,8 0,839 5,046 2,717 5,398 5,045\n\
11,27 12,86 0,8563 5,091 2,804 3,985 5,001\n\
11,87 13,02 0,8795 5,132 2,953 3,597 5,132\n\
10,82 12,83 0,8256 5,18 2,63 4,853 5,089\n\
12,11 13,27 0,8639 5,236 2,975 4,132 5,012\n\
12,8 13,47 0,886 5,16 3,126 4,873 4,914\n\
12,79 13,53 0,8786 5,224 3,054 5,483 4,958\n\
13,37 13,78 0,8849 5,32 3,128 4,67 5,091\n\
12,62 13,67 0,8481 5,41 2,911 3,306 5,231\n\
12,76 13,38 0,8964 5,073 3,155 2,828 4,83\n\
12,38 13,44 0,8609 5,219 2,989 5,472 5,045\n\
12,67 13,32 0,8977 4,984 3,135 2,3 4,745\n\
11,18 12,72 0,868 5,009 2,81 4,051 4,828\n\
12,7 13,41 0,8874 5,183 3,091 8,456 5\n\
12,37 13,47 0,8567 5,204 2,96 3,919 5,001\n\
12,19 13,2 0,8783 5,137 2,981 3,631 4,87\n\
11,23 12,88 0,8511 5,14 2,795 4,325 5,003\n\
13,2 13,66 0,8883 5,236 3,232 8,315 5,056\n\
11,84 13,21 0,8521 5,175 2,836 3,598 5,044\n\
12,3 13,34 0,8684 5,243 2,974 5,637 5,063";
//////////
// MAIN //
//////////
int main(int argc, char *argv[]) {
// DATA SET declaration
string seeds_data(seeds_data_char);
map <unsigned, vector<EXACT_RT> > my_DATA = data_parse(seeds_data);
// DT declaration
EXACT_Delaunay_any_d my_DT(7);
// DT construction
delaunay_d(my_DT, my_DATA);
return 0;
}
// DELAUNAY TRIANGULATION function
void delaunay_d(
EXACT_Delaunay_any_d &DT,
const map <unsigned, vector<EXACT_RT> > &data)
{
// Dim size variable
int d = ((data.begin()) ->second).size();
int i = 1;
// Scanning data set -- DT construction
for(map <unsigned, vector<EXACT_RT> >::const_iterator it = data.begin(); it != data.end(); it++, i++){
// Constructing Point objects
EXACT_Point tmp = EXACT_Point(d, (it ->second).begin(), (it ->second).end());
// Inserting point in the triangulation
EXACT_Vertex_handle v_tmp = DT.insert(tmp);
// DEBUG
std::cout << "-- DEBUG POST -- " << i << " -- DT.all_simplices().size() : " << DT.all_simplices().size() << " -- DT.current_dimension() : " << DT.current_dimension() << endl;
}
}
// PARSING DATA function
map <unsigned, vector<EXACT_RT> > data_parse(
const string &data_set)
{
// RETURNED map
map <unsigned, vector<EXACT_RT> > result;
// TMP variables declaration
vector<EXACT_RT> vect;
string tmp_value;
char current_char;
for (unsigned i=0; i<data_set.length(); i++)
{
current_char = data_set[i];
// Testing if read character is tab or space (i.e. end of a number) ...
if( (current_char == '\t') || (current_char == ' ')) {
double curr_num = atof(tmp_value.c_str());
vect.push_back(EXACT_RT(curr_num)); // Storing the double value.
tmp_value.clear(); // Clearing current number
}
// ... end of a line ...
else
if ( (current_char == '\n') || (current_char == '\r') ) {
double curr_num = atof(tmp_value.c_str());
vect.push_back(EXACT_RT(curr_num)); // Storing the double value.
result.insert ( pair <unsigned, vector<EXACT_RT> > (i++, vect) ); // Feeding returned map
tmp_value.clear(); // Clearing current number
vect.clear(); // Clearing the vector containing the converted values
}
// .. storing any other character
else {
// Dealing with decimal character (from ',' to '.')
if(current_char == ',') {
// Storing current character
tmp_value.push_back('.');
}
else
// Storing current character
tmp_value.push_back(current_char);
}
}
return result;
}
As I used exact number type CGAL::Gmpq for the computation of the DT, I suspect an internal bug of CGAL but I can't assert it. My error actually occurs within the call of function EXACT_Delaunay_any_d::insert()and I don't know how to find a way to debug it.
An “EXC_BAD_ACCESS” signal stops my program while trying to insert the 78-th point, after construction of 20926 simplices.
My questions are:
Should I use some other exact number type ?
Is it an internal issue of CGAL function EXACT_Delaunay_any_d::insert() ?
Is it a problem of memory allocation related to my OS (Mac OS X 10.6.8) ?
Thanks in advance if you have any answer / clue for investigation !
Octavio
Interestingly, you just reported a stack overflow on stackoverflow.com.
The function visibility_search in Convex_hull_d.h is recursive (not a terminal recursion) and the depth of the recursion is apparently not bounded. This is a bug. You should be able to get a bit further by increasing the stack size (the procedure is explained in other questions on this site). Let us know how that fares.
You can also try to reduce other stack use. Maybe using mpq_class or CGAL::Quotient<CGAL::MP_Float> instead of CGAL::Gmpq would help, or it might be even worse. You could also recompile the GMP library after replacing 65536 with 1024 in gmp-impl.h.