DAS  3.0
Das Analysis System
ClosestPair2D
+ Inheritance diagram for ClosestPair2D:
+ Collaboration diagram for ClosestPair2D:

Classes

class  Point
 
class  Shuffle
 
class  triplet
 

Public Member Functions

 ClosestPair2D (const std::vector< Coord2D > &positions, const Coord2D &left_corner, const Coord2D &right_corner)
 
 ClosestPair2D (const std::vector< Coord2D > &positions, const Coord2D &left_corner, const Coord2D &right_corner, const unsigned int max_size)
 
void closest_pair (unsigned int &ID1, unsigned int &ID2, double &distance2) const
 
void remove (unsigned int ID)
 
unsigned int insert (const Coord2D &)
 
virtual unsigned int replace (unsigned int ID1, unsigned int ID2, const Coord2D &position)
 
virtual void replace_many (const std::vector< unsigned int > &IDs_to_remove, const std::vector< Coord2D > &new_positions, std::vector< unsigned int > &new_IDs)
 
void print_tree_depths (std::ostream &outdev) const
 
unsigned int size ()
 
- Public Member Functions inherited from ClosestPair2DBase
virtual ~ClosestPair2DBase ()
 

Private Types

typedef SearchTree< ShuffleTree
 
typedef Tree::circulator circulator
 
typedef Tree::const_circulator const_circulator
 

Private Member Functions

void _initialize (const std::vector< Coord2D > &positions, const Coord2D &left_corner, const Coord2D &right_corner, const unsigned int max_size)
 
void _add_label (Point *point, unsigned int review_flag)
 
void _set_label (Point *point, unsigned int review_flag)
 
void _deal_with_points_to_review ()
 
void _remove_from_search_tree (Point *point_to_remove)
 
void _insert_into_search_tree (Point *new_point)
 
void _point2shuffle (Point &, Shuffle &, unsigned int shift)
 
int _ID (const Point *) const
 

Private Attributes

triplet< SharedPtr< Tree > > _trees
 
SharedPtr< MinHeap_heap
 
std::vector< Point_points
 
std::stack< Point * > _available_points
 
std::vector< Point * > _points_under_review
 
Coord2D _left_corner
 
double _range
 
triplet< unsigned int > _shifts
 
triplet< unsigned int > _rel_shifts
 
unsigned int _cp_search_range
 

Static Private Attributes

static const unsigned int _nshift = 3
 
static const unsigned int _remove_heap_entry = 1
 
static const unsigned int _review_heap_entry = 2
 
static const unsigned int _review_neighbour = 4
 

Member Typedef Documentation

◆ circulator

typedef Tree::circulator circulator
private

◆ const_circulator

◆ Tree

typedef SearchTree<Shuffle> Tree
private

Constructor & Destructor Documentation

◆ ClosestPair2D() [1/2]

ClosestPair2D ( const std::vector< Coord2D > &  positions,
const Coord2D left_corner,
const Coord2D right_corner 
)
inline
735  {
736  _initialize(positions, left_corner, right_corner, positions.size());
737  };

◆ ClosestPair2D() [2/2]

ClosestPair2D ( const std::vector< Coord2D > &  positions,
const Coord2D left_corner,
const Coord2D right_corner,
const unsigned int  max_size 
)
inline
740  {
741  _initialize(positions, left_corner, right_corner, max_size);
742  };

Member Function Documentation

◆ _add_label()

void _add_label ( Point point,
unsigned int  review_flag 
)
inlineprivate
1252  {
1253  if (point->review_flag == 0) _points_under_review.push_back(point);
1254  point->review_flag |= review_flag;
1255 }

◆ _deal_with_points_to_review()

