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

📄 prunefst.c

📁 生成直角Steiner树的程序包
💻 C
📖 第 1 页 / 共 4 页
字号:
			    (NOT BITON (cip -> required_edges, fsave))) {				if (NOT BITON (cip -> initial_edge_mask, fsave)) {					/* fatal: FST already removed */					fatal("prune_fsts: bug 1.");				}				SETBIT (cip -> required_edges, fsave);				required_total++;				made_req [req_count++] = fsave;			}		}#if 1		i = req_count;		req_count = bcc_find_required (cip, made_req, req_count);		required_total += (req_count - i);#else		/* Test if leaving out an FST disconnects the remaining FSTs */		/* CHANGE! This is rather time-consuming. Should be implemented using bicomps */		for (i = 0; i < nedges; i++) {			if ((BITON (cip -> initial_edge_mask, i)) AND			   (NOT BITON (cip -> required_edges, i))) {				/* create union-find data structure */				dsuf_create (&del_comps, cip -> num_verts);				for (t = 0; t < cip -> num_verts; t++) {					dsuf_makeset (&del_comps, t);				}				del_comps_count = cip -> num_verts;				for (j = 0; j < nedges; j++) {					if (BITON (cip -> initial_edge_mask, j)) {						if (j EQ i) continue; /* skip FST being tested */						/* Unite vertices spanned */						vp1 = cip -> edge [j];						vp2 = cip -> edge [j + 1] - 1;						while (vp1 < vp2) {							r1 = dsuf_find (&del_comps, *vp1);							r2 = dsuf_find (&del_comps, *vp2);							if (r1 NE r2) {								dsuf_unite (&del_comps, r1, r2);								del_comps_count--;							}							vp1++;						}						if (del_comps_count EQ 1) break;					}				}				if (del_comps_count > 1) {					/* FST must be included in SMT */					SETBIT (cip -> required_edges, i);					required_total++;					made_req [req_count++] = i;				}				dsuf_destroy (&del_comps);			}		}#endif		/* Now update data structures for new required FSTs */		for (j = 0; j < req_count; j++) {			fsave = made_req [j];			/* Unite vertices spanned */			vp1 = cip -> edge [fsave];			vp2 = cip -> edge [fsave + 1] - 1;			while (vp1 < vp2) {				r1 = dsuf_find (&comps, *vp1);				r2 = dsuf_find (&comps, *vp2);				if (r1 EQ r2) { /* fatal: cycle created */					fatal("prune_fsts: bug 2.");				}				dsuf_unite (&comps, r1, r2);				vp1++;			}			/* Prune all incompatible FSTs */			ep1 = cip -> inc_edges [fsave];			ep2 = cip -> inc_edges [fsave + 1];			while (ep1 < ep2) {				i = *ep1++;				if (BITON (cip -> initial_edge_mask, i)) {					if (BITON (cip -> required_edges, i)) {						/* fatal: FST already required */						fatal("prune_fsts: bug 3.");					}					CLRBIT (cip -> initial_edge_mask, i);					pruned_total++;				}			}		}		/* Remove FSTs making cycles among required FSTs */		for (i = 0; i < nedges; i++) {			if ((BITON (cip -> initial_edge_mask, i)) AND			    (NOT BITON (cip -> required_edges, i))) {				/* Check if a pair of vertices span the same component */				vp1 = cip -> edge [i];				vp2 = cip -> edge [i + 1];				while (vp1 < vp2) {					vp = vp1 + 1;					while (vp < vp2) {						r1 = dsuf_find (&comps, *vp1);						r2 = dsuf_find (&comps, *vp);						if (r1 EQ r2) { /* cycle created - remove FST */							CLRBIT (cip -> initial_edge_mask, i);							pruned_total++;							vp = vp1 = vp2;							break;						}						vp++;					}					vp1++;				}			}		}		if (req_count > 0) goto try_again;		if (old_pruned_total EQ pruned_total) break;		if (Print_Detailed_Timings) {			fprintf(stderr, "- scan %d finished. %6d FSTs pruned\n",				scan, pruned_total - old_pruned_total);		}	}	if (Print_Detailed_Timings) {		fprintf(stderr, "- pruning finished: before: %d  after: %d  required: %d\n",			nedges, nedges - pruned_total, required_total);	}	/* Free pruning data information... */	for (i = 0; i < nedges; i++) {		if (pinfo.clt_info[i] NE NULL) {			free ((char *) pinfo.clt_info [i]);		}	}	free ((char *) pinfo.clt_count);	free ((char *) pinfo.clt_info);	free ((char *) pinfo.steiner_index);	free ((char *) pinfo.pg_edges);	dsuf_destroy (&comps);	free ((char *) made_req);	free ((char *) comps_edge);	free ((char *) lfmask);	free ((char *) lflist);	free ((char *) ltmask);	free ((char *) ltlist);	free ((char *) pinfo.compat_mask);}/* * Remove FSTs permanently that have been marked as not needed. * However, MST edges (2-terminal FSTs) are not deleted even if * marked as never needed. * It should be noted that no arrays are reallocated; data is packed in place. */	static	voidzap_deleted_fsts (struct cinfo *	cip		/* IN/OUT - compatibility info */){int			i;int			j;int			k;int			new_nedges;int *			ni;int *			vp;int *			vp1;int *			vp2;int *			ep;int *			ep1;int *			ep2;struct full_set *	fsp;	/* First we count the number of FSTs that remain */	/* and set up map from old to new edge index */	new_nedges = 0;	ni  = NEWA (cip -> num_edges, int);	for (i = 0; i < cip -> num_edges; i++) {		if ((BITON (cip -> initial_edge_mask, i)) OR (cip -> edge_size [i] EQ 2))			ni[i] = new_nedges++;		else			ni[i] = -1;	}	/* Pack edge_size and cost arrays */	for (i = 0; i < cip -> num_edges; i++) {		if (ni[i] >= 0) {			cip -> edge_size [ ni[i] ] = cip -> edge_size [i];			cip -> cost	 [ ni[i] ] = cip -> cost [i];		}	}	/* Pack edge array */	vp = cip -> edge [0];	for (i = 0; i < cip -> num_edges; i++) {		if (ni[i] >= 0) {			vp1 = cip -> edge [i];			vp2 = cip -> edge [i + 1];			cip -> edge [ ni[i] ] = vp;			while (vp1 < vp2)				*(vp++) = *(vp1++);		}	}	cip -> edge [ new_nedges ] = vp;	/* Pack term_trees array */	ep = cip -> term_trees [0];	for (j = 0; j < cip -> num_verts; j++) {		vp1 = cip -> term_trees [j];		vp2 = cip -> term_trees [j + 1];		cip -> term_trees [j] = ep;		while (vp1 < vp2) {			i = *(vp1++);			if (ni[i] >= 0)				*(ep++) = ni[i];		}	}	cip -> term_trees[ cip -> num_verts ] = ep;	/* Pack inc_edges array */	ep = cip -> inc_edges [0];	for (i = 0; i < cip -> num_edges; i++) {		if (ni[i] >= 0) {			ep1 = cip -> inc_edges [i];			ep2 = cip -> inc_edges [i + 1];			cip -> inc_edges [ ni[i] ] = ep;			while (ep1 < ep2) {				k = *(ep1++);				if (ni[k] >= 0)					*(ep++) = ni [k];			}		}	}	cip -> inc_edges [ new_nedges ] = ep;	/* Pack full_trees array */	if (cip -> full_trees NE NULL) {		for (i = 0; i < cip -> num_edges; i++) {			if (ni[i] >= 0) {				cip -> full_trees [ ni[i] ] = cip -> full_trees [i];				cip -> full_trees [ ni[i] ] -> tree_num = ni[i];			}			else {				/* Free FST data */				fsp = cip -> full_trees [i];				free ((char *) (fsp -> terminals));				free ((char *) (fsp -> steiners));				free ((char *) (fsp -> edges));				free ((char *) fsp);			}		}	}	/* Pack bit maps */	for (i = 0; i < cip -> num_edges; i++) {		if (ni[i] >= 0) {			if (BITON (cip -> initial_edge_mask, i))				SETBIT (cip -> initial_edge_mask, ni[i]);			else				CLRBIT (cip -> initial_edge_mask, ni[i]);			if (BITON (cip -> required_edges, i))				SETBIT (cip -> required_edges, ni[i]);			else				CLRBIT (cip -> required_edges, ni[i]);		}	}	/* Finally set edge count */	cip -> num_edges      = new_nedges;	cip -> num_edge_masks = BMAP_ELTS (new_nedges);	free((char *) ni);}/* * Check if a given FST can be pruned */	static	boolprune_this_fst (struct cinfo *	cip,		/* IN - compatibility info */struct pinfo *	pip,		/* IN - pruning data structure */int		fst){int			i;int			clt_count;int			curr_clt;int			root;int			root1;int			root2;bool			prune_fst;struct dsuf		comps;struct pg_edge *	pg_edge;struct clt_info *	clt;	clt_count = pip -> clt_count [fst];	if (clt_count == 0) return FALSE;	/* Create disjoint set */	dsuf_create (&comps, pip -> num_pg_verts + 1);	for (i = 0; i < pip -> num_pg_verts + 1; i++)		dsuf_makeset (&comps, i);	/* Add pruning graph edges (in sorted order) */	prune_fst = FALSE;	curr_clt  = 0;	clt = &(pip -> clt_info [fst][curr_clt]);	for (i = 0; i < pip -> num_pg_edges; i++) {		pg_edge = &(pip -> pg_edges[i]);		while (pg_edge -> len > clt -> dist) {			root  = dsuf_find (&comps, clt -> term);			root1 = dsuf_find (&comps, clt -> aterm1);			root2 = dsuf_find (&comps, clt -> aterm2);			if ((root NE root1) AND (root NE root2)) {				prune_fst = TRUE; /* This FST can be pruned! */				goto prune_exit;			}			curr_clt++;			if (curr_clt >= clt_count)				goto prune_exit; /* This FST cannot be pruned... */			clt = &(pip -> clt_info [fst][curr_clt]);		}		/* Add edge if FST is not deleted or incompatible */		if (BITON (pip -> compat_mask, pg_edge -> fst)) {			root1 = dsuf_find (&comps, pg_edge -> p1);			root2 = dsuf_find (&comps, pg_edge -> p2);			if (root1 NE root2)				dsuf_unite (&comps, root1, root2);		}	}	prune_exit:	dsuf_destroy (&comps);	return prune_fst;}/* * Add a pair of FSTs as incompatible */	static	voidadd_incompat (struct incompat **	incompat,	/* IN/OUT - incomp. data structure */int			fst1,		/* IN	  - first FST */int			fst2,		/* IN	  - second FST */int*			counts		/* IN/OUT - incomp. counts */){struct incompat *	icp;	icp = incompat [fst1];	incompat [fst1] = NEW (struct incompat);	incompat [fst1] -> fst	= fst2;	incompat [fst1] -> next = icp;	counts [fst1]++;	icp = incompat [fst2];	incompat [fst2] = NEW (struct incompat);	incompat [fst2] -> fst	= fst1;	incompat [fst2] -> next = icp;	counts [fst2]++;}/* * Computes for each FST, a list of those FSTs which are incompatible, * that is, fulfill one of the following conditions: * 1. The FSTs have two ore more terminals in common * 2. The FSTs have one terminal in common and the BSD of their * terminals is shorter than the total length of the FSTs * 3. An heuristic tree spanning the terminals is shorter. * 4. Another pair of FSTs has shorther or equal length. * 5. The MSTHG for the FSTs within the terminals spanned *    together with BSD-MST edges is shorter. */	static	voidcompute_incompatibility_info (struct pinfo *		pip,	/* IN/OUT - pruning info */struct bsd *		bsd	/* IN	  - BSD data structure	*/){int			i;int			j;int			k;int			t;int			fs;int			common;int			comterm;int			nverts;int			nedges;int			kmasks;int			nmasks;int			total;bitmap_t *		fmask;bitmap_t *		lfmask;bitmap_t *		edge_mask;bitmap_t *		tmask;bitmap_t *		ltmask;struct pset *		ltlist;struct incompat *	icp;struct incompat *	icpn;struct incompat **	incompat;int *			ep1;int *			ep2;int *			vp1;int *			vp2;int *			flist;int *			lflist;int **			inc_edges;int *			counts;struct cinfo *		cip;	/* Initialize and allocate various variables and arrays */	cip	  = pip -> cip;	nverts	  = cip -> num_verts;	kmasks	  = cip -> num_vert_masks;	nedges	  = cip -> num_edges;	nmasks	  = cip -> num_edge_masks;	edge_mask = cip -> initial_edge_mask;	inc_edges = NEWA (nedges + 1, int *);	counts	  = NEWA (nedges, int);	incompat  = NEWA (nedges, struct incompat *);	flist	  = NEWA (nedges, int);	fmask	  = NEWA (nmasks, bitmap_t);	tmask	  = NEWA (kmasks, bitmap_t);	ltlist	  = NEW_PSET (nverts);	ltmask	  = NEWA (kmasks, bitmap_t);	lflist	  = NEWA (nedges, int);	lfmask	  = NEWA (nmasks, bitmap_t);	for (i = 0; i < kmasks; i++) {		tmask [i] = 0;		ltmask [i] = 0;	}	for (i = 0; i < nmasks; i++) {		fmask [i] = 0;		lfmask [i] = 0;	}	for (i = 0; i < nedges; i++) {		incompat [i] = NULL;		counts [i]   = 0;	}	/* Compute the list of (lists of) incomatible FSTs... */	total = 0;	if (Print_Detailed_Timings) {		fprintf(stderr, "- computing incompatible FSTs for each FST\n");	}	for (i = 0; i < nedges; i++) {		if (NOT BITON (edge_mask, i)) continue;		/* Develop list of all FSTs adjacent to FST i... */		k = 0; j = 0;		vp1 = cip -> edge [i];		vp2 = cip -> edge [i + 1];		while (vp1 < vp2) {			t = *vp1++;			SETBIT (tmask, t);			ep1 = cip -> term_trees [t];			ep2 = cip -> term_trees [t + 1];			while (ep1 < ep2) {				fs = *ep1++;				if (BITON (fmask, fs)) continue;				if (NOT BITON (edge_mask, fs)) continue;				if (fs <= i) continue; /* test pairs once */				SETBIT (fmask, fs);				flist [k++] = fs;			}		}		/* Now loop through all adjacent FSTs */		ep1 = &flist [0];		ep2 = &flist [k];		while (ep1 < ep2) {			fs = *ep1++;			CLRBIT (fmask, fs);			/* Count number of vertices in common. */			common = 0; comterm = 0;			vp1 = cip -> edge [fs];			vp2 = cip -> edge [fs + 1];			while (vp1 < vp2) {				t = *vp1++;				if (BITON (tmask, t)) {					++common; comterm = t;				}			}			if (common >= 2) {				/* Too many - retain as incompatible */				add_incompat(incompat, i, fs, counts); total += 2;				continue;			}			/* One terminal in common. Perform thorough upper tests. */			if (NOT passes_upper_bound_tests (pip, bsd, i, fs,							  ltlist, ltmask, lflist, lfmask)) {				/* Did not pass - retain as incompatible */				add_incompat(incompat, i, fs, counts); total += 2;				continue;			}		}		vp1 = cip -> edge [i];		vp2 = cip -> edge [i + 1];		while (vp1 < vp2) {			j = *vp1++;			CLRBIT (tmask, j);		}	}	/* Now allocate and copy into contiguous memory... */	ep1 = NEWA (total, int);	for (i = 0; i < nedges; i++) {		inc_edges [i] = ep1;		k = counts [i];		if (k <= 0) continue;		icp = incompat [i];		while (icp NE NULL) {			*ep1++ = icp -> fst;			icpn = icp -> next;			free ((char *) icp);			icp = icpn;		}		qsort(inc_edges [i], k, sizeof(int), comp_ints);	}	inc_edges [i] = ep1;	if (ep1 - inc_edges [0] NE total) {		fatal ("compute_incompatibility_info: bug 1.");	}	if (cip -> inc_edges NE NULL) {		if (cip -> inc_edges [0] NE NULL) {			free ((char *) (cip -> inc_edges [0]));		}		free ((char *) (cip -> inc_edges));	}	cip -> inc_edges = inc_edges;	/* Free allocated memory */	free ((char *) lfmask);	free ((char *) lflist);	free ((char *) ltmask);

⌨️ 快捷键说明

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