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

📄 bb.c

📁 生成直角Steiner树的程序包
💻 C
📖 第 1 页 / 共 5 页
字号:
 * And besides, it would be a shame to NOT notice something this important * -- especially if we don't have ANY upper bound yet! */	boolcheck_for_better_IFS (double *		x,		/* IN - solution to test */struct bbinfo *		bbip,		/* IN - branch and bound info */double *		true_z		/* OUT - true Z value, if integral */){int			i;int			nedges;int			nmasks;struct cinfo *		cip;double			z;double			real_z;int			num_frac;	cip = bbip -> cip;	nedges	= cip -> num_edges;	/* The special try_branch code for lp_solve can leave us with	*/	/* an LP solution that isn't primal feasible.  In fact, it may	*/	/* not even satisfy the variable bounds!  Detect this case	*/	/* right up front.						*/	for (i = 0; i < nedges; i++) {		if (x [i] < -FUZZ) return (FALSE);		if (x [i] > 1.0 + FUZZ) return (FALSE);	}	if (NOT integer_feasible_solution (x,					   bbip -> tmap,					   bbip -> fset_mask,					   cip,					   &num_frac)) {		/* Not integer feasible -- get out. */		return (FALSE);	}	/* We literally stumbled across an Integer Feasible Solution!	*/	/* Re-calculate the final objective function (in order to	*/	/* eliminate some of the LP solver's numerical errors)...	*/	z = 0.0;	for (i = 0; i < nedges; i++) {		if (x [i] + FUZZ < 1.0) continue;		z += cip -> cost [i];	}	/* Give caller the correct Z value... */	*true_z = z;	/* Damn Intel FPU is keeping 80 bits for Z... */	/* Damn compilers keep getting smarter too!  ;^> */	store_double (&real_z, z);	if (real_z >= bbip -> best_z) {		/* No better than what we have... */		return (FALSE);	}	/* We have a new best integer feasible solution!  Record it!	*/	nmasks = cip -> num_edge_masks;	for (i = 0; i < nmasks; i++) {		bbip -> smt [i] = 0;	}	for (i = 0; i < nedges; i++) {		if (x [i] >= 0.5) {			SETBIT (bbip -> smt, i);		}	}	new_upper_bound (real_z, bbip);	return (TRUE);}/* * This routine saves the current basis of the given LP. */#ifdef CPLEX	static	voidsave_LP_basis (LP_t *			lp,		/* IN - LP to save basis for */struct basis_save *	basp		/* OUT - saved basis info */){int		rows;int		cols;	rows = _MYCPX_getnumrows (lp);	cols = _MYCPX_getnumcols (lp);	basp -> cstat = NEWA (cols, int);	basp -> rstat = NEWA (rows, int);	if (_MYCPX_getbase (lp, basp -> cstat, basp -> rstat) NE 0) {		fatal ("save_LP_basis: Bug 1.");	}}/* * Destroy the saved basis info... */	static	voiddestroy_LP_basis (struct basis_save *	basp		/* IN - basis info to free up */){#if CPLEX >= 40	free ((char *) (basp -> rstat));	free ((char *) (basp -> cstat));#endif}#endif/* * This routine tries the given branch by solving the LP.  It * returns the resulting objective value, or INF_DISTANCE if something * goes wrong (like infeasible). */#ifdef CPLEX	static	doubletry_branch (LP_t *			lp,		/* IN - LP to re-optimize */int			var,		/* IN - variable to try branching */int			dir,		/* IN - branch direction, 0 or 1 */double *		x,		/* OUT - LP solution obtained */double			ival,		/* IN - value to give if infeasible */struct basis_save *	basp		/* IN - basis to restore when done */){int		status;double		z;int		b_index [2];char		b_lu [2];double		b_bd [2];	--var;		/* vars are zero-origined in CPLEX... */	b_index [0] = var;	b_lu [0] = 'L';	b_index [1] = var;	b_lu [1] = 'U';	if (dir EQ 0) {		b_bd [0] = 0.0;		b_bd [1] = 0.0;	}	else {		b_bd [0] = 1.0;		b_bd [1] = 1.0;	}	if (_MYCPX_chgbds (lp, 2, b_index, b_lu, b_bd) NE 0) {		fatal ("try_branch: Bug 1.");	}	/* Solve the current LP instance... */	status = _MYCPX_dualopt (lp);	if (status NE 0) {		tracef (" %%  WARNING dualopt: status = %d\n", status);	}	/* Get current LP solution... */	if (_MYCPX_solution (lp, &status, &z, x, NULL, NULL, NULL) NE 0) {		fatal ("try_branch: Bug 2.");	}	/* Determine type of LP result... */	switch (status) {	case CPX_OPTIMAL:	case CPX_OPTIMAL_INFEAS:		break;	case CPX_INFEASIBLE:	case CPX_UNBOUNDED:			/* (CPLEX 3.0 sometimes gives us infeasible!) */	case CPX_OBJ_LIM:	/* Objective limit exceeded in Phase II. */		z = ival;		break;	default:		tracef (" %% Status = %d\n", status);		_MYCPX_lpwrite (lp, "core.lp");		fatal ("try_branch: Bug 2.");		break;	}	b_bd [0] = 0.0;	b_bd [1] = 1.0;	if (_MYCPX_chgbds (lp, 2, b_index, b_lu, b_bd) NE 0) {		fatal ("try_branch: Bug 3.");	}	/* Restore the basis... */	status = _MYCPX_copybase (lp, basp -> cstat, basp -> rstat);	if (status NE 0) {		fprintf (stderr, "try_branch: status = %d\n", status);		fatal ("try_branch: Bug 4.");	}	return (z);}#endif/* * This routine computes the lower-bound for the current node, which * consists of solving the LP and generating violated constraints * until either: * *	- LP becomes infeasible *	- LP objective meets or exceeds cutoff value *	- LP solution is integral *	- separation finds no more violated constraints */	static	intcompute_good_lower_bound (struct bbinfo *		bbip		/* IN - branch-and-bound info */){int			i;int			j;int			n;int			num_const;int			status;bitmap_t *		tmap;bitmap_t *		fset_mask;struct cinfo *		cip;LP_t *			lp;struct bbnode *		nodep;double *		x;double			z;struct constraint *	cp;struct constraint *	tmp;int			iteration;int			fix_status;int			num_fractional;cpu_time_t		Tlp;cpu_time_t *		Tp;bool			is_int;char			tbuf1 [16];char			tbuf2 [256];char			time_str [256];char			title [256];cpu_time_t		Tn [20];	cip	  = bbip -> cip;	tmap	  = bbip -> tmap;	fset_mask = bbip -> fset_mask;	lp	  = bbip -> lp;	nodep	  = bbip -> node;	x	  = nodep -> x;	Tp = &Tn [0];	*Tp++ = get_cpu_time ();	iteration = 1;	num_const = 0;	for (;;) {		status = solve_LP_over_constraint_pool (bbip);		z = nodep -> z;		Tlp = get_cpu_time ();		++(bbip -> node -> iter);		++(bbip -> statp -> num_lps);#if 0		/* Display LP solution vector in machine-readable form... */		for (i = 0; i < cip -> num_edges; i++) {			tracef (" %% %08lx %08lx\n",				((bitmap_t *) &x [i]) [0],				((bitmap_t *) &x [i]) [1]);		}#endif		if (Check_Root_Constraints AND		    (bbip -> node -> depth EQ 0)) {			fwrite (x,				1,				cip -> num_edges * sizeof (*x),				rcfile);		}#if 1		convert_cpu_time (Tlp - *--Tp, time_str);		while (Tp > &Tn [0]) {			--Tp;			convert_cpu_time (Tp [1] - Tp [0], tbuf1);			(void) sprintf (tbuf2, "%s/%s", tbuf1, time_str);			strcpy (time_str, tbuf2);		}		(void) sprintf (title,				"Node %d LP %d Solution, length = %f, %s %d",				bbip -> node -> num, bbip -> node -> iter,				z, time_str, num_const);#if 0		plot_lp_solution (title, x, cip, BIG_PLOT);#else		(void) tracef ("  %% %s\n", title);#endif#endif		switch (status) {		case BBLP_OPTIMAL:			if (z >= bbip -> best_z) {				nodep -> z = bbip -> best_z;				return (LB_CUTOFF);			}			break;		case BBLP_CUTOFF:			nodep -> z = bbip -> best_z;			return (LB_CUTOFF);		case BBLP_INFEASIBLE:			nodep -> z = bbip -> best_z;			return (LB_INFEASIBLE);		default:			tracef ("%% solve status = %d\n", status);			fatal ("compute_good_lower_bound: Bug 3.");		}#ifdef CPLEX		/* Now get rid of any rows that have become	*/		/* slack.  (We don't lose these constraints:	*/		/* they're still sitting around in the		*/		/* constraint pool.)				*/		delete_slack_rows_from_LP (bbip);#endif		/* Solution is feasible, check for integer-feasible... */		is_int = integer_feasible_solution (x,						    tmap,						    fset_mask,						    cip,						    &num_fractional);		tracef (" %% %d fractional variables\n", num_fractional);		if (is_int) {			/* All vars are either 0 or 1 and the	*/			/* solution is connected -- we have a	*/			/* Steiner tree!			*/			/* Re-calculate the final objective	*/			/* function to eliminate numerical	*/			/* errors in the value of Z...		*/			z = 0.0;			for (i = 0; i < cip -> num_edges; i++) {				if (x [i] + FUZZ < 1.0) continue;				z += cip -> cost [i];			}			nodep -> z = z;			if (z >= bbip -> best_z) {				/* probably a repeat performance... */				nodep -> z = bbip -> best_z;				return (LB_CUTOFF);			}			bbip -> node -> optimal = TRUE;			return (LB_INTEGRAL);		}		/* Check to see if this node's objective value	*/		/* is now high enough to be preempted...	*/		if (nodep -> z > bbip -> preempt_z) {			/* Node's value is no longer the lowest...	*/			/* Preempt this one in favor of another.	*/			return (LB_PREEMPTED);		}		/* Perhaps we have a new lower bound? */		new_lower_bound (z, bbip);		Tp = &Tn [0];		*Tp++ = get_cpu_time ();		compute_heuristic_upper_bound (x, bbip);		/* If we have improved the upper bound, it is possible	*/		/* that this node can now be cutoff...			*/		if (nodep -> z >= bbip -> best_z) {			nodep -> z = bbip -> best_z;			return (LB_CUTOFF);		}		/* Try to fix some variables using reduced costs... */		fix_status = reduced_cost_var_fixing (bbip);		if (fix_status EQ VFIX_INFEASIBLE) {			nodep -> z = bbip -> best_z;			return (LB_INFEASIBLE);		}		if (fix_status EQ VFIX_FIXED_FRACTIONAL) {			continue;		}		if (force_branch_flag) {			/* User kicked us!  Stop separating and branch! */			force_branch_flag = FALSE;			break;		}		/* Apply all separation algorithms to solution... */		cp = do_separations (bbip, &Tp);		if (cp EQ NULL) {			/* No more violated constraints found! */			break;		}#ifdef LPSOLVE		/* Now get rid of any rows that have become	*/		/* slack.  (We don't lose these constraints:	*/		/* they're still sitting around in the		*/		/* constraint pool.)				*/		delete_slack_rows_from_LP (bbip);#endif		/* Add new contraints to the constraint pool. */		num_const = add_constraints (bbip, cp);		if (num_const <= 0) {			/* Separation routines found violations, but	*/			/* the constraint pool disagrees...		*/			fatal ("compute_good_lower_bound: Bug 4.");		}		while (cp NE NULL) {			tmp = cp;			cp = tmp -> next;			free ((char *) (tmp -> mask));			free ((char *) tmp);		}		++iteration;	}#if 1	/* Print execution times of final iteration... */	convert_cpu_time (0, time_str);	--Tp;	while (Tp > &Tn [0]) {		--Tp;		convert_cpu_time (Tp [1] - Tp [0], tbuf1);		(void) sprintf (tbuf2, "%s/%s", tbuf1, time_str);		strcpy (time_str, tbuf2);	}	(void) tracef ("  %% Final iteration: %s\n", time_str);#endif	/* Only get here with fractional solution and	*/	/* no more violated constraints were found.	*/	return (LB_FRACTIONAL);}/* * Routine to print out an updated lower bound value. */	static	voidnew_lower_bound (double			lb,		/* IN - new lower bound value */struct bbinfo *		bbip		/* IN - branch-and-bound info */){int			i;struct cinfo *		cip;struct scale_info *	sip;double			prev;double			old_gap;double			new_gap;cpu_time_t		t1;char			buf1 [32];	cip = bbip -> cip;	sip = &(cip -> scale);	prev = bbip -> prevlb;	if (lb <= prev) {		/* There has been no improvement - get out. */		return;	}	if (prev <= -DBL_MAX) {		/* Don't make lower bound jump from initial value... */		prev = lb;	}	/* Print out the old and new lower bounds, with timestamp. */	t1 = get_cpu_time ();	convert_cpu_time (t1 - bbip -> t0, buf1);	if ((bbip -> best_z >= DBL_MAX) OR (bbip -> best_z EQ 0.0)) {		old_gap = 99.9;		new_gap = 99.9;	}	else {		old_gap = 100.0 * (bbip -> best_z - prev) / bbip -> best_z;		new_gap = 100.0 * (bbip -> best_z - lb) / bbip -> best_z;	}	tracef (" %% @LO %s %24.20f %2.10f\n",		buf1, UNSCALE (prev, sip), old_gap);	tracef (" %% @LN %s %24.20f %2.10f\n",		buf1, UNSCALE (lb, sip), new_gap);	bbip -> prevlb = lb;}/* * Routine to print out an updated upper bound value. */	voidnew_upper_bound (double			ub,		/* IN - new upper bound value */struct bbinfo *		bbip		/* IN - branch-and-bound info */){struct cinfo *		cip;struct scale_info *	sip;double			prev;int			i;cpu_time_t		t1;double			old_gap;double			new_gap;char			buf1 [64];char			buf2 [64];	cip = bbip -> cip;	sip = &(cip -> scale);	prev = bbip -> best_z;	if (ub >= prev) {		/* Supposed to be an improvement! */		fatal ("new_upper_bound: Bug 1.");	}	/* We HAVE a new best solution! */	bbip -> best_z = ub;#if CPLEX	{ double toobig, toosmall, ulim;	  /* Set new cutoff value for future LPs... */	  ulim = ldexp (ub, -(bbip -> lpmem -> obj_scale));	  if (_MYCPX_setobjulim (ulim, &toosmall, &toobig) NE 0) {		fatal ("new_upper_bound: Bug 2.");	  }	}#endif#if LPSOLVE	/* Set new cutoff value for future LPs... */	/* (This may not really work in lp_solve.) */	bbip -> lp -> obj_bound = ub;#endif	cut_off_existing_nodes (ub, bbip -> bbtree);	/* Might want to do this if all other nodes were cut off. */	update_node_preempt_value (bbip);	/* Now print out the trace messages. */	if (prev >= DBL_MAX) {		/* Don't make upper bound jump from infinity... */		prev = ub;

⌨️ 快捷键说明

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