diff --git a/src/graph/helper.cc b/src/graph/helper.cc index 324170bb104a42d1abea03f7409ea01f3fce05cb..44797431db3510bc130bf3d30f78f3a4d16d8768 100644 --- a/src/graph/helper.cc +++ b/src/graph/helper.cc @@ -16,6 +16,9 @@ #include <hpp/manipulation/graph/helper.hh> +#include <tr1/unordered_map> +#include <tr1/unordered_set> + #include <boost/array.hpp> #include <boost/regex.hpp> #include <boost/foreach.hpp> @@ -544,6 +547,16 @@ namespace hpp { struct Result { GraphPtr_t graph; std::vector<NodeAndManifold_t> nodes; + typedef std::vector<NodeAndManifold_t>::size_type nodeid_type; + typedef std::pair<nodeid_type, nodeid_type> edgeid_type; + struct edgeid_hash { + std::tr1::hash<edgeid_type::first_type> first; + std::tr1::hash<edgeid_type::second_type> second; + std::size_t operator() (const edgeid_type& eid) const { + return first(eid.first) + second(eid.second); + } + }; + std::tr1::unordered_set<edgeid_type, edgeid_hash> edges; std::vector< boost::array<NumericalConstraintPtr_t,3> > graspCs; index_t nG, nOH; GraspV_t dims; @@ -595,12 +608,27 @@ namespace hpp { return true; } - NodeAndManifold_t& operator() (const GraspV_t& iG) + inline nodeid_type nodeid (const GraspV_t& iG) { - index_t iGOH = iG[0]; + nodeid_type iGOH = iG[0]; for (index_t i = 1; i < nG; ++i) iGOH += dims[i] * (iG[i]); - return nodes [iGOH]; + return iGOH; + } + + NodeAndManifold_t& operator() (const GraspV_t& iG) + { + return nodes [nodeid(iG)]; + } + + bool hasEdge (const GraspV_t& g1, const GraspV_t& g2) + { + return edges.count(edgeid_type(nodeid(g1), nodeid(g2))) > 0; + } + + void addEdge (const GraspV_t& g1, const GraspV_t& g2) + { + edges.insert(edgeid_type(nodeid(g1), nodeid(g2))); } inline boost::array<NumericalConstraintPtr_t,3>& graspConstraint ( @@ -764,6 +792,11 @@ namespace hpp { const GraspV_t& gFrom, const GraspV_t& gTo, const index_t iG, const int priority) { + if (r.hasEdge(gFrom, gTo)) { + hppDout (warning, "Prevented creation of duplicated edge\nfrom " + << r.name (gFrom) << "\nto " << r.name (gTo)); + return; + } const NodeAndManifold_t& from = makeNode (r, gFrom, priority), to = makeNode (r, gTo, priority+1); const Object_t& o = r.object (gTo[iG]); @@ -870,6 +903,7 @@ namespace hpp { grasp.foliated () , place.foliated(), submanifold); } + r.addEdge(gFrom, gTo); } /// idx are the available grippers @@ -932,6 +966,9 @@ namespace hpp { GraspV_t iG (r.nG, r.nOH); recurseGrippers (r, availG, availOH, iG, 0); + + hppDout (info, "Created a graph with " << r.nodes.size() << " states " + "and " << r.edges.size() << " edges."); } GraphPtr_t graphBuilder (