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

📄 refine.c

📁 graphcut源代码
💻 C
字号:
#include	<stdio.h>#include	"csa_types.h"#include	"csa_defs.h"#ifdef	QUICK_MIN#define	sort_insert(best, size, a, a_prc, nsize) \\{\unsigned	si_i, si_j;\\if (size == 0)\  best[0] = a;\else\  {\  si_j = size;\  for (si_i = 0; si_i < size; si_i++)\    if (a_prc < best[si_i]->c - best[si_i]->head->p)\      {\      si_j = si_i;\      for (si_i = nsize - 1; si_i > si_j; si_i--)\	best[si_i] = best[si_i - 1];\      break;\      }\  best[si_j] = a;\  }\}#endifextern	lhs_ptr		head_lhs_node, tail_lhs_node;#ifdef	DEBUGextern	rhs_ptr		head_rhs_node;#endifextern	double		epsilon;extern	unsigned	total_e;extern	ACTIVE_TYPE	active;extern	double		po_cost_thresh;#ifdef	USE_SP_AUGextern	void		sp_aug();#endif#ifdef	USE_P_UPDATEextern	WORK_TYPE	upd_work_thresh;extern	void		p_update();#endif#ifdef	STRONG_POextern	WORK_TYPE	po_work_thresh;extern	int		check_po_arcs();#endif#if	defined(DEBUG) && defined(CHECK_EPS_OPT)extern	void		check_e_o();#endif#ifdef	CHECK_EPS_OPTextern	int		check_e_o_node();extern	rhs_ptr		head_rhs_node;#endifextern	char		*st_pop(), *deq();extern	unsigned	myclock();extern	unsigned	refine_time;extern	unsigned	double_pushes, pushes, relabelings, refines;#ifdef	QUICK_MINextern	unsigned	rebuilds, scans, non_scans;#endif#ifdef	EXPLICIT_LHS_PRICESextern	unsigned	unnec_rel;#endif#ifdef	QUICK_MINvoid	best_build(v)lhs_ptr	v;{unsigned	i;lr_aptr		a, a_stop;double		red_cost, save_max;rebuilds++;for (i = 0, a = v->first; i < NUM_BEST; i++, a++)  {  red_cost = a->c - a->head->p;  sort_insert(v->best, i, a, red_cost, i + 1);  }#ifdef	LOOSE_BOUNDv->next_best = v->best[NUM_BEST - 1]->c -	       v->best[NUM_BEST - 1]->head->p;#else/*Calculate initial next_best by looking at the next arc in theadjacency list.*/if ((v->next_best = a->c - a->head->p) <    (red_cost = v->best[NUM_BEST - 1]->c -		v->best[NUM_BEST - 1]->head->p))  {  sort_insert(v->best, NUM_BEST, a, v->next_best, NUM_BEST);  v->next_best = red_cost;  }a++;#endif/*Now go through remaining arcs in adjacency list and place each oneat the appropriate place in best[], if any.*/a_stop = (v+1)->priced_out;for (; a != a_stop; a++)  {  if ((red_cost = a->c - a->head->p) < v->next_best)#ifdef	LOOSE_BOUND    {    sort_insert(v->best, NUM_BEST, a, red_cost, NUM_BEST);    v->next_best = v->best[NUM_BEST - 1]->c -		   v->best[NUM_BEST - 1]->head->p;    }#else    if (red_cost < (save_max = v->best[NUM_BEST - 1]->c -			       v->best[NUM_BEST - 1]->head->p))      {      sort_insert(v->best, NUM_BEST, a, red_cost, NUM_BEST);      v->next_best = save_max;      }    else      v->next_best = red_cost;#endif  }}#endif/* Assume v has excess (is unassigned) and do a double push from v. */void	double_push(v)lhs_ptr	v;{double	v_pref, v_second, red_cost, adm_gap;lr_aptr	a, a_stop, adm;rhs_ptr	w;lhs_ptr	u;#ifdef	QUICK_MINunsigned	i;lr_aptr		*check_arc;#endif#ifdef	DEBUG(void) printf("%lu p's, %lu dp's: dp on %ld ", pushes, double_pushes,	      v - head_lhs_node + 1);#endif/*Begin part I: Compute the following:  o adm, the minimum-reduced-cost arc incident to v,  o adm_gap, the amount by which the reduced cost of adm must be    increased to make it equal in reduced cost to another arc incident    to v, or enough to price the arc out if it is the only incident    arc.*/#ifdef	QUICK_MINif (v->node_info.few_arcs)  {  scans++;#endif  /*  If the input problem is feasible, it is never the case that  (a_stop == a) after the following two lines because we never get  excess at a node with no incident arcs.  */  a_stop = (v+1)->priced_out;  a = v->first;  v_pref = a->c - a->head->p;  v_second = v_pref + epsilon * (po_cost_thresh + 1.0);  adm = a;  /*  After this loop, v_pref is the minimum reduced cost of an edge out of  v, and v_second is the second-to-minimum such reduced cost.  */  for (a++; a != a_stop; a++)    if (v_pref > (red_cost = a->c - a->head->p))      {      v_second = v_pref;      v_pref = red_cost;      adm = a;      }    else if (v_second > red_cost)      v_second = red_cost;#ifdef	QUICK_MIN  }else  {  /*  Find the minimum and second-minimum edges listed in the node's  best[] array, and check whether their present partial reduced  costs are below the node's bound as stored in next_best. If they  are, we calculate adm_gap and are done with part I. If not, we  rebuild the best[] array and the next_best bound, and calculate the  required information.  */  adm = v->best[1];  v_second = adm->c - adm->head->p;  adm = v->best[0];  v_pref = adm->c - adm->head->p;  if (v_pref > v_second)    {    adm = v->best[1];    red_cost = v_second;    v_second = v_pref;    v_pref = red_cost;    }#if	(NUM_BEST > 2)  for (i = NUM_BEST - 2, check_arc = &v->best[2]; i > 0; i--, check_arc++)    {    a = *check_arc;    if (v_pref > (red_cost = a->c - a->head->p))      {      v_second = v_pref;      v_pref = red_cost;      adm = a;      }    else if (v_second > red_cost)      v_second = red_cost;    }#endif  if (v_second > v->next_best)    {    /*    Rebuild the best[] array and recalculate next_best.    !v->node_info.few_arcs, so we know there are enough incident arcs    to fill up best[] initially and have one left over for next_best.    */    best_build(v);    adm = v->best[1];    v_second = adm->c - adm->head->p;    adm = v->best[0];    v_pref = adm->c - adm->head->p;    }  else    non_scans++;  }#endifadm_gap = v_second - v_pref;#ifdef	EXPLICIT_LHS_PRICESif (v->p + v_pref > epsilon)  {  /*  v needs relabeling, so we rack up a relabeling that we wouldn't if  we were using implicit prices. This relabeling makes adm an  admissible arc.  */  unnec_rel++;  v->p = -v_pref;  }#endif#ifdef	DEBUG(void) printf("to %lu. Gap = %lg\n", adm->head - head_rhs_node + 1, adm_gap);#endif/*Begin part II: Using the information computed in part I,  o match v to w, adm's head, and  o unmatch the node (if any) formerly matched to w.In the case where w's current matching arc is priced out, we do notchange the matching, but we reset the value of adm_gap so that the(v, w) arc will be priced out.*/w = adm->head;if (u = w->matched)  /*  If w's matched arc is priced in, go ahead and unmatch (u, w) and  match (v, w). If w's matched arc is priced out, abort the double  push and relabel w so v no longer prefers w.  */  if (w->node_info.priced_in)    {    pushes += 2;    double_pushes++;    u->matched = NULL;    make_active(u);    v->matched = adm;    w->matched = v;    }  else    {    adm_gap = epsilon * po_cost_thresh;    make_active(v);    }else  {  total_e--;  pushes++;  v->matched = adm;  w->matched = v;  }#ifdef	EXPLICIT_LHS_PRICES/*Relabel v: v's price is chosen to make the reduced cost of v's newpreferred arc (v->p + v_pref + adm_gap) equal to zero.*/relabelings++;v->p = -(v_pref + adm_gap);#endif/*Relabel w: v's price is chosen to make the implicit reduced cost ofv's new preferred arc (v_pref + adm_gap) equal to zero. Then w's priceis chosen so that the arc just matched has implicit reduced cost-epsilon.*/relabelings++;w->p -= adm_gap + epsilon;}void	refine(){lhs_ptr	v;#ifdef	USE_P_UPDATEWORK_TYPE	old_refine_work_upd;#endif#ifdef	STRONG_POWORK_TYPE	old_refine_work_po;#endifrefine_time -= myclock();refines++;/*Saturate all negative arcs: Negative arcs are exactly thoseright-to-left matching arcs with negative reduced cost, and there isan interpretation of the implicit price function on the left thatadmits all right-to-left matching arcs. This interpretation isalways consistent with the stored prices of lhs nodes in the caseof EXPLICIT_PRICES.*/total_e = 0;for (v = head_lhs_node; v != tail_lhs_node; v++)  {  if (v->matched && v->matched->head->node_info.priced_in)    {    v->matched->head->matched = NULL;    v->matched = NULL;    }  if (v->matched == NULL)    {    total_e++;    make_active(v);    }  }#ifdef	USE_P_UPDATEold_refine_work_upd = REFINE_WORK;#endif#ifdef	STRONG_POold_refine_work_po = REFINE_WORK;#endif#ifdef	STRONG_POwhile ((total_e > 0) || (old_refine_work_po = REFINE_WORK,			 !check_po_arcs()))#elsewhile (total_e > EXCESS_THRESH)#endif  {#ifdef	USE_P_UPDATE  if (REFINE_WORK - old_refine_work_upd > upd_work_thresh)    {    old_refine_work_upd = REFINE_WORK;    p_update();#if	defined(DEBUG) && defined(CHECK_EPS_OPT)    check_e_o(epsilon);#endif    }#endif#ifdef	STRONG_PO  if (REFINE_WORK - old_refine_work_po > po_work_thresh)    {    old_refine_work_po = REFINE_WORK;    (void) check_po_arcs();#if	defined(DEBUG) && defined(CHECK_EPS_OPT)    check_e_o(epsilon);#endif    }#endif  get_active_node(v);  double_push(v);  }#ifdef	USE_SP_AUGif (total_e > 0)  sp_aug();#endifrefine_time += myclock();}

⌨️ 快捷键说明

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