示例#1
0
/*
 * Returns the active c-node of RBC list containing "u".
 * Traverses only nodes with label_b <= dfspos_num[w].
 * Let z be the first element of RBC.
 * All traversed nodes, but z, are inserted in "nl".
 * Pre-conditions:
 * - "u" is not the 1st element in RBC list;
 * - ptritem[u] is the pointer to the item containing "u";
 * - "u" is a node that is an ancestor of a neighbor of w;
 * - state[v] == NOT_VISITED for each node v in RBC list that was not
 *   traversed.
 */
node PlanarityTestImpl::findActiveCNode(node u, node w, list<node> &nl) {
  list<node> traversedNodesInRBC;
  assert(isCNode(parent.get(u.id)));

  if (state.get(u.id) != NOT_VISITED) {
    assert(!isCNode(parent.get(parent.get(u.id).id)));
    return parent.get(u.id);
  }

  BmdLink<node> *it1 = ptrItem.get(u.id); // ptrItem[u];
  assert(it1 != nullptr);

  state.set(u.id, VISITED_IN_RBC);
  traversedNodesInRBC.push_back(u);
  BmdLink<node> *it = searchRBC(1, it1, w, traversedNodesInRBC);

  if (it == nullptr)
    it = searchRBC(0, it1, w, traversedNodesInRBC);

  assert(it != nullptr);

  node v = it->getData();
  node cNode;

  if (it->prev() != nullptr && it->succ() != nullptr)
    cNode = parent.get(v.id); // path compressed;
  else
    cNode = activeCNode[it];

  assert(cNode != NULL_NODE);

  node first = RBC[cNode].firstItem()->getData();

  // path compression;
  // forall(v, traversedNodesInRBC)
  for (list<node>::iterator it = traversedNodesInRBC.begin(); it != traversedNodesInRBC.end();
       ++it) {
    if (*it != first) {
      if (*it != u)
        nl.push_back(v);

      parent.set((*it).id, cNode);
    } else
      state.set((*it).id, NOT_VISITED);
  }

  return cNode;
}
示例#2
0
//=================================================================
BmdLink<node> *PlanarityTestImpl::searchRBC(int dir, BmdLink<node> *it, node n,
                                            list<node> &traversedNodesInRBC) {
  if (it != nullptr && (it->prev() == nullptr || it->succ() == nullptr)) // 1st or last item in RBC;
    return it;

  BmdLink<node> *prev = it;
  BmdLink<node> *aux1 = it->prev();
  BmdLink<node> *aux2 = it->succ();

  if (dir == 1) {
    // leda_swap(aux1, aux2);
    BmdLink<node> *tmp = aux1;
    aux1 = aux2;
    aux2 = tmp;
  }

  it = aux1;
  node u = it->getData();
  int b = labelB.get(u.id);

  while (it != nullptr && (b <= dfsPosNum.get(n.id) || dir != 1) &&
         state.get(u.id) == NOT_VISITED) {
    aux1 = it->prev();

    if (aux1 == prev)
      aux1 = it->succ();

    prev = it;
    it = aux1;
    u = prev->getData();
    state.set(u.id, VISITED_IN_RBC);
    traversedNodesInRBC.push_back(u);

    if (it != nullptr) {
      u = it->getData();
      b = labelB.get(u.id);
    }
  }

  if (it == nullptr)
    return prev;
  else if (state.get(u.id) != NOT_VISITED || (it->prev() == nullptr || it->succ() == nullptr))
    return it;
  else
    return nullptr;
}
示例#3
0
//=================================================================
void PlanarityTestImpl::addOldCNodeRBCToNewRBC(node oldCNode, node, node n, node n1, node n2,
                                               tlp::BmdList<node> &nodeList) {
  // compress RBC[oldCNode]:
  // removes all nodes v in RBC[oldCNode] s.t. label_b[v] < dfspos_num[n]
  // or v = parent[oldCNode].

  BmdLink<node> *firstItem = RBC[oldCNode].firstItem();
  BmdLink<node> *predItem = RBC[oldCNode].cyclicPred(firstItem, nullptr);
  BmdLink<node> *succItem = RBC[oldCNode].cyclicSucc(firstItem, nullptr);

  node predNode = predItem->getData();
  node succNode = succItem->getData();
  node ul;
  node ur;

  // goes to the left;
  while (labelB.get(predNode.id) == dfsPosNum.get(n.id) && predNode != n1 && predNode != n2) {
    if (!ul.isValid())
      ul = predNode;

    BmdLink<node> *tmp = predItem;
    predItem = RBC[oldCNode].cyclicPred(predItem, firstItem);
    predNode = predItem->getData();
    RBC[oldCNode].delItem(tmp);
  }

  // goes to right;
  while (labelB.get(succNode.id) == dfsPosNum.get(n.id) && succNode != n1 && succNode != n2) {
    if (!ur.isValid())
      ur = succNode;

    BmdLink<node> *tmp = succItem;
    succItem = RBC[oldCNode].cyclicSucc(succItem, firstItem);
    succNode = succItem->getData();
    RBC[oldCNode].delItem(tmp);
  }

  RBC[oldCNode].delItem(RBC[oldCNode].firstItem());

  // endpoint to correctly concatentates with RBC[new_cnode];
  node first = n1;

  if (!n1.isValid()) {
    if (ul.isValid())
      first = predNode;
    else
      first = succNode;
  }

  // note that oldCNode may have flipped;
  if (RBC[oldCNode].lastItem()->getData() == first)
    RBC[oldCNode].reverse();

  // reoves n1 and n2 from RBC[oldCNode];
  if (n1.isValid()) {
    RBC[oldCNode].delItem(RBC[oldCNode].firstItem());
  }

  if (n2.isValid()) {
    RBC[oldCNode].delItem(RBC[oldCNode].lastItem());
  }

  nodeList.conc(RBC[oldCNode]);
}
示例#4
0
/*
 * Moves embedding of oldCNode to embList - note that oldCNode may
 * flip - and embeds all edges in path from w (starting with a back-edge from w) and
 * ending in a node in RBC[oldCNode].
 * All representants to be embedded later is ordered and inserted in toEmbedLater.
 * emb_back_edges_out_w is false only in case of 2 terminal
 * nodes, for one of the two terminals (see calculate_partial_embedding).
 * Preconditions:
 * - for a back-edge e, if u is representant of source(e) and  u in RBC[oldCNode],
 *   then e is in list b_edges_repres[u];
 * - the first element in list RBC[oldCNode] is parent[oldCNode];
 * - if u != nil then u is a node in RBC[oldCNode] s.t. label_b[u] > dfspos_num[w]
 *   and there exists a path from u to w that doesn't contain any node in the
 *   2-connected component represented by oldCNode, except u.
 */
