Exemple #1
0
/*
   -----------------------------------------------
   sort a list in ascending order using merge sort

   created -- 95sep22, cca
   -----------------------------------------------
*/
IP *
IP_mergeSortUp (
    IP   *ip0
) {
    int   i, m, m1 ;
    IP    *ip, *ip1, *ip2, *prev ;
    /*
       ----------------------------------------
       count the number of elements in the list
       ----------------------------------------
    */
#if MYDEBUG > 0
    fprintf(stdout, "\n inside IP_mergeSortUp :") ;
    IP_fp80(stdout, ip0, 25) ;
    fflush(stdout) ;
#endif
    for ( ip = ip0, m = 0 ; ip != NULL ; ip = ip->next ) {
        m++ ;
    }
    if ( m <= 1 ) {
        return(ip0) ;
    } else {
        m1 = m / 2 ;
#if MYDEBUG > 0
        fprintf(stdout, "\n m = %d, m1 = %d, m2 = %d", m, m1, m-m1) ;
        fflush(stdout) ;
#endif
        for ( i = 1, ip = ip0, prev = NULL ; i < m1 ; i++ ) {
            prev = ip ;
            ip = ip->next ;
        }
        ip2 = ip->next ;
        ip->next = NULL ;
        ip1 = ip0 ;
#if MYDEBUG > 0
        fprintf(stdout, "\n calling IP_mergeSortUp :") ;
        IP_fp80(stdout, ip1, 13) ;
        fflush(stdout) ;
#endif
        ip1 = IP_mergeSortUp(ip1) ;
#if MYDEBUG > 0
        fprintf(stdout, "\n return from IP_mergeSortUp :") ;
        IP_fp80(stdout, ip1, 13) ;
        fprintf(stdout, "\n calling IPmergeSortUp :") ;
        IP_fp80(stdout, ip2, 13) ;
#endif
        ip2 = IP_mergeSortUp(ip2) ;
#if MYDEBUG > 0
        fprintf(stdout, "\n return from IP_mergeSortUp :") ;
        IP_fp80(stdout, ip2, 13) ;
        fprintf(stdout, "\n calling IP_mergeUp :") ;
        fprintf(stdout, "\n first list") ;
        IP_fp80(stdout, ip1, 13) ;
        fprintf(stdout, "\n second list") ;
        IP_fp80(stdout, ip2, 13) ;
#endif
        ip  = IP_mergeUp(ip1, ip2) ;
#if MYDEBUG > 0
        fprintf(stdout, "\n return from IP_mergeUp, sorted list : ") ;
        IP_fp80(stdout, ip, 40) ;
        fflush(stdout) ;
#endif
        return(ip) ;
    }
}
Exemple #2
0
/*
   -----------------------------------------
   purpose -- eliminate vertex v
      1) create v's boundary list
      2) merge boundary list onto reach list
      3) for each vertex in the boundary
         3.1) add v to the subtree list

   created -- 96feb25, cca
   -----------------------------------------
*/
void 
MSMD_eliminateVtx ( 
   MSMD       *msmd,
   MSMDvtx    *v,
   MSMDinfo   *info 
) {
int       i, ierr, j, nadj, nbnd, nedge, uid, wid, wght ;
int       *adj, *bnd, *edges ;
IP        *ip, *ip2, *prev ;
IV        *reachIV ;
MSMDvtx   *u, *w ;
/*
   ---------------
   check the input
   ---------------
*/
if ( msmd == NULL || v == NULL || info == NULL ) {
   fprintf(stderr, "\n fatal error in MSMD_eliminateVtx(%p,%p,%p)"
           "\n bad input\n", msmd, v, info) ;
   exit(-1) ;
}
adj     = IV_entries(&msmd->ivtmpIV) ;
reachIV = &msmd->reachIV ;
/*
   -----------------------------
   create the boundary set for v
   -----------------------------
*/
v->mark = 'X' ;
if ( v->subtrees == NULL ) {
/*
   --------------------------------------------------------
   v is a leaf, look at its uncovered edge list, move v and 
   any indistinguishable vertices to the end of the list
   --------------------------------------------------------
*/
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n vertex %d is a leaf", v->id) ;
      fflush(info->msgFile) ;
   }
   v->status = 'L' ;
   nedge = v->nadj ;
   edges = v->adj  ;
   i = 0 ; j = nedge - 1 ;
   while ( i <= j ) {
      wid = edges[i] ;
      w   = msmd->vertices + wid ;
      if ( w == v || w->status == 'I' ) {
         edges[i] = edges[j] ;
         edges[j] = wid      ;
         j-- ;
      } else {
         w->mark = 'X' ;
         i++ ;
      }
   }
   v->nadj = j + 1 ;
} else {
/*
   ----------------------------------------------------
   v is not a leaf, merge its subtrees' boundaries
   with its uncovered edge list to get the new boundary
   ----------------------------------------------------
*/
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n vertex %d is not a leaf", v->id) ;
      fprintf(info->msgFile, "\n  vertex %d, subtrees :", v->id) ;
      IP_fp80(info->msgFile, v->subtrees, 20) ;
      fflush(info->msgFile) ;
   }
   v->status = 'E' ;
   nadj = 0 ;
   while ( (ip = v->subtrees) != NULL ) {
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, "\n    subtree %d, ip(%p)<%d,%p>",
                 ip->val, ip, ip->val, ip->next) ;
         fflush(info->msgFile) ;
      }
      uid    = ip->val ;
      u      = msmd->vertices + uid ;
      u->par = v ;
      nbnd   = u->nadj ;
      bnd    = u->adj  ;
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, "\n    bnd of adj subtree %d :", u->id) ;
         IVfp80(info->msgFile, nbnd, bnd, 25, &ierr) ;
         fflush(info->msgFile) ;
      }
      for ( i = 0 ; i < nbnd ; i++ ) {
         wid = bnd[i] ;
         w   = msmd->vertices + wid ;
         if ( w->mark == 'O' && w->status != 'I' ) {
            w->mark = 'X' ;
            adj[nadj++] = wid ;
         }
      }
      if ( u->status == 'E' ) {
/*
         ------------------------------------------
         u is not a leaf, free its boundary storage
         ------------------------------------------
*/
         IVfree(u->adj) ;
         info->nbytes -= u->nadj * sizeof(int) ;
      }
      u->adj  = NULL ;
      u->nadj =   0  ;
/*
      --------------------------------------
      put this IP structure on the free list
      --------------------------------------
*/
      v->subtrees = ip->next    ;
      ip->val     = -1          ;
      ip->next    = msmd->freeIP ;
      msmd->freeIP = ip          ;
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, 
                 "\n   v->subtrees = %p, msmd->freeIP = %p",
                 v->subtrees, msmd->freeIP) ;
         fflush(info->msgFile) ;
      }
   }
/*
   ------------------------------------------------
   merge all uncovered edges into the boundary list
   ------------------------------------------------
*/
   nedge = v->nadj ;
   edges = v->adj  ;
   for ( i = 0 ; i < nedge ; i++ ) {
      wid = edges[i] ;
      w   = msmd->vertices + wid ;
      if ( w->mark == 'O' && w->status != 'I' ) {
         w->mark     = 'X' ;
         adj[nadj++] = wid ;
      }
   }
/*
   ----------------------------------------------------------
   if boundary is not empty, allocate new storage for entries
   ----------------------------------------------------------
*/
   v->nadj = nadj ;
   if ( nadj > 0 ) {
      v->adj = IVinit(nadj, -1) ;
      IVcopy(nadj, v->adj, adj) ;
      info->nbytes += nadj*sizeof(int) ;
      if ( info->maxnbytes < info->nbytes ) {
         info->maxnbytes = info->nbytes ;
      }
   } else {
      v->adj = NULL ;
   }
}
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n    bnd(%d) :", v->id) ;
   if ( v->nadj > 0 ) {
      IVfp80(info->msgFile, v->nadj, v->adj, 17, &ierr) ;
   }
   fflush(info->msgFile) ;
}
/*
   ----------------------------------------------
   for each boundary vertex
      1. add v to subtree list
      2. put v on reach set if not already there
      3. unmark and add weight to boundary weight
   ----------------------------------------------
*/
nbnd = v->nadj ;
bnd  = v->adj  ;
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n %d's bnd :", v->id) ;
   IVfp80(info->msgFile, nbnd, bnd, 12, &ierr) ;
   fflush(info->msgFile) ;
}
wght = 0 ;
for ( i = 0 ; i < nbnd ; i++ ) {
   wid = bnd[i] ;
   w   = msmd->vertices + wid ;
   if ( info->msglvl > 4 ) {
      fprintf(info->msgFile, "\n   adjacent vertex %d", w->id) ;
      fflush(info->msgFile) ;
   }
/*
   -------------------------------
   add v to the subtree list for w
   -------------------------------
*/
   if ( (ip = msmd->freeIP) == NULL ) {
      if ( info->msglvl > 2 ) {
         fprintf(info->msgFile, "\n   need to get more IP objects") ;
         fflush(info->msgFile) ;
      }
/*
      -------------------------------------------------
      no more free IP structures, allocate more storage
      -------------------------------------------------
*/
      if ( (ip = IP_init(msmd->incrIP, IP_FORWARD)) == NULL ) {
         fprintf(stderr, "\n fatal error in MSMD_eliminateVtx%p,%p,%p)"
                 "\n unable to allocate more IP objects",
                 msmd, v, info) ;
         exit(-1) ;
      }
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, "\n   old baseIP = %p", msmd->baseIP) ;
         fprintf(info->msgFile, "\n   new baseIP = %p", ip) ;
         fflush(info->msgFile) ;
      }
      ip->next = msmd->baseIP ;
      msmd->baseIP = ip ;
      info->nbytes += msmd->incrIP*sizeof(struct _IP) ;
      if ( info->maxnbytes < info->nbytes ) {
         info->maxnbytes = info->nbytes ;
      }
      ip = msmd->freeIP = msmd->baseIP + 1 ;
      if ( info->msglvl > 2 ) {
         fprintf(info->msgFile, "\n   all set") ;
         fflush(info->msgFile) ;
      }
   }
   msmd->freeIP = ip->next ;
   ip->val     = v->id    ;
   ip->next    = NULL     ;
   for ( ip2 = w->subtrees, prev = NULL ; 
         ip2 != NULL && ip2->val > ip->val ;
         ip2 = ip2->next ) {
      prev = ip2 ;
   }
   if ( prev == NULL ) {
      w->subtrees = ip ;
   } else {
      prev->next = ip ;
   }
   ip->next = ip2 ;
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n %d's subtrees :", w->id) ;
      IP_fp80(info->msgFile, w->subtrees, 15) ;
      fflush(info->msgFile) ;
   }
/*
   --------------------------------
   add w to reach list if necessary
   --------------------------------
*/
   if ( info->msglvl > 4 ) {
      fprintf(info->msgFile, "\n    status[%d] = %c", wid, w->status) ;
      fflush(info->msgFile) ;
   }
   switch ( w->status ) {
   case 'D' :
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, ", remove from heap") ;
         fflush(info->msgFile) ;
      }
      IIheap_remove(msmd->heap, wid) ;
   case 'O' :
   case 'B' :
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, ", add to reach set, nreach = %d",
                 IV_size(reachIV) + 1) ;
         fflush(info->msgFile) ;
      }
      IV_push(reachIV, wid) ;
      w->status = 'R' ;
   case 'R' :
      break ;
   case 'I' :
      break ;
   default :
      fprintf(stderr, "\n error in MSMD_eliminateVtx(%p,%p,%p)"
              "\n status[%d] = '%c'\n",
              msmd, v, info, wid, w->status) ;
      fprintf(stderr, "\n msmd->nvtx = %d", msmd->nvtx) ;
      exit(-1) ;
   }
/*
   --------------------------------
   unmark the boundary vertices and
   store the weight of the boundary
   --------------------------------
*/
   w->mark = 'O' ;
   wght += w->wght ;
}
/*
   ------------------------------------
   unmark v and set its boundary weight
   ------------------------------------
*/
v->mark    = 'O'  ;
v->bndwght = wght ;

return ; }
Exemple #3
0
/*
   ---------------------------------------------
   purpose -- to sort a singly linked list in
              ascending order using a radix sort

   created -- 95sep22, cca
   ---------------------------------------------
*/
IP *
IP_radixSortUp (
    IP   *ip
) {
    int   b1, b2, d, dneg, dpos, i, j, negmin, posmax ;
    IP    *head, *next, *tail ;
    IP    *poshead, *neghead, *zerohead ;
    IP    *postail, *negtail, *zerotail ;
#define BASE 10
    IP    *heads[BASE], *tails[BASE] ;
    /*
       --------------------------------------------------------
       split the list into negative, zero and positive sublists
       --------------------------------------------------------
    */
    poshead = postail = neghead = negtail = zerohead = NULL ;
    zerotail = NULL ;
    posmax = negmin = 0 ;
    while ( ip != NULL ) {
        next = ip->next ;
        if ( ip->val > 0 ) {
            ip->next = poshead, poshead = ip ;
            if ( posmax < ip->val ) {
                posmax = ip->val ;
            }
        } else if ( ip->val < 0 ) {
            ip->next = neghead, neghead = ip ;
            if ( negmin > ip->val ) {
                negmin = ip->val ;
            }
        } else {
            if ( zerohead == NULL ) {
                zerotail = ip ;
            }
            ip->next = zerohead, zerohead = ip ;
        }
        ip = next ;
    }
#if MYDEBUG > 0
    fprintf(stdout, "\n positive list :") ;
    IP_fp80(stdout, poshead, 16) ;
    fprintf(stdout, "\n zero list :") ;
    IP_fp80(stdout, zerohead, 16) ;
    fprintf(stdout, "\n negative list :") ;
    IP_fp80(stdout, neghead, 16) ;
    fflush(stdout) ;
#endif
    /*
       ---------------
       find the limits
       ---------------
    */
    dpos = 0 ;
    while ( posmax > 0 ) {
        dpos++ ;
        posmax /= 10 ;
    }
    negmin = - negmin ;
    dneg = 0 ;
    while ( negmin > 0 ) {
        dneg++ ;
        negmin /= 10 ;
    }
    if ( dpos > dneg ) {
        d = dpos ;
    } else {
        d = dneg ;
    }
#if MYDEBUG > 0
    fprintf(stdout, "\n dneg %d, dpos %d, d %d", dneg, dpos, d) ;
    fflush(stdout) ;
#endif
    /*
       ----------------------
       sort the positive list
       ----------------------
    */
#if MYDEBUG > 0
    fprintf(stdout, "\n sorting the positive list") ;
#endif
    for ( i = 0 ; i < BASE ; i++ ) {
        heads[i] = tails[i] = NULL ;
    }
    b1 = 1 ;
    for ( i = 0 ; i < dpos ; i++ ) {
        b2 = BASE * b1 ;
        ip = poshead ;
        poshead = NULL ;
#if MYDEBUG > 0
        fprintf(stdout, "\n b1 %d, b2 %d", b1, b2) ;
#endif
        while ( ip != NULL ) {
            next = ip->next ;
            j = (ip->val % b2) / b1 ;
#if MYDEBUG > 0
            fprintf(stdout, "\n    ip->val %d, j %d", ip->val, j) ;
#endif
            if ( heads[j] == NULL ) {
                heads[j] = ip ;
            } else {
                tails[j]->next = ip ;
            }
            tails[j] = ip ;
            ip = next ;
        }
        for ( j = 0 ; j < BASE ; j++ ) {
            if ( heads[j] != NULL ) {
                if ( poshead == NULL ) {
                    poshead = heads[j] ;
                } else {
                    postail->next = heads[j] ;
                }
                postail = tails[j] ;
                heads[j] = tails[j] = NULL ;
            }
        }
        postail->next = NULL ;
        b1 = b2 ;
    }
#if MYDEBUG > 0
    fprintf(stdout, "\n positive list") ;
    IP_fprintf(stdout, poshead) ;
#endif
    /*
       ----------------------
       sort the negative list
       ----------------------
    */
#if MYDEBUG > 0
    fprintf(stdout, "\n sorting the negative list") ;
#endif
    b1 = 1 ;
    for ( i = 0 ; i < dneg ; i++ ) {
        b2 = BASE * b1 ;
#if MYDEBUG > 0
        fprintf(stdout, "\n b1 %d, b2 %d", b1, b2) ;
#endif
        ip = neghead ;
        neghead = NULL ;
        while ( ip != NULL ) {
            next = ip->next ;
            j = ((-ip->val) % b2) / b1 ;
#if MYDEBUG > 0
            fprintf(stdout, "\n    ip->val %d, j %d", ip->val, j) ;
#endif
            if ( heads[j] == NULL ) {
                heads[j] = ip ;
            } else {
                tails[j]->next = ip ;
            }
            tails[j] = ip ;
            ip = next ;
        }
        for ( j = 0 ; j < BASE ; j++ ) {
            if ( heads[j] != NULL ) {
                if ( neghead == NULL ) {
                    neghead = heads[j] ;
                } else {
                    negtail->next = heads[j] ;
                }
                negtail = tails[j] ;
                heads[j] = tails[j] = NULL ;
            }
        }
        negtail->next = NULL ;
        b1 = b2 ;
    }
#if MYDEBUG > 0
    fprintf(stdout, "\n negative list") ;
    IP_fprintf(stdout, neghead) ;
#endif
    /*
       ---------------------------
       concatenate the three lists
       ---------------------------
    */
    head = tail = ip = neghead ;
    while ( ip != NULL ) {
        next = ip->next ;
        ip->next = head ;
        head = ip ;
        ip = next ;
    }
    if ( tail != NULL ) {
        tail->next = NULL ;
    }
#if MYDEBUG > 0
    fprintf(stdout, "\n 1. head = %p, tail = %p", head, tail) ;
#endif
    if ( zerohead != NULL ) {
        if ( tail != NULL ) {
            tail->next = zerohead ;
        } else {
            head = zerohead ;
        }
        tail = zerotail ;
    }
    if ( tail != NULL ) {
        tail->next = NULL ;
    }
#if MYDEBUG > 0
    fprintf(stdout, "\n 2. head = %p, tail = %p", head, tail) ;
#endif
    if ( poshead != NULL ) {
        if ( tail != NULL ) {
            tail->next = poshead ;
        } else {
            head = poshead ;
        }
        tail = postail ;
    }
    if ( tail != NULL ) {
        tail->next = NULL ;
    }
#if MYDEBUG > 0
    fprintf(stdout, "\n 3. head = %p, tail = %p", head, tail) ;
    IP_fprintf(stdout, head) ;
#endif

    return(head) ;
}
Exemple #4
0
/*
   ----------------------------------------------
   for each uncovered (v,w)
      if v->subtrees \cap w->subtrees != emptyset
         remove (v,w) from uncovered edges
      end if
   end for

   created -- 95nov08, cca
   ----------------------------------------------
*/
void
MSMD_cleanEdgeList ( 
   MSMD       *msmd,
   MSMDvtx    *v,
   MSMDinfo   *info
) {
int       i, ierr, j, nedge, wid ;
int       *edges ;
IP        *ip1, *ip2 ;
MSMDvtx   *w ;
/*
   ---------------
   check the input
   ---------------
*/
if ( msmd == NULL || v == NULL || info == NULL ) {
   fprintf(stderr, "\n inside MSMD_cleanEdgeList(%p,%p,%p)"
           "\n bad input\n", msmd, v, info) ;
   exit(-1) ;
}
/*
   --------------------------------------------
   remove covered edges from the uncovered list
   --------------------------------------------
*/
nedge = v->nadj ;
edges = v->adj  ;
if ( info->msglvl > 5 ) {
   fprintf(info->msgFile, "\n inside MSMD_cleanEdgeList(%p,%p)"
           "\n %d's edges :", msmd, v, v->id) ;
   IVfp80(info->msgFile, nedge, edges, 12, &ierr) ;
   fflush(info->msgFile) ;
}
i = 0 ; j = nedge - 1 ;
while ( i <= j ) {
   wid = edges[i] ;
   w = msmd->vertices + wid ;
   if ( info->msglvl > 5 ) {
      fprintf(info->msgFile, "\n   <%d,%c>", wid, w->status) ;
      fflush(info->msgFile) ;
   }
   if ( w == v ) {
/*
      --------------------------------
      purge v from uncovered edge list
      --------------------------------
*/
      edges[i] = edges[j] ;
      edges[j] = wid ;
      j-- ;
   } else {
      switch ( w->status ) {
      case 'I' :
      case 'L' :
      case 'E' :
/*
         --------------------------------
         purge w from uncovered edge list
         --------------------------------
*/
         edges[i] = edges[j] ;
         edges[j] = wid ;
         j-- ;
         break ;
      default :
         ip1 = v->subtrees ;
         ip2 = w->subtrees ;
         if ( info->msglvl > 5 ) {
            fprintf(info->msgFile, "\n subtree list for %d :", v->id) ;
            IP_fp80(info->msgFile, ip1, 30) ;
            fprintf(info->msgFile, "\n subtree list for %d :", w->id) ;
            IP_fp80(info->msgFile, ip2, 30) ;
         }
         while ( ip1 != NULL && ip2 != NULL ) {
            if ( ip1->val > ip2->val ) {
               ip1 = ip1->next ;
            } else if ( ip1->val < ip2->val ) {
               ip2 = ip2->next ;
            } else {
/*
               ---------------------------------
               this edge has been covered, break
               ---------------------------------
*/
               edges[i] = edges[j] ;
               edges[j] = wid ;
               j-- ;
               break ;
            }
         }
         if ( ip1 == NULL || ip2 == NULL ) {
/*
            -------------------------------
            this edge was not covered, keep
            -------------------------------
*/
            i++ ;
         }
      }
   }
}
v->nadj = j + 1 ;
if ( info->msglvl > 5 ) {
   fprintf(info->msgFile, "\n leaving MSMD_cleanEdgeList(%p,%p)"
           "\n %d's edges :", msmd, v, v->id) ;
   IVfp80(info->msgFile, v->nadj, edges, 12, &ierr) ;
   fflush(info->msgFile) ;
}

return ; }