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

📄 sec_comp.c

📁 生成直角Steiner树的程序包
💻 C
📖 第 1 页 / 共 4 页
字号:
 */	static	voidreduce_component_in_place (struct comp *		comp		/* IN - component to reduce */){int			i;int			j;int			nverts;int			nedges;int			src;int			dst;int			new_num_verts;int			new_num_edges;int *			ip1;int *			ip2;int *			ip3;int *			ip4;int *			vert_renum;int *			edge_renum;	if ((comp -> vert_mask EQ NULL) AND (comp -> edge_mask EQ NULL)) {		/* Already reduced... */		return;	}	create_masks (comp);	/* in case one exists, but not the other... */	nverts = comp -> num_verts;	nedges = comp -> num_edges;	if ((nverts <= 0) OR (nedges <= 0)) {		comp -> num_verts = 0;		comp -> num_edges = 0;		free ((char *) (comp -> vert_mask));		free ((char *) (comp -> edge_mask));		comp -> vert_mask = NULL;		comp -> edge_mask = NULL;		return;	}	/* Get arrays used to renumber the vertices and edges... */	vert_renum	= NEWA (nverts, int);	edge_renum	= NEWA (nedges, int);	/* Compute renumberings... */	j = 0;	for (i = 0; i < nverts; i++) {		if (BITON (comp -> vert_mask, i)) {			vert_renum [i] = j++;		}		else {			vert_renum [i] = -1;		}	}	new_num_verts = j;	j = 0;	for (i = 0; i < nedges; i++) {		if (BITON (comp -> edge_mask, i)) {			edge_renum [i] = j++;		}		else {			edge_renum [i] = -1;		}	}	new_num_edges = j;	/* Remap/delete entries in the edge-to-vertices mapping... */	dst = 0;	ip1 = comp -> everts [0];	for (src = 0; src < nedges; src++) {		if (edge_renum [src] < 0) continue;		ip2 = comp -> everts [src];		ip3 = comp -> everts [src + 1];		comp -> everts [dst] = ip1;		while (ip2 < ip3) {			j = *ip2++;			j = vert_renum [j];			if (j >= 0) {				*ip1++ = j;			}		}		comp -> x [dst] = comp -> x [src];		++dst;	}	comp -> everts [dst] = ip1;	if (dst NE new_num_edges) {		fatal ("reduce_component_in_place: Bug 1.");	}	comp -> num_edges = new_num_edges;	/* Remap/delete entries in the vertex-to-hyperedges mapping... */	dst = 0;	ip1 = comp -> vedges [0];	ip4 = comp -> rverts [0];	for (src = 0; src < nverts; src++) {		if (vert_renum [src] < 0) continue;		ip2 = comp -> vedges [src];		ip3 = comp -> vedges [src + 1];		comp -> vedges [dst] = ip1;		while (ip2 < ip3) {			j = *ip2++;			j = edge_renum [j];			if (j >= 0) {				*ip1++ = j;			}		}		comp -> tviol [dst] = comp -> tviol [src];		ip2 = comp -> rverts [src];		ip3 = comp -> rverts [src + 1];		comp -> rverts [dst] = ip4;		while (ip2 < ip3) {			*ip4++ = *ip2++;		}		++dst;	}	comp -> rverts [dst] = ip4;	comp -> vedges [dst] = ip1;	if (dst NE new_num_verts) {		fatal ("reduce_component_in_place: Bug 2.");	}	/* Component is now a different size... */	comp -> num_verts	= new_num_verts;	comp -> num_edges	= new_num_edges;	free ((char *) edge_renum);	free ((char *) vert_renum);	/* Free the valid vertices and edges masks... */	free ((char *) (comp -> edge_mask));	free ((char *) (comp -> vert_mask));	comp -> vert_mask	= NULL;	comp -> edge_mask	= NULL;}/* * This routine determines whether or not the given component is * "vacuous" -- too small to contain a subtour violation. */	static	intvacuous_component (struct comp *		p		/* IN - component to test */){	if (p -> num_verts <= 0) return (TRUE);	if (p -> num_edges <= 1) return (TRUE);	if (p -> num_verts EQ 1) {		/* Special check for exactly 1 vertex... */		if (p -> tviol [0] > FUZZ) {			/* We have a single vertex, but it is congested! */			/* This is a valid component... */			return (FALSE);		}		/* Only 1 vertex -- no congestion -- ignore this component */		return (TRUE);	}	/* We have a component worth looking at for violated SEC's... */	return (FALSE);}/* * This routine frees up the given congested component. */	voidfree_congested_component (struct comp *		p	/* IN - component to free */){	if (p -> vert_mask NE NULL) {		free ((char *) (p -> vert_mask));	}	if (p -> edge_mask NE NULL) {		free ((char *) (p -> edge_mask));	}	free ((char *) (p -> vedges [0]));	free ((char *) (p -> everts [0]));	free ((char *) (p -> rverts [0]));	free ((char *) (p -> rverts));	free ((char *) (p -> tviol));	free ((char *) (p -> vedges));	free ((char *) (p -> everts));	free ((char *) (p -> x));	free ((char *) p);}/* * This routine deletes a specified vertex from the given congested * component and then does all possible further simplifications on what * is left.  Note that it is possible that the given component splits * into several when this is done... * * Also note that the given component may be MODIFIED -- even FREED! */	struct comp *delete_vertex_from_component (int			t,		/* IN - vertex to delete */struct comp *		comp		/* IN - component to delete from */){	if (t >= comp -> num_verts) {		fatal ("delete_vertex_from_component: Bug 1.");	}	/* Create masks if not currently present... */	create_masks (comp);	if (t >= 0) {		if (NOT BITON (comp -> vert_mask, t)) {			/* Deleting a vertex that is not present. */			fatal ("delete_vertex_from_component: Bug 2.");		}		/* Remove the vertex from the bit-mask... */		CLRBIT (comp -> vert_mask, t);	}	else {		/* Caller has deleted vertices.  Just clean up.	*/	}	/* Now that we have removed a vertex, we can no longer	*/	/* be certain that the component is: fully congested,	*/	/* connected, bi-connected, etc...			*/	comp -> flags &= ~CFLG_ALL;	comp = simplify_one_component (comp);	return (comp);}/* * This routine adds the vertex and edge masks to the given * component, if they are NOT already present... */	static	voidcreate_masks (struct comp *		p		/* IN - component to put masks on */){int		i;int		n;int		nmasks;bitmap_t *	mask;	if (p -> vert_mask EQ NULL) {		/* Sprout a new vertex mask with all vertices present. */		n = p -> num_verts;		nmasks = BMAP_ELTS (n);		if (nmasks < 1) {			nmasks = 1;		}		mask = NEWA (nmasks, bitmap_t);		for (i = 0; i < nmasks; i++) {			mask [i] = 0;		}		for (i = 0; i < n; i++) {			SETBIT (mask, i);		}		p -> vert_mask = mask;	}	if (p -> edge_mask EQ NULL) {		/* Sprout a new edge mask with all edges present. */		n = p -> num_edges;		nmasks = BMAP_ELTS (n);		if (nmasks < 1) {			nmasks = 1;		}		mask = NEWA (nmasks, bitmap_t);		for (i = 0; i < nmasks; i++) {			mask [i] = 0;		}		for (i = 0; i < n; i++) {			SETBIT (mask, i);		}		p -> edge_mask = mask;	}}/* * This routine selects a vertex that is a member of the previous * solution S and has minimum weight. */	intfind_least_congested_vertex (bitmap_t *		S,	/* IN - previous separation solution */struct comp *		comp	/* IN - congested component */){int			i;int			j;int			nverts;int			nedges;int *			ip1;int *			ip2;int			min_vert;double			w;double			min_weight;	nverts	= comp -> num_verts;	nedges	= comp -> num_edges;	min_weight	= 2.0 * nedges;	min_vert	= -1;	for (i = 0; i < nverts; i++) {		if ((S NE NULL) AND (NOT BITON (S, i))) continue;		w = 0.0;		ip1 = comp -> vedges [i];		ip2 = comp -> vedges [i + 1];		while (ip1 < ip2) {			j = *ip1++;			w += comp -> x [j];		}		if (w < min_weight) {			min_weight = w;			min_vert   = i;		}	}	if (min_vert < 0) {		/* Least congested vertex not found? */		fatal ("find_least_congested_vertex: Bug 1.");	}	return (min_vert);}/* * This routine produces the proper constraints that are represented * by the given subset of the given component.  We try to "clean up" * the constraint by taking only the congested portion of the * vertices in it.  This can strengthen the constraints considerably. */	struct constraint *check_component_subtour (bitmap_t *		S,		/* IN - subtour (set of vertices) */struct comp *		comp,		/* IN - congested component */struct constraint *	cp,		/* IN - existing constraints */double *		x,		/* IN - LP solution vector */bitmap_t *		edge_mask,	/* IN - set of valid hyperedges */struct bbinfo *		bbip		/* IN - branch-and-bound info */){int			kmasks;struct comp *		vcomps;struct comp *		tmp;struct constraint *	cp2;struct cinfo *		cip;bool			print_flag;bitmap_t *		orig_stour;bitmap_t *		stour;bool			flag;	cip = bbip -> cip;	kmasks = cip -> num_vert_masks;	orig_stour = NEWA (2 * kmasks, bitmap_t);	stour	   = orig_stour + kmasks;#if 1	/* Construct a bitmask of the REAL vertices comprising	*/	/* this subtour...					*/	component_verts_to_real_verts (S, comp, orig_stour, kmasks);#if 1	/* Now that we have the subtour as "real" vertices,	*/	/* emit the constraint...				*/	cp = check_subtour (orig_stour, cp, x, edge_mask, cip);#endif#endif	/* Take the violated subtour and "clean" it up by computing the	*/	/* congested components for it.  This will get rid of some of	*/	/* the cruft, and help to strengthen the generated constraints.	*/#if 1	print_flag = FALSE;	vcomps = find_congested_components (x,					    orig_stour,					    edge_mask,					    print_flag,					    cip);#else	/* A more efficient alternative to starting all over! */ { int		i, j, k; int		nmasks; bitmap_t *	sedges; int *		ip1; int *		ip2;	/* Compute edges induced by the subtour vertices. */	nmasks = BMAP_ELTS (comp -> num_edges);	sedges = NEWA (nmasks, bitmap_t);	for (i = 0; i < nmasks; i++) {		sedges [i] = 0;	}	for (i = 0; i < comp -> num_edges; i++) {		ip1 = comp -> everts [i];		ip2 = comp -> everts [i + 1];		k = 0;		while (ip1 < ip2) {			j = *ip1++;			if (BITON (S, j)) {				++k;				if (k >= 2) {					SETBIT (sedges, i);					break;				}			}		}	}	vcomps = copy_subcomponent (comp, S, sedges);	vcomps = simplify_one_component (vcomps); }#endif	flag = FALSE;#if 0	{ int i = 0;		for (tmp = vcomps; tmp NE NULL; tmp = tmp -> next) {			++i;		}		if (i >= 3) {			plot_lp_solution ("Full LP Solution",					  x, cip, BIG_PLOT);			plot_subtour ("Separated Subtour",				      x, cip, orig_stour, BIG_PLOT);			flag = TRUE;		}	}#endif#if 1	for (tmp = vcomps; tmp NE NULL; tmp = tmp -> next) {		cp2 = add_component_subtour (tmp, x, edge_mask, cip, cp, stour);		if (flag AND (cp2 NE cp)) {			plot_subtour ("Strengthed Subtour",				      x, cip, cp2 -> mask, BIG_PLOT);		}		cp = cp2;	}#endif	while (vcomps NE NULL) {		tmp = vcomps -> next;		vcomps -> next = NULL;		free_congested_component (vcomps);		vcomps = tmp;	}	free ((char *) orig_stour);	return (cp);}/* * Routine to add the subtour constraint designated by the given component * to the list of constraints. */	static	struct constraint *add_component_subtour (struct comp *		comp,		/* IN - component to add subtour of */double *		x,		/* IN - LP solution vector */bitmap_t *		edge_mask,	/* IN - set of valid hyperedges */struct cinfo *		cip,		/* IN - compatibility info */struct constraint *	cp,		/* IN - existing constraints */bitmap_t *		stour		/* IN - temporary bitmap buffer */){int			kmasks;struct constraint *	cp2;	kmasks = cip -> num_vert_masks;	component_verts_to_real_verts (comp -> vert_mask, comp, stour, kmasks);	/* See if this constraint is already present... */	for (cp2 = cp; cp2 NE NULL; cp2 = cp2 -> next) {		if (is_equal (stour, cp2 -> mask, kmasks)) {			/* Already there... */			return (cp);		}	}	/* Add it to the list (if it is a violation) */	cp = check_subtour (stour, cp, x, edge_mask, cip);	return (cp);}/* * This routine converts a vertex subset within a given component * back into the corresponding subset of the original vertices. * Specifying a NULL pointer for comp_S is a convenient way to specify * that the entire component is to be translated back out. */	static	voidcomponent_verts_to_real_verts (bitmap_t *		comp_S,	/* IN - subset of vertices in component */struct comp *		comp,	/* IN - component those vertices are in */bitmap_t *		real_S,	/* OUT - real set of vertices */int			kmasks	/* IN - size of real_S */){int			i;int			j;int *			ip1;int *			ip2;	/* Zero out entire set of real vertices... */	for (i = 0; i < kmasks; i++) {		real_S [i] = 0;	}	/* Set the "real" vertex number bits for each component vertex. */	for (i = 0; i < comp -> num_verts; i++) {		if ((comp_S NE NULL) AND (NOT BITON (comp_S, i))) continue;		ip1 = comp -> rverts [i];		ip2 = comp -> rverts [i + 1];		while (ip1 < ip2) {			j = *ip1++;			SETBIT (real_S, j);		}	}}

⌨️ 快捷键说明

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