From af99b0d1179a1c6ffe0461b6ad09e839dc2bcbfd Mon Sep 17 00:00:00 2001 From: Michal Kleinbort Date: Wed, 16 Nov 2011 12:00:05 +0000 Subject: [PATCH] added longest query path length method and change operator! of td_dag_node to is_null() --- .../CGAL/Arr_point_location/Td_dag_node.h | 204 ++++++++++-------- .../Trapezoidal_decomposition_2.h | 29 ++- .../Trapezoidal_decomposition_2_impl.h | 90 +++++++- .../CGAL/Arr_trapezoid_ric_point_location.h | 14 +- 4 files changed, 228 insertions(+), 109 deletions(-) diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_dag_node.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_dag_node.h index 85ec1f491b2..7d080e4b4f7 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_dag_node.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_dag_node.h @@ -25,7 +25,7 @@ template class Td_dag_node_base : public Handle { protected: - void init() { PTR = 0; } + void init() { PTR = 0; } //MICHAL: I think it is not used - so need to be removed public: //c'tors @@ -43,7 +43,11 @@ public: return *this; } - bool operator!() const { return PTR == 0; } + //bool operator!() const { return PTR == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar + bool is_null() const { return PTR == 0; } +protected: + Rep * ptr() const { return (Rep*) PTR; } + Rep *& ptr() { return (Rep*) PTR; } }; @@ -69,8 +73,8 @@ public: #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2 public: - using Td_dag_node_handle::PTR; - using Td_dag_node_handle::operator!; + //using Td_dag_node_handle::PTR; + //using Td_dag_node_handle::operator!; #endif //CGAL_CFG_USING_BASE_MEMBER_BUG_2 @@ -101,9 +105,10 @@ protected: //d'tor ~Node() { } - bool is_inner_node() const + bool is_inner_node() const //MICHAL: a node with only left child (like removed node) will be concidered as a leaf { - return !!m_left_child && !!m_right_child; + //return !!m_left_child && !!m_right_child; + return (!m_left_child.is_null() && !m_right_child.is_null()); } bool visited() const { return m_visited; } @@ -136,58 +141,57 @@ public: Td_dag_node(const Self& dag) : Td_dag_node_handle(dag) { } - Td_dag_node(const T& rootValue){ PTR = new Node(rootValue); } + Td_dag_node(const T& rootValue){ ptr() = new Node(rootValue); } Td_dag_node(const T& rootValue, unsigned long depth) - { PTR = new Node(rootValue, depth); } + { ptr() = new Node(rootValue, depth); } Td_dag_node(const T& rootValue, const Self& left, const Self& right) { - PTR = new Node( rootValue, left, right); + ptr() = new Node( rootValue, left, right); depth_propagation(); } Td_dag_node(const T& rootValue, const Self& left, const Self& right, unsigned long depth) { - PTR = new Node( rootValue, left, right, depth); + ptr() = new Node( rootValue, left, right, depth); depth_propagation(); } //d'tor ~Td_dag_node() { } - //information retrieval const Self& left_child() const { - CGAL_precondition(!operator!()); - return *(const Self*)&ptr()->m_left_child; + CGAL_precondition(!is_null()); + return *(const Self*)&node()->m_left_child; } Self& left_child() { - CGAL_precondition(!operator!()); - return (Self &)ptr()->m_left_child; + CGAL_precondition(!is_null()); + return (Self &)node()->m_left_child; } const Self& right_child() const { - CGAL_precondition(!operator!()); - return *(const Self*)&ptr()->m_right_child; + CGAL_precondition(!is_null()); + return *(const Self*)&node()->m_right_child; } Self& right_child() { - CGAL_precondition(!operator!()); - return (Self &)ptr()->m_right_child; + CGAL_precondition(!is_null()); + return (Self &)node()->m_right_child; } T& get_data() const { - CGAL_precondition(!operator!()); - return ptr()->m_data; + CGAL_precondition(!is_null()); + return node()->m_data; } T& operator*() const @@ -197,7 +201,7 @@ public: T* data_ptr() const { - CGAL_precondition(!operator!()); + CGAL_precondition(!is_null()); return &operator*(); } @@ -208,54 +212,60 @@ public: bool is_inner_node() const { - return !operator!() && ptr()->is_inner_node(); + return !is_null() && node()->is_inner_node(); } - unsigned long size_inaccurate() const + unsigned long size_inaccurate() const //exponential { - visit_none(); + init_visited(); unsigned long res = recursive_size_inaccurate(); - visit_none(); + init_visited(); return res; } unsigned long size() const { - visit_none(); + init_visited(); unsigned long res = recursive_size(); - visit_none(); + init_visited(); return res; } - unsigned long rec_depth() const + unsigned long rec_depth() const //exponential { - visit_none(); + init_visited(); unsigned long res = recursive_depth(); - visit_none(); + init_visited(); return res; } - +#if 0 + unsigned long rec_check(unsigned long rec_bound) const //exponential + { + unsigned long res = recursive_check(1,rec_bound); + return res; + } +#endif //0 unsigned long max_depth() const { - visit_none(); + init_visited(); unsigned long res = rec_max_depth(); - visit_none(); + init_visited(); return res; } const unsigned long& depth() const { - return ptr()->m_depth; + return node()->m_depth; } unsigned long& depth() { - return ptr()->m_depth; + return node()->m_depth; } bool operator==(const Self& b) const { - return PTR==b.PTR; + return ptr() == b.ptr(); } bool operator!=(const Self& b) const @@ -274,16 +284,16 @@ public: void set_data(const T& data) { - if (!operator!()) - ptr()->m_data = data; + if (!is_null()) + node()->m_data = data; else operator=(Self(data)); } void set_left_child(Self& left) { - CGAL_precondition(!operator!()); - ptr()->m_left_child = left; + CGAL_precondition(!is_null()); + node()->m_left_child = left; if (left.depth() < depth()+1) left.depth() = depth()+1; left.depth_propagation(); @@ -292,8 +302,8 @@ public: void set_right_child(Self& right) { - CGAL_precondition(!operator!()); - ptr()->m_right_child = right; + CGAL_precondition(!is_null()); + node()->m_right_child = right; if (right.depth() < depth()+1) right.depth() = depth()+1; right.depth_propagation(); @@ -308,28 +318,27 @@ public: } // Td_dag implementation not thread safe! - void visit_none() const + void init_visited() const { - if (!operator!()) - { - ptr()->m_visited = false; - left_child().visit_none(); - right_child().visit_none(); - } + if (is_null() || node()->m_visited == false) + return; + node()->m_visited = false; + left_child().init_visited(); + right_child().init_visited(); } - void visit_one() const + void visit_node() const { - if (!operator!()) - ptr()->m_visited = true; + if (!is_null()) + node()->m_visited = true; } /* -----output ---------------*/ #ifdef CGAL_PRE_IN_POST_ORDER - void preorder() const + void preorder() const //exponential { - if (!operator!()) + if (!is_null()) { std::cout << operator*() << '\t'; left_child().preorder(); @@ -337,9 +346,9 @@ public: } } - void inorder() const + void inorder() const //exponential { - if (!operator!()) + if (!is_null()) { left_child().inorder(); std::cout << operator*() << '\t'; @@ -347,9 +356,9 @@ public: } } - void postorder() const + void postorder() const //exponential { - if (!operator!()) + if (!is_null()) { left_child().postorder(); right_child().postorder(); @@ -362,8 +371,10 @@ public: template Container& filter(Container& c,const Predicate& pr) const { - visit_none(); - return recursive_filter(c,pr); + init_visited(); + Container& res = recursive_filter(c,pr); + init_visited(); + return res; } @@ -374,7 +385,7 @@ protected: // //Propagating depth for left child & right child if they exist // - void depth_propagation() + void depth_propagation() //exponential { if (!is_inner_node()) return; @@ -393,61 +404,70 @@ protected: unsigned long recursive_depth() const { - if (!operator!() && !ptr()->visited()) - return 1 + (std::max)(left_child().recursive_depth(), + if (is_null() || node()->visited()) + return 0; + return 1 + (std::max)(left_child().recursive_depth(), right_child().recursive_depth()); - return 0; } - +#if 0 + unsigned long recursive_check(unsigned long curr_rec_depth, unsigned long rec_bound) const + { + if (is_null()) + return 0; + //std::cout << curr_rec_depth << "," << std::flush; + if ( curr_rec_depth > rec_bound + 30) + { + std::cout << "passed " << rec_bound + 30 << ", stopping\n"; + return 0; + } + return 1 + (std::max)(left_child().recursive_check(curr_rec_depth + 1, rec_bound), + right_child().recursive_check(curr_rec_depth + 1, rec_bound)); + } +#endif //0 + unsigned long rec_max_depth() const { - if (!operator!() && !ptr()->visited()) - { - visit_one(); - if (is_inner_node()) - return std::max(left_child().rec_max_depth(), + if (is_null() || node()->visited()) + return 0; + visit_node(); + if (is_inner_node()) + return std::max(left_child().rec_max_depth(), right_child().rec_max_depth()); - else - return depth(); - } - return 0; + else + return depth(); } unsigned long recursive_size_inaccurate() const { - if (!operator!() && !ptr()->visited()) + if (!is_null() && !node()->visited()) return 1+ left_child().recursive_size_inaccurate() + right_child().recursive_size_inaccurate(); return 0; } unsigned long recursive_size() const { - if (operator!()) + if (is_null() || node()->visited()) return 0; - if (ptr()->visited()) - return 0; - - visit_one(); + visit_node(); return (1 + left_child().recursive_size() + right_child().recursive_size()); } template Container& recursive_filter(Container& c,const Predicate& pr) const { - if (!operator!() && !ptr()->visited()) - { - if (pr(operator*())) - c.insert(c.end(),operator*()); - visit_one(); - left_child().recursive_filter(c, pr); - right_child().recursive_filter(c, pr); - } + if (is_null() || node()->visited()) + return c; + if (pr(operator*())) + c.insert(c.end(),operator*()); + visit_node(); + left_child().recursive_filter(c, pr); + right_child().recursive_filter(c, pr); return c; } private: - Node* ptr() const { return (Node*)PTR; } + Node* node() const { return (Node*)PTR; } }; @@ -461,7 +481,7 @@ std::ostream& write (std::ostream& out, { static int depth; int i; - if (!!t) + if (!t.is_null()) { out << "\n"; for(i=0; i"; @@ -493,7 +513,7 @@ std::ostream& operator<< (std::ostream& out, { static int depth; int i; - if (!!t) + if (!t.is_null()) { out << "\n"; for(i=0; i"; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h index dc123f58aa9..9cce3f6e165 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h @@ -829,7 +829,7 @@ public: { return (traits->compare_curve_end_xy_2_object()(p, ce) == LARGER); } - + bool is_end_point_right_top(const Curve_end& ce1, const Curve_end& ce2) const { return (traits->compare_curve_end_xy_2_object()(ce1, ce2) == LARGER); @@ -1311,6 +1311,7 @@ public: { if (do_rebuild && needs_update()) { + std::cout << "starting over after " << number_of_curves() << std::flush; start_over = true; clear(); break; @@ -1324,7 +1325,7 @@ public: //after inserting the last halfedge in the range // perform another rebuild check - if (do_rebuild && not_within_limits()) //MICHAL: should I use needs_update() instead? + if (do_rebuild && not_within_limits()) //MICHAL: should I use needs_update() instead (with the random check)? { start_over = true; clear(); @@ -1841,17 +1842,28 @@ public: unsigned long largest_leaf_depth() { - CGAL_assertion((m_largest_leaf_depth + 1) == m_dag_root->rec_depth()); + //CGAL_assertion((m_largest_leaf_depth + 1) == m_dag_root->rec_depth()); return m_largest_leaf_depth; } +#if 0 + unsigned long rec_check() + { + return m_dag_root->rec_check(largest_leaf_depth()+1); + } +#endif //0 unsigned long number_of_dag_nodes() { - CGAL_assertion(m_number_of_dag_nodes == m_dag_root->size()); + //CGAL_assertion(m_number_of_dag_nodes == m_dag_root->size()); return m_number_of_dag_nodes; } - + unsigned long longest_query_path_length() + { + return longest_query_path_length_rec(true, *m_dag_root, + true, *m_dag_root, *m_dag_root); + } + protected: @@ -1874,7 +1886,12 @@ private: mutable X_trapezoid* prev_cv; #endif - + + unsigned long longest_query_path_length_rec( + bool minus_inf, Dag_node& min_node, + bool plus_inf, Dag_node& max_node, + Dag_node& node); + unsigned char build_boundaries_flag(const Curve_end& ce) { unsigned char bndry_flag = CGAL_TD_INTERIOR; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h index 2bd60ba26c9..9ff93a475a7 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h @@ -46,12 +46,12 @@ Trapezoidal_decomposition_2 { #ifndef CGAL_TD_DEBUG - CGAL_warning(!!tt); - if (!tt) return tt; + CGAL_warning(!tt.is_null()); + if (tt.is_null()) return tt; #else - CGAL_precondition(!!tt); + CGAL_precondition(!tt.is_null()); #endif @@ -178,12 +178,12 @@ void Trapezoidal_decomposition_2 #ifndef CGAL_TD_DEBUG - if (!tr_node|| + if (tr_node.is_null()|| !tr_node->is_active()|| !traits->is_degenerate_point(*tr_node)|| !traits->equal_curve_end_2_object()( tr_node->left()->curve_end(),ce)) { - CGAL_warning(!!tr_node); + CGAL_warning(!tr_node.is_null()); CGAL_warning(tr_node->is_active()); CGAL_warning(traits->is_degenerate_point(*tr_node)); CGAL_warning(traits->equal_curve_end_2_object() @@ -193,7 +193,7 @@ void Trapezoidal_decomposition_2 #else - CGAL_precondition(!!tr_node); + CGAL_precondition(!tr_node.is_null()); CGAL_precondition(tr_node->is_active()); CGAL_precondition(traits->is_degenerate_point(*tr_node)); CGAL_precondition(traits->equal_curve_end_2_object() @@ -2387,9 +2387,9 @@ Trapezoidal_decomposition_2 //print_dag_addresses(*m_dag_root); - //std:: cout << "Largest leaf depth: " << largest_leaf_depth() << std::endl; + //std:: cout << "Largest leaf depth+1: " << (largest_leaf_depth() + 1) << std::endl; //std:: cout << "Number of DAG nodes: " << number_of_dag_nodes() << std::endl; - + //std::cout << "Longest query path: " << longest_query_path_length() << std::endl; return *old_output; } @@ -3704,6 +3704,80 @@ void Trapezoidal_decomposition_2 } +//----------------------------------------------------------------------------- +// Description: +// +template +unsigned long +Trapezoidal_decomposition_2 +::longest_query_path_length_rec(bool minus_inf, Dag_node& min_node, + bool plus_inf, Dag_node& max_node, + Dag_node& node) +{ + //if NULL + if (node.is_null()) + return 0; + //if node represents a curve or trapezoid + if (!traits->is_degenerate_point(*node) ) + return (1 + std::max( + longest_query_path_length_rec(minus_inf, min_node, + plus_inf, max_node, + node.left_child()) , + longest_query_path_length_rec(minus_inf, min_node, + plus_inf, max_node, + node.right_child()) )); + //if this node represents a point + //check if it is within param min & max + + bool pnt_exists = false; + if (!node->is_active() && !node->is_on_boundaries()) + pnt_exists = true; + + // extract point (curve_end) from trapezoid + const Curve_end vtx_ce(node->is_active()? + node->left()->curve_end() : node->curve_end_for_rem_vtx()); + Point vtx_p; + if (pnt_exists) + vtx_p = node->point_for_inner_rem_vtx(); + + + //check if not smaller than min + if (!minus_inf) + { + // extract point (curve_end) from trapezoid + const Curve_end min_ce(min_node->is_active()? + min_node->left()->curve_end() : min_node->curve_end_for_rem_vtx()); + + //if smaller than the point represented by min_node + if ((!pnt_exists && is_end_point_left_low(vtx_ce, min_ce)) || + (pnt_exists && is_end_point_left_low(vtx_p, min_ce)) ) + return 0; + } + + //check if not larger than max + if (!plus_inf) + { + // extract point (curve_end) from trapezoid + const Curve_end max_ce(max_node->is_active()? + max_node->left()->curve_end() : max_node->curve_end_for_rem_vtx()); + + //if larger than the point represented by max_node + if ((!pnt_exists && is_end_point_right_top(vtx_ce, max_ce)) || + (pnt_exists && is_end_point_right_top(vtx_p, max_ce)) ) + return 0; + } + + //o/w continue with updated parameters + return (1 + std::max( + longest_query_path_length_rec(minus_inf, min_node, + false, node, + node.left_child()) , + longest_query_path_length_rec(false, node, + plus_inf, max_node, + node.right_child()) )); +} + + } //namespace CGAL diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_trapezoid_ric_point_location.h b/Arrangement_on_surface_2/include/CGAL/Arr_trapezoid_ric_point_location.h index 1d5df59c445..d3e9f73f962 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_trapezoid_ric_point_location.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_trapezoid_ric_point_location.h @@ -167,7 +167,17 @@ public: //if (td_traits) // delete (td_traits); } - + + unsigned long longest_dag_path() + { + return td.largest_leaf_depth() + 1; + } + + unsigned long longest_query_path_length() + { + return td.longest_query_path_length(); + } + /*! * Locate the arrangement feature containing the given point. * \param p The query point. @@ -348,8 +358,6 @@ protected: } td.insert(he_container.begin(), he_container.end()); - - std::cout << "Longest path length is " << td.largest_leaf_depth() << std::endl; } /*! gets the unbounded face that contains the point when the trapezoid is unbounded