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

📄 construct.w,v

📁 Lin-Kernighan heuristic for the TSP and minimum weight perfect matching
💻 W,V
📖 第 1 页 / 共 5 页
字号:
@@<Pick a new potential mate for |u|@@>=if (E2_case) {	next_edge->other_end = E2_nn(u);	next_edge->len = cost(u,next_edge->other_end);	pq_insert(pq_edge,next_edge);} else { 	pool_free(nn_link_pool,next_edge);	if ( farthest_in_queue[u] == v ) {		const int x = u, not_me = x;		@@<Get fresh neighbours for |x|, excepting |not_me|@@>@@;	}}@@ Verbose output.Here are some sections of code I used to debug this codethe second time around.  (I goofed up my priority queue handling whenI added randomized construction heuristics.)@@<Verbose: accept this edge@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 1000if ( verbose >= 1000 ) printf(" accept\n");#endif#endif@@@@<Verbose: PQ before getting an edge@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 2000if ( verbose >= 2000 ) {printf("Priority queue before Get one short valid edge or NULL:\n");pq_print(pq_edge,stdout);printf("\n");}#endif#endif@@@@<Verbose: extracted |e|@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 2000if ( verbose >= 2000 ) {printf("Extract ");pq_edge_print(stdout,e);printf("\nPriority queue just after extract:\n");pq_print(pq_edge,stdout);printf("\n");}#endif#endif@@@@<Verbose: got a valid edge@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 1000if ( verbose >= 2000 ) {printf("Priority queue AFTER Get one short valid edge or NULL:\n");pq_print(pq_edge,stdout);printf("\n");}if ( verbose >= 1000 ) printf(" valid");#endif#endif@@@@<Verbose: All neighbours@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 500fprintf(stderr,"construct: All neighbours for %d, excepting %d\n",	x,not_me);fflush(stderr);#endif#endif@@@@<Verbose: mark as saturated@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 500fprintf(stderr,"             Marking %d as saturated (inv= %d)\n",c,inv);#endif#endif@@@@<Verbose: allocate new link@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 750fprintf(stderr,"construct: alloc new link (%d,%d) "	length_t_native_spec"\n",	e->this_end,e->other_end,length_t_native_pcast(e->len));fflush(stderr);#endif#endif@@@@<Verbose: select fresh neighbours@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 750fprintf(stderr,"construct: Select fresh neighbours for %d, excepting %d\n",	x,not_me);fflush(stderr);#endif#endif@@@@<Verbose: need to refresh@@>=#if defined(CONSTRUCT_MAX_VERBOSE)#if CONSTRUCT_MAX_VERBOSE >= 750fprintf(stderr,"Need to refresh because I got x=%d %d y=%d %d "		length_t_native_spec"\n",	x, e->this_end, y, e->other_end, length_t_native_pcast(e->len));#endif#endif@@*Index.@1.140log@Fixed two bugs:1) I wasn't updating inv unsaturated properly.2) I fixed a subtle bug with getting maximum weight city in the queue fora given start point x.  (The max value was initialized wrong.)Check values of e->len.@text@d53 7d218 1a218 1const char *construct_rcs_id = "$Id: construct.w,v 1.139 1998/08/09 20:53:12 neto Exp neto $";d673 1a673 1fprintf(stderr,"             Marking %d as saturated (inv= %d)\n",c,inv);d739 1a739 2fprintf(stderr,"construct: All neighbours for %d, excepting %d\n",	x,not_me);fflush(stderr);d759 1a759 3	fprintf(stderr,"construct: alloc new link (%d,%d) "		length_t_native_spec"\n",		e->this_end,e->other_end,length_t_native_pcast(e->len));fflush(stderr);d769 1a769 2fprintf(stderr,"construct: Select fresh neighbours for %d, excepting %d\n",		x,not_me);fflush(stderr);d1040 1a1040 3fprintf(stderr,"Need to refresh because I got x=%d %d y=%d %d "		length_t_native_spec"\n",	x, e->this_end, y, e->other_end, length_t_native_pcast(e->len));d1371 48@1.139log@Removed some debugging output.Made random vs. deterministic a compile-time difference rather thana runtime test.@text@d53 5d211 1a211 1const char *construct_rcs_id = "$Id: construct.w,v 1.138 1998/08/09 20:36:27 neto Exp neto $";d662 6a667 2	if (inv<num_unsaturated && unsaturated[inv]==c) 		unsaturated[inv]=unsaturated[--num_unsaturated];d674 3d688 4d703 2a704 1We choose to put in up to |max_per_city_nn_cache| neighbours at a timed707 2d718 1a718 1@@d max_per_city_nn_cache 30d723 38d765 2d775 1a775 1	num_chosen=min(w,max_per_city_nn_cache);d779 2a780 2	farthest_len = nn_work[i].len;	farthest_city = nn_work[i].other_end;d782 2a783 1		pq_edge_t *e=pool_alloc(nn_link_pool);d786 1a786 1		if ( farthest_len < e->len ) { d1037 3@1.138log@Fixed the exhausted queue problem with matching.(I forgot to break out of the loop!.@text@d53 4d206 1a206 1const char *construct_rcs_id = "$Id: construct.w,v 1.137 1998/08/09 19:09:42 neto Exp neto $";d411 17d432 1a432 1	const int do_random = heuristic == CONSTRUCT_GREEDY_RANDOM;d439 1a858 4In the deterministic case, just choose one.  Now is that much simpler!d860 2a861 1if ( do_random ) {a878 2} else { /* Deterministic choice */	@@<Get one short valid edge or |NULL|@@>@@;d880 7a886 4errorif(e==NULL,"Exhausted the priority queue of links.");@@<Verbose: accept this edge@@>@@;x=e->this_end;y=e->other_end;d892 1d894 1d904 3a906 1if ( do_random ) { random_stream = prng_new(PRNG_DEFAULT,random_seed^(6502*6510)); }d910 3a912 1if ( do_random ) prng_free(random_stream);d943 2a944 1First, we must add the length of the edge upon which we decided.d947 2d950 2d1097 15d1115 1a1115 1	const int do_random = alg == CONSTRUCT_GREEDY_RANDOM;d1122 1d1171 3a1173 2The randomized case looks the same.  It's a shame (and my fault)that we couldn't just use the same code sequence.  Alas.d1176 2a1177 1if ( do_random ) {a1178 3printf("About to extract two edges:\n");pq_print(pq_edge,stdout);printf("\n");a1188 4printf("\nHere are the two edges:\n");pq_edge_print(stdout,candidate[0]);pq_edge_print(stdout,candidate[1]);printf("\n");a1193 1printf("chose %d\n",chosen);a1195 2} else { /* Deterministic choice */	@@<Get one short |next_edge| for matching, or |NULL|@@>@@;d1197 8a1225 3printf("About to extract an edge:\n");pq_print(pq_edge,stdout);printf("\n");a1226 3printf("Got edge: ");pq_edge_print(stdout,next_edge);printf("\n");a1229 1printf(" mate[%d]=%d mate[%d]=%d\n",u,mate[u],v,mate[v]);@1.137log@Better randomization through checking and discarding reversed copiesof same edge when withdrawing from queue.@text@d53 4d202 1a202 1const char *construct_rcs_id = "$Id: construct.w,v 1.136 1998/08/09 18:06:35 neto Exp neto $";d551 2a552 2#The distance function is assumed to be symmetric.  So if we have $(u,v)$#in the queue, there is no point in d853 1d1104 5a1108 3	if (mate[u]>=0) continue; /* Node |u| is already saturated. */	if (mate[v]>=0) { @@<Pick a new potential mate for |u|@@> continue;}@@;	mate[u]=v; /* Otherwise, insert |(u,v)| into the matching. */d1130 3d1143 5d1164 5d1179 3d1183 3d1189 5a1193 2	if (mate[u]>=0) continue; /* Node |u| is already saturated. */	if (mate[v]>=0) { @@<Pick a new potential mate for |u|@@> continue;}@@;@1.136log@I believe this is fixed now.Now I will reorganized to remove run-time ``do random'' tests.@text@d53 4d198 1a198 1const char *construct_rcs_id = "$Id: construct.w,v 1.135 1998/08/08 22:45:38 neto Exp neto $";d424 6a429 3@@ The first data structure we'll need is a priority queue of edges.  We'llrecord at most one edge per  vertex in the graph.  It will be convenientto store the edges in an array indexed by city number.  Each entry recordsd451 2a452 2void pq_edge_print(FILE *out, void *edgep);voidd458 1a458 1		fprintf(out,"{%x,%d,%d," length_t_spec "}",d547 3d553 1a553 3In the non-Euclidean case, we do a bulk search of I'll have to modify this for the case when the @@^unfinished code@@>d823 11a833 1Otherwise, just choose one.d840 7a846 4	int i;	for (i=0;i<2;i++) {		@@<Get one short valid edge or |NULL|@@>@@; 		candidate[i]=e;d848 1d850 1a850 1		const int chosen = prng_unif_int(random_stream,3) == 0; d1124 1a1124 1		@@+ candidate[0]=next_edge;d1126 7a1132 1		@@+ candidate[1]=next_edge;d1137 1@1.135log@I believe I've got the bug.But it must wait for Sunday.@text@d53 4d194 1a194 1const char *construct_rcs_id = "$Id: construct.w,v 1.134 1998/08/08 22:17:57 neto Exp $";d800 1a800 1	else { @@<Insert a new link for |x|@@> }d822 5a826 2	@@<Get one short valid edge or |NULL|@@>@@; @@+ candidate[0]=e;	@@<Get one short valid edge or |NULL|@@>@@; @@+ candidate[1]=e;d837 1a837 1printf(" accept\n");d841 19a873 1d875 1a875 3printf("Priority queue before Get one short valid edge or NULL:\n");pq_print(pq_edge,stdout);printf("\n");d879 1a879 6printf("Extract ");pq_edge_print(stdout,e);printf("Priority queue just after extract:\n");pq_print(pq_edge,stdout);printf("\n");d885 1a885 1	dict_insert(unused,e);d887 1a887 25printf("Priority queue AFTER Get one short valid edge or NULL:\n");pq_print(pq_edge,stdout);printf("\n");printf(" valid");@@ Of course, we need to define a random number stream for the randomizedchoice$\ldots$@@<Declare the data structures for Greedy@@>=prng_t *random_stream=NULL;@@ $\ldots$and initialize it too.@@^Commodore PET@@>@@^Commodore 64@@>@@^C64@@>@@^6502@@>@@^6510@@>@@<Build the data structures for Greedy.@@>=if ( do_random ) { random_stream = prng_new(PRNG_DEFAULT,random_seed^(6502*6510)); }@@ And when we're done, we should get rid of it too.@@<Destroy the data structures for Greedy@@>=if ( do_random ) prng_free(random_stream);a893 1@@<Re-insert unused edges@@>@@;a894 9@@ dict_delete(unused,e); { pq_edge_t *e;while ( (e=dict_delete_any(unused)) != NULL ) {	int x = e->this_end;	int y = e->other_end;	@@<Insert a new link for |x|@@>@@;}}d896 2a897 1@@ This section finds a new candidate link for city |x|.d908 1a908 1@@<Insert a new link for |x|@@>=d1158 53@1.134log@Added better debuggging output.@text@d53 3d190 1a190 1const char *construct_rcs_id = "$Id: construct.w,v 1.133 1998/08/08 20:51:40 neto Exp neto $";d867 1d896 1a896 2First, we must insert a new link for the key city |x|.Second, we must add the length of the edge upon which we decided.a898 1@@<Insert a new link for |x|@@>@@;d900 11@1.133log@First cut at implementing randomized greedy heuristic.But this bombs on lin105 (both det and rand) with "exhausted priorityqueue".@text@d53 5d187 1a187 1const char *construct_rcs_id = "$Id: construct.w,v 1.132 1998/07/16 21:58:55 neto Exp neto $";d435 14d475 1a475 1pq_set_print_func(pq_edge,nn_link_prn);d827 1d847 3d853 6d865 5a937 9@@@@<Module subroutines@@>=static void nn_link_prn(void *p);voidnn_link_prn(void *p) {	pq_edge_t *np=(pq_edge_t*)p;	printf(" %d,%d ",np->this_end,np->other_end);}@1.132log@Added the LGPL notice in each file.@text@d53 3d182 1a182 1const char *construct_rcs_id = "$Id: construct.w,v 1.131 1998/06/19 14:55:53 neto Exp neto $";d210 1a210 1|heuristic| parameter.  Some of these heuristics use the integer-valuedd213 4

⌨️ 快捷键说明

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