void _deal_with_points_to_review ( )
private
1297  {
1298  unsigned int CP_range = min(_cp_search_range, size()-1);
1299  while(_points_under_review.size() > 0) {
1300  Point * this_point = _points_under_review.back();
1301  _points_under_review.pop_back();
1302  if (this_point->review_flag & _remove_heap_entry) {
1303  assert(!(this_point->review_flag ^ _remove_heap_entry));
1304  _heap->remove(_ID(this_point));
1305  }
1306  else {
1307  if (this_point->review_flag & _review_neighbour) {
1308  this_point->neighbour_dist2 = numeric_limits<double>::max();
1309  // among all three shifts
1310  for (unsigned int ishift = 0; ishift < _nshift; ishift++) {
1311  circulator other = this_point->circ[ishift];
1312  // among points within CP_range
1313  for (unsigned i=0; i < CP_range; i++) {
1314  ++other;
1315  double dist2 = this_point->distance2(*other->point);
1316  if (dist2 < this_point->neighbour_dist2) {
1317  this_point->neighbour_dist2 = dist2;
1318  this_point->neighbour = other->point;
1319  }
1320  }
1321  }
1322  }
1323  _heap->update(_ID(this_point), this_point->neighbour_dist2);
1324  }
1325  this_point->review_flag = 0;
1326  }
1327 }

◆ _ID()

int _ID ( const Point point) const
inlineprivate
817  {
818  return point - &(_points[0]);
819 }

◆ _initialize()

void _initialize ( const std::vector< Coord2D > &  positions,
const Coord2D left_corner,
const Coord2D right_corner,
const unsigned int  max_size 
)
private
1192  {
1193  unsigned int n_positions = positions.size();
1194  assert(max_size >= n_positions);
1195  _points.resize(max_size);
1196  for (unsigned int i = n_positions; i < max_size; i++) {
1197  _available_points.push(&(_points[i]));
1198  }
1199  _left_corner = left_corner;
1200  _range = max((right_corner.x - left_corner.x),
1201  (right_corner.y - left_corner.y));
1202  vector<Shuffle> shuffles(n_positions);
1203  for (unsigned int i = 0; i < n_positions; i++) {
1204  _points[i].coord = positions[i];
1205  _points[i].neighbour_dist2 = numeric_limits<double>::max();
1206  _points[i].review_flag = 0;
1207  _point2shuffle(_points[i], shuffles[i], 0);
1208  }
1209  for (unsigned ishift = 0; ishift < _nshift; ishift++) {
1210  _shifts[ishift] = static_cast<unsigned int>(((twopow31*1.0)*ishift)/_nshift);
1211  if (ishift == 0) {_rel_shifts[ishift] = 0;}
1212  else {_rel_shifts[ishift] = _shifts[ishift] - _shifts[ishift-1];}
1213  }
1214  _cp_search_range = 30;
1216  for (unsigned int ishift = 0; ishift < _nshift; ishift++) {
1217  if (ishift > 0) {
1218  unsigned rel_shift = _rel_shifts[ishift];
1219  for (unsigned int i = 0; i < shuffles.size(); i++) {
1220  shuffles[i] += rel_shift; }
1221  }
1222  sort(shuffles.begin(), shuffles.end());
1223  _trees[ishift] = SharedPtr<Tree>(new Tree(shuffles, max_size));
1224  circulator circ = _trees[ishift]->somewhere(), start=circ;
1225  unsigned int CP_range = min(_cp_search_range, n_positions-1);
1226  do {
1227  Point * this_point = circ->point;
1228  this_point->circ[ishift] = circ;
1229  circulator other = circ;
1230  for (unsigned i=0; i < CP_range; i++) {
1231  ++other;
1232  double dist2 = this_point->distance2(*other->point);
1233  if (dist2 < this_point->neighbour_dist2) {
1234  this_point->neighbour_dist2 = dist2;
1235  this_point->neighbour = other->point;
1236  }
1237  }
1238  } while (++circ != start);
1239  }
1240  vector<double> mindists2(n_positions);
1241  for (unsigned int i = 0; i < n_positions; i++) {
1242  mindists2[i] = _points[i].neighbour_dist2;}
1243  _heap = SharedPtr<MinHeap>(new MinHeap(mindists2, max_size));
1244 }

◆ _insert_into_search_tree()

