File indexing completed on 2025-08-03 08:19:40
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <GTL/planarity.h>
0010 #include <GTL/pq_tree.h>
0011 #include <GTL/biconnectivity.h>
0012 #include <GTL/debug.h>
0013
0014 #include <iostream>
0015 #include <cstdio>
0016 #include <fstream>
0017 #include <sstream>
0018
0019 #ifdef __GTL_MSVCC
0020 # ifdef _Debug
0021 # ifndef SEARCH_MEMORY_LEAKS_ENABLED
0022 # error SEARCH NOT ENABLED
0023 # endif
0024 # define new DEBUG_NEW
0025 # undef THIS_FILE
0026 static char THIS_FILE[] = __FILE__;
0027 # endif
0028 #endif
0029
0030 __GTL_BEGIN_NAMESPACE
0031
0032
0033
0034
0035
0036
0037 planarity::planarity() :
0038 algorithm (), emp (false), kup (false), bip (true)
0039 {
0040 #ifdef _DEBUG
0041 GTL_debug::init_debug();
0042 #endif
0043 };
0044
0045 planarity::~planarity()
0046 {
0047 #ifdef _DEBUG
0048 GTL_debug::close_debug();
0049 #endif
0050 };
0051
0052
0053 int planarity::check (graph& G)
0054 {
0055 return algorithm::GTL_OK;
0056 }
0057
0058 bool planarity::run_on_biconnected (graph& G, planar_embedding& em)
0059 {
0060
0061 if (G.number_of_edges() == 0) return algorithm::GTL_OK;
0062
0063 st_number st_;
0064
0065
0066
0067
0068
0069
0070 graph::edge_iterator
0071 edge_it = G.edges_begin(),
0072 edge_end = G.edges_end();
0073
0074 edge st;
0075
0076 while (edge_it != edge_end) {
0077 if ((*edge_it).source() != (*edge_it).target()) {
0078 st = *edge_it;
0079 break;
0080 }
0081 ++edge_it;
0082 }
0083
0084
0085
0086
0087
0088 if (st == edge()) {
0089 if (emp) {
0090 em.init (G);
0091 edge_it = G.edges_begin();
0092 edge_end = G.edges_end();
0093
0094 for (;edge_it != edge_end; ++edge_it) {
0095 em.self.push_back (*edge_it);
0096 }
0097 }
0098
0099 return algorithm::GTL_OK;
0100 }
0101
0102 st_.st_edge (st);
0103 st_.s_node (st.source());
0104 int res = st_.check(G);
0105 assert (res == algorithm::GTL_OK);
0106 res = st_.run(G);
0107 assert (res == algorithm::GTL_OK);
0108 int size = G.number_of_nodes();
0109
0110 if (emp) {
0111 em.init (G);
0112 }
0113
0114 list<pq_leaf*> neighbors;
0115 st_number::iterator st_it = st_.begin();
0116 node curr = *st_it;
0117 node::out_edges_iterator o_it = curr.out_edges_begin();
0118 node::out_edges_iterator o_end = curr.out_edges_end();
0119 node::in_edges_iterator i_it = curr.in_edges_begin();
0120 node::in_edges_iterator i_end = curr.in_edges_end();
0121 list<edge> self_loops;
0122 node opp;
0123 node_map<int> visited_from (G, 0);
0124 pq_leaf* tmp_leaf;
0125 vector< list<pq_leaf*> > leaves (size);
0126
0127 for (; o_it != o_end; ++o_it) {
0128 opp = curr.opposite (*o_it);
0129
0130 if (opp != curr) {
0131 if (visited_from[opp] == st_[curr] && emp) {
0132 em.multi.push_back (*o_it);
0133 } else {
0134 visited_from[opp] = st_[curr];
0135 tmp_leaf = new pq_leaf (st_[opp], st_[curr], *o_it, opp);
0136 leaves[st_[opp]-1].push_back (tmp_leaf);
0137 neighbors.push_back (tmp_leaf);
0138 }
0139
0140 } else if (emp) {
0141 em.self.push_back (*o_it);
0142 }
0143 }
0144
0145 for (; i_it != i_end; ++i_it) {
0146 opp = curr.opposite (*i_it);
0147
0148 if (opp != curr) {
0149 if (visited_from[opp] == st_[curr] && emp) {
0150 em.multi.push_back (*i_it);
0151 } else {
0152 visited_from[opp] = st_[curr];
0153 tmp_leaf = new pq_leaf (st_[opp], st_[curr], *i_it, opp);
0154 leaves[st_[opp]-1].push_back (tmp_leaf);
0155 neighbors.push_back (tmp_leaf);
0156 }
0157 }
0158 }
0159
0160 node_map<list<direction_indicator> > dirs;
0161
0162
0163
0164
0165
0166
0167
0168
0169 #ifndef __GTL_MSVCC
0170 dirs.init (G);
0171 #endif
0172 pq_tree PQ (st_[curr], curr, neighbors);
0173 neighbors.erase (neighbors.begin(), neighbors.end());
0174 ++st_it;
0175 curr = *st_it;
0176
0177 while (st_[curr] < size) {
0178
0179 #ifdef _DEBUG
0180 char filename[10] = "out";
0181 char buffer[12];
0182 #ifdef __GTL_MSVCC
0183 _snprintf (buffer, 12, "%s%d.gml", filename, st_[curr]);
0184 #else
0185 snprintf (buffer, 12, "%s%d.gml", filename, st_[curr]);
0186 #endif
0187 ofstream os (buffer, ios::out | ios::trunc);
0188 os << PQ << endl;
0189 os.close();
0190 bool ret_flag = PQ.integrity_check();
0191 assert(ret_flag);
0192 #endif
0193
0194 if (!PQ.reduce (leaves[st_[curr]-1])) {
0195 #ifdef _DEBUG
0196 os.open ("fail.gml", ios::out | ios::trunc);
0197 os << PQ << endl;
0198 os.close ();
0199 #endif
0200 if (kup) {
0201 examine_obstruction (G, st_, curr,
0202 PQ.get_fail(), PQ.is_fail_root(), em, dirs, &PQ);
0203 }
0204
0205 PQ.reset();
0206 return false;
0207 }
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218 o_it = curr.out_edges_begin();
0219 o_end = curr.out_edges_end();
0220 i_it = curr.in_edges_begin();
0221 i_end = curr.in_edges_end();
0222
0223 for (; o_it != o_end; ++o_it) {
0224 opp = curr.opposite (*o_it);
0225
0226 if (st_[opp] > st_[curr]) {
0227 if (visited_from[opp] == st_[curr] && emp) {
0228 em.multi.push_back (*o_it);
0229 } else {
0230 visited_from[opp] = st_[curr];
0231 tmp_leaf = new pq_leaf (st_[opp], st_[curr], *o_it, opp);
0232 leaves[st_[opp]-1].push_back (tmp_leaf);
0233 neighbors.push_back (tmp_leaf);
0234 }
0235
0236 } else if (st_[opp] == st_[curr] && emp) {
0237 em.self.push_back (*o_it);
0238 }
0239 }
0240
0241 for (; i_it != i_end; ++i_it) {
0242 opp = curr.opposite (*i_it);
0243
0244 if (st_[opp] > st_[curr]) {
0245 if (visited_from[opp] == st_[curr] && emp) {
0246 em.multi.push_back (*i_it);
0247 } else {
0248 visited_from[opp] = st_[curr];
0249 tmp_leaf = new pq_leaf (st_[opp], st_[curr], *i_it, opp);
0250 leaves[st_[opp]-1].push_back (tmp_leaf);
0251 neighbors.push_back (tmp_leaf);
0252 }
0253 }
0254 }
0255
0256 if (emp) {
0257 PQ.replace_pert (st_[curr], curr, neighbors, &em, &(dirs[curr]));
0258 #ifdef _DEBUG
0259 GTL_debug::os() << "Embedding of " << st_[curr] << ":: ";
0260 planar_embedding::iterator adit, adend;
0261 for (adit = em.adj_edges_begin (curr), adend = em.adj_edges_end (curr); adit != adend; ++adit) {
0262 GTL_debug::os() << "[" << st_[curr.opposite (*adit)] << "]";
0263 }
0264 GTL_debug::os() << endl;
0265 GTL_debug::os() << "Direction Indicators for: " << st_[curr] << ":: ";
0266 list<direction_indicator>::iterator dit, dend;
0267
0268 for (dit = dirs[curr].begin(), dend = dirs[curr].end(); dit != dend; ++dit) {
0269 GTL_debug::os() << "[";
0270 if ((*dit).direction)
0271 GTL_debug::os() << ">> " << (*dit).id << " >>";
0272 else
0273 GTL_debug::os() << "<< " << (*dit).id << " <<";
0274 GTL_debug::os() << "]";
0275 }
0276 GTL_debug::os() << endl;
0277 #endif
0278
0279 } else {
0280 PQ.replace_pert (st_[curr], curr, neighbors);
0281 }
0282
0283 PQ.reset();
0284
0285
0286 neighbors.erase (neighbors.begin(), neighbors.end());
0287 ++st_it;
0288 curr = *st_it;
0289 }
0290
0291 if (emp) {
0292 PQ.get_frontier (em, dirs[curr]);
0293
0294
0295
0296
0297
0298
0299 o_it = curr.out_edges_begin();
0300 o_end = curr.out_edges_end();
0301
0302 for (; o_it != o_end; ++o_it) {
0303 if ((*o_it).target() == (*o_it).source()) {
0304 em.self.push_back (*o_it);
0305 }
0306 }
0307
0308
0309
0310
0311
0312
0313 correct_embedding(em, st_, dirs);
0314
0315 node_map<int> mark;
0316 mark.init (G, 0);
0317 node_map<symlist<edge>::iterator > upward_begin;
0318 upward_begin.init (G);
0319 node tmp;
0320
0321 forall_nodes (tmp, G) {
0322 upward_begin[tmp] = em.adjacency(tmp).begin();
0323 }
0324
0325 extend_embedding(curr, em, mark, upward_begin);
0326 }
0327
0328 return true;
0329 }
0330
0331
0332 int planarity::run (graph& G)
0333 {
0334 bool directed = false;
0335
0336 if (G.is_directed()) {
0337 G.make_undirected();
0338 directed = true;
0339 }
0340
0341 biconnectivity biconn;
0342
0343 if (bip) {
0344 biconn.make_biconnected (true);
0345 } else {
0346 biconn.store_components (true);
0347 }
0348
0349 biconn.check (G);
0350 biconn.run (G);
0351
0352 if (emp) {
0353 embedding.init (G);
0354 }
0355
0356 planar_embedding em;
0357
0358 if (!biconn.is_biconnected() && !bip) {
0359 biconnectivity::component_iterator c_it, c_end;
0360
0361 for (c_it = biconn.components_begin(), c_end = biconn.components_end();
0362 c_it != c_end; ++c_it) {
0363
0364 switch_to_component (G, c_it);
0365
0366 #ifdef _DEBUG
0367 GTL_debug::os() << "Component is: " << endl;
0368 GTL_debug::os() << G << endl;
0369 #endif
0370 if (!run_on_biconnected (G, em)) {
0371 if (directed) {
0372 G.make_directed();
0373 }
0374
0375 G.restore_graph();
0376 planar = false;
0377 return algorithm::GTL_OK;
0378 }
0379
0380 if (emp) {
0381 add_to_embedding (G, em);
0382 }
0383 }
0384
0385 G.restore_graph();
0386
0387 } else {
0388
0389
0390
0391
0392
0393 GTL_debug::debug_message ("graph is biconnected\n");
0394
0395 if (!run_on_biconnected (G, embedding)) {
0396 if (directed) {
0397 G.make_directed();
0398 }
0399
0400 planar = false;
0401 return algorithm::GTL_OK;
0402 }
0403 }
0404
0405 if (bip) {
0406 list<edge>::iterator it, end;
0407 it = biconn.additional_begin();
0408 end = biconn.additional_end();
0409
0410 for (; it != end; ++it) {
0411
0412 if (emp) {
0413 node s = (*it).source();
0414 node t = (*it).target();
0415 embedding.adj[s].erase (embedding.s_pos[*it]);
0416 embedding.adj[t].erase (embedding.t_pos[*it]);
0417 }
0418
0419 G.del_edge (*it);
0420 }
0421 }
0422
0423 if (directed) {
0424 G.make_directed();
0425 }
0426
0427 planar = true;
0428 return algorithm::GTL_OK;
0429 }
0430
0431 void planarity::add_to_embedding (graph& G, planar_embedding& em)
0432 {
0433 node n;
0434 forall_nodes (n, G) {
0435 planar_embedding::iterator it = em.adj_edges_begin (n);
0436 planar_embedding::iterator end = em.adj_edges_end (n);
0437
0438 for (; it != end; ++it) {
0439 embedding.pos (n, *it) = em.pos (n, *it);
0440 }
0441
0442 embedding.adjacency(n).splice (
0443 embedding.adj_edges_end (n),
0444 em.adj_edges_begin (n),
0445 em.adj_edges_end (n));
0446 }
0447
0448 embedding.self.splice (
0449 embedding.self.end(),
0450 em.self, em.self.begin(), em.self.end());
0451 embedding.multi.splice (
0452 embedding.multi.end(),
0453 em.multi, em.multi.begin(), em.multi.end());
0454 }
0455
0456
0457 void planarity::reset ()
0458 {
0459 ob_edges.erase (ob_edges.begin(), ob_edges.end());
0460 ob_nodes.erase (ob_nodes.begin(), ob_nodes.end());
0461 }
0462
0463
0464 void planarity::correct_embedding (
0465 planar_embedding& em,
0466 st_number& st_,
0467 node_map<list<direction_indicator> >& dirs)
0468 {
0469 st_number::reverse_iterator it = st_.rbegin();
0470 st_number::reverse_iterator end = st_.rend();
0471 bool* turn = new bool[st_[*it]];
0472
0473 for (int i = 0; i < st_[*it]; ++i) {
0474 turn[i] = false;
0475 }
0476
0477 while (it != end) {
0478 node curr = *it;
0479
0480 if (turn[st_[curr] - 1]) {
0481 em.adjacency(curr).reverse();
0482 }
0483
0484 list<direction_indicator>::iterator d_it = dirs[curr].begin();
0485
0486 while (!dirs[curr].empty()) {
0487
0488 if ((*d_it).direction && turn[st_[curr] - 1] ||
0489 !(*d_it).direction && !turn[st_[curr] - 1]) {
0490 turn[(*d_it).id - 1] = true;
0491 }
0492
0493 d_it = dirs[curr].erase (d_it);
0494 }
0495
0496 ++it;
0497 }
0498
0499 delete[] turn;
0500 }
0501
0502
0503 void planarity::extend_embedding (
0504 node n,
0505 planar_embedding& em,
0506 node_map<int>& mark,
0507 node_map<symlist<edge>::iterator >& upward_begin)
0508 {
0509 mark[n] = 1;
0510
0511 symlist<edge>::iterator it = upward_begin[n];
0512 symlist<edge>::iterator end = em.adjacency(n).end();
0513 node other;
0514
0515 for (; it != end; ++it) {
0516 em.pos (n, *it) = it;
0517 other = n.opposite (*it);
0518 em.pos (other, *it) = em.push_front (other, *it);
0519
0520 if (mark[other] == 0) {
0521 extend_embedding (other, em, mark, upward_begin);
0522 }
0523 }
0524 }
0525
0526 void planarity::switch_to_component (graph& G,
0527 biconnectivity::component_iterator c_it)
0528 {
0529
0530
0531
0532
0533 list<node> dummy;
0534 G.induced_subgraph (dummy);
0535
0536
0537
0538
0539
0540 list<node>::iterator it = (*c_it).first.begin();
0541 list<node>::iterator end = (*c_it).first.end();
0542
0543 for (; it != end; ++it) {
0544 G.restore_node (*it);
0545 }
0546
0547
0548
0549
0550
0551 list<edge>::iterator e_it = (*c_it).second.begin();
0552 list<edge>::iterator e_end = (*c_it).second.end();
0553
0554 for (; e_it != e_end; ++e_it) {
0555 G.restore_edge (*e_it);
0556 }
0557 }
0558
0559 void planarity::examine_obstruction (graph& G,
0560 st_number& st_,
0561 node act,
0562 pq_node* fail,
0563 bool is_root,
0564 planar_embedding& em,
0565 node_map<list<direction_indicator> >& dirs,
0566 pq_tree* PQ)
0567 {
0568 node_map<int> used (G, 0);
0569 node_map<edge> to_father (G);
0570
0571
0572
0573
0574
0575
0576
0577
0578 dfs_bushform (st_.s_node(), used, st_, st_[act], to_father);
0579
0580 if (fail->kind() == pq_node::Q_NODE) {
0581
0582
0583
0584
0585
0586
0587
0588 q_node* q_fail = fail->Q();
0589
0590 pq_tree::sons_iterator s_it = q_fail->sons.begin();
0591 pq_tree::sons_iterator s_end = q_fail->sons.end();
0592 node greatest = fail->n;
0593
0594 while (s_it != s_end) {
0595 if ((*s_it)->kind() == pq_node::DIR) {
0596 direction_indicator* dir = (*s_it)->D();
0597 pq_tree::sons_iterator tmp = s_it;
0598
0599 if (++tmp == ++(dir->pos)) {
0600 dir->direction = true;
0601 } else {
0602 dir->direction = false;
0603 }
0604
0605 dirs[act].push_back (*dir);
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618 s_it = PQ->remove_dir_ind(q_fail, s_it);
0619 } else {
0620 if (st_[(*s_it)->up] > st_[greatest]) {
0621 greatest = (*s_it)->up;
0622 }
0623
0624 ++s_it;
0625 }
0626 }
0627
0628 correct_embedding (em, st_, dirs);
0629 node_map<int> mark;
0630 mark.init (G, 0);
0631 node_map<symlist<edge>::iterator > upward_begin;
0632 upward_begin.init (G);
0633 node tmp;
0634
0635 em.adjacency(fail->n).erase (
0636 em.adjacency(fail->n).begin(),
0637 em.adjacency(fail->n).end());
0638
0639 forall_nodes (tmp, G) {
0640 upward_begin[tmp] = em.adjacency(tmp).begin();
0641 }
0642
0643
0644
0645
0646
0647
0648
0649
0650 extend_embedding(greatest, em, mark, upward_begin);
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673 #ifdef _DEBUG
0674 GTL_debug::os() << "Embedding so far (st_numbered): " << endl;
0675 em.write_st (GTL_debug::os(), st_);
0676 #endif
0677
0678 attachment_cycle (fail->n, em);
0679
0680 if (!q_fail->pert_cons) {
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692 GTL_debug::debug_message ("CASE C (non consecutive pertinent children)\n");
0693 pq_tree::sons_iterator tmp = q_fail->pert_begin;
0694 pq_leaf* leaves[3];
0695 node nodes[3];
0696 leaves[0] = search_full_leaf (*tmp);
0697 nodes[0] = (*tmp)->up;
0698
0699 tmp = q_fail->pert_end;
0700 leaves[2] = search_full_leaf (*tmp);
0701 nodes[2] = (*tmp)->up;
0702
0703 --tmp;
0704 while ((*tmp)->kind() == pq_node::DIR) {
0705 --tmp;
0706 }
0707
0708 leaves[1] = search_empty_leaf (*tmp);
0709 nodes[1] = (*tmp)->up;
0710
0711 case_C (nodes, leaves, st_, to_father, G, q_fail);
0712
0713 } else if (!(*(q_fail->pert_end))->is_endmost && !is_root) {
0714
0715 GTL_debug::debug_message ("CASE D (non-root q-node with both endmost sons empty)\n");
0716 pq_tree::sons_iterator tmp = q_fail->sons.begin();
0717 pq_leaf* leaves[3];
0718 node nodes[3];
0719 leaves[0] = search_empty_leaf (*tmp);
0720 nodes[0] = (*tmp)->up;
0721
0722 tmp = --(q_fail->sons.end());
0723 leaves[2] = search_empty_leaf (*tmp);
0724 nodes[2] = (*tmp)->up;
0725
0726 tmp = q_fail->pert_begin;
0727 leaves[1] = search_full_leaf (*tmp);
0728 nodes[1] = (*tmp)->up;
0729
0730 case_D (nodes, leaves, st_, to_father, G, q_fail);
0731
0732 } else if (q_fail->partial_count == 1) {
0733 if (q_fail->partial_pos[0] == q_fail->pert_end) {
0734 GTL_debug::debug_message ("CASE D (non-root q-node with partial child at end of pertinent children\n");
0735 pq_tree::sons_iterator tmp = q_fail->sons.begin();
0736 pq_leaf* leaves[3];
0737 node nodes[3];
0738 leaves[0] = search_empty_leaf (*tmp);
0739 nodes[0] = (*tmp)->up;
0740
0741 tmp = q_fail->pert_end;
0742 leaves[2] = search_empty_leaf (*tmp);
0743 nodes[2] = (*tmp)->up;
0744
0745 tmp = q_fail->pert_begin;
0746 leaves[1] = search_full_leaf (*tmp);
0747 nodes[1] = (*tmp)->up;
0748
0749 case_D (nodes, leaves, st_, to_father, G, q_fail);
0750 } else {
0751 GTL_debug::debug_message ("CASE C (q-node with partial children surrounded by pertinent children)\n");
0752 pq_tree::sons_iterator tmp = q_fail->pert_begin;
0753 pq_leaf* leaves[3];
0754 node nodes[3];
0755 leaves[0] = search_full_leaf (*tmp);
0756 nodes[0] = (*tmp)->up;
0757
0758 tmp = q_fail->pert_end;
0759 leaves[2] = search_full_leaf (*tmp);
0760 nodes[2] = (*tmp)->up;
0761
0762 tmp = q_fail->partial_pos[0];
0763 leaves[1] = search_empty_leaf (*tmp);
0764 nodes[1] = (*tmp)->up;
0765
0766
0767 case_C (nodes, leaves, st_, to_father, G, q_fail);
0768 }
0769
0770 } else if ((q_fail->partial_pos[0] == q_fail->pert_begin ||
0771 q_fail->partial_pos[0] == q_fail->pert_end) &&
0772 (q_fail->partial_pos[1] == q_fail->pert_begin ||
0773 q_fail->partial_pos[1] == q_fail->pert_end)) {
0774
0775 if (++(q_fail->sons.begin()) == --(q_fail->sons.end())) {
0776
0777
0778
0779
0780
0781 pq_tree::sons_iterator tmp = q_fail->sons.begin();
0782 pq_leaf* leaves[4];
0783 node nodes[2];
0784 leaves[0] = search_empty_leaf (*tmp);
0785 nodes[0] = (*tmp)->up;
0786 leaves[1] = search_full_leaf (*tmp);
0787
0788 ++tmp;
0789 leaves[2] = search_empty_leaf (*tmp);
0790 nodes[1] = (*tmp)->up;
0791 leaves[3] = search_full_leaf (*tmp);
0792
0793 case_E (nodes, leaves, st_, to_father, G, q_fail);
0794
0795 } else if (q_fail->partial_count == 2) {
0796 GTL_debug::debug_message ("CASE D (non-root q_node with first and last pertinent children partial)\n");
0797
0798
0799
0800
0801
0802 pq_tree::sons_iterator tmp = q_fail->sons.begin();
0803 pq_leaf* leaves[3];
0804 node nodes[3];
0805 leaves[0] = search_empty_leaf (*tmp);
0806 nodes[0] = (*tmp)->up;
0807
0808 tmp = q_fail->pert_end;
0809 leaves[2] = search_empty_leaf (*tmp);
0810 nodes[2] = (*tmp)->up;
0811
0812 tmp = q_fail->pert_begin;
0813
0814 if (tmp == q_fail->sons.begin()) {
0815 ++tmp;
0816 }
0817
0818 leaves[1] = search_full_leaf (*tmp);
0819 nodes[1] = (*tmp)->up;
0820
0821 case_D (nodes, leaves, st_, to_father, G, q_fail);
0822
0823 } else {
0824 GTL_debug::debug_message ("CASE C (q_node with at least three partial children)\n");
0825
0826
0827
0828
0829
0830 pq_tree::sons_iterator tmp = q_fail->pert_begin;
0831 pq_leaf* leaves[3];
0832 node nodes[3];
0833 leaves[0] = search_full_leaf (*tmp);
0834 nodes[0] = (*tmp)->up;
0835
0836 tmp = q_fail->pert_end;
0837 leaves[2] = search_full_leaf (*tmp);
0838 nodes[2] = (*tmp)->up;
0839
0840 tmp = q_fail->partial_pos[2];
0841 leaves[1] = search_empty_leaf (*tmp);
0842 nodes[1] = (*tmp)->up;
0843
0844 case_C (nodes, leaves, st_, to_father, G, q_fail);
0845 }
0846
0847 } else {
0848
0849
0850
0851
0852
0853 GTL_debug::debug_message ("CASE C (q_node with at least two partial children, at least one surrounded by pertinent)\n");
0854 pq_tree::sons_iterator tmp = q_fail->pert_begin;
0855 pq_leaf* leaves[3];
0856 node nodes[3];
0857 leaves[0] = search_full_leaf (*tmp);
0858 nodes[0] = (*tmp)->up;
0859
0860 tmp = q_fail->pert_end;
0861 leaves[2] = search_full_leaf (*tmp);
0862 nodes[2] = (*tmp)->up;
0863
0864 tmp = q_fail->partial_pos[0];
0865
0866 if (tmp == q_fail->pert_begin || tmp == q_fail->pert_end) {
0867 tmp = q_fail->partial_pos[1];
0868 }
0869
0870 leaves[1] = search_empty_leaf (*tmp);
0871 nodes[1] = (*tmp)->up;
0872
0873 case_C (nodes, leaves, st_, to_father, G, q_fail);
0874 }
0875
0876 } else {
0877
0878
0879
0880
0881
0882 p_node* p_fail = fail->P();
0883
0884 if (p_fail->partial_count == 2) {
0885 GTL_debug::debug_message ("CASE B (non-root p-node with two partial children)\n");
0886 case_B (p_fail, act, st_, to_father, G);
0887
0888 } else {
0889
0890
0891
0892
0893
0894 GTL_debug::debug_message ("CASE A (p-node with at least three partial children)\n");
0895 case_A (p_fail, act, st_, to_father, G);
0896 }
0897 }
0898 }
0899
0900
0901
0902 void planarity::case_A (p_node* p_fail,
0903 node act,
0904 st_number& st_,
0905 node_map<edge> to_father,
0906 graph& G)
0907 {
0908 node art = p_fail->n;
0909 ob_nodes.push_back (art);
0910 ob_nodes.push_back (act);
0911 node_map<int> mark (G, 0);
0912 mark[art] = 1;
0913 pq_leaf* empty[3];
0914 pq_tree::sons_iterator part_pos = p_fail->partial_sons.begin();
0915 int i;
0916
0917 for (i = 0; i < 3; ++i) {
0918 q_node* q_part = (*part_pos)->Q();
0919 empty[i] = run_through_partial (q_part, mark, to_father, art);
0920 ++part_pos;
0921 }
0922
0923 node t_node = st_.s_node().opposite (st_.st_edge());
0924 mark[t_node] = 1;
0925 node tmp[3];
0926
0927 for (i = 0; i < 3; ++i) {
0928 tmp[i] = up_until_marked (empty[i]->n, mark, st_);
0929 }
0930
0931 assert (tmp[0] == t_node);
0932 node tmp_node;
0933
0934
0935
0936
0937
0938
0939
0940
0941 if (st_[tmp[1]] < st_[tmp[2]]) {
0942 tmp_node = tmp[2];
0943 ob_nodes.push_back (tmp[1]);
0944 } else {
0945 tmp_node = tmp[1];
0946 ob_nodes.push_back (tmp[2]);
0947 }
0948
0949
0950 if (tmp_node != t_node) {
0951 list<edge>::iterator it, end;
0952 int max_st = st_[tmp_node];
0953
0954 it = ob_edges.begin();
0955 end = ob_edges.end();
0956
0957 while (it != end) {
0958 edge cur = *it;
0959
0960 if (st_[cur.source()] > max_st || st_[cur.target()] > max_st) {
0961 it = ob_edges.erase (it);
0962 } else {
0963 ++it;
0964 }
0965 }
0966 }
0967 }
0968
0969
0970
0971 void planarity::case_B (p_node* p_fail,
0972 node act,
0973 st_number& st_,
0974 node_map<edge> to_father,
0975 graph& G)
0976 {
0977
0978
0979
0980
0981
0982 node art = p_fail->n;
0983 ob_nodes.push_back (art);
0984 ob_nodes.push_back (act);
0985 node_map<int> mark (G, 0);
0986 node_map<int> below (G, 0);
0987 mark[art] = 1;
0988
0989
0990
0991
0992
0993 pq_tree::sons_iterator it, end;
0994 for (it = p_fail->full_sons.begin(), end = p_fail->full_sons.end(); it != end; ++it) {
0995 mark_all_neighbors_of_leaves (*it, below);
0996 }
0997
0998
0999
1000
1001
1002
1003 pq_tree::sons_iterator part_pos = p_fail->partial_sons.begin();
1004 q_node* q_part = (*part_pos)->Q();
1005 pq_leaf* empty1 = run_through_partial (q_part, mark, to_father, art);
1006
1007 for (it = q_part->pert_begin, end = ++(q_part->pert_end); it != end; ++it) {
1008 mark_all_neighbors_of_leaves (*it, below);
1009 }
1010
1011
1012
1013
1014
1015
1016 ++part_pos;
1017 q_part = (*part_pos)->Q();
1018 pq_leaf* empty2 = run_through_partial (q_part, mark, to_father, art);
1019
1020
1021 for (it = q_part->pert_begin, end = ++(q_part->pert_end); it != end; ++it) {
1022 mark_all_neighbors_of_leaves (*it, below);
1023 }
1024
1025
1026
1027
1028
1029
1030 node::adj_edges_iterator a_it, a_end;
1031
1032 for (a_it = act.adj_edges_begin(), a_end = act.adj_edges_end(); a_it != a_end; ++a_it) {
1033 if (below[act.opposite (*a_it)] == 0 && st_[act.opposite (*a_it)] < st_[act]) {
1034 break;
1035 }
1036 }
1037
1038 assert (a_it != a_end);
1039 mark[st_.s_node()] = 1;
1040 mark[art] = 0;
1041 node tmp = up_until_marked (art, mark, to_father);
1042 assert (tmp == st_.s_node());
1043 tmp = up_until_marked (act.opposite (*a_it), mark, to_father);
1044 assert(tmp != art);
1045 ob_nodes.push_back (tmp);
1046 ob_edges.push_back (*a_it);
1047 ob_edges.push_back (st_.st_edge());
1048
1049
1050
1051
1052
1053 node t_node = st_.s_node().opposite (st_.st_edge());
1054 mark[t_node] = 1;
1055 tmp = up_until_marked (empty1->n, mark, st_);
1056 assert (tmp == t_node);
1057 tmp = up_until_marked (empty2->n, mark, st_);
1058 ob_nodes.push_back (tmp);
1059 }
1060
1061
1062 void planarity::case_C (node* nodes,
1063 pq_leaf** leaves,
1064 st_number& st_,
1065 node_map<edge> to_father,
1066 graph& G,
1067 q_node* q_fail)
1068 {
1069 int i;
1070 node_map<int> mark (G, 0);
1071 node y_0 = q_fail->n;
1072
1073 for (i = 0; i < 3; ++i) {
1074 mark[nodes[i]] = 1;
1075 edge tmp_edge = leaves[i]->e;
1076 node tmp_node = leaves[i]->n;
1077 ob_edges.push_back (tmp_edge);
1078 tmp_node = up_until_marked (tmp_node.opposite (tmp_edge), mark, to_father);
1079 assert (tmp_node == nodes[i]);
1080 ob_nodes.push_back (nodes[i]);
1081 }
1082
1083 ob_nodes.push_back (y_0);
1084 mark[st_.s_node()] = 1;
1085 node tmp = up_until_marked (y_0, mark, to_father);
1086 assert (tmp == st_.s_node ());
1087
1088 ob_nodes.push_back (leaves[2]->n);
1089 ob_edges.push_back (st_.st_edge());
1090
1091 node t_node = st_.s_node().opposite (st_.st_edge());
1092 mark[t_node] = 1;
1093 tmp = up_until_marked (leaves[1]->n, mark, st_);
1094 assert (tmp == t_node);
1095 tmp = up_until_marked (leaves[2]->n, mark, st_);
1096 ob_nodes.push_back (tmp);
1097 }
1098
1099
1100 void planarity::case_D (node* nodes,
1101 pq_leaf** leaves,
1102 st_number& st_,
1103 node_map<edge> to_father,
1104 graph& G,
1105 q_node* q_fail)
1106 {
1107
1108
1109
1110
1111 node y_0 = q_fail->n;
1112 pq_tree::sons_iterator it, end;
1113 node_map<int> below (G, 0);
1114 node act = leaves[1]->n;
1115
1116 for (it = q_fail->sons.begin(), end = q_fail->sons.end(); it != end; ++it) {
1117 mark_all_neighbors_of_leaves (*it, below);
1118 }
1119
1120 node::adj_edges_iterator a_it, a_end;
1121
1122 for (a_it = act.adj_edges_begin(), a_end = act.adj_edges_end(); a_it != a_end; ++a_it) {
1123 if (below[act.opposite (*a_it)] == 0 && st_[act.opposite (*a_it)] < st_[act]) {
1124 break;
1125 }
1126 }
1127
1128
1129
1130
1131
1132
1133
1134
1135 assert (a_it != a_end);
1136
1137 int i;
1138 node_map<int> mark (G, 0);
1139
1140 for (i = 0; i < 3; ++i) {
1141 mark[nodes[i]] = 1;
1142 edge tmp_edge = leaves[i]->e;
1143 node tmp_node = leaves[i]->n;
1144 ob_edges.push_back (tmp_edge);
1145 tmp_node = up_until_marked (tmp_node.opposite (tmp_edge), mark, to_father);
1146 assert (tmp_node == nodes[i]);
1147 ob_nodes.push_back (nodes[i]);
1148 }
1149
1150 ob_nodes.push_back (y_0);
1151 mark[st_.s_node()] = 1;
1152 node tmp = up_until_marked (y_0, mark, to_father);
1153 assert (tmp == st_.s_node ());
1154 ob_edges.push_back (*a_it);
1155 tmp = up_until_marked (act.opposite (*a_it), mark, to_father);
1156
1157
1158
1159
1160
1161
1162
1163 if (tmp != st_.s_node()) {
1164 list<edge>::iterator it, end;
1165 int min_st = st_[tmp];
1166 it = ob_edges.begin();
1167 end = ob_edges.end();
1168
1169 while (it != end) {
1170 edge cur = *it;
1171
1172 if (st_[cur.source()] < min_st || st_[cur.target()] < min_st) {
1173 it = ob_edges.erase (it);
1174 } else {
1175 ++it;
1176 }
1177 }
1178 }
1179
1180 ob_nodes.push_back (act);
1181
1182 node t_node = st_.s_node().opposite (st_.st_edge());
1183 mark[t_node] = 1;
1184 node tmp_nodes[3];
1185
1186 for (i = 0; i < 3; ++i) {
1187 tmp_nodes[i] = up_until_marked (leaves[i]->n, mark, st_);
1188 }
1189
1190 assert (tmp_nodes[0] == t_node);
1191
1192
1193
1194
1195
1196
1197
1198
1199 if (st_[tmp_nodes[1]] < st_[tmp_nodes[2]]) {
1200 tmp = tmp_nodes[2];
1201 ob_nodes.push_back (tmp_nodes[1]);
1202 } else {
1203 tmp = tmp_nodes[1];
1204 ob_nodes.push_back (tmp_nodes[2]);
1205 }
1206
1207
1208 if (tmp != t_node) {
1209 list<edge>::iterator it, end;
1210 int max_st = st_[tmp];
1211 it = ob_edges.begin();
1212 end = ob_edges.end();
1213
1214 while (it != end) {
1215 edge cur = *it;
1216
1217 if (st_[cur.source()] > max_st || st_[cur.target()] > max_st) {
1218 it = ob_edges.erase (it);
1219 } else {
1220 ++it;
1221 }
1222 }
1223 }
1224 }
1225
1226
1227 void planarity::case_E (node* nodes,
1228 pq_leaf** leaves,
1229 st_number& st_,
1230 node_map<edge> to_father,
1231 graph& G,
1232 q_node* q_fail)
1233 {
1234
1235
1236
1237
1238
1239 node y_0 = q_fail->n;
1240 pq_tree::sons_iterator it, end;
1241 node_map<int> below (G, 0);
1242 node act = leaves[1]->n;
1243
1244 for (it = q_fail->pert_begin, end = ++(q_fail->pert_end); it != end; ++it) {
1245 mark_all_neighbors_of_leaves (*it, below);
1246 }
1247
1248 node::adj_edges_iterator a_it, a_end;
1249
1250 for (a_it = act.adj_edges_begin(), a_end = act.adj_edges_end(); a_it != a_end; ++a_it) {
1251 if (below[act.opposite (*a_it)] == 0 && st_[act.opposite (*a_it)] < st_[act]) {
1252 break;
1253 }
1254 }
1255
1256
1257
1258
1259
1260
1261
1262
1263 assert (a_it != a_end);
1264
1265
1266
1267
1268
1269
1270
1271 list<edge>::iterator paths_begin[3];
1272 list<edge>::iterator l_it, l_end;
1273 node next = y_0;
1274
1275 for (l_it = ob_edges.begin(), l_end = ob_edges.end(); l_it != l_end; ++l_it) {
1276 next = next.opposite (*l_it);
1277
1278 if (next == nodes[1]) {
1279 node tmp = nodes[1];
1280 nodes[1] = nodes[0];
1281 nodes[0] = tmp;
1282 pq_leaf* tmp_leaf = leaves[2];
1283 leaves[2] = leaves[0];
1284 leaves[0] = tmp_leaf;
1285 tmp_leaf = leaves[3];
1286 leaves[3] = leaves[1];
1287 leaves[1] = tmp_leaf;
1288
1289 paths_begin[0] = l_it;
1290 ++paths_begin[0];
1291 break;
1292 } else if (next == nodes[0]) {
1293 paths_begin[0] = l_it;
1294 ++paths_begin[0];
1295 break;
1296 }
1297 }
1298
1299 assert (l_it != l_end);
1300 ++l_it;
1301 assert (l_it != l_end);
1302
1303 for (; l_it != l_end; ++l_it) {
1304 next = next.opposite (*l_it);
1305
1306 if (next == nodes[1]) {
1307 paths_begin[1] = l_it;
1308 ++paths_begin[1];
1309 break;
1310 }
1311 }
1312
1313 assert (l_it != l_end);
1314
1315 paths_begin[2] = --l_end;
1316
1317 node y[3];
1318 int i;
1319 node_map<int> mark (G, 0);
1320 list<edge> from_act[3];
1321 list<edge>::iterator pos;
1322
1323 for (i = 0; i < 2; ++i) {
1324 mark[nodes[i]] = 1;
1325 edge tmp_edge = leaves[2 * i]->e;
1326 node tmp_node = leaves[2 * i]->n;
1327 ob_edges.push_back (tmp_edge);
1328 tmp_node = up_until_marked (tmp_node.opposite (tmp_edge), mark, to_father);
1329 assert (tmp_node == nodes[i]);
1330 tmp_edge = leaves[2 * i + 1]->e;
1331 tmp_node = leaves[2 * i + 1]->n;
1332 pos = ob_edges.insert (ob_edges.end(), tmp_edge);
1333 y[i + 1] = up_until_marked (tmp_node.opposite (tmp_edge), mark, to_father);
1334 from_act[i + 1].splice (from_act[i + 1].begin(), ob_edges, pos, ob_edges.end());
1335 }
1336
1337 mark[st_.s_node()] = 1;
1338 node tmp = up_until_marked (y_0, mark, to_father);
1339 assert (tmp == st_.s_node ());
1340 pos = ob_edges.insert (ob_edges.end(), *a_it);
1341 y[0] = up_until_marked (act.opposite (*a_it), mark, to_father);
1342 from_act[0].splice (from_act[0].begin(), ob_edges, pos, ob_edges.end());
1343
1344 node t_node = st_.s_node().opposite (st_.st_edge());
1345 mark[t_node] = 1;
1346 node tmp_nodes[3];
1347 node_map<int> from_where (G, 0);
1348
1349 for (i = 0; i < 2; ++i) {
1350 pos = --(ob_edges.end());
1351 tmp_nodes[i] = up_until_marked (leaves[2 * i]->n, mark, st_);
1352 for (l_it = ++pos, l_end = ob_edges.end(); l_it != l_end; ++l_it) {
1353 from_where[(*l_it).source()] = i + 1;
1354 from_where[(*l_it).target()] = i + 1;
1355 }
1356 }
1357
1358 assert (tmp_nodes[0] == t_node);
1359
1360 if (y_0 != y[0]) {
1361 ob_nodes.push_back (y_0);
1362 ob_nodes.push_back (y[0]);
1363 ob_nodes.push_back (y[1]);
1364 ob_nodes.push_back (y[2]);
1365 ob_nodes.push_back (act);
1366 ob_nodes.push_back (tmp_nodes[1]);
1367
1368 l_it = paths_begin[0];
1369 l_end = paths_begin[1];
1370 ob_edges.erase (l_it, l_end);
1371
1372 for (i = 0; i < 3; ++i) {
1373 ob_edges.splice (ob_edges.end(), from_act[i], from_act[i].begin(), from_act[i].end());
1374 }
1375
1376 GTL_debug::debug_message ("CASE E(i)\n");
1377
1378 } else if (nodes[0] != y[1]) {
1379 ob_nodes.push_back (y_0);
1380 ob_nodes.push_back (y[1]);
1381 ob_nodes.push_back (nodes[0]);
1382 ob_nodes.push_back (y[2]);
1383 ob_nodes.push_back (act);
1384 ob_nodes.push_back (tmp_nodes[1]);
1385 l_it = paths_begin[1];
1386 l_end = paths_begin[2];
1387 ++l_end;
1388 ob_edges.erase (l_it, l_end);
1389
1390 for (i = 0; i < 3; ++i) {
1391 ob_edges.splice (ob_edges.end(), from_act[i], from_act[i].begin(), from_act[i].end());
1392 }
1393
1394 GTL_debug::debug_message ("CASE E(ii)\n");
1395
1396 } else if (nodes[1] != y[2]) {
1397 ob_nodes.push_back (y_0);
1398 ob_nodes.push_back (y[1]);
1399 ob_nodes.push_back (nodes[1]);
1400 ob_nodes.push_back (y[2]);
1401 ob_nodes.push_back (act);
1402 ob_nodes.push_back (tmp_nodes[1]);
1403 l_it = ob_edges.begin();
1404 l_end = paths_begin[0];
1405 ob_edges.erase (l_it, l_end);
1406
1407 for (i = 0; i < 3; ++i) {
1408 ob_edges.splice (ob_edges.end(), from_act[i], from_act[i].begin(), from_act[i].end());
1409 }
1410
1411 GTL_debug::debug_message ("CASE E(ii)\n");
1412
1413 } else {
1414 tmp_nodes[2] = up_until_marked (leaves[1]->n, mark, st_);
1415 ob_nodes.push_back (y_0);
1416 ob_nodes.push_back (y[1]);
1417 ob_nodes.push_back (tmp_nodes[1]);
1418 ob_nodes.push_back (y[2]);
1419 ob_nodes.push_back (act);
1420
1421 if (st_[tmp_nodes[1]] < st_[tmp_nodes[2]]) {
1422 ob_nodes.push_back (tmp_nodes[2]);
1423 l_it = paths_begin[0];
1424 l_end = paths_begin[1];
1425 ob_edges.erase (l_it, l_end);
1426
1427 for (i = 1; i < 3; ++i) {
1428 ob_edges.splice (ob_edges.end(), from_act[i], from_act[i].begin(), from_act[i].end());
1429 }
1430
1431 GTL_debug::debug_message ("CASE E(iii) (1)\n");
1432
1433 } else if (st_[tmp_nodes[1]] > st_[tmp_nodes[2]]) {
1434 edge last_edge = *(--(ob_edges.end()));
1435 ob_nodes.push_back (tmp_nodes[2]);
1436 ob_edges.splice (ob_edges.end(), from_act[0], from_act[0].begin(), from_act[0].end());
1437 int from;
1438
1439 if (from_where[last_edge.source()] > 0) {
1440 from = from_where[last_edge.source()];
1441 } else {
1442 from = from_where[last_edge.target()];
1443 }
1444
1445 assert (from > 0);
1446
1447 if (from == 1) {
1448 ob_edges.splice (ob_edges.end(), from_act[2], from_act[2].begin(), from_act[2].end());
1449
1450 l_it = paths_begin[1];
1451 l_end = paths_begin[2];
1452 ++l_end;
1453 ob_edges.erase (l_it, l_end);
1454
1455 } else {
1456 ob_edges.splice (ob_edges.end(), from_act[1], from_act[1].begin(), from_act[1].end());
1457
1458 l_it = ob_edges.begin();
1459 l_end = paths_begin[0];
1460 ob_edges.erase (l_it, l_end);
1461 }
1462
1463 GTL_debug::debug_message ("CASE E(iii) (2)\n");
1464
1465 } else {
1466 for (i = 0; i < 3; ++i) {
1467 ob_edges.splice (ob_edges.end(), from_act[i], from_act[i].begin(), from_act[i].end());
1468 }
1469
1470 GTL_debug::debug_message ("CASE E(iii) (3)\n");
1471 }
1472 }
1473
1474 ob_edges.push_back (st_.st_edge());
1475 }
1476
1477
1478 pq_leaf* planarity::search_full_leaf (pq_node* n)
1479 {
1480 switch (n->kind()) {
1481 case pq_node::LEAF:
1482 return n->L();
1483
1484 case pq_node::P_NODE:
1485 case pq_node::Q_NODE:
1486 return search_full_leaf (*(--(n->sons.end())));
1487
1488 default:
1489 assert (false);
1490 return 0;
1491 }
1492 }
1493
1494
1495 pq_leaf* planarity::search_empty_leaf (pq_node* n)
1496 {
1497 switch (n->kind()) {
1498 case pq_node::LEAF:
1499 return n->L();
1500
1501 case pq_node::Q_NODE:
1502 case pq_node::P_NODE:
1503 return search_empty_leaf (*(n->sons.begin()));
1504
1505 default:
1506 assert (false);
1507 return 0;
1508 }
1509 }
1510
1511
1512
1513 void planarity::mark_all_neighbors_of_leaves (pq_node* act, node_map<int>& mark)
1514 {
1515 if (act->kind() == pq_node::LEAF) {
1516 mark[((pq_leaf*)act)->e.opposite(((pq_leaf*)act)->n)] = 1;
1517 } else {
1518 pq_tree::sons_iterator it, end;
1519
1520 for (it = act->sons.begin(), end = act->sons.end(); it != end; ++it) {
1521 mark_all_neighbors_of_leaves (*it, mark);
1522 }
1523 }
1524 }
1525
1526
1527 pq_leaf* planarity::run_through_partial (q_node* part, node_map<int>& mark, node_map<edge>& to_father, node v)
1528 {
1529 pq_leaf* tmp = search_full_leaf (part);
1530 edge tmp_edge = tmp->e;
1531 node tmp_node = tmp->n;
1532 ob_edges.push_back (tmp_edge);
1533 tmp_node = up_until_marked (tmp_node.opposite (tmp_edge), mark, to_father);
1534
1535 tmp = search_empty_leaf (part);
1536 tmp_node = tmp->n;
1537 tmp_edge = tmp->e;
1538 ob_edges.push_back (tmp_edge);
1539 tmp_node = up_until_marked (tmp_node.opposite (tmp_edge), mark, to_father);
1540 assert (tmp_node != v);
1541 ob_nodes.push_back (tmp_node);
1542
1543 return tmp->L();
1544 }
1545
1546
1547 node planarity::up_until_marked (node act, node_map<int>& mark, node_map<edge>& to_father)
1548 {
1549 while (mark[act] == 0) {
1550 mark[act] = 1;
1551 edge next = to_father[act];
1552 ob_edges.push_back (next);
1553 act = act.opposite (next);
1554 }
1555
1556 return act;
1557 }
1558
1559 node planarity::up_until_marked (node act, node_map<int>& mark, st_number& st_)
1560 {
1561 while (mark[act] == 0) {
1562 mark[act] = 1;
1563 node opp;
1564 node::adj_edges_iterator it, end;
1565
1566 for (it = act.adj_edges_begin(), end = act.adj_edges_end(); it != end; ++it) {
1567 opp = act.opposite (*it);
1568 if (st_[opp] > st_[act]) {
1569 break;
1570 }
1571 }
1572
1573 assert (it != end);
1574 ob_edges.push_back (*it);
1575 act = opp;
1576 }
1577
1578 return act;
1579 }
1580
1581 void planarity::attachment_cycle (node start, planar_embedding& em)
1582 {
1583 edge act = em.adjacency(start).front();
1584 node next = start.opposite (act);
1585 ob_edges.push_back (act);
1586
1587 while (next != start) {
1588 act = em.cyclic_next (next, act);
1589 next = next.opposite (act);
1590 ob_edges.push_back (act);
1591 }
1592 }
1593
1594
1595 void planarity::dfs_bushform (node n,
1596 node_map<int>& used,
1597 st_number& st_,
1598 int stop,
1599 node_map<edge>& to_father)
1600 {
1601 used[n] = 1;
1602 node::adj_edges_iterator it, end;
1603
1604 for (it = n.adj_edges_begin(), end = n.adj_edges_end(); it != end; ++it) {
1605 edge act = *it;
1606 node other = n.opposite(act);
1607
1608 if (used[other] == 0 && st_[other] < stop) {
1609 to_father[other] = *it;
1610 dfs_bushform (other, used, st_, stop, to_father);
1611 }
1612 }
1613 }
1614
1615 #ifdef _DEBUG
1616
1617 void planarity::write_node(ostream& os, int id, int label, int mark) {
1618 os << "node [\n" << "id " << id << endl;
1619 os << "label \"" << label << "\"\n";
1620 os << "graphics [\n" << "x 100\n" << "y 100 \n";
1621 if (mark == 1) {
1622 os << "outline \"#ff0000\"\n";
1623 }
1624 os << "]\n";
1625 os << "]" << endl;
1626 }
1627 #endif
1628
1629 #ifdef _DEBUG
1630 void planarity::write_bushform(graph& G, st_number& st_, int k, const char* name, const node_map<int>& mark,
1631 const node_map<edge>& to_father)
1632 {
1633
1634 st_number::iterator st_it, st_end;
1635 int id = 0;
1636 node_map<int> ids (G);
1637 ofstream os (name, ios::out | ios::trunc);
1638
1639 os << "graph [\n" << "directed 1" << endl;
1640
1641 for (st_it = st_.begin(), st_end = st_.end(); st_it != st_end && st_[*st_it] <= k; ++st_it) {
1642 write_node(os, id, st_[*st_it], mark[*st_it]);
1643 ids[*st_it] = id;
1644 id++;
1645 }
1646
1647 for (st_it = st_.begin(), st_end = st_.end(); st_it != st_end && st_[*st_it] <= k; ++st_it) {
1648 node::adj_edges_iterator ait, aend;
1649
1650 for (ait = (*st_it).adj_edges_begin(), aend = (*st_it).adj_edges_end(); ait != aend; ait++) {
1651 node other = (*ait).opposite(*st_it);
1652 int other_id;
1653 if (st_[*st_it] < st_[other]) {
1654 if(st_[other] > k) {
1655 write_node(os, id, st_[other], mark[other]);
1656 other_id = id;
1657 id++;
1658 } else {
1659 other_id = ids[other];
1660 }
1661
1662 os << "edge [\n" << "source " << ids[*st_it] << "\ntarget " << other_id << endl;
1663 if (*ait == to_father[*st_it] || *ait == to_father[other]) {
1664 os << "graphics [\n" << "fill \"#0000ff\"" << endl;
1665 os << "width 4.0\n]" << endl;
1666 }
1667 os << "\n]" << endl;
1668 }
1669 }
1670 }
1671
1672 os << "]" << endl;
1673 }
1674
1675 #endif
1676
1677 __GTL_END_NAMESPACE
1678
1679
1680
1681