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

📄 match.c

📁 A salient-boundary extraction software package based on the paper: S. Wang, T. Kubota, J. M. Siskind
💻 C
📖 第 1 页 / 共 5 页
字号:
#include "match.h"#define NDEBUG   /* remove this to turn assertions on */#include <assert.h>#define GREEDY_DUAL_CHANGE #define SWITCH_LEVEL 32#define MAX_BAD_PORTION 0.25#define PRINT_LEVEL 0#define SHRINKS_SIZE 1000/* infinity */#define INTEGER_MIN -999999999#define INTEGER_MAX  999999999/* for labels */#define NIX 0#define PLUS 1#define MINUS 2/* for status */#define UNMATCHED 0#define HALVES 1#define MATCHED 2/* for x */#define HALF 2/*#define OTHEREND(e,n,list)  ((list) + (e)->nod1 + (e)->nod2 - ((n) - (list)))*/#define OTHEREND(e,n,list) (((e)->nod1 + (list)) == (n) ?                \                             (e)->nod2 + (list) : (e)->nod1 + (list))#define OTHEREND_INT(e,n) ((e)->nod1 + (e)->nod2 - (n))#define FIND_SURFACE(n) {                                                \            while((n)->blossom_parent != -1) {                           \                (n)=G->nodelist+(n)->blossom_parent;                     \            }                                                            \        }#define SHRINK_SORT_CONST 3#define BADCOUNT_CONST 10000#define PNODE(n) (G->nodelist + (n))#define PEDGE(e) (G->edgelist + (e))#define INODE(n) ((n) - G->nodelist)#define IEDGE(e) ((e) - G->edgelist)typedef struct edge {    int   slack;    int   label; /* added by S. Wang */    char  mark;      char  x;     int   ptrs[2];    int   nod1;    int   nod2;    int   orig_nod1;    int   orig_nod2;} edge;typedef struct node {    int   edg_list;    int   matched_edge;    /* These are for the augmenting path tree */    int   child;    int   sibling;    int   parent;    int   parent_edge;    /* These are for the blossom_tree */    int   blossom_next;    int   blossom_parent;    int   blossom_root;    int   blossom_next_edge;    int   penultimate;    int   pi;    int   mark;      /* unused pseudo nodes are linked by mark */    int   tree_root;    char  status;    char  label;    char  hit;    int   dummy;    /* just to pad to multiple of 8 bytes */} node;typedef struct nodeptr {    int next;    int surf;    int delta;    int dad;    int sum;    int status;#ifdef GREEDY_DUAL_CHANGE    char tree_processed;    int gnext;      /* used to pad to multiple of 8 bytes and in reordering */#endif} nodeptr;typedef struct shrink_ary_T {    int node_i;    int node_j;    int node_k;    int edge;    int size;    int next;} shrink_ary_T;typedef struct shrink_T {    shrink_ary_T *ary;    int length;} shrink_T;typedef struct expand_T {    int *node;    int length;} expand_T;typedef struct stats {    int expand_count;    int shrink_count;    int dualchange_count;    int dualzero_count;} stats;typedef struct graph {    edge *edgelist;    node *nodelist;    int nnodes;    int nedges;    int max_nedges;    int unused;    int unmatched;    nodeptr *roots;    int unmatched_count;}graph;typedef struct srkstuff {    expand_T expands;    shrink_T shrinks;    int shrinks_max;    int expands_max;    int shrinks_[SHRINKS_SIZE];} srkstuff;typedef struct stack {    int*             ary;    int              count;} stack;#ifdef  CC_PROTOTYPE_ANSIextern void    adjust_match (graph *G),    init_tree (graph *G, node *n),    clear_tree (graph *G, node *n),    make_cycle_halves (graph *G, node *node_i, node *node_j, node *node_k,        edge *e),    shrink_tree (graph *G, node *newnode),    label_penultimate (graph *G, node *n, int label),    fix_matching (graph *G, node *oldnode, node *x),    fix_tree (graph *G, node *oldnode, node *x, node *y),    flip_cycle (graph *G, node *node_i),    augment_path (graph *G, node *node_i, int fractional),    vereinigung (graph *G, int x, int y),    set_vereinigung (graph *G, node *n),    unmatch_edge (graph *G, edge *e),    dual_match_len (graph *G, int fractional, double *val),    fix_match (graph *G, int blossom),     *CCutil_allocrus (unsigned int size),    CCutil_freerus (void *p);extern int     perfect_match (graph *G, int *elen),    build_graph (graph *G, int ncount, int ecount, int *elist, int *elen),    init (graph *G, srkstuff *srk),    match_main_frac (graph *G, stats *scount, srkstuff *srk),    match_main (graph *G, stats *scount, srkstuff *srk, int use_all),    augment_blossom (graph *G, edge *, int fractional, srkstuff *srk),    lower_edges (graph *G, node *old),    expand_blossom (graph *G, node *oldnode, stats *scount),    lift_edges (graph *G, node *newnode),    add_to_tree (graph *G, edge *e, node *node_i, node *node_j, int fractional),    checkout_node (graph *G, node *n, int fractional, srkstuff *srk),    grow_tree_no_shrink (graph *G, node *n, int fractional, srkstuff *srk),    grow_tree (graph *G, node *n, int fractional, stats *scount, srkstuff *srk,               int *found_aug),    apply_dual_change (graph *G, node *n, int delta),    find_parity_sum (graph *G, int n),    parity_correction (graph *G, stats *scount),    find_single_dual_change (graph *G, node *n),    find_dual_change_forest (graph *G, node *n),    make_dual_change_forest (graph *G, stats *scount),    match_main_more_in_forest (graph *G, stats *scount, srkstuff *srk),    match_main_forest (graph *G, stats *scount, srkstuff *srk),    match_main_tree (graph *G, stats *scount, srkstuff *srk),    make_match (graph *G),    write_match (graph *G, int *elen, int *elen2, int *esolid, int *elabel_penul, char* match_file),    label_match (graph *G, int *elen, int *elen2, int *elen_bak, int *esolid,                  int *cycle1_min, int *cycle2_min, int *cycle1_orig_min, int *elabel),    CCutil_readint (FILE *f);extern node    *shrink_blossom (graph *G, node *node_i, node *node_j, node *node_k,        edge *e, stats *scount),    *common_parent (graph *G, node *node_i, node *node_j, int *size),    *find_below (graph *G, node *n, int blossom);#elseextern void    adjust_match (),    init_tree (),    clear_tree (),    make_cycle_halves (),    shrink_tree (),    label_penultimate (),    fix_matching (),    fix_tree (),    flip_cycle (),    augment_path (),    vereinigung (),    set_vereinigung (),    unmatch_edge (),    dual_match_len (),    fix_match (),    *CCutil_allocrus (),    CCutil_freerus ();extern int     perfect_match (),    build_graph (),    init (),    match_main_frac (),    match_main (),    augment_blossom (),    lower_edges (),    expand_blossom (),    lift_edges (),    add_to_tree (),    checkout_node (),    grow_tree_no_shrink (),    grow_tree (),    apply_dual_change (),    find_parity_sum (),    parity_correction (),    find_single_dual_change (),    find_dual_change_forest (),    make_dual_change_forest (),    make_match (),    match_main_more_in_forest (),    match_main_forest (),    match_main_tree (),    write_match (),    label_match (),    CCutil_readint ();extern node    *shrink_blossom (),    *common_parent (),    *find_below ();#endif#if PRINT_LEVELstatic graph *PG = (graph *) NULL;#endif#ifdef CC_PROTOTYPE_ANSIint min_ratio_cycle (int ncount, int ecount, int **elist, int **elen,     int **elen2, int **esolid, char *mat_filename, int NumIteration)#elseint min_ratio_cycle (ncount, ecount, elist, elen, elen2, esolid,                      mat_filename, NumIteration)int ncount, ecount;int **elist, **elen, **elen2, **esolid;char *mat_filename;#endif{    graph G;    int **elabel, **elabel_penul, **elen_bak, **elen2_bak, **elen_bak2;    int hh, i, end1, end2, cycle1_min, cycle2_min, cycle1_orig_min;    int iter;    char current_filename[255];    int node_inv[ncount], merge_w1[ncount], merge_w2[ncount];     //edge *e;    hh =0;    for (i = 0; i < ecount; i++)      hh = hh + ((*esolid)[i])%2; /* 0: dashed; 1: solid; 2: boundary dashed */    fprintf (stderr, "# of node = %i\n", ncount);    fprintf (stderr, "# of solid-edges = %i\n", hh);    fprintf (stderr, "# of dashed-edges= %i\n", ecount-hh);      elabel = CC_SAFE_MALLOC(1, int *);     elabel_penul = CC_SAFE_MALLOC(1, int *);    elen_bak = CC_SAFE_MALLOC(1, int *);    elen2_bak = CC_SAFE_MALLOC(1, int *);    elen_bak2 = CC_SAFE_MALLOC(1, int *);    *elabel = CC_SAFE_MALLOC(ecount, int);    if (!(*elabel)) {        fprintf (stderr, "out of memory in getedgelist\n");        CC_FREE (*elabel, int);        return 1;    }    *elabel_penul = CC_SAFE_MALLOC(ecount, int);    if (!(*elabel_penul)) {        fprintf (stderr, "out of memory in getedgelist\n");        CC_FREE (*elabel_penul, int);        return 1;    }    *elen_bak = CC_SAFE_MALLOC(ecount, int);    if (!(*elen_bak)) {        fprintf (stderr, "out of memory in getedgelist\n");        CC_FREE (*elen_bak, int);        return 1;    }    *elen2_bak = CC_SAFE_MALLOC(ecount, int);    if (!(*elen2_bak)) {        fprintf (stderr, "out of memory in getedgelist\n");        CC_FREE (*elen2_bak, int);        return 1;    }    *elen_bak2 = CC_SAFE_MALLOC(ecount, int);    if (!(*elen_bak2)) {       fprintf (stderr, "out of memory in getedgelist\n");       CC_FREE (*elen_bak2, int);       return 1;    }    for (iter = 0; iter < NumIteration; iter ++){        sprintf(current_filename, "%s-%d.cycle", mat_filename, iter);        for (i = 0; i < ncount; i++) 	     node_inv[i] = 0;        for (i = 0; i < ecount; i++) {          (*elabel)[i] = 0;  /* initialize the edge labels*/          (*elen_bak)[i] = (*elen)[i]; /* make a copy of edge weight */                    (*elen2_bak)[i] = (*elen2)[i]; /* make a copy of second edge weight */          (*elen)[i] = (*elen)[i]*2; /* double all the first weights */                    (*elen2)[i] = (*elen2)[i]*2; /* double all the second weights */        }        for (i = 0; i < ecount; i++) {	   if ((*esolid)[i] == 1) {	      end1 = (*elist)[i*2];              end2 = (*elist)[i*2+1];              merge_w1[end1] = (*elen_bak)[i]; /* set solid-edge weights to be zero */              merge_w2[end1] = (*elen2_bak)[i];              merge_w1[end2] = (*elen_bak)[i];              merge_w2[end2] = (*elen2_bak)[i];              (*elen)[i] = 0;              (*elen2)[i] = 0;	   }         }               for (i = 0; i < ecount; i++) {	  if ((*esolid)[i] != 1) {	     end1 = (*elist)[i*2]; /* merge solid weights to the dashed ones */             end2 = (*elist)[i*2+1];             (*elen)[i] = (*elen)[i] + merge_w1[end1] + merge_w1[end2];             (*elen2)[i] = (*elen2)[i] + merge_w2[end1] + merge_w2[end2];	  }         }     #if PRINT_LEVEL        PG = &G;    #endif        cycle1_min = 600;        //cycle1_orig_min = 600;        cycle1_orig_min = 0; //This is for negative cycles        cycle2_min=1;        for (i = 0; i < ecount; i++)            (*elen_bak2)[i] = (*elen)[i]; /* make a temp copy of current edge weight */                  /* linearly transforming the (first) edge weights */        while (cycle1_min!=0) {              for (i = 0; i < ecount; i++) {	      (*elabel_penul)[i] = (*elabel)[i]; /* record the min-ratio-cycle in the penultimate step */              (*elen)[i]=(*elen_bak2)[i] * cycle2_min - cycle1_orig_min * (*elen2)[i] ;	    }            G.edgelist = (edge *) NULL;            G.nodelist = (node *) NULL;            G.unused = -1;            G.unmatched = -1;            G.roots = (nodeptr *) NULL;            if (build_graph (&G, ncount, ecount, *elist, *elen)) {                fprintf (stderr, "build_graph failed\n");                goto CLEANUP;            }            /* do perfect matching on solid-dashed graph G */            if (perfect_match (&G, *elen)){                fprintf (stderr, "perfect matching failed\n");                goto CLEANUP;            }            /* find the (minimum-cycle-ratio) negative weight cycle with perfect matching */            if (label_match (&G, *elen, *elen2, *elen_bak2, *esolid,                        &cycle1_min, &cycle2_min, &cycle1_orig_min, *elabel)){                fprintf (stderr, "match labelling failed\n");                goto CLEANUP;            }        }        for (i = 0; i < ecount; i++) {            (*elen)[i]=(*elen_bak)[i]; /* recover the edge weight */            (*elen2)[i]=(*elen2_bak)[i];	}        hh =0;        for (i = 0; i < ecount; i++)            hh = hh + (*elabel_penul)[i];        fprintf (stderr, "# edges(nodes) in MRC = %i\n", hh);        /* if the mrc ratio is zero, go ahead and output the result */        if (current_filename !=  (char *) NULL) {            if (write_match (&G, *elen, *elen2, *esolid, *elabel_penul, current_filename)) {                fprintf (stderr, "write_match failed\n");                goto CLEANUP;            }        }        for (i = 0; i < ecount; i++) {          if (((*elabel_penul)[i] == 1) && ((*esolid)[i] != 1)) {	      node_inv[G.edgelist[i].orig_nod1] = 1;              node_inv[G.edgelist[i].orig_nod2] = 1;              // following added for negative cycle with mirror edges              node_inv[G.edgelist[i].orig_nod1-(2*(G.edgelist[i].orig_nod1 % 2)-1)] = 1;              node_inv[G.edgelist[i].orig_nod2-(2*(G.edgelist[i].orig_nod2 % 2)-1)] = 1;              //	  }	}        for (i = 0; i < ecount; i++)	  if ((*esolid)[i] != 1)	    if ((node_inv[G.edgelist[i].orig_nod1] == 1) || (node_inv[G.edgelist[i].orig_nod2] == 1)) {               //(*elen)[i]=600;               //(*elen2)[i]=1;               (*elen)[i] = 600; // modified for negative cycle               (*elen2)[i] = 0;            }    }CLEANUP:    CC_IFFREE (G.nodelist, node);    CC_IFFREE (G.edgelist, edge);    CC_IFFREE (G.roots, nodeptr);    CC_FREE (*elist, int);    CC_FREE (*elabel, int);     CC_FREE (*elabel_penul, int);    CC_FREE (*elen, int);    CC_FREE (*elen_bak, int);    CC_FREE (elabel, int *);    CC_FREE (elabel_penul, int *);    CC_FREE (elen_bak, int *);    CC_FREE (elen2_bak, int *);    CC_FREE (elen_bak2, int *);    return 0;}#ifdef CC_PROTOTYPE_ANSIextern int perfect_match (graph *G, int *elen)#elseextern int perfect_match (G, elen)graph *G;int *elen;#endif{    srkstuff srk;    stats scount;    double val;    int finished = 1;    int use_all_trees=0;    srk.expands.node = (int *) NULL;    srk.shrinks.ary = (shrink_ary_T *) NULL;

⌨️ 快捷键说明

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