Added boost header
This commit is contained in:
418
test/external/boost/graph/detail/self_avoiding_walk.hpp
vendored
Normal file
418
test/external/boost/graph/detail/self_avoiding_walk.hpp
vendored
Normal file
@@ -0,0 +1,418 @@
|
||||
//=======================================================================
|
||||
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
||||
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
||||
//
|
||||
// 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)
|
||||
//=======================================================================
|
||||
#ifndef BOOST_SELF_AVOIDING_WALK_HPP
|
||||
#define BOOST_SELF_AVOIDING_WALK_HPP
|
||||
|
||||
/*
|
||||
This file defines necessary components for SAW.
|
||||
|
||||
mesh language: (defined by myself to clearify what is what)
|
||||
A triangle in mesh is called an triangle.
|
||||
An edge in mesh is called an line.
|
||||
A vertex in mesh is called a point.
|
||||
|
||||
A triangular mesh corresponds to a graph in which a vertex is a
|
||||
triangle and an edge(u, v) stands for triangle u and triangle v
|
||||
share an line.
|
||||
|
||||
After this point, a vertex always refers to vertex in graph,
|
||||
therefore it is a traingle in mesh.
|
||||
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
|
||||
#define SAW_SENTINAL -1
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class T1, class T2, class T3>
|
||||
struct triple {
|
||||
T1 first;
|
||||
T2 second;
|
||||
T3 third;
|
||||
triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
|
||||
triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
|
||||
};
|
||||
|
||||
typedef triple<int, int, int> Triple;
|
||||
|
||||
/* Define a vertex property which has a triangle inside. Triangle is
|
||||
represented by a triple. */
|
||||
struct triangle_tag { enum { num = 100 }; };
|
||||
typedef property<triangle_tag,Triple> triangle_property;
|
||||
|
||||
/* Define an edge property with a line. A line is represented by a
|
||||
pair. This is not required for SAW though.
|
||||
*/
|
||||
struct line_tag { enum { num = 101 }; };
|
||||
template <class T> struct line_property
|
||||
: public property<line_tag, std::pair<T,T> > { };
|
||||
|
||||
/*Precondition: Points in a Triangle are in order */
|
||||
template <class Triangle, class Line>
|
||||
inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
|
||||
{
|
||||
l.first = SAW_SENTINAL;
|
||||
l.second = SAW_SENTINAL;
|
||||
|
||||
if ( a.first == b.first ) {
|
||||
l.first = a.first;
|
||||
if ( a.second == b.second || a.second == b.third )
|
||||
l.second = a.second;
|
||||
else if ( a.third == b.second || a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.first == b.second ) {
|
||||
l.first = a.first;
|
||||
if ( a.second == b.third )
|
||||
l.second = a.second;
|
||||
else if ( a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.first == b.third ) {
|
||||
l.first = a.first;
|
||||
|
||||
|
||||
} else if ( a.second == b.first ) {
|
||||
l.first = a.second;
|
||||
if ( a.third == b.second || a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.second == b.second ) {
|
||||
l.first = a.second;
|
||||
if ( a.third == b.third )
|
||||
l.second = a.third;
|
||||
|
||||
} else if ( a.second == b.third ) {
|
||||
l.first = a.second;
|
||||
|
||||
|
||||
} else if ( a.third == b.first
|
||||
|| a.third == b.second
|
||||
|| a.third == b.third )
|
||||
l.first = a.third;
|
||||
|
||||
/*Make it in order*/
|
||||
if ( l.first > l.second ) {
|
||||
typename Line::first_type i = l.first;
|
||||
l.first = l.second;
|
||||
l.second = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class TriangleDecorator, class Vertex, class Line>
|
||||
struct get_vertex_sharing {
|
||||
typedef std::pair<Vertex, Line> Pair;
|
||||
get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
|
||||
inline Line operator()(const Vertex& u, const Vertex& v) const {
|
||||
Line l;
|
||||
get_sharing(td[u], td[v], l);
|
||||
return l;
|
||||
}
|
||||
inline Line operator()(const Pair& u, const Vertex& v) const {
|
||||
Line l;
|
||||
get_sharing(td[u.first], td[v], l);
|
||||
return l;
|
||||
}
|
||||
inline Line operator()(const Pair& u, const Pair& v) const {
|
||||
Line l;
|
||||
get_sharing(td[u.first], td[v.first], l);
|
||||
return l;
|
||||
}
|
||||
TriangleDecorator td;
|
||||
};
|
||||
|
||||
/* HList has to be a handle of data holder so that pass-by-value is
|
||||
* in right logic.
|
||||
*
|
||||
* The element of HList is a pair of vertex and line. (remember a
|
||||
* line is a pair of two ints.). That indicates the walk w from
|
||||
* current vertex is across line. (If the first of line is -1, it is
|
||||
* a point though.
|
||||
*/
|
||||
template < class TriangleDecorator, class HList, class IteratorD>
|
||||
class SAW_visitor
|
||||
: public bfs_visitor<>, public dfs_visitor<>
|
||||
{
|
||||
typedef typename boost::property_traits<IteratorD>::value_type iter;
|
||||
/*use boost shared_ptr*/
|
||||
typedef typename HList::element_type::value_type::second_type Line;
|
||||
public:
|
||||
|
||||
typedef tree_edge_tag category;
|
||||
|
||||
inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
|
||||
: td(_td), hlist(_hlist), iter_d(ia) {}
|
||||
|
||||
template <class Vertex, class Graph>
|
||||
inline void start_vertex(Vertex v, Graph&) {
|
||||
Line l1;
|
||||
l1.first = SAW_SENTINAL;
|
||||
l1.second = SAW_SENTINAL;
|
||||
hlist->push_front(std::make_pair(v, l1));
|
||||
iter_d[v] = hlist->begin();
|
||||
}
|
||||
|
||||
/*Several symbols:
|
||||
w(i): i-th triangle in walk w
|
||||
w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
|
||||
w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
|
||||
w(i) -> w(i+1): w enter w(i+1) from w(i)
|
||||
w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
|
||||
*/
|
||||
template <class Edge, class Graph>
|
||||
bool tree_edge(Edge e, Graph& G) {
|
||||
using std::make_pair;
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
|
||||
Vertex tau = target(e, G);
|
||||
Vertex i = source(e, G);
|
||||
|
||||
get_vertex_sharing<TriangleDecorator, Vertex, Line> get_sharing_line(td);
|
||||
|
||||
Line tau_i = get_sharing_line(tau, i);
|
||||
|
||||
iter w_end = hlist->end();
|
||||
|
||||
iter w_i = iter_d[i];
|
||||
|
||||
iter w_i_m_1 = w_i;
|
||||
iter w_i_p_1 = w_i;
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* true false
|
||||
*==========================================================
|
||||
*a w(i-1) |- w(i) w(i-1) ~> w(i) or w(i-1) is null
|
||||
*----------------------------------------------------------
|
||||
*b w(i) |- w(i+1) w(i) ~> w(i+1) or no w(i+1) yet
|
||||
*----------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool a = false, b = false;
|
||||
|
||||
--w_i_m_1;
|
||||
++w_i_p_1;
|
||||
b = ( w_i->second.first != SAW_SENTINAL );
|
||||
|
||||
if ( w_i_m_1 != w_end ) {
|
||||
a = ( w_i_m_1->second.first != SAW_SENTINAL );
|
||||
}
|
||||
|
||||
if ( a ) {
|
||||
|
||||
if ( b ) {
|
||||
/*Case 1:
|
||||
|
||||
w(i-1) |- w(i) |- w(i+1)
|
||||
*/
|
||||
Line l1 = get_sharing_line(*w_i_m_1, tau);
|
||||
|
||||
iter w_i_m_2 = w_i_m_1;
|
||||
--w_i_m_2;
|
||||
|
||||
bool c = true;
|
||||
|
||||
if ( w_i_m_2 != w_end ) {
|
||||
c = w_i_m_2->second != l1;
|
||||
}
|
||||
|
||||
if ( c ) { /* w(i-1) ^ tau != w(i-2) ^ w(i-1) */
|
||||
/*extension: w(i-1) -> tau |- w(i) */
|
||||
w_i_m_1->second = l1;
|
||||
/*insert(pos, const T&) is to insert before pos*/
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
|
||||
} else { /* w(i-1) ^ tau == w(i-2) ^ w(i-1) */
|
||||
/*must be w(i-2) ~> w(i-1) */
|
||||
|
||||
bool d = true;
|
||||
//need to handle the case when w_i_p_1 is null
|
||||
Line l3 = get_sharing_line(*w_i_p_1, tau);
|
||||
if ( w_i_p_1 != w_end )
|
||||
d = w_i_p_1->second != l3;
|
||||
if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3));
|
||||
} else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
|
||||
/*must be w(1+1) ~> w(i+2) */
|
||||
Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
|
||||
if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
|
||||
/*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */
|
||||
w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
w_i->second = w_i_m_1->second;
|
||||
w_i_m_1->second = l5;
|
||||
iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
|
||||
hlist->erase(w_i_m_1);
|
||||
} else {
|
||||
/*mesh is tetrahedral*/
|
||||
// dont know what that means.
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
/*Case 2:
|
||||
|
||||
w(i-1) |- w(i) ~> w(1+1)
|
||||
*/
|
||||
|
||||
if ( w_i->second.second == tau_i.first
|
||||
|| w_i->second.second == tau_i.second ) { /*w(i) ^ w(i+1) < w(i) ^ tau*/
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
Line l1 = get_sharing_line(*w_i_p_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
||||
} else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
|
||||
Line l1 = get_sharing_line(*w_i_m_1, tau);
|
||||
bool c = true;
|
||||
iter w_i_m_2 = w_i_m_1;
|
||||
--w_i_m_2;
|
||||
if ( w_i_m_2 != w_end )
|
||||
c = l1 != w_i_m_2->second;
|
||||
if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
|
||||
/*extension: w(i-1) -> tau |- w(i)*/
|
||||
w_i_m_1->second = l1;
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
} else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
|
||||
/*must be w(i-2)~>w(i-1)*/
|
||||
/*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
|
||||
w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
w_i->second = w_i_m_1->second;
|
||||
w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
|
||||
iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
|
||||
hlist->erase(w_i_m_1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( b ) {
|
||||
/*Case 3:
|
||||
|
||||
w(i-1) ~> w(i) |- w(i+1)
|
||||
*/
|
||||
bool c = false;
|
||||
if ( w_i_m_1 != w_end )
|
||||
c = ( w_i_m_1->second.second == tau_i.first)
|
||||
|| ( w_i_m_1->second.second == tau_i.second);
|
||||
|
||||
if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau*/
|
||||
/* extension: w(i-1) -> tau |- w(i) */
|
||||
if ( w_i_m_1 != w_end )
|
||||
w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
} else {
|
||||
bool d = true;
|
||||
Line l1;
|
||||
l1.first = SAW_SENTINAL;
|
||||
l1.second = SAW_SENTINAL;
|
||||
if ( w_i_p_1 != w_end ) {
|
||||
l1 = get_sharing_line(*w_i_p_1, tau);
|
||||
d = l1 != w_i_p_1->second;
|
||||
}
|
||||
if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
||||
} else {
|
||||
/*must be w(i+1) ~> w(i+2)*/
|
||||
/*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */
|
||||
iter w_i_p_2 = w_i_p_1;
|
||||
++w_i_p_2;
|
||||
|
||||
w_i_p_1->second = w_i->second;
|
||||
iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
|
||||
hlist->erase(w_i);
|
||||
Line l2 = get_sharing_line(*w_i_p_2, tau);
|
||||
iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/*Case 4:
|
||||
|
||||
w(i-1) ~> w(i) ~> w(i+1)
|
||||
|
||||
*/
|
||||
bool c = false;
|
||||
if ( w_i_m_1 != w_end ) {
|
||||
c = (w_i_m_1->second.second == tau_i.first)
|
||||
|| (w_i_m_1->second.second == tau_i.second);
|
||||
}
|
||||
if ( c ) { /*w(i-1) ^ w(i) < w(i) ^ tau */
|
||||
/*extension: w(i-1) -> tau |- w(i) */
|
||||
if ( w_i_m_1 != w_end )
|
||||
w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
|
||||
} else {
|
||||
/*extension: w(i) |- tau -> w(i+1) */
|
||||
w_i->second = tau_i;
|
||||
Line l1;
|
||||
l1.first = SAW_SENTINAL;
|
||||
l1.second = SAW_SENTINAL;
|
||||
if ( w_i_p_1 != w_end )
|
||||
l1 = get_sharing_line(*w_i_p_1, tau);
|
||||
iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
TriangleDecorator td; /*a decorator for vertex*/
|
||||
HList hlist;
|
||||
/*This must be a handle of list to record the SAW
|
||||
The element type of the list is pair<Vertex, Line>
|
||||
*/
|
||||
|
||||
IteratorD iter_d;
|
||||
/*Problem statement: Need a fast access to w for triangle i.
|
||||
*Possible solution: mantain an array to record.
|
||||
iter_d[i] will return an iterator
|
||||
which points to w(i), where i is a vertex
|
||||
representing triangle i.
|
||||
*/
|
||||
};
|
||||
|
||||
template <class Triangle, class HList, class Iterator>
|
||||
inline
|
||||
SAW_visitor<Triangle, HList, Iterator>
|
||||
visit_SAW(Triangle t, HList hl, Iterator i) {
|
||||
return SAW_visitor<Triangle, HList, Iterator>(t, hl, i);
|
||||
}
|
||||
|
||||
template <class Tri, class HList, class Iter>
|
||||
inline
|
||||
SAW_visitor< random_access_iterator_property_map<Tri*,Tri,Tri&>,
|
||||
HList, random_access_iterator_property_map<Iter*,Iter,Iter&> >
|
||||
visit_SAW_ptr(Tri* t, HList hl, Iter* i) {
|
||||
typedef random_access_iterator_property_map<Tri*,Tri,Tri&> TriD;
|
||||
typedef random_access_iterator_property_map<Iter*,Iter,Iter&> IterD;
|
||||
return SAW_visitor<TriD, HList, IterD>(t, hl, i);
|
||||
}
|
||||
|
||||
// should also have combo's of pointers, and also const :(
|
||||
|
||||
}
|
||||
|
||||
#endif /*BOOST_SAW_H*/
|
||||
Reference in New Issue
Block a user