📄 snaphu_cs2.c
字号:
} /* end of price_update *//****************************************************** relabel *********/static int relabel ( i )register node *i; /* node for relabelling */{register arc *a, /* current arc from i */ *a_stop, /* first arc from the next node */ *a_max; /* arc which provides maximum price */register double p_max, /* current maximal price */ i_price, /* price of node i */ dp; /* current arc partial residual cost */p_max = price_min;i_price = i -> price;for ( a = i -> current + 1, a_stop = ( i + 1 ) -> suspended; a != a_stop; a ++ ) { if ( OPEN ( a ) && ( ( dp = ( ( a -> head ) -> price ) - dn*( a -> cost ) ) > p_max ) ) { if ( i_price < dp ) { i -> current = a; return ( 1 ); } p_max = dp; a_max = a; } } /* 1/2 arcs are scanned */for ( a = i -> first, a_stop = ( i -> current ) + 1; a != a_stop; a ++ ) { if ( OPEN ( a ) && ( ( dp = ( ( a -> head ) -> price ) - dn*( a -> cost ) ) > p_max ) ) { if ( i_price < dp ) { i -> current = a; return ( 1 ); } p_max = dp; a_max = a; } } /* 2/2 arcs are scanned *//* finishup */if ( p_max != price_min ) { i -> price = p_max - epsilon; i -> current = a_max; }else { /* node can't be relabelled */ if ( i -> suspended == i -> first ) { if ( i -> excess == 0 ) { i -> price = price_min; } else { if ( n_ref == 1 ) { err_end ( UNFEASIBLE ); } else { err_end ( PRICE_OFL ); } } } else /* node can't be relabelled because of suspended arcs */ { flag_price = 1; } }n_relabel ++;n_rel ++;return ( 0 );} /* end of relabel *//***************************************************** discharge *********/static void discharge ( i )register node *i; /* node to be discharged */{register arc *a; /* an arc from i */arc *b, /* an arc from j */ *ra; /* reversed arc (j,i) */register node *j; /* head of a */register long df; /* amoumt of flow to be pushed through a */excess_t j_exc; /* former excess of j */int empty_push; /* number of unsuccessful attempts to push flow out of i. If it is too big - it is time for global update */n_discharge ++;empty_push = 0;a = i -> current;j = a -> head;if ( !ADMISSIBLE ( i, j, a ) ) { relabel ( i ); a = i -> current; j = a -> head; }while ( 1 ){ j_exc = j -> excess; if ( j_exc >= 0 ) { b = j -> current; if ( ADMISSIBLE ( j, b -> head, b ) || relabel ( j ) ) { /* exit from j exists */ df = LESSEROF ( i -> excess, a -> r_cap ); if (j_exc == 0) n_src++; INCREASE_FLOW ( i, j, a, df )n_push ++; if ( OUT_OF_EXCESS_Q ( j ) ) { INSERT_TO_EXCESS_Q ( j ); } } else { /* push back */ ra = a -> sister; df = LESSEROF ( j -> excess, ra -> r_cap ); if ( df > 0 ) { INCREASE_FLOW ( j, i, ra, df ); if (j->excess == 0) n_src--;n_push ++; } if ( empty_push ++ >= empty_push_bound ) { flag_price = 1; return; } } } else /* j_exc < 0 */ { df = LESSEROF ( i -> excess, a -> r_cap ); INCREASE_FLOW ( i, j, a, df )n_push ++; if ( j -> excess >= 0 ) { if ( j -> excess > 0 ) { n_src++; relabel ( j ); INSERT_TO_EXCESS_Q ( j ); } total_excess += j_exc; } else total_excess -= df; } if (i -> excess <= 0) n_src--; if ( i -> excess <= 0 || flag_price ) break; relabel ( i ); a = i -> current; j = a -> head;}i -> current = a;} /* end of discharge *//***************************************************** price_in *******/static int price_in (){node *i, /* current node */ *j;arc *a, /* current arc from i */ *a_stop, /* first arc from the next node */ *b, /* arc to be exchanged with suspended */ *ra, /* opposite to a */ *rb; /* opposite to b */double rc; /* reduced cost */int n_in_bad, /* number of priced_in arcs with negative reduced cost */ bad_found; /* if 1 we are at the second scan if 0 we are at the first scan */excess_t i_exc, /* excess of i */ df; /* an amount to increase flow */bad_found = 0;n_in_bad = 0; restart:FOR_ALL_NODES_i { for ( a = ( i -> first ) - 1, a_stop = ( i -> suspended ) - 1; a != a_stop; a -- ) { rc = REDUCED_COST ( i, a -> head, a ); if ( (rc < 0) && ( a -> r_cap > 0) ) { /* bad case */ if ( bad_found == 0 ) { bad_found = 1; UPDATE_CUT_OFF; goto restart; } df = a -> r_cap; INCREASE_FLOW ( i, a -> head, a, df ); ra = a -> sister; j = a -> head; b = -- ( i -> first ); EXCHANGE ( a, b ); if ( SUSPENDED ( j, ra ) ) { rb = -- ( j -> first ); EXCHANGE ( ra, rb ); } n_in_bad ++; } else if ( ( rc < cut_on ) && ( rc > -cut_on ) ) { b = -- ( i -> first ); EXCHANGE ( a, b ); } } }if ( n_in_bad != 0 ) { n_bad_pricein ++; /* recalculating excess queue */ total_excess = 0; n_src=0; RESET_EXCESS_Q; FOR_ALL_NODES_i { i -> current = i -> first; i_exc = i -> excess; if ( i_exc > 0 ) { /* i is a source */ total_excess += i_exc; n_src++; INSERT_TO_EXCESS_Q ( i ); } } INSERT_TO_EXCESS_Q ( dummy_node ); }if (time_for_price_in == TIME_FOR_PRICE_IN2) time_for_price_in = TIME_FOR_PRICE_IN3;if (time_for_price_in == TIME_FOR_PRICE_IN1) time_for_price_in = TIME_FOR_PRICE_IN2;return ( n_in_bad );} /* end of price_in *//************************************************** refine **************/static void refine () {node *i; /* current node */excess_t i_exc; /* excess of i *//* long np, nr, ns; */ /* variables for additional print */int pr_in_int; /* current number of updates between price_in *//*np = n_push; nr = n_relabel; ns = n_scan;*/n_refine ++;n_ref ++;n_rel = 0;pr_in_int = 0;/* initialize */total_excess = 0;n_src=0;RESET_EXCESS_Qtime_for_price_in = TIME_FOR_PRICE_IN1;FOR_ALL_NODES_i { i -> current = i -> first; i_exc = i -> excess; if ( i_exc > 0 ) { /* i is a source */ total_excess += i_exc; n_src++; INSERT_TO_EXCESS_Q ( i ) } }if ( total_excess <= 0 ) return;/* main loop */while ( 1 ) { if ( EMPTY_EXCESS_Q ) { if ( n_ref > PRICE_OUT_START ) { price_in (); } if ( EMPTY_EXCESS_Q ) break; } REMOVE_FROM_EXCESS_Q ( i ); /* push all excess out of i */ if ( i -> excess > 0 ) { discharge ( i ); if ( TIME_FOR_UPDATE || flag_price ) { if ( i -> excess > 0 ) { INSERT_TO_EXCESS_Q ( i ); } if ( flag_price && ( n_ref > PRICE_OUT_START ) ) { pr_in_int = 0; price_in (); flag_price = 0; } price_update(); while ( flag_updt ) { if ( n_ref == 1 ) { err_end ( UNFEASIBLE ); } else { flag_updt = 0; UPDATE_CUT_OFF; n_bad_relabel++; pr_in_int = 0; price_in (); price_update (); } } n_rel = 0; if ( n_ref > PRICE_OUT_START && (pr_in_int ++ > time_for_price_in) ) { pr_in_int = 0; price_in (); } } /* time for update */ } } /* end of main loop */return;} /*----- end of refine *//*************************************************** price_refine **********/static int price_refine (){node *i, /* current node */ *j, /* opposite node */ *ir, /* nodes for passing over the negative cycle */ *is;arc *a, /* arc (i,j) */ *a_stop, /* first arc from the next node */ *ar;long bmax; /* number of farest nonempty bucket */long i_rank, /* rank of node i */ j_rank, /* rank of node j */ j_new_rank; /* new rank of node j */bucket *b, /* current bucket */ *b_old, /* old and new buckets of current node */ *b_new;double rc, /* reduced cost of a */ dr, /* ranks difference */ dp;int cc; /* return code: 1 - flow is epsilon optimal 0 - refine is needed */long df; /* cycle capacity */int nnc, /* number of negative cycles cancelled during one iteration */ snc; /* total number of negative cycle cancelled */n_prefine ++;cc=1;snc=0;snc_max = ( n_ref >= START_CYCLE_CANCEL ) ? MAX_CYCLES_CANCELLED : 0;/* main loop */while ( 1 ){ /* while negative cycle is found or eps-optimal solution is constructed */nnc=0;FOR_ALL_NODES_i { i -> rank = 0; i -> inp = WHITE; i -> current = i -> first; }RESET_STACKQFOR_ALL_NODES_i { if ( i -> inp == BLACK ) continue; i -> b_next = NULL; /* deapth first search */ while ( 1 ) { i -> inp = GREY; /* scanning arcs from node i starting from current */ FOR_ALL_CURRENT_ARCS_a_FROM_i { if ( OPEN ( a ) ) { j = a -> head; if ( REDUCED_COST ( i, j, a ) < 0 ) { if ( j -> inp == WHITE ) { /* fresh node - step forward */ i -> current = a; j -> b_next = i; i = j; a = j -> current; a_stop = (j+1) -> suspended; break; } if ( j -> inp == GREY ) { /* cycle detected */ cc = 0; nnc++; i -> current = a; is = ir = i; df = BIGGEST_FLOW; while ( 1 ) { ar = ir -> current; if ( ar -> r_cap <= df ) { df = ar -> r_cap; is = ir; } if ( ir == j ) break; ir = ir -> b_next; } ir = i; while ( 1 ) { ar = ir -> current; INCREASE_FLOW( ir, ar -> head, ar, df) if ( ir == j ) break; ir = ir -> b_next; } if ( is != i ) { for ( ir = i; ir != is; ir = ir -> b_next ) ir -> inp = WHITE; i = is; a = (is -> current) + 1; a_stop = (is+1) -> suspended; break; } } } /* if j-color is BLACK - continue search from i */ } } /* all arcs from i are scanned */ if ( a == a_stop ) { /* step back */ i -> inp = BLACK;n_prscan1++; j = i -> b_next; STACKQ_PUSH ( i ); if ( j == NULL ) break; i = j; i -> current ++; } } /* end of deapth first search */ } /* all nodes are scanned *//* no negative cycle *//* computing longest paths with eps-precision */snc += nnc;if ( snc<snc_max ) cc = 1;if ( cc == 0 ) break;bmax = 0;while ( NONEMPTY_STACKQ ) {n_prscan2++; STACKQ_POP ( i ); i_rank = i -> rank; FOR_ALL_ARCS_a_FROM_i { if ( OPEN ( a ) ) { j = a -> head;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -