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

📄 ub.c

📁 生成直角Steiner树的程序包
💻 C
📖 第 1 页 / 共 2 页
字号:
					      ranking);		/* Sort the zero-weight FSTs by rank only. */		sort_fst_list_by_rank (edges_0, count_0, ranking);		/* Try several greedy trees using this ordering of FSTs. */		try_trees (edge_list, nedges, bbip);		/* Create a second ordering by deleting all of the MST	*/		/* edges and placing them last.				*/		ep1 = edge_list;		ep2 = edge_list + nedges;		ep3 = temp_edges;		while (ep1 < ep2) {			e = *ep1++;			if (cip -> edge_size [e] <= 2) continue;			*ep3++ = e;		}		ep1 = ubip -> mst_edges;		ep2 = ep1 + (cip -> num_verts - 1);		while (ep1 < ep2) {			*ep3++ = *ep1++;		}		/* Try a few greedy trees using this ordering. */		try_trees (temp_edges, ep3 - temp_edges, bbip);	}	free ((char *) temp_edges);	free ((char *) edge_list);	if (ubip -> best_z < bbip -> best_z) {		new_upper_bound (ubip -> best_z, bbip);	}}/* * This routine sorts the full sets of integral weight (both 0.0 and 1.0). * In this case, only the given ranking is used. */	static	voidsort_fst_list_by_rank (int *		array,		/* IN - list of full set numbers to sort */int		n,		/* IN - number of full sets to sort */int *		ranking		/* IN - rank ordering of FSTs */){int		h;int		t1;int		t2;int		key1;int *		p1;int *		p2;int *		p3;int *		p4;int *		endp;	endp = &array [n];	for (h = 1; h <= n; h = 3*h+1) {	}	do {		h = h / 3;		p4 = &array [h];		p1 = p4;		while (p1 < endp) {			t1 = *p1;			key1 = ranking [t1];			p2 = p1;			while (TRUE) {				p3 = (p2 - h);				t2 = *p3;				if (ranking [t2] <= key1) break;				*p2 = t2;				p2 = p3;				if (p2 < p4) break;			}			*p2 = t1;			++p1;		}	} while (h > 1);}/* * This routine sorts the fractional full sets.  The primary key is LP * solution weight, ties are broken using the given ranking. */	static	voidsort_fst_list_by_lp_and_rank (int *		array,		/* IN - list of full set numbers to sort */int		n,		/* IN - number of full sets to sort */double *	x,		/* IN - LP solution weights */int *		ranking		/* IN - rank ordering of FSTs */){int		h;int		t1;int		t2;double		key1;int *		p1;int *		p2;int *		p3;int *		p4;int *		endp;	endp = &array [n];	for (h = 1; h <= n; h = 3*h+1) {	}	do {		h = h / 3;		p4 = &array [h];		p1 = p4;		while (p1 < endp) {			t1 = *p1;			key1 = x [t1];			p2 = p1;			while (TRUE) {				p3 = (p2 - h);				t2 = *p3;				if (x [t2] > key1) break;				if ((x [t2] EQ key1) AND				    (ranking [t2] <= ranking [t1])) break;				*p2 = t2;				p2 = p3;				if (p2 < p4) break;			}			*p2 = t1;			++p1;		}	} while (h > 1);}/* * This routine constructs several trees according to the given sorted * list of FSTs.  It uses the greedy Kruskal algorithm to build an * initial tree.  It then constructs a sequence of DIFFERENT trees as * follows: * *	1. Find an edge that has NOT been used in any of the trees *	   constructed previously by this routine. *	2. Build a new tree using the same list, but putting this *	   previously unused edge in FIRST. * * Given M edges, we repeat the edge-forcing operation until we have * tried O(log(M)) unused edges, or until we run out of edges to force. */	static	voidtry_trees (int *			edge_list,	/* IN - ordered list of edges */int			nedges,		/* IN - number of edges in list */struct bbinfo *		bbip		/* IN - branch-and-bound info */){int			i;int			j;int			nverts;int			nmasks;int			limit;struct cinfo *		cip;struct ubinfo *		ubip;int *			temp_edges;bitmap_t *		used;	ubip	= bbip -> ubip;	cip	= bbip -> cip;	nverts	= cip -> num_verts;	nmasks	= cip -> num_edge_masks;	/* None of the edges have been used yet. */	used = NEWA (nmasks, bitmap_t);	for (i = 0; i < nmasks; i++) {		used [i] = 0;	}	/* Construct the initial tree.  Note which edges were used. */	ub_kruskal (edge_list, nedges, used, bbip);	/* Copy the list so that we can quickly add an edge	*/	/* onto the front of the list...			*/	temp_edges = NEWA (nedges + 1, int);	for (i = 0; i < nedges; i++) {		temp_edges [i + 1] = edge_list [i];	}	/* Determine the limit of edges to try. */	for (limit = 2; (1 << limit) < nedges; limit++) {	}#if 0 /* Randomized rounding. */	{	int k;	for (;;) {		k = 0;		for (i = 0; i < nedges; i++) {			j = edge_list[i];			if (((BITON (bbip -> fixed, j)) AND			     (BITON (bbip -> value, j))) OR			    (cip -> edge_size [j] EQ 2) OR			    (drand48 () < 0.49*bbip -> x [j] + 0.5)) {				temp_edges [k++] = j;			}		}		ub_kruskal (temp_edges, k, used, bbip);		if (--limit <= 0) break;	}	}#endif#if 1 /* Greedy local search. */	{	int e, k, org_limit;	dist_t l, old_l, small_gap, curr_gap, fraction, quadratic;	bool have_reset;	have_reset = FALSE;	org_limit  = limit;	old_l      = INF_DISTANCE;	k = nedges + 1;	for (i = 0; i < nedges; i++) {		e = edge_list [i];		if (BITON (used, e)) continue;		/* Force edge e to be chosen FIRST. */		temp_edges [0] = e;		/* Clear old used map */		for (j = 0; j < nmasks; j++) {			used [j] = 0;		}		l = ub_kruskal (temp_edges, k, used, bbip);		/* If improved solution then replace temp_edges */		if (l < old_l) {			k = 1;			for (j = 0; j < nedges; j++) {				e = edge_list [j];				if (BITON (used, e) OR				    (cip -> edge_size [e] EQ 2)) {					temp_edges [k++] = e;				}			}			old_l = l;			/* Compute "small" absolute gap value */			small_gap = 0.0001 * fabs (ubip -> best_z);			if (small_gap < 1.0) {				small_gap = 1.0;			}		}		/* If we are really close to optimum then restart	*/		/* and intensify search.				*/		curr_gap = l - ubip -> best_z;		if ((NOT have_reset) AND (curr_gap <= small_gap)) {#if 0			tracef (" %% upper bound heuristic intensifying"				" search (absolute gap is %.3f)\n",				curr_gap);#endif			/* Let the new limit be double, plus an a*x**2	*/			/* term whose coefficient is linearly dependent	*/			/* on the gap.					*/			fraction = (small_gap - curr_gap) / small_gap;			quadratic = floor (fraction * (org_limit * org_limit));			limit = 2 * org_limit + (int) quadratic;			i = 0;			have_reset = TRUE;		}		if (--limit <= 0) break;	}	}#endif#if 0 /* Round robin. */	{	int old_force_edge;	static int force_edge = 0;	if (force_edge EQ 0) {		old_force_edge = nedges - 1;	}	else {		old_force_edge = force_edge - 1;	}	for (;;) {		if (NOT BITON (used, force_edge)) {			/* Force edge force_edge to be chosen FIRST. */			temp_edges [0] = force_edge;			ub_kruskal (temp_edges, nedges + 1, used, bbip);			--limit;		}		if (limit <= 0) break;		if (force_edge EQ old_force_edge) break;		++force_edge;		if (force_edge EQ nedges) {			force_edge = 0;		}	}	}#endif#if 0 /* Very greedy. */	for (i = 0; i < nedges; i++) {		j = edge_list [i];		if (BITON (used, j)) continue;		/* Force edge j to be chosen FIRST. */		temp_edges [0] = j;		ub_kruskal (temp_edges, nedges + 1, used, bbip);		if (--limit <= 0) break;	}#endif#if 0 /* Less greedy. */	{	int iskip, nowskip;	iskip = 1;	nowskip = 0;	limit *= 10;	/* !!!!!!!!! */	for (i = 0; i < nedges; i++) {		j = edge_list [i];		if (BITON (used, j)) continue;		if (++nowskip < iskip) continue;		/* Force edge j to be chosen FIRST. */		temp_edges [0] = j		ub_kruskal (temp_edges, nedges + 1, used, bbip);		nowskip = 0;		iskip++;		if (--limit <= 0) break;	}	}#endif	free ((char *) temp_edges);	free ((char *) used);}/* * Use Kruskal's algorithm (extended for hypergraphs) to greedily construct * a tree from the given sequence of FSTs.  If this yields a better * solution than previously known, record it and update the upper bound. */	static	dist_tub_kruskal (int *			edge_list,	/* IN - ordered list of edges */int			nedges,		/* IN - number of edges in list */bitmap_t *		used,		/* IN - marks FSTs used (ever) */struct bbinfo *		bbip		/* IN - branch-and-bound info */){int			i;int			j;int			e;int			nverts;int *			ep1;int *			ep2;int *			ep3;int *			vp1;int *			vp2;int *			vp3;int *			vp4;int *			tree_edges;struct cinfo *		cip;struct ubinfo *		ubip;int *			roots;bool *			mark;int			components;dist_t			length;struct dsuf		sets;	ubip		= bbip -> ubip;	cip		= bbip -> cip;	nverts		= cip -> num_verts;	/* Initialize one disjoint subtree for each terminal. */	dsuf_create (&sets, nverts);	for (i = 0; i < nverts; i++) {		dsuf_makeset (&sets, i);	}	tree_edges = NEWA (nverts - 1, int);	mark = NEWA (nverts, bool);	for (i = 0; i < nverts; i++) {		mark [i] = FALSE;	}	roots = NEWA (nverts, int);	/* Start the greedy Kruskal procedure... */	components = nverts;	length = 0.0;	ep1 = tree_edges;	ep2 = edge_list;	ep3 = edge_list + nedges;	while (components > 1) {		if (ep2 >= ep3) {			/* FSTs ran out before tree constructed! */			fatal ("kruskal: Bug 1.");		}		e = *ep2++;		vp3 = roots;		vp1 = cip -> edge [e];		vp2 = cip -> edge [e + 1];		for (;;) {			if (vp1 >= vp2) {				/* No cycle!  Include e in solution! */				*ep1++ = e;				length += cip -> cost [e];				SETBIT (used, e);				/* Unite all subtrees joined, and clear	*/				/* out the mark bits...			*/				vp4 = roots;				i = *vp4++;				mark [i] = FALSE;				while (vp4 < vp3) {					j = *vp4++;					mark [j] = FALSE;					dsuf_unite (&sets, i, j);					i = dsuf_find (&sets, i);					--components;				}				break;			}			j = dsuf_find (&sets, *vp1++);			if (mark [j]) {				/* This FST would form a cycle. */				while (roots < vp3) {					mark [*--vp3] = FALSE;				}				break;			}			/* This FST terminal is in distinct subtree... */			mark [j] = TRUE;			*vp3++ = j;		}	}	if (length < ubip -> best_z) {		/* We have a better feasible integer solution! */		for (i = 0; i < cip -> num_edge_masks; i++) {			bbip -> smt [i] = 0;		}		while (ep1 > tree_edges) {			e = *--ep1;			SETBIT (bbip -> smt, e);		}		ubip -> best_z = length;	}	free ((char *) roots);	free ((char *) mark);	free ((char *) tree_edges);	dsuf_destroy (&sets);	return (length);}

⌨️ 快捷键说明

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