void _insert_into_search_tree ( Point new_point)
private
1367  {
1368  _set_label(new_point, _review_heap_entry);
1369  new_point->neighbour_dist2 = numeric_limits<double>::max();
1370  unsigned int CP_range = min(_cp_search_range, size()-1);
1371  for (unsigned ishift = 0; ishift < _nshift; ishift++) {
1372  Shuffle new_shuffle;
1373  _point2shuffle(*new_point, new_shuffle, _shifts[ishift]);
1374  circulator new_circ = _trees[ishift]->insert(new_shuffle);
1375  new_point->circ[ishift] = new_circ;
1376  circulator right_edge = new_circ; right_edge++;
1377  circulator left_edge = new_circ;
1378  for (unsigned int i = 0; i < CP_range; i++) {left_edge--;}
1379  do {
1380  Point * left_point = left_edge->point;
1381  Point * right_point = right_edge->point;
1382  double new_dist2 = left_point->distance2(*new_point);
1383  if (new_dist2 < left_point->neighbour_dist2) {
1384  left_point->neighbour_dist2 = new_dist2;
1385  left_point->neighbour = new_point;
1386  _add_label(left_point, _review_heap_entry);
1387  }
1388  new_dist2 = new_point->distance2(*right_point);
1389  if (new_dist2 < new_point->neighbour_dist2) {
1390  new_point->neighbour_dist2 = new_dist2;
1391  new_point->neighbour = right_point;
1392  }
1393  if (left_point->neighbour == right_point) {
1394  _add_label(left_point, _review_neighbour);
1395  }
1396  right_edge++;
1397  } while (++left_edge != new_circ);
1398  }
1399 }

◆ _point2shuffle()

void _point2shuffle ( Point point,
Shuffle shuffle,
unsigned int  shift 
)
private
1172  {
1173  Coord2D renorm_point = (point.coord - _left_corner)/_range;
1174  assert(renorm_point.x >=0);
1175  assert(renorm_point.x <=1);
1176  assert(renorm_point.y >=0);
1177  assert(renorm_point.y <=1);
1178  shuffle.x = static_cast<unsigned int>(twopow31 * renorm_point.x) + shift;
1179  shuffle.y = static_cast<unsigned int>(twopow31 * renorm_point.y) + shift;
1180  shuffle.point = &point;
1181 }

◆ _remove_from_search_tree()

void _remove_from_search_tree ( Point point_to_remove)
private
1265  {
1266  _available_points.push(point_to_remove);
1267  _set_label(point_to_remove, _remove_heap_entry);
1268  unsigned int CP_range = min(_cp_search_range, size()-1);
1269  for (unsigned int ishift = 0; ishift < _nshift; ishift++) {
1270  circulator removed_circ = point_to_remove->circ[ishift];
1271  circulator right_end = removed_circ.next();
1272  _trees[ishift]->remove(removed_circ);
1273  circulator left_end = right_end, orig_right_end = right_end;
1274  for (unsigned int i = 0; i < CP_range; i++) {left_end--;}
1275  if (size()-1 < _cp_search_range) {
1276  left_end--; right_end--;
1277  }
1278  do {
1279  Point * left_point = left_end->point;
1280  if (left_point->neighbour == point_to_remove) {
1281  // we'll deal with it later...
1282  _add_label(left_point, _review_neighbour);
1283  } else {
1284  // check to see if right point has become its closest neighbour
1285  double dist2 = left_point->distance2(*right_end->point);
1286  if (dist2 < left_point->neighbour_dist2) {
1287  left_point->neighbour = right_end->point;
1288  left_point->neighbour_dist2 = dist2;
1289  // NB: (LESSER) REVIEW NEEDED HERE TOO...
1290  _add_label(left_point, _review_heap_entry);
1291  }
1292  }
1293  ++right_end;
1294  } while (++left_end != orig_right_end);
1295  } // ishift...
1296 }

◆ _set_label()