void PlanarityTestImpl::addOldCNodeToEmbedding(bool embBackEdgesOutW,
    Graph *sG,
    node w,
    node oldCNode,
    node u,
    map<node, list<edge> >& bEdgesRepres,
    list<node>& traversedNodes,
    list<node>& toEmbedLater,
    tlp::BmdList<edge>& embList) {

  BmdLink<node> *it  = RBC[oldCNode].firstItem();
  BmdLink<node> *itl = RBC[oldCNode].cyclicPred(it, 0);
  BmdLink<node> *itr = RBC[oldCNode].cyclicSucc(it, 0);
  node jl = itl->getData();
  node jr = itr->getData();

  list<node> listNodesL, listNodesR;
  // goes to the left;
  BmdLink<node> *aux = NULL;
  BmdLink<node> *s = it;

  while (labelB.get(jl.id) <= dfsPosNum.get(w.id)) {
    assert(jl != u);

    if (labelB.get(jl.id) == dfsPosNum.get(w.id))
      listNodesL.push_back(jl);

    aux = itl;
    itl = RBC[oldCNode].cyclicPred(itl, s);
    s = aux;
    jl = itl->getData();
  }

  // goes to the right;
  BmdLink<node> *p = it;

  while (labelB.get(jr.id) <= dfsPosNum.get(w.id)) {
    assert(jr != u);

    if (labelB.get(jr.id) == dfsPosNum.get(w.id))
      listNodesR.push_back(jr);

    aux = itr;
    itr = RBC[oldCNode].cyclicSucc(itr, p);
    p = aux;
    jr = itr->getData();
  }

  // checks if need to flip oldCNode;
  // u == nil when oldCNode is a terminal node;
  bool flipped = ((!listNodesL.empty() && (jl == u || u == NULL_NODE))
                  || (jr != u && u != NULL_NODE));

  if (flipped)
    listNodesL.swap(listNodesR);

  // embeds all back-edges in oldCNode;
  // listNodesR.reverse_items();
  listNodesR.reverse();
  node t;

  //forall(t, listNodesR)
  for (list<node>::iterator it = listNodesR.begin() ;
       it != listNodesR.end() ; it++) {
    t = *it;
    embedBackEdges(embBackEdgesOutW, sG, t, traversedNodes,
                   bEdgesRepres[t], embList);
  }

  if (flipped)
    embedList[oldCNode].reverse();


  embedList[oldCNode].conc(embList);
  embedList[oldCNode].swap(embList);

  //toEmbedLater.conc(listNodesL, LEDA::before);
  toEmbedLater.splice(toEmbedLater.begin(), listNodesL);
}