📄 kdtree.w,v
字号:
Revision 1.158 1998/02/13 21:16:55 netoMade prototypes and function declarations match w.r.t. const.,Revision 1.157 1997/10/25 21:44:06 netoFinished coding quadrant stuff (I think). Must compile and test.Revision 1.156 1997/10/25 19:49:11 netoCompact the code.Revision 1.155 1997/10/18 15:23:37 netoI had missed a swapint conversion. Now it compiles.Revision 1.154 1997/10/18 14:40:25 netoAdded E2 supports()Revision 1.153 1997/10/18 14:31:05 netoMade all floats into doubles.Checked for CEIL 2D compliance, and added comments in key places.Minor editing.Revision 1.152 1997/10/17 21:48:51 netoRemoved CUTDIMEN and THISDIMEN kludge by recasting the coord 2d structureas an array instead of two named fields.Revision 1.151 1997/10/17 20:47:35 netoMove short fields to end of E2 node struct.Revision 1.150 1997/09/27 18:06:44 netoFixed RCS log behaviour.Revision 1.149 1997/08/15 20:18:25 netoAdded Index major section.Revision 1.148 1997/05/16 18:11:41 netoBreak locks by david and neto.Include <config.h> and "lkconfig.h"Revision 1.147 1997/01/21 21:55:55 davidAdded standard copyright notice by including copyrt.wRevision 1.146 1997/01/21 17:42:14 davidMake showing of partitioning optional.Revision 1.145 1997/01/17 21:15:44 netoFixed a printing leak.Revision 1.144 96/12/13 15:08:17 netoMention hypotRevision 1.143 96/12/02 15:26:06 netoAdded copyright notice.Revision 1.142 96/11/11 16:36:44 netofixed a spelling mistake.Revision 1.141 96/09/03 15:14:03 netoMacro for ML programming language name.Revision 1.140 96/08/16 13:04:53 netoAdded fixincludes.Revision 1.139 96/08/16 12:42:26 netoConverted putchar to printf. Otherwise, I'd never get a prototypefor SunOS' \_flusbuf.Revision 1.138 96/08/15 14:20:27 netoFixed the prototype for E2\_rnnRevision 1.137 96/08/15 12:54:30 netoMake it pass -WallRevision 1.136 96/07/30 17:15:34 netoFixed editing bug with respect to recurse if not hidden in E2\_rnn.Revision 1.135 96/07/30 13:03:33 netoFixed to compile.Revision 1.134 96/07/30 12:59:52 netoAdded KD\_BUILD\_SMALLEST\_SEGMENT\_FIRSTRevision 1.133 96/07/29 17:08:56 netoFixed to compile.Revision 1.132 96/07/29 16:19:56 netoAdded *\_rcs\_id.Made sure RCS log is activated within this file.Revision 1.131 96/07/26 16:19:54 netoReport experiments with hidden bit.Revision 1.130 96/07/26 15:41:44 netoAdded KD\_NO\_HIDDEN\_RNN\_TESTRevision 1.129 96/07/26 13:44:55 netoAdded compile-time-option KD\_NO\_HIDDEN\_BITRevision 1.128 96/07/26 13:21:36 netoRecurse in rnn ony if not hidden.Revision 1.127 96/07/26 12:45:03 netoDon't be preachy about recursing on largest last.Revision 1.126 96/07/25 14:02:54 netoFixed some minor editing of english.Replaced INFINITY by a computed (floating point!) upper bound.Isolated debugging output and made it subject to verbose value andcompile-time choices.Revision 1.125 96/07/25 12:09:27 netoMore info to catch dsj1000 bug.Revision 1.124 96/07/24 15:57:27 netoRemoved 117 debugging output.Made bbox checkig optional.Revision 1.123 96/07/24 15:48:46 netoFixed the bbox bug. I wasn't updating the boboounding boxon the b and c elemnts that were swapped.Revision 1.122 96/07/24 13:51:38 netoMore debugging outupt for failure kcase on lin318Revision 1.121 1996/07/15 22:28:48 davidSimplified the code a bit.It fails on lin318.tspRevision 1.120 1996/07/15 21:18:21 davidBounding box every 1/kd\_bucket\_skip fraction, not 1-that fraction.Big bug removed: bounding box initialization during Dutch National Flagproblem is now fixed. (Had max's at infinity instead of effectivelynegative infinity.)Factored the nn search in a bucket. The general case now is freefrom checking that it doesn't return the seed. It should be faster.Added PostScript debugging output to draw the buckets.Revision 1.119 1996/07/15 18:33:24 davidFixed a name of a section.Fixed bucket search for nearer neighbour.Revision 1.118 1996/07/15 16:00:08 davidCompiles now. I had to add |f.i.| to many of the field names.I also had to add $E2\_nn\_dist$ back in for the bounding box test.Revision 1.117 1996/07/15 15:23:55 davidGive up on FRNN, ball searching for now.We don't need them for Greedy / MF heuristic.Revision 1.116 1996/07/05 21:02:33 davidContinued a bit on fixed radius nearest neighbours.Added more about stack overflow. Referenced Peyton Jones' ImplementingFunctional Languages.Revision 1.115 1996/07/05 20:34:02 davidI forgot to mention the move to using only squared distances innearest neighbour search.Revision 1.114 1996/07/05 20:31:31 davidChanged $E2\_tree$ to $E2\_root$.Implemented $unhide\_all$ and $hide\_all$.Got started on comments about fixed radius nearest neighbour.Revision 1.113 1996/07/05 17:13:32 davidAdded some index references to people.changed is\_internal to is\_bucket.Worked on nearest neighbours computation.Revision 1.112 1996/07/04 20:07:38 davidClarify comments in first part of the document.Make the recursive building more CWEB-like.Finished the hiding/unhiding part, but I haven't tried compiling it.Revision 1.111 96/06/28 14:00:54 netoAdded comments about persistence.Fixed too-long-line for cweave.Worked on hiding/unhidingAdded to nn.Revision 1.110 96/06/28 12:58:29 netoEnsure theat recursing won't break the stack.Start work on nearest neighbour query.Revision 1.109 96/06/26 12:15:42 netoMade coord a static variable.Revision 1.108 96/06/26 12:08:19 netoBe careful with macro parameters. Parenthesize them.Revision 1.107 96/06/26 12:05:44 netoThis file was added after I went to 100 and above.Revision 1.6 96/06/26 12:02:28 netoFixed my in-file log. (I edited, saved, and committed the revision,but didn't reload before the next commit...)Revision 1.5 96/06/26 11:38:41 netoRemoved some printing clutter.Revision 1.4 96/06/26 11:35:41 netoMost importantly, I fixed the construction bug. The code that wasmoving equal elements to the middle did not handle the left end properly.It was 0-based instead of being based at the real lower end: lo.I added comments about what to do with an empty bucket, and why.I added better paranoid checking diagnostics.Revision 1.3 96/06/25 17:10:15 netoAdded missing break.Fixed a swap. Duh.More precise output.Revision 1.2 96/06/25 16:41:37 netoFixed typo in med3 computation.Added better debugging output for paranoid.Fails paranoid check on lin105.tspRevision 1.1 96/06/24 17:16:26 netoInitial revision}@@s near void@@s far int@@*$k$-dimensional search structures.Many geometrical algorithms can be made to run faster in practice if weuse a $k$-dimensional search structure. Bentley (INSERT REFERENCE) has@@^Bentley, Jon Louis@@>shown this to be true of many algorithms related to the TSP. Bentley (INSERT REFERENCE) uses a $k$-d search tree over \term{semi-dynamic point sets}@@^semi-dynamic point sets@@>:these are sets of points where all the points are known in advance,and individual points may be hidden and unhidden from the queries. Bentley actually describes the hiding and unhiding as \term{deletion} and \term{undeletion}.But as the points still remain in the structure and may be recovered, Iprefer the concept of hiding; it seems a more accurate description ofwhat is going on. This is related in some ways to the notion ofpersistency.In general, we say a data structure is \term{(fully) persistent}@@^persistence, full@@>if we can completely recover the visible part of any of its old states; we say it is \term{partially persistent} if we may query any of its old states, but@@^persistence, partial@@>may update only its latest state. Persistency is a hot topic in data structures, and has led to some interestingand intuitive new algorithms (INSERT REFERENCE).@@^Tarjan, Robert Endre@@>@@^Sleator@@>This module implements $k$-d trees for semi-dynamic point sets.Actually, only one tree at a time is supported by this module. This is all I need (so far)in the TSP application. This scheme is also simpler to implement,and it saves a lot ofparameter passing time (or indirection time) as compared with fully object-oriented code. Besides, the code that Bentley describesfor his experiments in (INSERT REFERENCE) only supports one tree at a time.%Some of his parameters and maybe even conclusions might change if he%wrote fully object-oriented code.%%%% Is that true? Check C++ meaning for |static| storage class specifier%%%% for a class member.The outline of this module is as follows:@@c#include <config.h>#include "lkconfig.h"@@<System headers@@>@@;@@<Early module headers@@>@@;@@<Module headers@@>@@;@@<Early module type definitions@@>@@;@@<Module type definitions@@>@@;@@<Module variables@@>@@;@@<Global variables@@>@@;@@<Module subroutines@@>@@;@@<Subroutines@@>@@;const char *kdtree_rcs_id = "$Id: kdtree.w,v 1.164 1998/10/09 21:34:29 neto Exp neto $";@@ The exported interface is contained in the \file{kdtree.h} header file,which has the following form.@@(kdtree.h@@>=#if !defined(_KDTREE_H_)#define _KDTREE_H_extern const char *kdtree_rcs_id;@@<Exported type definitions@@>@@;@@<Exported variables@@>@@;@@<Exported macros@@>@@;@@<Exported subroutines@@>@@;#endif@@ To ensure consistency between the interface and the implementation,we include our own header.@@<Module headers@@>=#include "kdtree.h"@@*Interface. This section presents the interface to the $k$-d tree as specified byBentley. I have altered the names of the procedures to fit within mynaming scheme for modules. @@^Bentley, Jon Louis@@>Currently this module only supports 2-dimensional pointsets with the Euclidean metric.The names of the procedures all end with $E2$ to reflect this fact.The interface is as follows:|void E2_create(tsp_instance_t *tsp)| creates a tree based on the TSP instance |tsp|. The structure is definedin the \module{READ} module.|void E2_destroy()| destroys the search tree.|void E2_hide(int i)| hides point |i| from future queries (until thenext |unhide| operation).|void E2_unhide(int i)| makes point |i| visible to future queries (until thenext |hide| operation).|void E2_hide_all(void)| hides all points. |void E2_unhide_all(void)| hides all points.|int E2_nn(int i)| returns the index of an unhidden point that is nearestto point |i|, but is not |i| itself. If there is none, $-1$ is returned.|int E2_nn_quadrant(int i, int q)| returns the index of an unhidden point in relative quadrant $q$ that is nearestto point |i|, and is not |i| itself. If there is none, $-1$ is returned.For example, quadrant 1 relative to point |i| is the set of all pointsto the northeast of |i|.For efficiency reasons, we also have bulk versions of the nearest neighbour searches.Function |int E2_nn_bulk(int i, int num_wanted, kd_bin_t *buffer)|tries to find the nearest |num_wanted| neighbours to city |i|, andwrites them into |buffer|.It returns the number of vertices actually found.Naturally, the number found is as close as possible but nogreater than |num_wanted|.Function|int E2_nn_quadrant_bulk(int i, int num_wanted, kd_bin_t *buffer, int qmask)| does the same for quadrant-based searches.In neither case are the buffers ordered in any particular way;at least we don't promise so.To help sort out the buffer we also supply comparison functions |kd_bin_cmp_increasing|and|kd_bin_cmp_decreasing|suitable for passing to |qsort| and related functions.To access the city field within a bin, we export the macro |kd_bin_city|.To access the field within a bin that is monotonic with the distance to thecity, we export the macro |kd_bin_monotonic_len|.|void E2_frnn(int i, double rad, void (*proc)(int j))| is a \term{fixed-radius nearest neighbour search}@@^fixed-radius nearest neighbour search@@>.It calls |proc| on all points |j| that lie within |rad| units of point |i|.The following two procedures are used to implement \term{sphere of influence}@@^sphere of influence@@>computations.|void E2_set_radius(int i, double r)| sets the radius of the active sphere aroundpoint |i| to |r| units.|void E2_ball_search(int i, void (*proc)(int j))| calls |proc| on everypoint |j| in whose active sphere point |i| lies.% The girl the boy the dog bit hit cried.Get that? Let's try it a different way: this procedure determines whichpoints |j| have point |i| somewhere within their own (|j|'s) active sphere; it calls|proc| on every such |j|.@@<Exported subroutines@@>=void E2_create(tsp_instance_t *tsp);void E2_destroy(void);void E2_hide(int i);void E2_unhide(int i);void E2_hide_all(void);void E2_unhide_all(void);int E2_nn_func(int i);int E2_nn_quadrant(int i, const int qmask);int E2_nn_bulk_func(int i, int num_wanted, kd_bin_t *buffer);int E2_nn_quadrant_bulk(int i, int num_wanted, kd_bin_t *buffer, int qmask);int kd_bin_cmp_increasing(const void *a, const void *b);int kd_bin_cmp_decreasing(const void *a, const void *b);void E2_frnn(int i, double rad, void (*proc)(int j));void E2_set_radius(int i, double r);void E2_ball_search(int i, void (*proc)(int j));@@ It is also useful to know when a 2-d trees may be used with a particularTSP instance.@@<Exported subroutines@@>=int E2_supports(tsp_instance_t *tsp);@@ These routines support TSP instances with |EUC_2D|, |CEIL_2D|, and|ATT| cost functions.Now, |EUC_2D| and |CEIL_2D| are obvious choices, since they use essentiallyjust 2-d Euclidean distance. (|EUC_2D| rounds to the nearest integer,and |CEIL_2D| always rounds toward postivie infinity.)|ATT| uses a scaled Euclidean distance; it still has 2-d coordinates.Now, the nearest neighbour searches use only relative ordering based on raw Euclidean distance. Since the scaling and rounding are monotonic functions, we can supportall three.@@<Subroutines@@>=int E2_supports(tsp_instance_t *tsp) { switch(tsp->edge_weight_type) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -