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

📄 snaphu_cs2.c

📁 phase unwrapping algorithm for SAR interferometry
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************   This code is derived from cs2 v3.7  Written by Andrew V. Goldberg and Boris Cherkassky  Modifications for use in snaphu by Curtis W. Chen   The cs2 code is used here with permission for strictly noncommerical  use.  The original cs2 source code can be downloaded from     http://www.igsystems.com/cs2  The original cs2 copyright is stated as follows:    COPYRIGHT C 1995 IG Systems, Inc.  Permission to use for    evaluation purposes is granted provided that proper    acknowledgments are given.  For a commercial licence, contact    igsys@eclipse.net.        This software comes with NO WARRANTY, expressed or implied. By way    of example, but not limitation, we make no representations of    warranties of merchantability or fitness for any particular    purpose or that the use of the software components or    documentation will not infringe any patents, copyrights,    trademarks, or other rights.  Copyright 2002 Board of Trustees, Leland Stanford Jr. University*************************************************************************//* min-cost flow *//* successive approximation algorithm *//* Copyright C IG Systems, igsys@eclipse.com *//* any use except for evaluation purposes requires a licence *//* parser changed to take input from passed data *//* main() changed to callable function *//* outputs parsed as flow *//* functions made static *//* MAX and MIN macros renamed GREATEROF and LESSEROF */#ifndef NO_CS2/************************************** constants  &  parameters ********/#include <stdio.h>#include <stdlib.h>#include <math.h>#include <signal.h>#include <limits.h>#include <float.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#include <assert.h>#include "snaphu.h"/* for measuring time *//* definitions of types: node & arc */#define PRICE_MAX           1e30#define BIGGEST_FLOW        LARGESHORT#include "snaphu_cs2types.h"/* parser for getting  DIMACS format input and transforming the   data to the internal representation */#include "snaphu_cs2parse.c"#define N_NODE( i ) ( ( (i) == NULL ) ? -1 : ( (i) - ndp + nmin ) )#define N_ARC( a ) ( ( (a) == NULL )? -1 : (a) - arp )#define UNFEASIBLE          2#define ALLOCATION_FAULT    5#define PRICE_OFL           6/* parameters */#define UPDT_FREQ      0.4#define UPDT_FREQ_S    30#define SCALE_DEFAULT  12.0/* PRICE_OUT_START may not be less than 1 */#define PRICE_OUT_START 1#define CUT_OFF_POWER    0.44#define CUT_OFF_COEF     1.5#define CUT_OFF_POWER2   0.75#define CUT_OFF_COEF2    1#define CUT_OFF_GAP      0.8#define CUT_OFF_MIN      12#define CUT_OFF_INCREASE 4/*#define TIME_FOR_PRICE_IN    5*/#define TIME_FOR_PRICE_IN1    2#define TIME_FOR_PRICE_IN2    4#define TIME_FOR_PRICE_IN3    6#define EMPTY_PUSH_COEF      1.0/*#define MAX_CYCLES_CANCELLED 10#define START_CYCLE_CANCEL   3*/#define MAX_CYCLES_CANCELLED 0#define START_CYCLE_CANCEL   100/************************************************ shared macros *******/#define GREATEROF( x, y ) ( ( (x) > (y) ) ?  x : y )#define LESSEROF( x, y ) ( ( (x) < (y) ) ? x : y )#define OPEN( a )   ( a -> r_cap > 0 )#define CLOSED( a )   ( a -> r_cap <= 0 )#define REDUCED_COST( i, j, a ) ( (i->price) + dn*(a->cost) - (j->price) )#define FEASIBLE( i, j, a )     ( (i->price) + dn*(a->cost) < (j->price) )#define ADMISSIBLE( i, j, a )   ( OPEN(a) && FEASIBLE( i, j, a ) )#define INCREASE_FLOW( i, j, a, df )\{\   (i) -> excess            -= df;\   (j) -> excess            += df;\   (a)            -> r_cap  -= df;\  ((a) -> sister) -> r_cap  += df;\}\/*---------------------------------- macros for excess queue */#define RESET_EXCESS_Q \{\   for ( ; excq_first != NULL; excq_first = excq_last )\     {\	excq_last            = excq_first -> q_next;\        excq_first -> q_next = sentinel_node;\     }\}#define OUT_OF_EXCESS_Q( i )  ( i -> q_next == sentinel_node )#define EMPTY_EXCESS_Q    ( excq_first == NULL )#define NONEMPTY_EXCESS_Q ( excq_first != NULL )#define INSERT_TO_EXCESS_Q( i )\{\   if ( NONEMPTY_EXCESS_Q )\     excq_last -> q_next = i;\   else\     excq_first  = i;\\   i -> q_next = NULL;\   excq_last   = i;\}#define INSERT_TO_FRONT_EXCESS_Q( i )\{\   if ( EMPTY_EXCESS_Q )\     excq_last = i;\\   i -> q_next = excq_first;\   excq_first  = i;\}#define REMOVE_FROM_EXCESS_Q( i )\{\   i           = excq_first;\   excq_first  = i -> q_next;\   i -> q_next = sentinel_node;\}/*---------------------------------- excess queue as a stack */#define EMPTY_STACKQ      EMPTY_EXCESS_Q#define NONEMPTY_STACKQ   NONEMPTY_EXCESS_Q#define RESET_STACKQ  RESET_EXCESS_Q#define STACKQ_PUSH( i )\{\   i -> q_next = excq_first;\   excq_first  = i;\}#define STACKQ_POP( i ) REMOVE_FROM_EXCESS_Q( i )/*------------------------------------ macros for buckets */node dnd, *dnode;#define RESET_BUCKET( b )  ( b -> p_first ) = dnode;#define INSERT_TO_BUCKET( i, b )\{\i -> b_next                  = ( b -> p_first );\( b -> p_first ) -> b_prev   = i;\( b -> p_first )             = i;\}#define NONEMPTY_BUCKET( b ) ( ( b -> p_first ) != dnode )#define GET_FROM_BUCKET( i, b )\{\i    = ( b -> p_first );\( b -> p_first ) = i -> b_next;\}#define REMOVE_FROM_BUCKET( i, b )\{\if ( i == ( b -> p_first ) )\       ( b -> p_first ) = i -> b_next;\  else\    {\       ( i -> b_prev ) -> b_next = i -> b_next;\       ( i -> b_next ) -> b_prev = i -> b_prev;\    }\}/*------------------------------------------- misc macros */#define UPDATE_CUT_OFF \{\   if (n_bad_pricein + n_bad_relabel == 0) \     {\	cut_off_factor = CUT_OFF_COEF2 * pow ( (double)n, CUT_OFF_POWER2 );\        cut_off_factor = GREATEROF ( cut_off_factor, CUT_OFF_MIN );\        cut_off        = cut_off_factor * epsilon;\        cut_on         = cut_off * CUT_OFF_GAP;\      }\     else\       {\	cut_off_factor *= CUT_OFF_INCREASE;\        cut_off        = cut_off_factor * epsilon;\        cut_on         = cut_off * CUT_OFF_GAP;\	}\}#define TIME_FOR_UPDATE \( n_rel > n * UPDT_FREQ + n_src * UPDT_FREQ_S )#define FOR_ALL_NODES_i        for ( i = nodes; i != sentinel_node; i ++ )#define FOR_ALL_ARCS_a_FROM_i \for ( a = i -> first, a_stop = ( i + 1 ) -> suspended; a != a_stop; a ++ )#define FOR_ALL_CURRENT_ARCS_a_FROM_i \for ( a = i -> current, a_stop = ( i + 1 ) -> suspended; a != a_stop; a ++ )#define WHITE 0#define GREY  1#define BLACK 2arc     *sa, *sb;long    d_cap;#define EXCHANGE( a, b )\{\if ( a != b )\  {\     sa = a -> sister;\     sb = b -> sister;\\     d_arc.r_cap = a -> r_cap;\     d_arc.cost  = a -> cost;\     d_arc.head  = a -> head;\\     a -> r_cap  = b -> r_cap;\     a -> cost   = b -> cost;\     a -> head   = b -> head;\\     b -> r_cap  = d_arc.r_cap;\     b -> cost   = d_arc.cost;\     b -> head   = d_arc.head;\\     if ( a != sb )\       {\	  b -> sister = sa;\	  a -> sister = sb;\	  sa -> sister = b;\	  sb -> sister = a;\        }\\     d_cap       = cap[a-arcs];\     cap[a-arcs] = cap[b-arcs];\     cap[b-arcs] = d_cap;\  }\}#define SUSPENDED( i, a ) ( a < i -> first ) long n_push      =0,     n_relabel   =0,     n_discharge =0,     n_refine    =0,     n_update    =0,     n_scan      =0,     n_prscan    =0,     n_prscan1   =0,     n_prscan2   =0,     n_bad_pricein = 0,     n_bad_relabel = 0,     n_prefine   =0;long   n,                    /* number of nodes */       m;                    /* number of arcs */short   *cap;                 /* array containig capacities */node   *nodes,               /* array of nodes */       *sentinel_node,       /* next after last */       *excq_first,          /* first node in push-queue */       *excq_last;           /* last node in push-queue */arc    *arcs,                /* array of arcs */       *sentinel_arc;        /* next after last */bucket *buckets,             /* array of buckets */       *l_bucket;            /* last bucket */long   linf;                 /* number of l_bucket + 1 */double dlinf;                /* copy of linf in double mode */int time_for_price_in;double epsilon,              /* optimality bound */       low_bound,            /* lowest bound for epsilon */       price_min,            /* lowest bound for prices */       f_scale,              /* scale factor */       dn,                   /* cost multiplier - number of nodes  + 1 */       mmc,                  /* multiplied maximal cost */       cut_off_factor,       /* multiplier to produce cut_on and cut_off				from n and epsilon */       cut_on,               /* the bound for returning suspended arcs */       cut_off;              /* the bound for suspending arcs */double total_excess;         /* total excess */long   n_rel,                /* number of relabels from last price update */       n_ref,                /* current number of refines */       n_src;                /* current number of nodes with excess */int   flag_price = 0,        /* if = 1 - signal to start price-in ASAP - 				maybe there is infeasibility because of				susoended arcs */      flag_updt = 0;         /* if = 1 - update failed some sources are 				unreachable: either the problem is				unfeasible or you have to return                                 suspended arcs */long  empty_push_bound;      /* maximal possible number of zero pushes                                during one discharge */int   snc_max;               /* maximal number of cycles cancelled                                during price refine */arc   d_arc;                 /* dummy arc - for technical reasons */node  d_node,                /* dummy node - for technical reasons */      *dummy_node;           /* the address of d_node *//************************************************ abnormal finish **********/static void err_end ( cc )int cc;{fprintf ( sp0, "\ncs2 solver: Error %d ", cc );if(cc==ALLOCATION_FAULT){  fprintf(sp0,"(allocation fault)\n");}else if(cc==UNFEASIBLE){  fprintf(sp0,"(problem infeasible)\n");}else if(cc==PRICE_OFL){  fprintf(sp0,"(price overflow)\n");}/*2 - problem is unfeasible5 - allocation fault6 - price overflow*/exit(ABNORMAL_EXIT);/* exit ( cc ); */}/************************************************* initialization **********/static void cs_init ( n_p, m_p, nodes_p, arcs_p, f_sc, max_c, cap_p )long    n_p,        /* number of nodes */        m_p;        /* number of arcs */node    *nodes_p;   /* array of nodes */arc     *arcs_p;    /* array of arcs */long    f_sc;       /* scaling factor */double  max_c;      /* maximal cost */short    *cap_p;     /* array of capacities (changed to short by CWC) */{node   *i;          /* current node *//*arc    *a;  */        /* current arc */bucket *b;          /* current bucket */n             = n_p;nodes         = nodes_p;sentinel_node = nodes + n;m    = m_p;arcs = arcs_p;sentinel_arc  = arcs + m;cap = cap_p;f_scale = f_sc;low_bound = 1.00001; dn = (double) n ;  /*for ( a = arcs ; a != sentinel_arc ; a ++ )  a -> cost *= dn;  */mmc = max_c * dn;linf   = n * f_scale + 2;dlinf  = (double)linf;buckets = (bucket*) CAlloc ( linf, sizeof (bucket) );if ( buckets == NULL )    err_end ( ALLOCATION_FAULT );l_bucket = buckets + linf;dnode = &dnd;for ( b = buckets; b != l_bucket; b ++ )   RESET_BUCKET ( b );epsilon = mmc;if ( epsilon < 1 )  epsilon = 1;price_min = - PRICE_MAX;FOR_ALL_NODES_i   {    i -> price  = 0;    i -> suspended = i -> first;    i -> q_next = sentinel_node;  }sentinel_node -> first = sentinel_node -> suspended = sentinel_arc;cut_off_factor = CUT_OFF_COEF * pow ( (double)n, CUT_OFF_POWER );cut_off_factor = GREATEROF ( cut_off_factor, CUT_OFF_MIN );n_ref = 0;flag_price = 0;dummy_node = &d_node;excq_first = NULL;empty_push_bound = n * EMPTY_PUSH_COEF;} /* end of initialization *//********************************************** up_node_scan *************/static void up_node_scan ( i )node *i;                      /* node for scanning */{node   *j;                     /* opposite node */arc    *a,                     /* ( i, j ) */       *a_stop,                /* first arc from the next node */       *ra;                    /* ( j, i ) */bucket *b_old,                 /* old bucket contained j */       *b_new;                 /* new bucket for j */long   i_rank,       j_rank,                 /* ranks of nodes */       j_new_rank;             double rc,                     /* reduced cost of (j,i) */       dr;                     /* rank difference */n_scan ++;i_rank = i -> rank;FOR_ALL_ARCS_a_FROM_i   {    ra = a -> sister;    if ( OPEN ( ra ) )      {	j = a -> head;	j_rank = j -> rank;	if ( j_rank > i_rank )	  {	    if ( ( rc = REDUCED_COST ( j, i, ra ) ) < 0 ) 	        j_new_rank = i_rank;	    else	      {		dr = rc / epsilon;		j_new_rank = ( dr < dlinf ) ? i_rank + (long)dr + 1		                            : linf;	      }	    if ( j_rank > j_new_rank )	      {		j -> rank = j_new_rank;		j -> current = ra;		if ( j_rank < linf )		  {		    b_old = buckets + j_rank;		    REMOVE_FROM_BUCKET ( j, b_old )		  }		b_new = buckets + j_new_rank;		INSERT_TO_BUCKET ( j, b_new )  	      }	  }      }  } /* end of scanning arcs */i -> price -= i_rank * epsilon;i -> rank = -1;}/*************************************************** price_update *******/static void  price_update (){register node   *i;double remain;                 /* total excess of unscanned nodes with                                  positive excess */bucket *b;                     /* current bucket */double dp;                     /* amount to be subtracted from prices */n_update ++;FOR_ALL_NODES_i   {    if ( i -> excess < 0 )      {	INSERT_TO_BUCKET ( i, buckets );	i -> rank = 0;      }    else      {        i -> rank = linf;      }  }remain = total_excess;if ( remain < 0.5 ) return;/* main loop */for ( b = buckets; b != l_bucket; b ++ )  {    while ( NONEMPTY_BUCKET ( b ) )       {	 GET_FROM_BUCKET ( i, b )	 up_node_scan ( i );	 if ( i -> excess > 0 )	   {	     remain -= (double)(i -> excess);             if ( remain <= 0  ) break; 	   }       } /* end of scanning the bucket */    if ( remain <= 0  ) break;   } /* end of scanning buckets */if ( remain > 0.5 ) flag_updt = 1;/* finishup *//* changing prices for nodes which were not scanned during main loop */dp = ( b - buckets ) * epsilon;FOR_ALL_NODES_i   {    if ( i -> rank >= 0 )    {      if ( i -> rank < linf )	REMOVE_FROM_BUCKET ( i, (buckets + i -> rank) );      if ( i -> price > price_min )	i -> price -= dp;    }  }

⌨️ 快捷键说明

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