⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nn.w,v

📁 Lin-Kernighan heuristic for the TSP and minimum weight perfect matching
💻 W,V
📖 第 1 页 / 共 4 页
字号:
@text@d8 3d159 1a159 1const char *nn_rcs_id="$Id: nn.w,v 1.126 1998/04/10 21:20:23 neto Exp neto $";d528 5@1.126log@Checked that this module is safe for use by TSPs with arbitrary costfunctions.  It is.Also, made the non-Euclidean case more efficient by using the selectfunction from module DSORT.  That's a lazy sorting function that onlydoes enough to select the appropriate subrange.@text@d8 7d156 1a156 1const char *nn_rcs_id="$Id: nn.w,v 1.125 1997/10/28 21:23:19 neto Exp neto $";d514 1a514 1@@  We use the handy-dandy partial sorting selection function |select| fromd523 1a523 1select((void *)work,(size_t)n-1,sizeof(nn_entry_t),cmp_entry_compress,@1.125log@It now runs ok with nn.  It was reallocating improperly and notinitializing work next@text@d8 4d149 1a149 1const char *nn_rcs_id="$Id: nn.w,v 1.124 1997/10/28 20:41:08 neto Exp neto $";d453 1a453 1In the future we may want to smart partitioning, like a truncatedd463 2a464 3		@@<Compute all the distances@@>@@;		@@<Sort the entries@@>@@;		@@<Copy the first |num_pure| cities@@>@@;d494 1a494 1@@<Compute all the distances@@>=d496 1a496 1	for (j=0;j<n;j++) {d500 4d507 4a510 10@@ Again we use a sorting function, and we may as well reuse the previouscomparison function.@@<Sort the entries@@>=sort((char *)work,(size_t)n,sizeof(nn_entry_t),cmp_entry_compress);@@  Now we copy the cities from the work array to the output array.The only tricky part is to skip city |i| itself.  This is only trickybecause there may be multiple cities with distance zero to city |i|.d515 3a517 7@@<Copy the first |num_pure| cities@@>={ int r,w;	for ( r=w=start_work; w<start_work+num_pure; r++ ) { 		if ( work[r].city != i ) work[w++] = work[r];	}	work_next = w;}@1.124log@Now it compiles.and links.@text@d8 4d145 1a145 1const char *nn_rcs_id="$Id: nn.w,v 1.123 1997/10/28 20:27:50 neto Exp neto $";d287 1a288 1	n = tsp_instance->n;d293 2d313 1d405 1a405 1@@<|nn_build| variables@@>=d408 1a437 1	mem_realloc(list,sizeof(int)*new_size);d439 1d614 19a632 3if ( verbose >= 25 ) {	printf("nn: Resize list from %d elements to %d elements", 		list_size, new_size);@1.123log@Removed FINISH signal to finish coding.Removed old balanced quadrant material.Added maintenance of nn max bound, that jbmr requires.@text@d8 5d141 1a141 1const char *nn_rcs_id="$Id: nn.w,v 1.121 1997/10/18 20:39:43 neto Exp neto $";d234 1a234 1begin = new_arr_of(int *,n+1);d316 1a316 1	"%d nearest neighbours specified, but there are only %d cities",num_pure,n;d319 2a320 1@@<Module headers@@>=a321 1#include "read.h"d387 1a387 1sort(work,work_next,sizeof(nn_entry_t),cmp_entry_compress);d447 1a447 1	int start_work = next_work;d472 3a474 3		work[next_work].city = city;		work[next_work].len = cost(i,city);		next_work++;d477 1a477 1	for (j=start_work;j<next_work;j++) E2_unhide(work[j].city);d511 1a511 1	next_work = w;d566 1a566 1{ int j, start_work=next_work;d570 3a572 3		work[next_work].city = city;		work[next_work].len = cost(i,city);		next_work++;d575 1a575 1	for (j=start_work;j<next_work;j++) E2_unhide(work[j].city);@1.122log@Done coding the quadrants.Will remove old stuff.@text@d8 4d120 3d131 1d151 1d159 9d270 2d282 1d288 1a290 12#if FINISH 		/* Build the list for city |i| */			/*Build a pure list for city |i|*/			errorif(!E2_supports(tsp_instance), 				"NN_QUADRANT requires 2D instance");			/* Build a quadrant-balanced list for city |i|*/#endifa322 1@@d min(A,B) ((A)<(B) ? (A) : (B))d533 1a533 1if ( num_pure ) {d552 1a552 1to be balanced; they are congruent.d557 3d563 1a563 1		const int city = E2_nn_quadrant(i,quadrant);d578 1a578 1We cheat a little by redefining the |num_quadrant| variable temporarily.d586 4d591 3a593 11	for (j=0;j<num_pure;j++) {		city = E2_nn(i);		if ( city == -1 ) break; /* No such neighbour. */		work[next_work].city = city;		work[next_work].len = cost(i,city);		next_work++;		E2_hide(city);	}@@<Find up to |num_quadrant| neighbours in quadrant |quadrant|@@>@@;{ int quadrant}d595 2a596 114@@ Building quadrant-balanced lists is more interesting.We'd like the nearest representatives from each of the four quadrants surrounding city |i|, but we want equal representation fromall four quadrants.We'd like to find them efficiently, \ie, without too many passes over the data.The tricky part comes in the case when a quadrant doesn't have|nn_bound/4| members.@@<Build a quadrant-balanced list for city |i|@@>=@@<Compute all the distances@@>@@;@@<Sort the entries@@>@@;{ int j, w[5], r[5], wsum;double ix = tsp_instance->coord[i].x[0];double iy = tsp_instance->coord[i].x[1];@@<Copy the first |nn_bound| entries from each quadrant to their own lists@@>@@;@@<Copy the entries from each of the lists in a balanced manner@@>@@;@@<Sort the short list@@>@@;@@<Copy the first |nn_bound| cities from the |work| array into |nn_list[i]|@@>@@;}@@ We need arrays for {\it five} regions: the four quadrants, and all citiesthat lie on the same coordinates as city |i|.@@<Module variables@@>=static nn_entry_t **q;@@ We need to allocate space for these quadrant arrays.@@<Set up the array data structures@@>={ int j;q = new_arr_of(nn_entry_t *,5);for ( j=0;j<5;j++ ) {	q[j] = new_arr_of(nn_entry_t,max_bound);}}@@ |wsum| allows us to terminate early in the common case.  It is always defined as |wsum = +w[1]+w[2]+w[3]+w[4]|.  We don't count |w[0]| in this because there are likely no `zero-quadrant' cities.  If we did count it, then we wouldn't get early termination inthis common case:  we'd never satisfy |w[0] == nn_bound|.We're also careful to define the quadrants in a half-closed/half-open manner.We've partitioned the plane (and hence there is no overlap and thereare no missing pieces).@@<Copy the first |nn_bound| entries from each quadrant to their own lists@@>=w[0] = w[1] = w[2] = w[3] = w[4] = wsum = 0;for ( j=0; wsum < nn_bound * 4 && j<n ; j++ ) {	double jx = tsp_instance->coord[work[j].city].x[0];	double jy = tsp_instance->coord[work[j].city].x[1];	if ( jx == ix && jy == iy ) {		if ( work[j].city != i && w[0] < nn_bound ) {			q[0][w[0]++] = work[j];		}	} else if ( jx > ix && jy >= iy ) {		if ( w[1] < nn_bound ) {			q[1][w[1]++] = work[j];			wsum++;		}	} else if ( jx <= ix && jy > iy ) {		if ( w[2] < nn_bound ) {			q[2][w[2]++] = work[j];			wsum++;		}	} else if ( jx < ix && jy <= iy ) {		if ( w[3] < nn_bound ) {			q[3][w[3]++] = work[j];			wsum++;		}	} else if ( jx >= ix && jy < iy ) {		if ( w[3] < nn_bound ) {			q[4][w[4]++] = work[j];			wsum++;		}	} else {		errorif(1,"Bad quadrant checking code!\n");	}}@@ First priority goes to the zero quadrant cities.  Then we take citiesin a balanced manner from each of the other four quadrants.  We copy them back into the |work| array.Think of |l| as a radar sweeping beam.@@<Copy the entries from each of the lists in a balanced manner@@>={ int l;r[0] = r[1] = r[2] = r[3] = r[4] = 0;for ( j=0;j<w[0] ; j++ ) {	work[j] = q[0][j];}l=1;while ( j < nn_bound ) {	if ( r[l] < w[l] ) {		work[j] = q[l][r[l]];		r[l]++;		j++;	}	l++; if ( l==5 ) l=1;}}@@ The merged entres may not be in sorted order because we biased theirselection in favour of quadrant balance.  So we need to sort them inascending order.@@<Sort the short list@@>=sort((char *)work,(size_t)nn_bound,sizeof(nn_entry_t),cmp_entry);a605 3@@*TODO.@@		@@<Build a Delauney work list for city |i|@@>=d607 1@1.121log@Restructuring so that we really do use multiple criteria.Also, change to a single list structure with variable sublists.@text@d8 4a125 1@@<Global variables@@>@@;d128 1a128 1const char *nn_rcs_id="$Id: nn.w,v 1.120 1997/10/18 17:26:28 neto Exp neto $";d211 1a211 1begin = new_arr_of(int *,n);d230 1a230 1if ( begin ) { free_mem(begin);mem_deduct(sizeof(int)*n); }d241 1a241 1in a particular quadrant, or a city near in the Delauney triangulation.d247 4a250 1in the Delauney triangulation of the instance.d258 1a258 3	errorif(num_pure==0 && num_quadrant==0 && num_delauney==0,		"Must specify some candidates");a259 2	errorif(num_pure >= n-1, "num_pure = % > %d = n-1", num_pure, n-1);d274 2a275 2		@@<Build the list for city |i|@@>@@;			@@<Build a pure list for city |i|@@>@@;d279 1a279 1			@@<Build a quadrant-balanced list for city |i|@@>@@;d287 16d366 2a367 1Module \module{LK} sets the |sort| pointer.d388 1a388 1We promise to put nearerd403 3a405 1@@ We use repeated doubling to expand the |list| array.  d409 1a409 1There is no performance penalty because we access the memory we don'td414 1a414 1	int new_size = last_size;d421 1a421 1@@*1 The pure list.d424 1a424 1Otherwise, for now we're going to use a quick and dirty method to calculated427 2d447 2a448 2@@ Let's do the fast way first.It uses the $k$-d search structure implemented in \module{KDTREE}.d463 1a463 3	for (j=start_work;j<next_work;j++) {		E2_unhide(work[j].city);	}d501 86a586 1#if FINISHa587 1#endifd710 3@1.120log@Added support for CEIL 2D.@text@d8 3d100 1a100 1via a parameter passed to the construction routine.d107 1a107 2Procedure |nn_build| builds the nearest neighbour arrays.  This is storedin the global array variable |nn_list| which is indexed by city number.d109 2d125 1a125 1const char *nn_rcs_id="$Id: nn.w,v 1.119 1997/10/17 21:27:34 neto Exp neto $";a133 1#include <assert.h>a139 2@@<Exported constants@@>@@;@@<Exported variables@@>@@;d151 3a153 2The exported array, |nn_list| stores only the neighbouring cities.  Thissaves a lot on space.  (For most 32-bit architectures, it saves 2/3 ofd155 2a156 1usually 8 bytes.)d170 23a192 2@@ We need to declare the |nn_list| array.  It is an array of arrays of integers.d194 3a196 16We also want |nn_bound|, which is the number of entriesin each city's array.Every city will have the same number of neighbours in its |nn_list| entry,namely |nn_bound|.The neighbour lists themselves are stored contiguouslyin the array |nn_list_pool|.@@<Global variables@@>=int **nn_list, *nn_list_pool;int nn_bound;@@ We export these variables.@@<Exported variables@@>=extern int **nn_list;extern int nn_bound;d198 2a199 2@@ It will be convenient to store |n|, the number of cities, and |max_bound|,the maximum number of entries in each city's list.d202 1a202 1static int n, max_bound=-1;d204 2a205 2@@ These variables get allocated in the setup routine.  We will be addingto this code later, so we separate it out in a new named section.d207 3a209 15@@<Subroutines@@>=voidnn_setup(int num_vertices, int the_max_bound) {	@@<Set up the array data structure@@>@@;}@@@@<Set up the array data structure@@>=n = num_vertices;max_bound = the_max_bound;errorif(max_bound <= 0, "NN list min bound too low: %d", max_bound);errorif(max_bound > n, "NN list max bound too high: max_bound == %d > n == %d",	max_bound, n);nn_list = new_arr_of(int *,n);nn_list_pool = new_arr_of(int,n*max_bound);d222 1a222 1	@@<Clean up the array data structure@@>@@;d226 2a227 7@@<Clean up the array data structure@@>=if ( nn_list ) {	free_mem(nn_list);mem_deduct(sizeof(int *)*n);	free_mem(nn_list_pool);mem_deduct(sizeof(int)*n*max_bound);}max_bound = -1;nn_bound = -1;d229 1a229 1@@ Both these procedures must be declared externally.a230 1void nn_setup(int num_vertices, int the_max_bound);d236 9a244 2The first parameter tells it how long each city's list should be.The second tells it whether to build a pure list or a region-oriented list.d248 3a250 1nn_build(int list_len, int kind) {d252 6a257 4	errorif( max_bound < 0, "nn_setup must be called before nn_build" );	errorif( list_len > max_bound, "list_len == %d > max_bound == %d!",		list_len, max_bound);	nn_bound = list_len;d259 1d261 12a272 3		nn_list[i]=nn_list_pool + list_len*i;		switch( kind ) {		case NN_PURE:d274 1a274 2			break;		case NN_QUADRANT:d278 1a278 5			break;		default :			errorif(1,"Invalid kind value == %d\n",kind);		}	}d281 1a281 6@@ We need to export the special values |NN_PURE| and |NN_QUADRANT|.@@<Exported constants@@>=#define NN_PURE (0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -