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

📄 mw_matching0.t

📁 A Library of Efficient Data Types and Algorithms,封装了常用的ADT及其相关算法的软件包
💻 T
📖 第 1 页 / 共 5 页
字号:
  if (p == nil) return;

  bool was_min = (p == minptr);

  if (cmp(p->key, infinity) == 0) return;
  else {
    conc_pq_node *start = increase_prio(p, infinity);
    if (was_min) minptr = locate_min(start);
  }
}


bool conc_pq_tree::decrease_key(conc_pq_node *p, GenPtr k) {
  // the key of p is decreased to k. in case k >= p->key 
  // we return false, else true to signalize, if the operation
  // was succesfull, or not

  int r = cmp(k, p->key);

  if (r >= 0) return false;
  else {
    if (cmp(k, minptr->key) < 0)
      minptr = p;
    decrease_prio(p, k);
    return true;
  }
}




bool conc_pq_tree::increase_key(conc_pq_node *p, GenPtr k) {
  // increases the key of p to k. if p->key >= k false is returned,
  // and true otherwise

  if (p == nil) return false;
  
  bool was_min = (p == minptr);
  
  if (cmp(p->key, k) >= 0) return false;
  else {
    conc_pq_node *start = increase_prio(p, k);
    if (was_min) minptr = locate_min(start);
    return true;
  }
}





inline void conc_pq_tree::traverse_tree(conc_pq_node* cur, GenPtr k) {
  // traverses the tree. for each node v: sets the key of v to k 
  // (case k != nil), or deletes v (case k == nil)

  if (cur == nil) return; 

  register conc_pq_node* it = cur->child;
  
  while(it && (it != cur->child->left)) {
    traverse_tree(it, k);
    it = it->right;
  }
  if (it) traverse_tree(it, k);
 
  if (k != nil) {
    copy_key(k);
    cur->key = k;
  }
  else {
    clear_key(cur->key);
    clear_inf(cur->inf);    
    // GSchange
    // std_memory.deallocate_bytes(cur, sizeof(conc_pq_node));
    delete cur;
  }
}


void conc_pq_tree::reset() { 
  if (!root) return;
  if (cmp(minptr->key, infinity) == 0) return;
 
  // increase all priorities to infty
  conc_pq_node *cur = first_item();
  while (cur) {
    increase_prio(cur, infinity);
    cur = next_item(cur);
  }
}


void conc_pq_tree::clear() {
  if (!root) return;

  // GSchange
  float t = used_time();
  // delete tree
  traverse_tree(root);
  conc_pq_del_t += used_time(t);  

  // std_memory.deallocate_list(head_leaf, tail_leaf, sizeof(conc_pq_node));
  
  head_leaf = tail_leaf = nil;
  root = minptr = nil;
}




void conc_pq_tree::print_item(conc_pq_node *it, ostream &out) const {
  if (it == nil) return;
  out << "<";
  print_key(it->key, out);
  out << ", ";
  print_inf(it->inf, out);
  out << ">";
}

void conc_pq_tree::print(ostream &out, string s, char space) const {

  out << s;
  conc_pq_node *cur = first_item();
  
  while (cur) {
    print_item(cur, out);
    out << space;
    cur = next_item(cur);
  }
  out.flush();
}



conc_pq_node* my_root(conc_pq_node *p) {
  conc_pq_node *cur = p;
  
  if (cur == nil) return nil;
    
  while (cur->parent) cur = cur->parent;
  
  return cur;
}


conc_pq_tree* my_tree(conc_pq_node *p) {
  conc_pq_node *cur = my_root(p);

  if (cur == nil) return nil;
  else return cur->tree;
}


GenPtr get_owner(conc_pq_node* it) 
{ return (it ? my_tree(it)->owner : nil); }





// ----- #include "concat_pq.h"

/*{\Manpage {concat_pq} {P, I} {Concatenable Priority Queues} {Q}}*/

typedef conc_pq_tree::item c_pq_item;

template<class P, class I>
class concat_pq : public virtual conc_pq_tree {

/*{\Mtext 
We implemented a data structure |\Mtype| supporting all needed 
operations of data type {\it concatenable \pq} as introduced in
\secref{sec: concatenable pq}.
The implementation is based on $(a,b)$--trees; we chose $a=2$ and $b=16$.
|concat| and |split_at_item| are essentially realized as discussed
at the end of \secref{sec: concatenable pq}. 
We do not intend to 
go into the implementation details. Instead, the specification of all 
operations needed in the subsequent sections is given.


In \secref{sec: survey} we outlined the idea of using a {\it union--find} data
structure with {\it split} operation to handle the surface graph. 
The method we use in our implementation is different. Since a concatenable \pq\ 
will be assigned to each surface blossom, we decided to extend the functionality 
of |\Mtype| such that it also enables the maintenance of the surface graph.
We use the underlying $(a,b)$--trees to identify a setable object (which will 
be the surface blossom) of a given item (which will correspond to a vertex).
The way this is achieved is as follows. 
Each root of an $(a,b)$--tree stores a pointer to the object representing 
that tree. 
Traversing from an item |it| towards the root, we can identify the 
$(a,b)$--tree object containing the item |it|. 
Moreover, each $(a,b)$--tree object has a generic pointer |owner| (a generic
pointer is of type |void*|) which is setable by the user; see operation 
|set_owner|. Consequently, the |owner| of any item |it| can be 
identified (operation |get_owner|) in time $O(\log n)$, where $n$ denotes the 
number of items in the $(a,b)$--tree.
}*/


  /*{\Mdefinition
    An instance |\Mvar| of the parameterized data type |\Mname| is a collection of items
    (type |c_pq_item|). 
    Every item contains a priority from a linearly ordered type $P$ and an information from 
    an arbitrary type $I$. We use $\Litem{p,i}$ to denote a |c_pq_item| with priority $p$ 
    and information $i$.
    \ignore{|P| is called the priority type and |I| the information type of |\Mvar|.}
    The data structure requires a designated element |infinity| of |P|, with
    $|infinity| \geq p$ for all $p \in P$ and equality holds only if |p=infinity|.
    An item $\Litem{p,i}$ with |p=infinity| is {\it irrelevant} to |\Mvar|. 
    The number of items in |\Mvar| is called the |size| of |\Mvar|. |\Mvar| is {\it empty} 
    when all its items are irrelevant, or when |\Mvar| has size zero. 
    A setable generic pointer |owner| (type |void*|) is associated with |\Mvar|. 
  }*/
  
  const leda_cmp_base<P>* cmp_ptr;

  int (*cmp_ptr1)(const P&, const P&);
  
  int cmp(GenPtr x, GenPtr y)  const { 
    if (cmp_ptr1)
      return LEDA_CALL2(*cmp_ptr1, P, x, y);
    else
      return LEDA_CALL2(*cmp_ptr, P, x, y);
  }

  int  ktype_id;
  int  key_type_id() const  { return ktype_id; }  

  void clear_key(GenPtr &x) const { LEDA_CLEAR(P, x); }
  void clear_inf(GenPtr &x) const { LEDA_CLEAR(I, x); }
  void copy_key(GenPtr &x)  const { LEDA_COPY(P, x); }
  void copy_inf(GenPtr &x)  const { LEDA_COPY(I, x); }
  void print_key(GenPtr &x, ostream &out = cout)  const { LEDA_PRINT(P, x, out); }
  void print_inf(GenPtr &x, ostream &out = cout)  const { LEDA_PRINT(I, x, out); }


public:

/* {\Mtypes 5} */ 

  typedef c_pq_item item;
  /* {\Mtypemember   the item type.} */

  typedef P prio_type;  
  /* {\Mtypemember   the priority type.} */  

  typedef I inf_type;
  /* {\Mtypemember   the information type.} */ 

// was 5.5
/*{\Mcreation Q 6.2}*/

  concat_pq(const leda_cmp_base<P>& cmp, P infty) : conc_pq_tree() {
    cmp_ptr  = &cmp; 
    cmp_ptr1 = 0; 
    ktype_id = UNKNOWN_TYPE_ID; 
    conc_pq_tree::infinity = leda_cast(infty);
    conc_pq_tree::owner = this;
  }

  concat_pq() : conc_pq_tree() {    
    cmp_ptr1 = compare;
    ktype_id = LEDA_TYPE_ID(P);    
    conc_pq_tree::infinity = leda_cast(MAX_VALUE(P));
    conc_pq_tree::owner = this;
  }
  /*{\Mcreate   creates an instance |\Mvar| of type |\Mname| based on the linear
    order defined by the global compare function |compare(const P&, const P&)| 
    and initializes it with the empty priority queue. |infinity| is set to the 
    maximum value of type |P|.}*/

  concat_pq(P p, I i) : conc_pq_tree(leda_cast(p), leda_cast(i)) {
    cmp_ptr1 = compare;
    ktype_id = LEDA_TYPE_ID(P); 
    conc_pq_tree::infinity = leda_cast(MAX_VALUE(P));
    conc_pq_tree::owner = this;
  }

  concat_pq(int (*cmp)(const P&, const P&), P infty) : conc_pq_tree() {
    cmp_ptr1 = cmp;
    ktype_id = UNKNOWN_TYPE_ID; 
    conc_pq_tree::infinity = leda_cast(infty);
    conc_pq_tree::owner = this;
  }
  /* {\Mcreate   creates an instance |\Mvar| of type |\Mname| based on the linear order
    defined by the compare function |cmp| and sets the designated element |infinity| 
    to |infty|. |\Mvar| is initialized with the empty priority queue.
    \precond |cmp| must define a linear order on |P| and |infty| satisfies the conditions
    stated above, i.e.~$|cmp|(|infty|, p) \geq 0$ for all $p \in P$.} */


  ~concat_pq() { conc_pq_tree::clear(); }


// was 1.8 3.7
/*{\Moperations 1.8 4.4}*/   

  P& infinity() { return LEDA_ACCESS(P, conc_pq_tree::infinity); }
  /* {\Mop   returns a reference to the value of |infinity|.} */

  c_pq_item init(P p, I i) {
    return conc_pq_tree::init(leda_cast(p), leda_cast(i));
  }
  /*{\Mop   initializes |\Mvar| to the priority queue containing 
    only the item $\Litem{p, i}$ and returns that item.}*/

  virtual const P& prio(c_pq_item it) const { 
    return LEDA_CONST_ACCESS(P, conc_pq_tree::key(it)); 
  }
  /*{\Mop   returns the priority of item $it$.
    \precond $it$ is an item in |\Mvar|.}*/

  virtual I& inf(c_pq_item it) {
    return LEDA_ACCESS(I, conc_pq_tree::inf(it)); 
  }

  virtual const I& inf(c_pq_item it) const { 
    return LEDA_CONST_ACCESS(I, conc_pq_tree::inf(it)); 
  }
  /*{\Mop   returns the information of item $it$.
    \precond $it$ is an item in |\Mvar|.}*/

  virtual c_pq_item insert(P p, I i) {
    return conc_pq_tree::insert(leda_cast(p), leda_cast(i));
  }
  /* {\Mop   adds a new item $\Litem{p, i}$ to |\Mvar| and returns it. All items in
    |\Mvar| precede $\Litem{p, i}$.} */


  void concat(concat_pq<P,I> &pq, int dir = leda::after) {
    conc_pq_tree::conc(pq);
  }
  /*{\Mop   concatenates |\Mvar| with |pq|. The items in |\Mvar| precede (succeed)   
    the items of |pq|, when $|dir|=|after|$ ($|dir|=|before|$). |pq| is 
    made empty, i.e.~contains no items thereafter.}*/

  void split_at_item(c_pq_item it, concat_pq<P,I> &pq1, concat_pq<P,I> &pq2) { 
    conc_pq_tree::split_at_item(it, pq1, pq2); 
  }
  /*{\Mopl  splits |\Mvar| at item |it| into |pq1| and |pq2| such that |it| is 
    the last item of |pq1|. 
    In case $|it|=|nil|$, |pq2| becomes |\Mvar| and |pq1| becomes empty.
    The instance |\Mvar| is empty thereafter, unless it is given as one
    of the arguments.}*/

  virtual c_pq_item find_min() const { return conc_pq_tree::find_min(); }
  /*{\Mop   returns an item with minimal priority (|nil| if |\Mvar| is empty).}*/

  virtual P del_min() { 
    P x = prio(find_min()); 
    conc_pq_tree::del_min(); 
    return x; 
  }
  /*{\Mop   makes the item $|it|=|\Mvar.find_min|()$ irrelevant to |\Mvar| by
    setting its priority to |infinity|. The former priority is returned.}*/
     
  virtual void del_item(c_pq_item it) { conc_pq_tree::del_item(it); }
  /*{\Mopl   makes the item $it$ irrelevant to |\Mvar|.
    \precond |it| is an item in |\Mvar|.}*/

  virtual bool decrease_p(c_pq_item it, const P& x) { 
    return conc_pq_tree::decrease_key(it, leda_cast(x)); 
  }
  /*{\Mopl   makes $x$ the new priority of item $it$. The function returns |true| iff
    the operation was successful, i.e.~|\Mvar.prio(it)| was larger than $x$.}*/

  virtual bool increase_p(c_pq_item it, const P& x) { 
    return conc_pq_tree::increase_key(it, leda_cast(x)); 
  }
  /*{\Mopl   makes $x$ the new priority of item $it$. The function returns |true| iff
    the operation was successful, i.e.~|\Mvar.prio(it)| was smaller than $x$.}*/

  virtual const I& operator[](c_pq_item it) const
  { return LEDA_CONST_ACCESS(I, conc_pq_tree::inf(it)); }

  
  virtual I& operator[](c_pq_item it) 
  { return LEDA_ACCESS(I, conc_pq_tree::inf(it)); }
  /* {\Marrop   returns a reference to the information of item $it$.
    \precond $it$ is an item in |\Mvar|.} */


  int  size() const { return conc_pq_tree::size(); }
  /*{\Mop   returns the size of |\Mvar|.}*/


  bool empty() const { return conc_pq_tree::empty(); }
  /*{\Mop   returns |true|, if |\Mvar| is empty, and |false| otherwise.}*/


  void reset() { conc_pq_tree::reset(); }
  /*{\Mop   makes |\Mvar| the empty priority queue by setting all priorities to |infinity|.}*/


  void clear() { conc_pq_tree::clear(); }
  /*{\Mop   makes |\Mvar| the empty priority queue by deleting all items. }*/


  void set_owner(GenPtr pt) { conc_pq_tree::set_owner(pt); }
  /*{\Mop   sets |owner| of |\Mvar| to the object pointed to by the 
            generic pointer |pt| (type |void*|).}*/


/*{\Mtext \mansection{Friend Functions}}*/

/*
  friend GenPtr get_owner(c_pq_item it);
*/
  /*{\Mfunc returns the generic pointer |owner| of the instance containing item |it|.}*/


/*{\Mtext \mansection{Iteration}

{\bf forall\_items}($it, Q$)       
$\{$ ``the items of $Q$ are successively assigned to $it$'' $\}$

{\bf forall}($i, Q$)       
$\{$ ``the information parts of the items of $Q$ are successively assigned to $i$'' $\}$ 
}*/


};

c_pq_item my_root(c_pq_item it);
/* {\Mfunc   returns the root of item |it|.} */


template<class P, class I> 
inline c_pq_item create_concat_pq(P p, I i) {
  concat_pq<P, I> *pq = new concat_pq<P, I>;
  return pq->init(p, i);
}

template<class P, class I> 
inline c_pq_item create_concat_pq(P p, I i, concat_pq<P, I>* &pq) {
  pq = new concat_pq<P, I>;
  return pq->init(p, i);
}

template<class P, class I> 
inline void my_concat_pq(c_pq_item it, concat_pq<P, I>* &pq) {
  pq = (concat_pq<P, I>*)(my_tree(it)->owner);
}
/* {\Mfunc   returns a pointer to the instance of type |\Mname| that contains 
  item |it| in |pq|.} */



/*{\Mimplementation
  All access operations take time O(1). 
  |concat| and |split_at_item| take time $O(\log n)$, where $n$ is the (maximum) number of 
  elements in the priority queue(s). Operations |clear| and |reset| take time $O(n)$.
  All other operations take time (at most) $O(\log n)$.
}*/         


// ----- #include "greedy.t"


#if defined(_CHECK) 
#undef _CHECK
#endif


template<class NT>
__temp_func_inline
int greedy_matching(const graph &G, const edge_array<NT> &w, 
                    node_array<NT> &pot, node_array<node> &mate, 
                    bool perfect) {
#ifdef _INFO
  cout << "\t\tCREATING greedy matching..." << std::flush;
  float t = used_time();
#endif

  
  edge e;
  node u, v;
  pot.init(G, -MAX_VALUE(NT));

  forall_nodes(u, G)
    if (degree(u) == 0) pot[u] = 0;

  forall_edges(e, G) {
    u = source(e);
    v = target(e);

⌨️ 快捷键说明

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