void _set_label ( Point point,
unsigned int  review_flag 
)
inlineprivate
1256  {
1257  if (point->review_flag == 0) _points_under_review.push_back(point);
1258  point->review_flag = review_flag;
1259 }

◆ closest_pair()

void closest_pair ( unsigned int &  ID1,
unsigned int &  ID2,
double &  distance2 
) const
virtual

Implements ClosestPair2DBase.

1246  {
1247  ID1 = _heap->minloc();
1248  ID2 = _ID(_points[ID1].neighbour);
1249  distance2 = _points[ID1].neighbour_dist2;
1250  if (ID1 > ID2) std::swap(ID1,ID2);
1251 }

◆ insert()

unsigned int insert ( const Coord2D new_coord)
virtual

Implements ClosestPair2DBase.

1328  {
1329  assert(_available_points.size() > 0);
1330  Point * new_point = _available_points.top();
1331  _available_points.pop();
1332  new_point->coord = new_coord;
1333  _insert_into_search_tree(new_point);
1335  return _ID(new_point);
1336 }

◆ print_tree_depths()

void print_tree_depths ( std::ostream &  outdev) const
inline
752  {
753  outdev << _trees[0]->max_depth() << " "
754  << _trees[1]->max_depth() << " "
755  << _trees[2]->max_depth() << "\n";
756  };

◆ remove()

void remove ( unsigned int  ID)
virtual

Implements ClosestPair2DBase.

1260  {
1261  Point * point_to_remove = & (_points[ID]);
1262  _remove_from_search_tree(point_to_remove);
1264 }

◆ replace()

unsigned int replace ( unsigned int  ID1,
unsigned int  ID2,
const Coord2D position 
)
virtual

Reimplemented from ClosestPair2DBase.

1338  {
1339  Point * point_to_remove = & (_points[ID1]);
1340  _remove_from_search_tree(point_to_remove);
1341  point_to_remove = & (_points[ID2]);
1342  _remove_from_search_tree(point_to_remove);
1343  Point * new_point = _available_points.top();
1344  _available_points.pop();
1345  new_point->coord = position;
1346  _insert_into_search_tree(new_point);
1348  return _ID(new_point);
1349 }

◆ replace_many()

void replace_many ( const std::vector< unsigned int > &  IDs_to_remove,
const std::vector< Coord2D > &  new_positions,
std::vector< unsigned int > &  new_IDs 
)
virtual

Reimplemented from ClosestPair2DBase.

1353  {
1354  for (unsigned int i = 0; i < IDs_to_remove.size(); i++) {
1355  _remove_from_search_tree(& (_points[IDs_to_remove[i]]));
1356  }
1357  new_IDs.resize(0);
1358  for (unsigned int i = 0; i < new_positions.size(); i++) {
1359  Point * new_point = _available_points.top();
1360  _available_points.pop();
1361  new_point->coord = new_positions[i];
1362  _insert_into_search_tree(new_point);
1363  new_IDs.push_back(_ID(new_point));
1364  }
1366 }

◆ size()

unsigned int size ( )
inlinevirtual

Implements ClosestPair2DBase.

820  {
821  return _points.size() - _available_points.size();
822 }

Member Data Documentation

◆ _available_points

std::stack<Point *> _available_points
private

◆ _cp_search_range

unsigned int _cp_search_range
private

◆ _heap

SharedPtr<MinHeap> _heap
private

◆ _left_corner

Coord2D _left_corner
private

◆ _nshift

const unsigned int _nshift = 3
staticprivate

◆ _points

std::vector<Point> _points
private

◆ _points_under_review

std::vector<Point *> _points_under_review
private

◆ _range

double _range
private

◆ _rel_shifts

triplet<unsigned int> _rel_shifts
private

◆ _remove_heap_entry

const unsigned int _remove_heap_entry = 1
staticprivate

◆ _review_heap_entry

const unsigned int _review_heap_entry = 2
staticprivate

◆ _review_neighbour

const unsigned int _review_neighbour = 4
staticprivate

◆ _shifts

triplet<unsigned int> _shifts
private

◆ _trees

triplet<SharedPtr<Tree> > _trees
private

The documentation for this class was generated from the following file:
SharedPtr
Definition: fjcore.hh:294
ClosestPair2D::_set_label
void _set_label(Point *point, unsigned int review_flag)
Definition: fjcore.cc:1256
MinHeap::update
void update(unsigned int, double)
Definition: fjcore.cc:3708
ClosestPair2D::_range
double _range
Definition: fjcore.cc:796
MinHeap::remove
void remove(unsigned int loc)
Definition: fjcore.cc:659
ClosestPair2D::_point2shuffle
void _point2shuffle(Point &, Shuffle &, unsigned int shift)
Definition: fjcore.cc:1171
MinHeap
Definition: fjcore.cc:647
ClosestPair2D::_shifts
triplet< unsigned int > _shifts
Definition: fjcore.cc:798
ClosestPair2D::_initialize
void _initialize(const std::vector< Coord2D > &positions, const Coord2D &left_corner, const Coord2D &right_corner, const unsigned int max_size)
Definition: fjcore.cc:1189
ClosestPair2D::_left_corner
Coord2D _left_corner
Definition: fjcore.cc:795
Coord2D::x
double x
Definition: fjcore.cc:677
ClosestPair2D::_add_label
void _add_label(Point *point, unsigned int review_flag)
Definition: fjcore.cc:1252
ClosestPair2D::_remove_from_search_tree
void _remove_from_search_tree(Point *point_to_remove)
Definition: fjcore.cc:1265
ClosestPair2D::_ID
int _ID(const Point *) const
Definition: fjcore.cc:817
ClosestPair2D::Tree
SearchTree< Shuffle > Tree
Definition: fjcore.cc:778
ClosestPair2D::_insert_into_search_tree
void _insert_into_search_tree(Point *new_point)
Definition: fjcore.cc:1367
ClosestPair2D::_trees
triplet< SharedPtr< Tree > > _trees
Definition: fjcore.cc:781
Coord2D
Definition: fjcore.cc:675
ClosestPair2D::_heap
SharedPtr< MinHeap > _heap
Definition: fjcore.cc:782
twopow31
FJCORE_END_NAMESPACE FJCORE_BEGIN_NAMESPACE const unsigned int twopow31
Definition: fjcore.cc:1169
SearchTree::circulator::next
circulator next() const
Definition: fjcore.cc:318
swap
void swap(SharedPtr< T > &a, SharedPtr< T > &b)
Definition: fjcore.hh:412
ClosestPair2D::size
unsigned int size()
Definition: fjcore.cc:820
ClosestPair2D::_review_heap_entry
static const unsigned int _review_heap_entry
Definition: fjcore.cc:787
ClosestPair2D::_nshift
static const unsigned int _nshift
Definition: fjcore.cc:762
ClosestPair2D::_available_points
std::stack< Point * > _available_points
Definition: fjcore.cc:784
MinHeap::minloc
unsigned int minloc() const
Definition: fjcore.cc:655
ClosestPair2D::_points_under_review
std::vector< Point * > _points_under_review
Definition: fjcore.cc:785
ClosestPair2D::_rel_shifts
triplet< unsigned int > _rel_shifts
Definition: fjcore.cc:799
ClosestPair2D::_review_neighbour
static const unsigned int _review_neighbour
Definition: fjcore.cc:788
ClosestPair2D::_points
std::vector< Point > _points
Definition: fjcore.cc:783
ClosestPair2D::_remove_heap_entry
static const unsigned int _remove_heap_entry
Definition: fjcore.cc:786
ClosestPair2D::circulator
Tree::circulator circulator
Definition: fjcore.cc:779
ClosestPair2D::_cp_search_range
unsigned int _cp_search_range
Definition: fjcore.cc:800
Coord2D::y
double y
Definition: fjcore.cc:677
ClosestPair2D::_deal_with_points_to_review
void _deal_with_points_to_review()
Definition: fjcore.cc:1297