gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Planarity checking function instead of class (#62)
0 2 0
default
2 files changed with 388 insertions and 385 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_PLANARITY_H
20 20
#define LEMON_PLANARITY_H
21 21

	
22 22
/// \ingroup planar
23 23
/// \file
24 24
/// \brief Planarity checking, embedding, drawing and coloring
25 25

	
26 26
#include <vector>
27 27
#include <list>
28 28

	
29 29
#include <lemon/dfs.h>
30 30
#include <lemon/bfs.h>
31 31
#include <lemon/radix_sort.h>
32 32
#include <lemon/maps.h>
33 33
#include <lemon/path.h>
34 34
#include <lemon/bucket_heap.h>
35 35
#include <lemon/adaptors.h>
36 36
#include <lemon/edge_set.h>
37 37
#include <lemon/color.h>
38 38
#include <lemon/dim2.h>
39 39

	
40 40
namespace lemon {
41 41

	
42 42
  namespace _planarity_bits {
43 43

	
44 44
    template <typename Graph>
45 45
    struct PlanarityVisitor : DfsVisitor<Graph> {
46 46

	
47 47
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
48 48

	
49 49
      typedef typename Graph::template NodeMap<Arc> PredMap;
50 50

	
51 51
      typedef typename Graph::template EdgeMap<bool> TreeMap;
52 52

	
53 53
      typedef typename Graph::template NodeMap<int> OrderMap;
54 54
      typedef std::vector<Node> OrderList;
55 55

	
56 56
      typedef typename Graph::template NodeMap<int> LowMap;
57 57
      typedef typename Graph::template NodeMap<int> AncestorMap;
58 58

	
59 59
      PlanarityVisitor(const Graph& graph,
60 60
                       PredMap& pred_map, TreeMap& tree_map,
61 61
                       OrderMap& order_map, OrderList& order_list,
62 62
                       AncestorMap& ancestor_map, LowMap& low_map)
63 63
        : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
64 64
          _order_map(order_map), _order_list(order_list),
65 65
          _ancestor_map(ancestor_map), _low_map(low_map) {}
66 66

	
67 67
      void reach(const Node& node) {
68 68
        _order_map[node] = _order_list.size();
69 69
        _low_map[node] = _order_list.size();
70 70
        _ancestor_map[node] = _order_list.size();
71 71
        _order_list.push_back(node);
72 72
      }
73 73

	
74 74
      void discover(const Arc& arc) {
75 75
        Node source = _graph.source(arc);
76 76
        Node target = _graph.target(arc);
77 77

	
78 78
        _tree_map[arc] = true;
79 79
        _pred_map[target] = arc;
80 80
      }
81 81

	
82 82
      void examine(const Arc& arc) {
83 83
        Node source = _graph.source(arc);
84 84
        Node target = _graph.target(arc);
85 85

	
86 86
        if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
87 87
          if (_low_map[source] > _order_map[target]) {
88 88
            _low_map[source] = _order_map[target];
89 89
          }
90 90
          if (_ancestor_map[source] > _order_map[target]) {
91 91
            _ancestor_map[source] = _order_map[target];
92 92
          }
93 93
        }
94 94
      }
95 95

	
96 96
      void backtrack(const Arc& arc) {
97 97
        Node source = _graph.source(arc);
98 98
        Node target = _graph.target(arc);
99 99

	
100 100
        if (_low_map[source] > _low_map[target]) {
101 101
          _low_map[source] = _low_map[target];
102 102
        }
103 103
      }
104 104

	
105 105
      const Graph& _graph;
106 106
      PredMap& _pred_map;
107 107
      TreeMap& _tree_map;
108 108
      OrderMap& _order_map;
109 109
      OrderList& _order_list;
110 110
      AncestorMap& _ancestor_map;
111 111
      LowMap& _low_map;
112 112
    };
113 113

	
114 114
    template <typename Graph, bool embedding = true>
115 115
    struct NodeDataNode {
116 116
      int prev, next;
117 117
      int visited;
118 118
      typename Graph::Arc first;
119 119
      bool inverted;
120 120
    };
121 121

	
122 122
    template <typename Graph>
123 123
    struct NodeDataNode<Graph, false> {
124 124
      int prev, next;
125 125
      int visited;
126 126
    };
127 127

	
128 128
    template <typename Graph>
129 129
    struct ChildListNode {
130 130
      typedef typename Graph::Node Node;
131 131
      Node first;
132 132
      Node prev, next;
133 133
    };
134 134

	
135 135
    template <typename Graph>
136 136
    struct ArcListNode {
137 137
      typename Graph::Arc prev, next;
138 138
    };
139 139

	
140
    template <typename Graph>
141
    class PlanarityChecking {
142
    private:
143
      
144
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
145

	
146
      const Graph& _graph;
147

	
148
    private:
149
      
150
      typedef typename Graph::template NodeMap<Arc> PredMap;
151
      
152
      typedef typename Graph::template EdgeMap<bool> TreeMap;
153
      
154
      typedef typename Graph::template NodeMap<int> OrderMap;
155
      typedef std::vector<Node> OrderList;
156

	
157
      typedef typename Graph::template NodeMap<int> LowMap;
158
      typedef typename Graph::template NodeMap<int> AncestorMap;
159

	
160
      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
161
      typedef std::vector<NodeDataNode> NodeData;
162

	
163
      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
164
      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
165

	
166
      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
167

	
168
      typedef typename Graph::template NodeMap<bool> EmbedArc;
169

	
170
    public:
171

	
172
      PlanarityChecking(const Graph& graph) : _graph(graph) {}
173

	
174
      bool run() {
175
        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
176

	
177
        PredMap pred_map(_graph, INVALID);
178
        TreeMap tree_map(_graph, false);
179

	
180
        OrderMap order_map(_graph, -1);
181
        OrderList order_list;
182

	
183
        AncestorMap ancestor_map(_graph, -1);
184
        LowMap low_map(_graph, -1);
185

	
186
        Visitor visitor(_graph, pred_map, tree_map,
187
                        order_map, order_list, ancestor_map, low_map);
188
        DfsVisit<Graph, Visitor> visit(_graph, visitor);
189
        visit.run();
190

	
191
        ChildLists child_lists(_graph);
192
        createChildLists(tree_map, order_map, low_map, child_lists);
193

	
194
        NodeData node_data(2 * order_list.size());
195

	
196
        EmbedArc embed_arc(_graph, false);
197

	
198
        MergeRoots merge_roots(_graph);
199

	
200
        for (int i = order_list.size() - 1; i >= 0; --i) {
201

	
202
          Node node = order_list[i];
203

	
204
          Node source = node;
205
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
206
            Node target = _graph.target(e);
207

	
208
            if (order_map[source] < order_map[target] && tree_map[e]) {
209
              initFace(target, node_data, order_map, order_list);
210
            }
211
          }
212

	
213
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
214
            Node target = _graph.target(e);
215

	
216
            if (order_map[source] < order_map[target] && !tree_map[e]) {
217
              embed_arc[target] = true;
218
              walkUp(target, source, i, pred_map, low_map,
219
                     order_map, order_list, node_data, merge_roots);
220
            }
221
          }
222

	
223
          for (typename MergeRoots::Value::iterator it =
224
                 merge_roots[node].begin(); 
225
               it != merge_roots[node].end(); ++it) {
226
            int rn = *it;
227
            walkDown(rn, i, node_data, order_list, child_lists,
228
                     ancestor_map, low_map, embed_arc, merge_roots);
229
          }
230
          merge_roots[node].clear();
231

	
232
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
233
            Node target = _graph.target(e);
234

	
235
            if (order_map[source] < order_map[target] && !tree_map[e]) {
236
              if (embed_arc[target]) {
237
                return false;
238
              }
239
            }
240
          }
241
        }
242

	
243
        return true;
244
      }
245

	
246
    private:
247

	
248
      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
249
                            const LowMap& low_map, ChildLists& child_lists) {
250

	
251
        for (NodeIt n(_graph); n != INVALID; ++n) {
252
          Node source = n;
253

	
254
          std::vector<Node> targets;
255
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
256
            Node target = _graph.target(e);
257

	
258
            if (order_map[source] < order_map[target] && tree_map[e]) {
259
              targets.push_back(target);
260
            }
261
          }
262

	
263
          if (targets.size() == 0) {
264
            child_lists[source].first = INVALID;
265
          } else if (targets.size() == 1) {
266
            child_lists[source].first = targets[0];
267
            child_lists[targets[0]].prev = INVALID;
268
            child_lists[targets[0]].next = INVALID;
269
          } else {
270
            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
271
            for (int i = 1; i < int(targets.size()); ++i) {
272
              child_lists[targets[i]].prev = targets[i - 1];
273
              child_lists[targets[i - 1]].next = targets[i];
274
            }
275
            child_lists[targets.back()].next = INVALID;
276
            child_lists[targets.front()].prev = INVALID;
277
            child_lists[source].first = targets.front();
278
          }
279
        }
280
      }
281

	
282
      void walkUp(const Node& node, Node root, int rorder,
283
                  const PredMap& pred_map, const LowMap& low_map,
284
                  const OrderMap& order_map, const OrderList& order_list,
285
                  NodeData& node_data, MergeRoots& merge_roots) {
286

	
287
        int na, nb;
288
        bool da, db;
289

	
290
        na = nb = order_map[node];
291
        da = true; db = false;
292

	
293
        while (true) {
294

	
295
          if (node_data[na].visited == rorder) break;
296
          if (node_data[nb].visited == rorder) break;
297

	
298
          node_data[na].visited = rorder;
299
          node_data[nb].visited = rorder;
300

	
301
          int rn = -1;
302

	
303
          if (na >= int(order_list.size())) {
304
            rn = na;
305
          } else if (nb >= int(order_list.size())) {
306
            rn = nb;
307
          }
308

	
309
          if (rn == -1) {
310
            int nn;
311

	
312
            nn = da ? node_data[na].prev : node_data[na].next;
313
            da = node_data[nn].prev != na;
314
            na = nn;
315

	
316
            nn = db ? node_data[nb].prev : node_data[nb].next;
317
            db = node_data[nn].prev != nb;
318
            nb = nn;
319

	
320
          } else {
321

	
322
            Node rep = order_list[rn - order_list.size()];
323
            Node parent = _graph.source(pred_map[rep]);
324

	
325
            if (low_map[rep] < rorder) {
326
              merge_roots[parent].push_back(rn);
327
            } else {
328
              merge_roots[parent].push_front(rn);
329
            }
330

	
331
            if (parent != root) {
332
              na = nb = order_map[parent];
333
              da = true; db = false;
334
            } else {
335
              break;
336
            }
337
          }
338
        }
339
      }
340

	
341
      void walkDown(int rn, int rorder, NodeData& node_data,
342
                    OrderList& order_list, ChildLists& child_lists,
343
                    AncestorMap& ancestor_map, LowMap& low_map,
344
                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
345

	
346
        std::vector<std::pair<int, bool> > merge_stack;
347

	
348
        for (int di = 0; di < 2; ++di) {
349
          bool rd = di == 0;
350
          int pn = rn;
351
          int n = rd ? node_data[rn].next : node_data[rn].prev;
352

	
353
          while (n != rn) {
354

	
355
            Node node = order_list[n];
356

	
357
            if (embed_arc[node]) {
358

	
359
              // Merging components on the critical path
360
              while (!merge_stack.empty()) {
361

	
362
                // Component root
363
                int cn = merge_stack.back().first;
364
                bool cd = merge_stack.back().second;
365
                merge_stack.pop_back();
366

	
367
                // Parent of component
368
                int dn = merge_stack.back().first;
369
                bool dd = merge_stack.back().second;
370
                merge_stack.pop_back();
371

	
372
                Node parent = order_list[dn];
373

	
374
                // Erasing from merge_roots
375
                merge_roots[parent].pop_front();
376

	
377
                Node child = order_list[cn - order_list.size()];
378

	
379
                // Erasing from child_lists
380
                if (child_lists[child].prev != INVALID) {
381
                  child_lists[child_lists[child].prev].next =
382
                    child_lists[child].next;
383
                } else {
384
                  child_lists[parent].first = child_lists[child].next;
385
                }
386

	
387
                if (child_lists[child].next != INVALID) {
388
                  child_lists[child_lists[child].next].prev =
389
                    child_lists[child].prev;
390
                }
391

	
392
                // Merging external faces
393
                {
394
                  int en = cn;
395
                  cn = cd ? node_data[cn].prev : node_data[cn].next;
396
                  cd = node_data[cn].next == en;
397

	
398
                }
399

	
400
                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
401
                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
402

	
403
              }
404

	
405
              bool d = pn == node_data[n].prev;
406

	
407
              if (node_data[n].prev == node_data[n].next &&
408
                  node_data[n].inverted) {
409
                d = !d;
410
              }
411

	
412
              // Embedding arc into external face
413
              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
414
              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
415
              pn = rn;
416

	
417
              embed_arc[order_list[n]] = false;
418
            }
419

	
420
            if (!merge_roots[node].empty()) {
421

	
422
              bool d = pn == node_data[n].prev;
423

	
424
              merge_stack.push_back(std::make_pair(n, d));
425

	
426
              int rn = merge_roots[node].front();
427

	
428
              int xn = node_data[rn].next;
429
              Node xnode = order_list[xn];
430

	
431
              int yn = node_data[rn].prev;
432
              Node ynode = order_list[yn];
433

	
434
              bool rd;
435
              if (!external(xnode, rorder, child_lists, 
436
                            ancestor_map, low_map)) {
437
                rd = true;
438
              } else if (!external(ynode, rorder, child_lists,
439
                                   ancestor_map, low_map)) {
440
                rd = false;
441
              } else if (pertinent(xnode, embed_arc, merge_roots)) {
442
                rd = true;
443
              } else {
444
                rd = false;
445
              }
446

	
447
              merge_stack.push_back(std::make_pair(rn, rd));
448

	
449
              pn = rn;
450
              n = rd ? xn : yn;
451

	
452
            } else if (!external(node, rorder, child_lists,
453
                                 ancestor_map, low_map)) {
454
              int nn = (node_data[n].next != pn ?
455
                        node_data[n].next : node_data[n].prev);
456

	
457
              bool nd = n == node_data[nn].prev;
458

	
459
              if (nd) node_data[nn].prev = pn;
460
              else node_data[nn].next = pn;
461

	
462
              if (n == node_data[pn].prev) node_data[pn].prev = nn;
463
              else node_data[pn].next = nn;
464

	
465
              node_data[nn].inverted =
466
                (node_data[nn].prev == node_data[nn].next && nd != rd);
467

	
468
              n = nn;
469
            }
470
            else break;
471

	
472
          }
473

	
474
          if (!merge_stack.empty() || n == rn) {
475
            break;
476
          }
477
        }
478
      }
479

	
480
      void initFace(const Node& node, NodeData& node_data,
481
                    const OrderMap& order_map, const OrderList& order_list) {
482
        int n = order_map[node];
483
        int rn = n + order_list.size();
484

	
485
        node_data[n].next = node_data[n].prev = rn;
486
        node_data[rn].next = node_data[rn].prev = n;
487

	
488
        node_data[n].visited = order_list.size();
489
        node_data[rn].visited = order_list.size();
490

	
491
      }
492

	
493
      bool external(const Node& node, int rorder,
494
                    ChildLists& child_lists, AncestorMap& ancestor_map,
495
                    LowMap& low_map) {
496
        Node child = child_lists[node].first;
497

	
498
        if (child != INVALID) {
499
          if (low_map[child] < rorder) return true;
500
        }
501

	
502
        if (ancestor_map[node] < rorder) return true;
503

	
504
        return false;
505
      }
506

	
507
      bool pertinent(const Node& node, const EmbedArc& embed_arc,
508
                     const MergeRoots& merge_roots) {
509
        return !merge_roots[node].empty() || embed_arc[node];
510
      }
511

	
512
    };
513

	
140 514
  }
141 515

	
142 516
  /// \ingroup planar
143 517
  ///
144 518
  /// \brief Planarity checking of an undirected simple graph
145 519
  ///
146
  /// This class implements the Boyer-Myrvold algorithm for planarity
147
  /// checking of an undirected graph. This class is a simplified
520
  /// This function implements the Boyer-Myrvold algorithm for
521
  /// planarity checking of an undirected graph. It is a simplified
148 522
  /// version of the PlanarEmbedding algorithm class because neither
149 523
  /// the embedding nor the kuratowski subdivisons are not computed.
150
  template <typename Graph>
151
  class PlanarityChecking {
152
  private:
153

	
154
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
155

	
156
    const Graph& _graph;
157

	
158
  private:
159

	
160
    typedef typename Graph::template NodeMap<Arc> PredMap;
161

	
162
    typedef typename Graph::template EdgeMap<bool> TreeMap;
163

	
164
    typedef typename Graph::template NodeMap<int> OrderMap;
165
    typedef std::vector<Node> OrderList;
166

	
167
    typedef typename Graph::template NodeMap<int> LowMap;
168
    typedef typename Graph::template NodeMap<int> AncestorMap;
169

	
170
    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
171
    typedef std::vector<NodeDataNode> NodeData;
172

	
173
    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
174
    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
175

	
176
    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
177

	
178
    typedef typename Graph::template NodeMap<bool> EmbedArc;
179

	
180
  public:
181

	
182
    /// \brief Constructor
183
    ///
184
    /// \note The graph should be simple, i.e. parallel and loop arc
185
    /// free.
186
    PlanarityChecking(const Graph& graph) : _graph(graph) {}
187

	
188
    /// \brief Runs the algorithm.
189
    ///
190
    /// Runs the algorithm.
191
    /// \return %True when the graph is planar.
192
    bool run() {
193
      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
194

	
195
      PredMap pred_map(_graph, INVALID);
196
      TreeMap tree_map(_graph, false);
197

	
198
      OrderMap order_map(_graph, -1);
199
      OrderList order_list;
200

	
201
      AncestorMap ancestor_map(_graph, -1);
202
      LowMap low_map(_graph, -1);
203

	
204
      Visitor visitor(_graph, pred_map, tree_map,
205
                      order_map, order_list, ancestor_map, low_map);
206
      DfsVisit<Graph, Visitor> visit(_graph, visitor);
207
      visit.run();
208

	
209
      ChildLists child_lists(_graph);
210
      createChildLists(tree_map, order_map, low_map, child_lists);
211

	
212
      NodeData node_data(2 * order_list.size());
213

	
214
      EmbedArc embed_arc(_graph, false);
215

	
216
      MergeRoots merge_roots(_graph);
217

	
218
      for (int i = order_list.size() - 1; i >= 0; --i) {
219

	
220
        Node node = order_list[i];
221

	
222
        Node source = node;
223
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
224
          Node target = _graph.target(e);
225

	
226
          if (order_map[source] < order_map[target] && tree_map[e]) {
227
            initFace(target, node_data, order_map, order_list);
228
          }
229
        }
230

	
231
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
232
          Node target = _graph.target(e);
233

	
234
          if (order_map[source] < order_map[target] && !tree_map[e]) {
235
            embed_arc[target] = true;
236
            walkUp(target, source, i, pred_map, low_map,
237
                   order_map, order_list, node_data, merge_roots);
238
          }
239
        }
240

	
241
        for (typename MergeRoots::Value::iterator it =
242
               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
243
          int rn = *it;
244
          walkDown(rn, i, node_data, order_list, child_lists,
245
                   ancestor_map, low_map, embed_arc, merge_roots);
246
        }
247
        merge_roots[node].clear();
248

	
249
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
250
          Node target = _graph.target(e);
251

	
252
          if (order_map[source] < order_map[target] && !tree_map[e]) {
253
            if (embed_arc[target]) {
254
              return false;
255
            }
256
          }
257
        }
258
      }
259

	
260
      return true;
261
    }
262

	
263
  private:
264

	
265
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
266
                          const LowMap& low_map, ChildLists& child_lists) {
267

	
268
      for (NodeIt n(_graph); n != INVALID; ++n) {
269
        Node source = n;
270

	
271
        std::vector<Node> targets;
272
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
273
          Node target = _graph.target(e);
274

	
275
          if (order_map[source] < order_map[target] && tree_map[e]) {
276
            targets.push_back(target);
277
          }
278
        }
279

	
280
        if (targets.size() == 0) {
281
          child_lists[source].first = INVALID;
282
        } else if (targets.size() == 1) {
283
          child_lists[source].first = targets[0];
284
          child_lists[targets[0]].prev = INVALID;
285
          child_lists[targets[0]].next = INVALID;
286
        } else {
287
          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
288
          for (int i = 1; i < int(targets.size()); ++i) {
289
            child_lists[targets[i]].prev = targets[i - 1];
290
            child_lists[targets[i - 1]].next = targets[i];
291
          }
292
          child_lists[targets.back()].next = INVALID;
293
          child_lists[targets.front()].prev = INVALID;
294
          child_lists[source].first = targets.front();
295
        }
296
      }
297
    }
298

	
299
    void walkUp(const Node& node, Node root, int rorder,
300
                const PredMap& pred_map, const LowMap& low_map,
301
                const OrderMap& order_map, const OrderList& order_list,
302
                NodeData& node_data, MergeRoots& merge_roots) {
303

	
304
      int na, nb;
305
      bool da, db;
306

	
307
      na = nb = order_map[node];
308
      da = true; db = false;
309

	
310
      while (true) {
311

	
312
        if (node_data[na].visited == rorder) break;
313
        if (node_data[nb].visited == rorder) break;
314

	
315
        node_data[na].visited = rorder;
316
        node_data[nb].visited = rorder;
317

	
318
        int rn = -1;
319

	
320
        if (na >= int(order_list.size())) {
321
          rn = na;
322
        } else if (nb >= int(order_list.size())) {
323
          rn = nb;
324
        }
325

	
326
        if (rn == -1) {
327
          int nn;
328

	
329
          nn = da ? node_data[na].prev : node_data[na].next;
330
          da = node_data[nn].prev != na;
331
          na = nn;
332

	
333
          nn = db ? node_data[nb].prev : node_data[nb].next;
334
          db = node_data[nn].prev != nb;
335
          nb = nn;
336

	
337
        } else {
338

	
339
          Node rep = order_list[rn - order_list.size()];
340
          Node parent = _graph.source(pred_map[rep]);
341

	
342
          if (low_map[rep] < rorder) {
343
            merge_roots[parent].push_back(rn);
344
          } else {
345
            merge_roots[parent].push_front(rn);
346
          }
347

	
348
          if (parent != root) {
349
            na = nb = order_map[parent];
350
            da = true; db = false;
351
          } else {
352
            break;
353
          }
354
        }
355
      }
356
    }
357

	
358
    void walkDown(int rn, int rorder, NodeData& node_data,
359
                  OrderList& order_list, ChildLists& child_lists,
360
                  AncestorMap& ancestor_map, LowMap& low_map,
361
                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
362

	
363
      std::vector<std::pair<int, bool> > merge_stack;
364

	
365
      for (int di = 0; di < 2; ++di) {
366
        bool rd = di == 0;
367
        int pn = rn;
368
        int n = rd ? node_data[rn].next : node_data[rn].prev;
369

	
370
        while (n != rn) {
371

	
372
          Node node = order_list[n];
373

	
374
          if (embed_arc[node]) {
375

	
376
            // Merging components on the critical path
377
            while (!merge_stack.empty()) {
378

	
379
              // Component root
380
              int cn = merge_stack.back().first;
381
              bool cd = merge_stack.back().second;
382
              merge_stack.pop_back();
383

	
384
              // Parent of component
385
              int dn = merge_stack.back().first;
386
              bool dd = merge_stack.back().second;
387
              merge_stack.pop_back();
388

	
389
              Node parent = order_list[dn];
390

	
391
              // Erasing from merge_roots
392
              merge_roots[parent].pop_front();
393

	
394
              Node child = order_list[cn - order_list.size()];
395

	
396
              // Erasing from child_lists
397
              if (child_lists[child].prev != INVALID) {
398
                child_lists[child_lists[child].prev].next =
399
                  child_lists[child].next;
400
              } else {
401
                child_lists[parent].first = child_lists[child].next;
402
              }
403

	
404
              if (child_lists[child].next != INVALID) {
405
                child_lists[child_lists[child].next].prev =
406
                  child_lists[child].prev;
407
              }
408

	
409
              // Merging external faces
410
              {
411
                int en = cn;
412
                cn = cd ? node_data[cn].prev : node_data[cn].next;
413
                cd = node_data[cn].next == en;
414

	
415
              }
416

	
417
              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
418
              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
419

	
420
            }
421

	
422
            bool d = pn == node_data[n].prev;
423

	
424
            if (node_data[n].prev == node_data[n].next &&
425
                node_data[n].inverted) {
426
              d = !d;
427
            }
428

	
429
            // Embedding arc into external face
430
            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
431
            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
432
            pn = rn;
433

	
434
            embed_arc[order_list[n]] = false;
435
          }
436

	
437
          if (!merge_roots[node].empty()) {
438

	
439
            bool d = pn == node_data[n].prev;
440

	
441
            merge_stack.push_back(std::make_pair(n, d));
442

	
443
            int rn = merge_roots[node].front();
444

	
445
            int xn = node_data[rn].next;
446
            Node xnode = order_list[xn];
447

	
448
            int yn = node_data[rn].prev;
449
            Node ynode = order_list[yn];
450

	
451
            bool rd;
452
            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
453
              rd = true;
454
            } else if (!external(ynode, rorder, child_lists,
455
                                 ancestor_map, low_map)) {
456
              rd = false;
457
            } else if (pertinent(xnode, embed_arc, merge_roots)) {
458
              rd = true;
459
            } else {
460
              rd = false;
461
            }
462

	
463
            merge_stack.push_back(std::make_pair(rn, rd));
464

	
465
            pn = rn;
466
            n = rd ? xn : yn;
467

	
468
          } else if (!external(node, rorder, child_lists,
469
                               ancestor_map, low_map)) {
470
            int nn = (node_data[n].next != pn ?
471
                      node_data[n].next : node_data[n].prev);
472

	
473
            bool nd = n == node_data[nn].prev;
474

	
475
            if (nd) node_data[nn].prev = pn;
476
            else node_data[nn].next = pn;
477

	
478
            if (n == node_data[pn].prev) node_data[pn].prev = nn;
479
            else node_data[pn].next = nn;
480

	
481
            node_data[nn].inverted =
482
              (node_data[nn].prev == node_data[nn].next && nd != rd);
483

	
484
            n = nn;
485
          }
486
          else break;
487

	
488
        }
489

	
490
        if (!merge_stack.empty() || n == rn) {
491
          break;
492
        }
493
      }
494
    }
495

	
496
    void initFace(const Node& node, NodeData& node_data,
497
                  const OrderMap& order_map, const OrderList& order_list) {
498
      int n = order_map[node];
499
      int rn = n + order_list.size();
500

	
501
      node_data[n].next = node_data[n].prev = rn;
502
      node_data[rn].next = node_data[rn].prev = n;
503

	
504
      node_data[n].visited = order_list.size();
505
      node_data[rn].visited = order_list.size();
506

	
507
    }
508

	
509
    bool external(const Node& node, int rorder,
510
                  ChildLists& child_lists, AncestorMap& ancestor_map,
511
                  LowMap& low_map) {
512
      Node child = child_lists[node].first;
513

	
514
      if (child != INVALID) {
515
        if (low_map[child] < rorder) return true;
516
      }
517

	
518
      if (ancestor_map[node] < rorder) return true;
519

	
520
      return false;
521
    }
522

	
523
    bool pertinent(const Node& node, const EmbedArc& embed_arc,
524
                   const MergeRoots& merge_roots) {
525
      return !merge_roots[node].empty() || embed_arc[node];
526
    }
527

	
528
  };
524
  template <typename GR>
525
  bool checkPlanarity(const GR& graph) {
526
    _planarity_bits::PlanarityChecking<GR> pc(graph);
527
    return pc.run();
528
  }
529 529

	
530 530
  /// \ingroup planar
531 531
  ///
532 532
  /// \brief Planar embedding of an undirected simple graph
533 533
  ///
534 534
  /// This class implements the Boyer-Myrvold algorithm for planar
535 535
  /// embedding of an undirected graph. The planar embedding is an
536 536
  /// ordering of the outgoing edges of the nodes, which is a possible
537 537
  /// configuration to draw the graph in the plane. If there is not
538 538
  /// such ordering then the graph contains a \f$ K_5 \f$ (full graph
539 539
  /// with 5 nodes) or a \f$ K_{3,3} \f$ (complete bipartite graph on
540 540
  /// 3 ANode and 3 BNode) subdivision.
541 541
  ///
542 542
  /// The current implementation calculates either an embedding or a
543 543
  /// Kuratowski subdivision. The running time of the algorithm is 
544 544
  /// \f$ O(n) \f$.
545 545
  template <typename Graph>
546 546
  class PlanarEmbedding {
547 547
  private:
548 548

	
549 549
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
550 550

	
551 551
    const Graph& _graph;
552 552
    typename Graph::template ArcMap<Arc> _embedding;
553 553

	
554 554
    typename Graph::template EdgeMap<bool> _kuratowski;
555 555

	
556 556
  private:
557 557

	
558 558
    typedef typename Graph::template NodeMap<Arc> PredMap;
559 559

	
560 560
    typedef typename Graph::template EdgeMap<bool> TreeMap;
561 561

	
562 562
    typedef typename Graph::template NodeMap<int> OrderMap;
563 563
    typedef std::vector<Node> OrderList;
564 564

	
565 565
    typedef typename Graph::template NodeMap<int> LowMap;
566 566
    typedef typename Graph::template NodeMap<int> AncestorMap;
567 567

	
568 568
    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
569 569
    typedef std::vector<NodeDataNode> NodeData;
570 570

	
571 571
    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
572 572
    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
573 573

	
574 574
    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
575 575

	
576 576
    typedef typename Graph::template NodeMap<Arc> EmbedArc;
577 577

	
578 578
    typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
579 579
    typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
580 580

	
581 581
    typedef typename Graph::template NodeMap<bool> FlipMap;
582 582

	
583 583
    typedef typename Graph::template NodeMap<int> TypeMap;
584 584

	
585 585
    enum IsolatorNodeType {
586 586
      HIGHX = 6, LOWX = 7,
587 587
      HIGHY = 8, LOWY = 9,
588 588
      ROOT = 10, PERTINENT = 11,
589 589
      INTERNAL = 12
590 590
    };
591 591

	
592 592
  public:
593 593

	
594 594
    /// \brief The map for store of embedding
595 595
    typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
596 596

	
597 597
    /// \brief Constructor
598 598
    ///
599 599
    /// \note The graph should be simple, i.e. parallel and loop arc
600 600
    /// free.
601 601
    PlanarEmbedding(const Graph& graph)
602 602
      : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
603 603

	
604 604
    /// \brief Runs the algorithm.
605 605
    ///
606 606
    /// Runs the algorithm.
607 607
    /// \param kuratowski If the parameter is false, then the
608 608
    /// algorithm does not compute a Kuratowski subdivision.
609 609
    ///\return %True when the graph is planar.
610 610
    bool run(bool kuratowski = true) {
611 611
      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
612 612

	
613 613
      PredMap pred_map(_graph, INVALID);
614 614
      TreeMap tree_map(_graph, false);
615 615

	
616 616
      OrderMap order_map(_graph, -1);
617 617
      OrderList order_list;
618 618

	
619 619
      AncestorMap ancestor_map(_graph, -1);
620 620
      LowMap low_map(_graph, -1);
621 621

	
622 622
      Visitor visitor(_graph, pred_map, tree_map,
623 623
                      order_map, order_list, ancestor_map, low_map);
624 624
      DfsVisit<Graph, Visitor> visit(_graph, visitor);
625 625
      visit.run();
626 626

	
627 627
      ChildLists child_lists(_graph);
628 628
      createChildLists(tree_map, order_map, low_map, child_lists);
629 629

	
630 630
      NodeData node_data(2 * order_list.size());
631 631

	
632 632
      EmbedArc embed_arc(_graph, INVALID);
633 633

	
634 634
      MergeRoots merge_roots(_graph);
635 635

	
636 636
      ArcLists arc_lists(_graph);
637 637

	
638 638
      FlipMap flip_map(_graph, false);
639 639

	
640 640
      for (int i = order_list.size() - 1; i >= 0; --i) {
641 641

	
642 642
        Node node = order_list[i];
643 643

	
644 644
        node_data[i].first = INVALID;
645 645

	
646 646
        Node source = node;
647 647
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
648 648
          Node target = _graph.target(e);
649 649

	
650 650
          if (order_map[source] < order_map[target] && tree_map[e]) {
651 651
            initFace(target, arc_lists, node_data,
652 652
                     pred_map, order_map, order_list);
653 653
          }
654 654
        }
655 655

	
656 656
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
657 657
          Node target = _graph.target(e);
658 658

	
659 659
          if (order_map[source] < order_map[target] && !tree_map[e]) {
660 660
            embed_arc[target] = e;
661 661
            walkUp(target, source, i, pred_map, low_map,
662 662
                   order_map, order_list, node_data, merge_roots);
663 663
          }
664 664
        }
665 665

	
666 666
        for (typename MergeRoots::Value::iterator it =
667 667
               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
668 668
          int rn = *it;
669 669
          walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
670 670
                   child_lists, ancestor_map, low_map, embed_arc, merge_roots);
671 671
        }
672 672
        merge_roots[node].clear();
673 673

	
674 674
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
675 675
          Node target = _graph.target(e);
676 676

	
677 677
          if (order_map[source] < order_map[target] && !tree_map[e]) {
678 678
            if (embed_arc[target] != INVALID) {
679 679
              if (kuratowski) {
680 680
                isolateKuratowski(e, node_data, arc_lists, flip_map,
681 681
                                  order_map, order_list, pred_map, child_lists,
682 682
                                  ancestor_map, low_map,
683 683
                                  embed_arc, merge_roots);
684 684
              }
685 685
              return false;
686 686
            }
687 687
          }
688 688
        }
689 689
      }
690 690

	
691 691
      for (int i = 0; i < int(order_list.size()); ++i) {
692 692

	
693 693
        mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
694 694
                            child_lists, arc_lists);
695 695
        storeEmbedding(order_list[i], node_data, order_map, pred_map,
696 696
                       arc_lists, flip_map);
697 697
      }
698 698

	
699 699
      return true;
700 700
    }
701 701

	
702 702
    /// \brief Gives back the successor of an arc
703 703
    ///
704 704
    /// Gives back the successor of an arc. This function makes
705 705
    /// possible to query the cyclic order of the outgoing arcs from
706 706
    /// a node.
707 707
    Arc next(const Arc& arc) const {
708 708
      return _embedding[arc];
709 709
    }
710 710

	
711 711
    /// \brief Gives back the calculated embedding map
712 712
    ///
713 713
    /// The returned map contains the successor of each arc in the
714 714
    /// graph.
715
    const EmbeddingMap& embedding() const {
715
    const EmbeddingMap& embeddingMap() const {
716 716
      return _embedding;
717 717
    }
718 718

	
719 719
    /// \brief Gives back true if the undirected arc is in the
720 720
    /// kuratowski subdivision
721 721
    ///
722 722
    /// Gives back true if the undirected arc is in the kuratowski
723 723
    /// subdivision
724 724
    /// \note The \c run() had to be called with true value.
725 725
    bool kuratowski(const Edge& edge) {
726 726
      return _kuratowski[edge];
727 727
    }
728 728

	
729 729
  private:
730 730

	
731 731
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
732 732
                          const LowMap& low_map, ChildLists& child_lists) {
733 733

	
734 734
      for (NodeIt n(_graph); n != INVALID; ++n) {
735 735
        Node source = n;
736 736

	
737 737
        std::vector<Node> targets;
738 738
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
739 739
          Node target = _graph.target(e);
740 740

	
741 741
          if (order_map[source] < order_map[target] && tree_map[e]) {
742 742
            targets.push_back(target);
743 743
          }
744 744
        }
745 745

	
746 746
        if (targets.size() == 0) {
747 747
          child_lists[source].first = INVALID;
748 748
        } else if (targets.size() == 1) {
749 749
          child_lists[source].first = targets[0];
750 750
          child_lists[targets[0]].prev = INVALID;
751 751
          child_lists[targets[0]].next = INVALID;
752 752
        } else {
753 753
          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
754 754
          for (int i = 1; i < int(targets.size()); ++i) {
755 755
            child_lists[targets[i]].prev = targets[i - 1];
756 756
            child_lists[targets[i - 1]].next = targets[i];
757 757
          }
758 758
          child_lists[targets.back()].next = INVALID;
759 759
          child_lists[targets.front()].prev = INVALID;
760 760
          child_lists[source].first = targets.front();
761 761
        }
762 762
      }
763 763
    }
764 764

	
765 765
    void walkUp(const Node& node, Node root, int rorder,
766 766
                const PredMap& pred_map, const LowMap& low_map,
767 767
                const OrderMap& order_map, const OrderList& order_list,
768 768
                NodeData& node_data, MergeRoots& merge_roots) {
769 769

	
770 770
      int na, nb;
771 771
      bool da, db;
772 772

	
773 773
      na = nb = order_map[node];
774 774
      da = true; db = false;
775 775

	
776 776
      while (true) {
777 777

	
778 778
        if (node_data[na].visited == rorder) break;
779 779
        if (node_data[nb].visited == rorder) break;
780 780

	
781 781
        node_data[na].visited = rorder;
782 782
        node_data[nb].visited = rorder;
783 783

	
784 784
        int rn = -1;
785 785

	
786 786
        if (na >= int(order_list.size())) {
787 787
          rn = na;
788 788
        } else if (nb >= int(order_list.size())) {
789 789
          rn = nb;
790 790
        }
791 791

	
792 792
        if (rn == -1) {
793 793
          int nn;
794 794

	
795 795
          nn = da ? node_data[na].prev : node_data[na].next;
796 796
          da = node_data[nn].prev != na;
797 797
          na = nn;
798 798

	
799 799
          nn = db ? node_data[nb].prev : node_data[nb].next;
800 800
          db = node_data[nn].prev != nb;
801 801
          nb = nn;
802 802

	
803 803
        } else {
804 804

	
805 805
          Node rep = order_list[rn - order_list.size()];
806 806
          Node parent = _graph.source(pred_map[rep]);
807 807

	
808 808
          if (low_map[rep] < rorder) {
809 809
            merge_roots[parent].push_back(rn);
810 810
          } else {
811 811
            merge_roots[parent].push_front(rn);
812 812
          }
813 813

	
814 814
          if (parent != root) {
815 815
            na = nb = order_map[parent];
816 816
            da = true; db = false;
817 817
          } else {
818 818
            break;
819 819
          }
820 820
        }
821 821
      }
822 822
    }
823 823

	
824 824
    void walkDown(int rn, int rorder, NodeData& node_data,
825 825
                  ArcLists& arc_lists, FlipMap& flip_map,
826 826
                  OrderList& order_list, ChildLists& child_lists,
827 827
                  AncestorMap& ancestor_map, LowMap& low_map,
828 828
                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
829 829

	
830 830
      std::vector<std::pair<int, bool> > merge_stack;
831 831

	
832 832
      for (int di = 0; di < 2; ++di) {
833 833
        bool rd = di == 0;
834 834
        int pn = rn;
835 835
        int n = rd ? node_data[rn].next : node_data[rn].prev;
836 836

	
837 837
        while (n != rn) {
838 838

	
839 839
          Node node = order_list[n];
840 840

	
841 841
          if (embed_arc[node] != INVALID) {
842 842

	
843 843
            // Merging components on the critical path
844 844
            while (!merge_stack.empty()) {
845 845

	
846 846
              // Component root
847 847
              int cn = merge_stack.back().first;
848 848
              bool cd = merge_stack.back().second;
849 849
              merge_stack.pop_back();
850 850

	
851 851
              // Parent of component
852 852
              int dn = merge_stack.back().first;
853 853
              bool dd = merge_stack.back().second;
854 854
              merge_stack.pop_back();
855 855

	
856 856
              Node parent = order_list[dn];
857 857

	
858 858
              // Erasing from merge_roots
859 859
              merge_roots[parent].pop_front();
860 860

	
861 861
              Node child = order_list[cn - order_list.size()];
862 862

	
863 863
              // Erasing from child_lists
864 864
              if (child_lists[child].prev != INVALID) {
865 865
                child_lists[child_lists[child].prev].next =
866 866
                  child_lists[child].next;
867 867
              } else {
868 868
                child_lists[parent].first = child_lists[child].next;
869 869
              }
870 870

	
871 871
              if (child_lists[child].next != INVALID) {
872 872
                child_lists[child_lists[child].next].prev =
873 873
                  child_lists[child].prev;
874 874
              }
875 875

	
876 876
              // Merging arcs + flipping
877 877
              Arc de = node_data[dn].first;
878 878
              Arc ce = node_data[cn].first;
879 879

	
880 880
              flip_map[order_list[cn - order_list.size()]] = cd != dd;
881 881
              if (cd != dd) {
882 882
                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
883 883
                ce = arc_lists[ce].prev;
884 884
                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
885 885
              }
886 886

	
887 887
              {
888 888
                Arc dne = arc_lists[de].next;
889 889
                Arc cne = arc_lists[ce].next;
890 890

	
891 891
                arc_lists[de].next = cne;
892 892
                arc_lists[ce].next = dne;
893 893

	
894 894
                arc_lists[dne].prev = ce;
895 895
                arc_lists[cne].prev = de;
896 896
              }
897 897

	
898 898
              if (dd) {
899 899
                node_data[dn].first = ce;
900 900
              }
901 901

	
902 902
              // Merging external faces
903 903
              {
904 904
                int en = cn;
905 905
                cn = cd ? node_data[cn].prev : node_data[cn].next;
906 906
                cd = node_data[cn].next == en;
907 907

	
908 908
                 if (node_data[cn].prev == node_data[cn].next &&
909 909
                    node_data[cn].inverted) {
910 910
                   cd = !cd;
911 911
                 }
912 912
              }
913 913

	
914 914
              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
915 915
              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
916 916

	
917 917
            }
918 918

	
919 919
            bool d = pn == node_data[n].prev;
920 920

	
921 921
            if (node_data[n].prev == node_data[n].next &&
922 922
                node_data[n].inverted) {
923 923
              d = !d;
924 924
            }
925 925

	
926 926
            // Add new arc
927 927
            {
928 928
              Arc arc = embed_arc[node];
929 929
              Arc re = node_data[rn].first;
930 930

	
931 931
              arc_lists[arc_lists[re].next].prev = arc;
932 932
              arc_lists[arc].next = arc_lists[re].next;
933 933
              arc_lists[arc].prev = re;
934 934
              arc_lists[re].next = arc;
935 935

	
936 936
              if (!rd) {
937 937
                node_data[rn].first = arc;
938 938
              }
939 939

	
940 940
              Arc rev = _graph.oppositeArc(arc);
941 941
              Arc e = node_data[n].first;
942 942

	
943 943
              arc_lists[arc_lists[e].next].prev = rev;
944 944
              arc_lists[rev].next = arc_lists[e].next;
945 945
              arc_lists[rev].prev = e;
946 946
              arc_lists[e].next = rev;
947 947

	
948 948
              if (d) {
949 949
                node_data[n].first = rev;
950 950
              }
951 951

	
952 952
            }
953 953

	
954 954
            // Embedding arc into external face
955 955
            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
956 956
            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
957 957
            pn = rn;
958 958

	
959 959
            embed_arc[order_list[n]] = INVALID;
960 960
          }
961 961

	
962 962
          if (!merge_roots[node].empty()) {
963 963

	
964 964
            bool d = pn == node_data[n].prev;
965 965
            if (node_data[n].prev == node_data[n].next &&
966 966
                node_data[n].inverted) {
967 967
              d = !d;
968 968
            }
969 969

	
970 970
            merge_stack.push_back(std::make_pair(n, d));
971 971

	
972 972
            int rn = merge_roots[node].front();
973 973

	
974 974
            int xn = node_data[rn].next;
975 975
            Node xnode = order_list[xn];
976 976

	
977 977
            int yn = node_data[rn].prev;
978 978
            Node ynode = order_list[yn];
979 979

	
980 980
            bool rd;
981 981
            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
982 982
              rd = true;
983 983
            } else if (!external(ynode, rorder, child_lists,
984 984
                                 ancestor_map, low_map)) {
985 985
              rd = false;
986 986
            } else if (pertinent(xnode, embed_arc, merge_roots)) {
987 987
              rd = true;
988 988
            } else {
989 989
              rd = false;
990 990
            }
991 991

	
992 992
            merge_stack.push_back(std::make_pair(rn, rd));
993 993

	
994 994
            pn = rn;
995 995
            n = rd ? xn : yn;
996 996

	
997 997
          } else if (!external(node, rorder, child_lists,
998 998
                               ancestor_map, low_map)) {
999 999
            int nn = (node_data[n].next != pn ?
1000 1000
                      node_data[n].next : node_data[n].prev);
1001 1001

	
1002 1002
            bool nd = n == node_data[nn].prev;
1003 1003

	
1004 1004
            if (nd) node_data[nn].prev = pn;
1005 1005
            else node_data[nn].next = pn;
1006 1006

	
1007 1007
            if (n == node_data[pn].prev) node_data[pn].prev = nn;
1008 1008
            else node_data[pn].next = nn;
1009 1009

	
1010 1010
            node_data[nn].inverted =
1011 1011
              (node_data[nn].prev == node_data[nn].next && nd != rd);
1012 1012

	
1013 1013
            n = nn;
1014 1014
          }
1015 1015
          else break;
1016 1016

	
1017 1017
        }
1018 1018

	
1019 1019
        if (!merge_stack.empty() || n == rn) {
1020 1020
          break;
1021 1021
        }
1022 1022
      }
1023 1023
    }
1024 1024

	
1025 1025
    void initFace(const Node& node, ArcLists& arc_lists,
1026 1026
                  NodeData& node_data, const PredMap& pred_map,
1027 1027
                  const OrderMap& order_map, const OrderList& order_list) {
1028 1028
      int n = order_map[node];
1029 1029
      int rn = n + order_list.size();
1030 1030

	
1031 1031
      node_data[n].next = node_data[n].prev = rn;
1032 1032
      node_data[rn].next = node_data[rn].prev = n;
1033 1033

	
1034 1034
      node_data[n].visited = order_list.size();
1035 1035
      node_data[rn].visited = order_list.size();
1036 1036

	
1037 1037
      node_data[n].inverted = false;
1038 1038
      node_data[rn].inverted = false;
1039 1039

	
1040 1040
      Arc arc = pred_map[node];
1041 1041
      Arc rev = _graph.oppositeArc(arc);
1042 1042

	
1043 1043
      node_data[rn].first = arc;
1044 1044
      node_data[n].first = rev;
1045 1045

	
1046 1046
      arc_lists[arc].prev = arc;
1047 1047
      arc_lists[arc].next = arc;
1048 1048

	
1049 1049
      arc_lists[rev].prev = rev;
1050 1050
      arc_lists[rev].next = rev;
1051 1051

	
1052 1052
    }
1053 1053

	
1054 1054
    void mergeRemainingFaces(const Node& node, NodeData& node_data,
1055 1055
                             OrderList& order_list, OrderMap& order_map,
1056 1056
                             ChildLists& child_lists, ArcLists& arc_lists) {
1057 1057
      while (child_lists[node].first != INVALID) {
1058 1058
        int dd = order_map[node];
1059 1059
        Node child = child_lists[node].first;
1060 1060
        int cd = order_map[child] + order_list.size();
1061 1061
        child_lists[node].first = child_lists[child].next;
1062 1062

	
1063 1063
        Arc de = node_data[dd].first;
1064 1064
        Arc ce = node_data[cd].first;
1065 1065

	
1066 1066
        if (de != INVALID) {
1067 1067
          Arc dne = arc_lists[de].next;
1068 1068
          Arc cne = arc_lists[ce].next;
1069 1069

	
1070 1070
          arc_lists[de].next = cne;
1071 1071
          arc_lists[ce].next = dne;
1072 1072

	
1073 1073
          arc_lists[dne].prev = ce;
1074 1074
          arc_lists[cne].prev = de;
1075 1075
        }
1076 1076

	
1077 1077
        node_data[dd].first = ce;
1078 1078

	
1079 1079
      }
1080 1080
    }
1081 1081

	
1082 1082
    void storeEmbedding(const Node& node, NodeData& node_data,
1083 1083
                        OrderMap& order_map, PredMap& pred_map,
1084 1084
                        ArcLists& arc_lists, FlipMap& flip_map) {
1085 1085

	
1086 1086
      if (node_data[order_map[node]].first == INVALID) return;
1087 1087

	
1088 1088
      if (pred_map[node] != INVALID) {
1089 1089
        Node source = _graph.source(pred_map[node]);
1090 1090
        flip_map[node] = flip_map[node] != flip_map[source];
1091 1091
      }
1092 1092

	
1093 1093
      Arc first = node_data[order_map[node]].first;
1094 1094
      Arc prev = first;
1095 1095

	
1096 1096
      Arc arc = flip_map[node] ?
1097 1097
        arc_lists[prev].prev : arc_lists[prev].next;
1098 1098

	
1099 1099
      _embedding[prev] = arc;
1100 1100

	
1101 1101
      while (arc != first) {
1102 1102
        Arc next = arc_lists[arc].prev == prev ?
1103 1103
          arc_lists[arc].next : arc_lists[arc].prev;
1104 1104
        prev = arc; arc = next;
1105 1105
        _embedding[prev] = arc;
1106 1106
      }
1107 1107
    }
1108 1108

	
1109 1109

	
1110 1110
    bool external(const Node& node, int rorder,
1111 1111
                  ChildLists& child_lists, AncestorMap& ancestor_map,
1112 1112
                  LowMap& low_map) {
1113 1113
      Node child = child_lists[node].first;
1114 1114

	
1115 1115
      if (child != INVALID) {
1116 1116
        if (low_map[child] < rorder) return true;
1117 1117
      }
1118 1118

	
1119 1119
      if (ancestor_map[node] < rorder) return true;
1120 1120

	
1121 1121
      return false;
1122 1122
    }
1123 1123

	
1124 1124
    bool pertinent(const Node& node, const EmbedArc& embed_arc,
1125 1125
                   const MergeRoots& merge_roots) {
1126 1126
      return !merge_roots[node].empty() || embed_arc[node] != INVALID;
1127 1127
    }
1128 1128

	
1129 1129
    int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
1130 1130
                 AncestorMap& ancestor_map, LowMap& low_map) {
1131 1131
      int low_point;
1132 1132

	
1133 1133
      Node child = child_lists[node].first;
1134 1134

	
1135 1135
      if (child != INVALID) {
1136 1136
        low_point = low_map[child];
1137 1137
      } else {
1138 1138
        low_point = order_map[node];
1139 1139
      }
1140 1140

	
1141 1141
      if (low_point > ancestor_map[node]) {
1142 1142
        low_point = ancestor_map[node];
1143 1143
      }
1144 1144

	
1145 1145
      return low_point;
1146 1146
    }
1147 1147

	
1148 1148
    int findComponentRoot(Node root, Node node, ChildLists& child_lists,
1149 1149
                          OrderMap& order_map, OrderList& order_list) {
1150 1150

	
1151 1151
      int order = order_map[root];
1152 1152
      int norder = order_map[node];
1153 1153

	
1154 1154
      Node child = child_lists[root].first;
1155 1155
      while (child != INVALID) {
1156 1156
        int corder = order_map[child];
1157 1157
        if (corder > order && corder < norder) {
1158 1158
          order = corder;
1159 1159
        }
1160 1160
        child = child_lists[child].next;
1161 1161
      }
1162 1162
      return order + order_list.size();
1163 1163
    }
1164 1164

	
1165 1165
    Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
1166 1166
                       EmbedArc& embed_arc, MergeRoots& merge_roots) {
1167 1167
      Node wnode =_graph.target(node_data[order_map[node]].first);
1168 1168
      while (!pertinent(wnode, embed_arc, merge_roots)) {
1169 1169
        wnode = _graph.target(node_data[order_map[wnode]].first);
1170 1170
      }
1171 1171
      return wnode;
1172 1172
    }
1173 1173

	
1174 1174

	
1175 1175
    Node findExternal(Node node, int rorder, OrderMap& order_map,
1176 1176
                      ChildLists& child_lists, AncestorMap& ancestor_map,
1177 1177
                      LowMap& low_map, NodeData& node_data) {
1178 1178
      Node wnode =_graph.target(node_data[order_map[node]].first);
1179 1179
      while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1180 1180
        wnode = _graph.target(node_data[order_map[wnode]].first);
1181 1181
      }
1182 1182
      return wnode;
1183 1183
    }
1184 1184

	
1185 1185
    void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
1186 1186
                        OrderList& order_list, OrderMap& order_map,
1187 1187
                        NodeData& node_data, ArcLists& arc_lists,
1188 1188
                        EmbedArc& embed_arc, MergeRoots& merge_roots,
1189 1189
                        ChildLists& child_lists, AncestorMap& ancestor_map,
1190 1190
                        LowMap& low_map) {
1191 1191

	
1192 1192
      Node cnode = node;
1193 1193
      Node pred = INVALID;
1194 1194

	
1195 1195
      while (true) {
1196 1196

	
1197 1197
        bool pert = pertinent(cnode, embed_arc, merge_roots);
1198 1198
        bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
1199 1199

	
1200 1200
        if (pert && ext) {
1201 1201
          if (!merge_roots[cnode].empty()) {
1202 1202
            int cn = merge_roots[cnode].back();
1203 1203

	
1204 1204
            if (low_map[order_list[cn - order_list.size()]] < rorder) {
1205 1205
              Arc arc = node_data[cn].first;
1206 1206
              _kuratowski.set(arc, true);
1207 1207

	
1208 1208
              pred = cnode;
1209 1209
              cnode = _graph.target(arc);
1210 1210

	
1211 1211
              continue;
1212 1212
            }
1213 1213
          }
1214 1214
          wnode = znode = cnode;
1215 1215
          return;
1216 1216

	
1217 1217
        } else if (pert) {
1218 1218
          wnode = cnode;
1219 1219

	
1220 1220
          while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
1221 1221
            Arc arc = node_data[order_map[cnode]].first;
1222 1222

	
1223 1223
            if (_graph.target(arc) == pred) {
1224 1224
              arc = arc_lists[arc].next;
1225 1225
            }
1226 1226
            _kuratowski.set(arc, true);
1227 1227

	
1228 1228
            Node next = _graph.target(arc);
1229 1229
            pred = cnode; cnode = next;
1230 1230
          }
1231 1231

	
1232 1232
          znode = cnode;
1233 1233
          return;
1234 1234

	
1235 1235
        } else if (ext) {
1236 1236
          znode = cnode;
1237 1237

	
1238 1238
          while (!pertinent(cnode, embed_arc, merge_roots)) {
1239 1239
            Arc arc = node_data[order_map[cnode]].first;
1240 1240

	
1241 1241
            if (_graph.target(arc) == pred) {
1242 1242
              arc = arc_lists[arc].next;
1243 1243
            }
1244 1244
            _kuratowski.set(arc, true);
1245 1245

	
1246 1246
            Node next = _graph.target(arc);
1247 1247
            pred = cnode; cnode = next;
1248 1248
          }
1249 1249

	
1250 1250
          wnode = cnode;
1251 1251
          return;
1252 1252

	
1253 1253
        } else {
1254 1254
          Arc arc = node_data[order_map[cnode]].first;
1255 1255

	
1256 1256
          if (_graph.target(arc) == pred) {
1257 1257
            arc = arc_lists[arc].next;
1258 1258
          }
1259 1259
          _kuratowski.set(arc, true);
1260 1260

	
1261 1261
          Node next = _graph.target(arc);
1262 1262
          pred = cnode; cnode = next;
1263 1263
        }
1264 1264

	
1265 1265
      }
1266 1266

	
1267 1267
    }
1268 1268

	
1269 1269
    void orientComponent(Node root, int rn, OrderMap& order_map,
1270 1270
                         PredMap& pred_map, NodeData& node_data,
1271 1271
                         ArcLists& arc_lists, FlipMap& flip_map,
1272 1272
                         TypeMap& type_map) {
1273 1273
      node_data[order_map[root]].first = node_data[rn].first;
1274 1274
      type_map[root] = 1;
1275 1275

	
1276 1276
      std::vector<Node> st, qu;
1277 1277

	
1278 1278
      st.push_back(root);
1279 1279
      while (!st.empty()) {
1280 1280
        Node node = st.back();
1281 1281
        st.pop_back();
1282 1282
        qu.push_back(node);
1283 1283

	
1284 1284
        Arc arc = node_data[order_map[node]].first;
1285 1285

	
1286 1286
        if (type_map[_graph.target(arc)] == 0) {
1287 1287
          st.push_back(_graph.target(arc));
1288 1288
          type_map[_graph.target(arc)] = 1;
1289 1289
        }
1290 1290

	
1291 1291
        Arc last = arc, pred = arc;
1292 1292
        arc = arc_lists[arc].next;
1293 1293
        while (arc != last) {
1294 1294

	
1295 1295
          if (type_map[_graph.target(arc)] == 0) {
1296 1296
            st.push_back(_graph.target(arc));
1297 1297
            type_map[_graph.target(arc)] = 1;
1298 1298
          }
1299 1299

	
1300 1300
          Arc next = arc_lists[arc].next != pred ?
1301 1301
            arc_lists[arc].next : arc_lists[arc].prev;
1302 1302
          pred = arc; arc = next;
1303 1303
        }
1304 1304

	
1305 1305
      }
1306 1306

	
1307 1307
      type_map[root] = 2;
1308 1308
      flip_map[root] = false;
1309 1309

	
1310 1310
      for (int i = 1; i < int(qu.size()); ++i) {
1311 1311

	
1312 1312
        Node node = qu[i];
1313 1313

	
1314 1314
        while (type_map[node] != 2) {
1315 1315
          st.push_back(node);
1316 1316
          type_map[node] = 2;
1317 1317
          node = _graph.source(pred_map[node]);
1318 1318
        }
1319 1319

	
1320 1320
        bool flip = flip_map[node];
1321 1321

	
1322 1322
        while (!st.empty()) {
1323 1323
          node = st.back();
1324 1324
          st.pop_back();
1325 1325

	
1326 1326
          flip_map[node] = flip != flip_map[node];
1327 1327
          flip = flip_map[node];
1328 1328

	
1329 1329
          if (flip) {
1330 1330
            Arc arc = node_data[order_map[node]].first;
1331 1331
            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
1332 1332
            arc = arc_lists[arc].prev;
1333 1333
            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
1334 1334
            node_data[order_map[node]].first = arc;
1335 1335
          }
1336 1336
        }
1337 1337
      }
1338 1338

	
1339 1339
      for (int i = 0; i < int(qu.size()); ++i) {
1340 1340

	
1341 1341
        Arc arc = node_data[order_map[qu[i]]].first;
1342 1342
        Arc last = arc, pred = arc;
1343 1343

	
1344 1344
        arc = arc_lists[arc].next;
1345 1345
        while (arc != last) {
1346 1346

	
1347 1347
          if (arc_lists[arc].next == pred) {
1348 1348
            std::swap(arc_lists[arc].next, arc_lists[arc].prev);
1349 1349
          }
1350 1350
          pred = arc; arc = arc_lists[arc].next;
1351 1351
        }
1352 1352

	
1353 1353
      }
1354 1354
    }
1355 1355

	
1356 1356
    void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
1357 1357
                      OrderMap& order_map, NodeData& node_data,
1358 1358
                      TypeMap& type_map) {
1359 1359
      Node node = _graph.target(node_data[order_map[root]].first);
1360 1360

	
1361 1361
      while (node != ynode) {
1362 1362
        type_map[node] = HIGHY;
1363 1363
        node = _graph.target(node_data[order_map[node]].first);
1364 1364
      }
1365 1365

	
1366 1366
      while (node != wnode) {
1367 1367
        type_map[node] = LOWY;
1368 1368
        node = _graph.target(node_data[order_map[node]].first);
1369 1369
      }
1370 1370

	
1371 1371
      node = _graph.target(node_data[order_map[wnode]].first);
1372 1372

	
1373 1373
      while (node != xnode) {
1374 1374
        type_map[node] = LOWX;
1375 1375
        node = _graph.target(node_data[order_map[node]].first);
1376 1376
      }
1377 1377
      type_map[node] = LOWX;
1378 1378

	
1379 1379
      node = _graph.target(node_data[order_map[xnode]].first);
1380 1380
      while (node != root) {
1381 1381
        type_map[node] = HIGHX;
1382 1382
        node = _graph.target(node_data[order_map[node]].first);
1383 1383
      }
1384 1384

	
1385 1385
      type_map[wnode] = PERTINENT;
1386 1386
      type_map[root] = ROOT;
1387 1387
    }
1388 1388

	
1389 1389
    void findInternalPath(std::vector<Arc>& ipath,
1390 1390
                          Node wnode, Node root, TypeMap& type_map,
1391 1391
                          OrderMap& order_map, NodeData& node_data,
1392 1392
                          ArcLists& arc_lists) {
1393 1393
      std::vector<Arc> st;
1394 1394

	
1395 1395
      Node node = wnode;
1396 1396

	
1397 1397
      while (node != root) {
1398 1398
        Arc arc = arc_lists[node_data[order_map[node]].first].next;
1399 1399
        st.push_back(arc);
1400 1400
        node = _graph.target(arc);
1401 1401
      }
1402 1402

	
1403 1403
      while (true) {
1404 1404
        Arc arc = st.back();
1405 1405
        if (type_map[_graph.target(arc)] == LOWX ||
1406 1406
            type_map[_graph.target(arc)] == HIGHX) {
1407 1407
          break;
1408 1408
        }
1409 1409
        if (type_map[_graph.target(arc)] == 2) {
1410 1410
          type_map[_graph.target(arc)] = 3;
1411 1411

	
1412 1412
          arc = arc_lists[_graph.oppositeArc(arc)].next;
1413 1413
          st.push_back(arc);
1414 1414
        } else {
1415 1415
          st.pop_back();
1416 1416
          arc = arc_lists[arc].next;
1417 1417

	
1418 1418
          while (_graph.oppositeArc(arc) == st.back()) {
1419 1419
            arc = st.back();
1420 1420
            st.pop_back();
1421 1421
            arc = arc_lists[arc].next;
1422 1422
          }
1423 1423
          st.push_back(arc);
1424 1424
        }
1425 1425
      }
1426 1426

	
1427 1427
      for (int i = 0; i < int(st.size()); ++i) {
1428 1428
        if (type_map[_graph.target(st[i])] != LOWY &&
1429 1429
            type_map[_graph.target(st[i])] != HIGHY) {
1430 1430
          for (; i < int(st.size()); ++i) {
1431 1431
            ipath.push_back(st[i]);
1432 1432
          }
1433 1433
        }
1434 1434
      }
1435 1435
    }
1436 1436

	
1437 1437
    void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
1438 1438
      for (int i = 1; i < int(ipath.size()); ++i) {
1439 1439
        type_map[_graph.source(ipath[i])] = INTERNAL;
1440 1440
      }
1441 1441
    }
1442 1442

	
1443 1443
    void findPilePath(std::vector<Arc>& ppath,
1444 1444
                      Node root, TypeMap& type_map, OrderMap& order_map,
1445 1445
                      NodeData& node_data, ArcLists& arc_lists) {
1446 1446
      std::vector<Arc> st;
1447 1447

	
1448 1448
      st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
1449 1449
      st.push_back(node_data[order_map[root]].first);
1450 1450

	
1451 1451
      while (st.size() > 1) {
1452 1452
        Arc arc = st.back();
1453 1453
        if (type_map[_graph.target(arc)] == INTERNAL) {
1454 1454
          break;
1455 1455
        }
1456 1456
        if (type_map[_graph.target(arc)] == 3) {
1457 1457
          type_map[_graph.target(arc)] = 4;
1458 1458

	
1459 1459
          arc = arc_lists[_graph.oppositeArc(arc)].next;
1460 1460
          st.push_back(arc);
1461 1461
        } else {
1462 1462
          st.pop_back();
1463 1463
          arc = arc_lists[arc].next;
1464 1464

	
1465 1465
          while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
1466 1466
            arc = st.back();
1467 1467
            st.pop_back();
1468 1468
            arc = arc_lists[arc].next;
1469 1469
          }
1470 1470
          st.push_back(arc);
1471 1471
        }
1472 1472
      }
1473 1473

	
1474 1474
      for (int i = 1; i < int(st.size()); ++i) {
1475 1475
        ppath.push_back(st[i]);
1476 1476
      }
1477 1477
    }
1478 1478

	
1479 1479

	
1480 1480
    int markExternalPath(Node node, OrderMap& order_map,
1481 1481
                         ChildLists& child_lists, PredMap& pred_map,
1482 1482
                         AncestorMap& ancestor_map, LowMap& low_map) {
1483 1483
      int lp = lowPoint(node, order_map, child_lists,
1484 1484
                        ancestor_map, low_map);
1485 1485

	
1486 1486
      if (ancestor_map[node] != lp) {
1487 1487
        node = child_lists[node].first;
1488 1488
        _kuratowski[pred_map[node]] = true;
1489 1489

	
1490 1490
        while (ancestor_map[node] != lp) {
1491 1491
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
1492 1492
            Node tnode = _graph.target(e);
1493 1493
            if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
1494 1494
              node = tnode;
1495 1495
              _kuratowski[e] = true;
1496 1496
              break;
1497 1497
            }
1498 1498
          }
1499 1499
        }
1500 1500
      }
1501 1501

	
1502 1502
      for (OutArcIt e(_graph, node); e != INVALID; ++e) {
1503 1503
        if (order_map[_graph.target(e)] == lp) {
1504 1504
          _kuratowski[e] = true;
1505 1505
          break;
1506 1506
        }
1507 1507
      }
1508 1508

	
1509 1509
      return lp;
1510 1510
    }
1511 1511

	
1512 1512
    void markPertinentPath(Node node, OrderMap& order_map,
1513 1513
                           NodeData& node_data, ArcLists& arc_lists,
1514 1514
                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
1515 1515
      while (embed_arc[node] == INVALID) {
1516 1516
        int n = merge_roots[node].front();
1517 1517
        Arc arc = node_data[n].first;
1518 1518

	
1519 1519
        _kuratowski.set(arc, true);
1520 1520

	
1521 1521
        Node pred = node;
1522 1522
        node = _graph.target(arc);
1523 1523
        while (!pertinent(node, embed_arc, merge_roots)) {
1524 1524
          arc = node_data[order_map[node]].first;
1525 1525
          if (_graph.target(arc) == pred) {
1526 1526
            arc = arc_lists[arc].next;
1527 1527
          }
1528 1528
          _kuratowski.set(arc, true);
1529 1529
          pred = node;
1530 1530
          node = _graph.target(arc);
1531 1531
        }
1532 1532
      }
1533 1533
      _kuratowski.set(embed_arc[node], true);
1534 1534
    }
1535 1535

	
1536 1536
    void markPredPath(Node node, Node snode, PredMap& pred_map) {
1537 1537
      while (node != snode) {
1538 1538
        _kuratowski.set(pred_map[node], true);
1539 1539
        node = _graph.source(pred_map[node]);
1540 1540
      }
1541 1541
    }
1542 1542

	
1543 1543
    void markFacePath(Node ynode, Node xnode,
1544 1544
                      OrderMap& order_map, NodeData& node_data) {
1545 1545
      Arc arc = node_data[order_map[ynode]].first;
1546 1546
      Node node = _graph.target(arc);
1547 1547
      _kuratowski.set(arc, true);
1548 1548

	
1549 1549
      while (node != xnode) {
1550 1550
        arc = node_data[order_map[node]].first;
1551 1551
        _kuratowski.set(arc, true);
1552 1552
        node = _graph.target(arc);
1553 1553
      }
1554 1554
    }
1555 1555

	
1556 1556
    void markInternalPath(std::vector<Arc>& path) {
1557 1557
      for (int i = 0; i < int(path.size()); ++i) {
1558 1558
        _kuratowski.set(path[i], true);
1559 1559
      }
1560 1560
    }
1561 1561

	
1562 1562
    void markPilePath(std::vector<Arc>& path) {
1563 1563
      for (int i = 0; i < int(path.size()); ++i) {
1564 1564
        _kuratowski.set(path[i], true);
1565 1565
      }
1566 1566
    }
1567 1567

	
1568 1568
    void isolateKuratowski(Arc arc, NodeData& node_data,
1569 1569
                           ArcLists& arc_lists, FlipMap& flip_map,
1570 1570
                           OrderMap& order_map, OrderList& order_list,
1571 1571
                           PredMap& pred_map, ChildLists& child_lists,
1572 1572
                           AncestorMap& ancestor_map, LowMap& low_map,
1573 1573
                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
1574 1574

	
1575 1575
      Node root = _graph.source(arc);
1576 1576
      Node enode = _graph.target(arc);
1577 1577

	
1578 1578
      int rorder = order_map[root];
1579 1579

	
1580 1580
      TypeMap type_map(_graph, 0);
1581 1581

	
1582 1582
      int rn = findComponentRoot(root, enode, child_lists,
1583 1583
                                 order_map, order_list);
1584 1584

	
1585 1585
      Node xnode = order_list[node_data[rn].next];
1586 1586
      Node ynode = order_list[node_data[rn].prev];
1587 1587

	
1588 1588
      // Minor-A
1589 1589
      {
1590 1590
        while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
1591 1591

	
1592 1592
          if (!merge_roots[xnode].empty()) {
1593 1593
            root = xnode;
1594 1594
            rn = merge_roots[xnode].front();
1595 1595
          } else {
1596 1596
            root = ynode;
1597 1597
            rn = merge_roots[ynode].front();
1598 1598
          }
1599 1599

	
1600 1600
          xnode = order_list[node_data[rn].next];
1601 1601
          ynode = order_list[node_data[rn].prev];
1602 1602
        }
1603 1603

	
1604 1604
        if (root != _graph.source(arc)) {
1605 1605
          orientComponent(root, rn, order_map, pred_map,
1606 1606
                          node_data, arc_lists, flip_map, type_map);
1607 1607
          markFacePath(root, root, order_map, node_data);
1608 1608
          int xlp = markExternalPath(xnode, order_map, child_lists,
1609 1609
                                     pred_map, ancestor_map, low_map);
1610 1610
          int ylp = markExternalPath(ynode, order_map, child_lists,
1611 1611
                                     pred_map, ancestor_map, low_map);
1612 1612
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1613 1613
          Node lwnode = findPertinent(ynode, order_map, node_data,
1614 1614
                                      embed_arc, merge_roots);
1615 1615

	
1616 1616
          markPertinentPath(lwnode, order_map, node_data, arc_lists,
1617 1617
                            embed_arc, merge_roots);
1618 1618

	
1619 1619
          return;
1620 1620
        }
1621 1621
      }
1622 1622

	
1623 1623
      orientComponent(root, rn, order_map, pred_map,
1624 1624
                      node_data, arc_lists, flip_map, type_map);
1625 1625

	
1626 1626
      Node wnode = findPertinent(ynode, order_map, node_data,
1627 1627
                                 embed_arc, merge_roots);
1628 1628
      setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
1629 1629

	
1630 1630

	
1631 1631
      //Minor-B
1632 1632
      if (!merge_roots[wnode].empty()) {
1633 1633
        int cn = merge_roots[wnode].back();
1634 1634
        Node rep = order_list[cn - order_list.size()];
1635 1635
        if (low_map[rep] < rorder) {
1636 1636
          markFacePath(root, root, order_map, node_data);
1637 1637
          int xlp = markExternalPath(xnode, order_map, child_lists,
1638 1638
                                     pred_map, ancestor_map, low_map);
1639 1639
          int ylp = markExternalPath(ynode, order_map, child_lists,
1640 1640
                                     pred_map, ancestor_map, low_map);
1641 1641

	
1642 1642
          Node lwnode, lznode;
1643 1643
          markCommonPath(wnode, rorder, lwnode, lznode, order_list,
1644 1644
                         order_map, node_data, arc_lists, embed_arc,
1645 1645
                         merge_roots, child_lists, ancestor_map, low_map);
1646 1646

	
1647 1647
          markPertinentPath(lwnode, order_map, node_data, arc_lists,
1648 1648
                            embed_arc, merge_roots);
1649 1649
          int zlp = markExternalPath(lznode, order_map, child_lists,
1650 1650
                                     pred_map, ancestor_map, low_map);
1651 1651

	
1652 1652
          int minlp = xlp < ylp ? xlp : ylp;
1653 1653
          if (zlp < minlp) minlp = zlp;
1654 1654

	
1655 1655
          int maxlp = xlp > ylp ? xlp : ylp;
1656 1656
          if (zlp > maxlp) maxlp = zlp;
1657 1657

	
1658 1658
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1659 1659

	
1660 1660
          return;
1661 1661
        }
1662 1662
      }
1663 1663

	
1664 1664
      Node pxnode, pynode;
1665 1665
      std::vector<Arc> ipath;
1666 1666
      findInternalPath(ipath, wnode, root, type_map, order_map,
1667 1667
                       node_data, arc_lists);
1668 1668
      setInternalFlags(ipath, type_map);
1669 1669
      pynode = _graph.source(ipath.front());
1670 1670
      pxnode = _graph.target(ipath.back());
1671 1671

	
1672 1672
      wnode = findPertinent(pynode, order_map, node_data,
1673 1673
                            embed_arc, merge_roots);
1674 1674

	
1675 1675
      // Minor-C
1676 1676
      {
1677 1677
        if (type_map[_graph.source(ipath.front())] == HIGHY) {
1678 1678
          if (type_map[_graph.target(ipath.back())] == HIGHX) {
1679 1679
            markFacePath(xnode, pxnode, order_map, node_data);
1680 1680
          }
1681 1681
          markFacePath(root, xnode, order_map, node_data);
1682 1682
          markPertinentPath(wnode, order_map, node_data, arc_lists,
1683 1683
                            embed_arc, merge_roots);
1684 1684
          markInternalPath(ipath);
1685 1685
          int xlp = markExternalPath(xnode, order_map, child_lists,
1686 1686
                                     pred_map, ancestor_map, low_map);
1687 1687
          int ylp = markExternalPath(ynode, order_map, child_lists,
1688 1688
                                     pred_map, ancestor_map, low_map);
1689 1689
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1690 1690
          return;
1691 1691
        }
1692 1692

	
1693 1693
        if (type_map[_graph.target(ipath.back())] == HIGHX) {
1694 1694
          markFacePath(ynode, root, order_map, node_data);
1695 1695
          markPertinentPath(wnode, order_map, node_data, arc_lists,
1696 1696
                            embed_arc, merge_roots);
1697 1697
          markInternalPath(ipath);
1698 1698
          int xlp = markExternalPath(xnode, order_map, child_lists,
1699 1699
                                     pred_map, ancestor_map, low_map);
1700 1700
          int ylp = markExternalPath(ynode, order_map, child_lists,
1701 1701
                                     pred_map, ancestor_map, low_map);
1702 1702
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1703 1703
          return;
1704 1704
        }
1705 1705
      }
1706 1706

	
1707 1707
      std::vector<Arc> ppath;
1708 1708
      findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
1709 1709

	
1710 1710
      // Minor-D
1711 1711
      if (!ppath.empty()) {
1712 1712
        markFacePath(ynode, xnode, order_map, node_data);
1713 1713
        markPertinentPath(wnode, order_map, node_data, arc_lists,
1714 1714
                          embed_arc, merge_roots);
1715 1715
        markPilePath(ppath);
1716 1716
        markInternalPath(ipath);
1717 1717
        int xlp = markExternalPath(xnode, order_map, child_lists,
1718 1718
                                   pred_map, ancestor_map, low_map);
1719 1719
        int ylp = markExternalPath(ynode, order_map, child_lists,
1720 1720
                                   pred_map, ancestor_map, low_map);
1721 1721
        markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1722 1722
        return;
1723 1723
      }
1724 1724

	
1725 1725
      // Minor-E*
1726 1726
      {
1727 1727

	
1728 1728
        if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1729 1729
          Node znode = findExternal(pynode, rorder, order_map,
1730 1730
                                    child_lists, ancestor_map,
1731 1731
                                    low_map, node_data);
1732 1732

	
1733 1733
          if (type_map[znode] == LOWY) {
1734 1734
            markFacePath(root, xnode, order_map, node_data);
1735 1735
            markPertinentPath(wnode, order_map, node_data, arc_lists,
1736 1736
                              embed_arc, merge_roots);
1737 1737
            markInternalPath(ipath);
1738 1738
            int xlp = markExternalPath(xnode, order_map, child_lists,
1739 1739
                                       pred_map, ancestor_map, low_map);
1740 1740
            int zlp = markExternalPath(znode, order_map, child_lists,
1741 1741
                                       pred_map, ancestor_map, low_map);
1742 1742
            markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
1743 1743
          } else {
1744 1744
            markFacePath(ynode, root, order_map, node_data);
1745 1745
            markPertinentPath(wnode, order_map, node_data, arc_lists,
1746 1746
                              embed_arc, merge_roots);
1747 1747
            markInternalPath(ipath);
1748 1748
            int ylp = markExternalPath(ynode, order_map, child_lists,
1749 1749
                                       pred_map, ancestor_map, low_map);
1750 1750
            int zlp = markExternalPath(znode, order_map, child_lists,
1751 1751
                                       pred_map, ancestor_map, low_map);
1752 1752
            markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
1753 1753
          }
1754 1754
          return;
1755 1755
        }
1756 1756

	
1757 1757
        int xlp = markExternalPath(xnode, order_map, child_lists,
1758 1758
                                   pred_map, ancestor_map, low_map);
1759 1759
        int ylp = markExternalPath(ynode, order_map, child_lists,
1760 1760
                                   pred_map, ancestor_map, low_map);
1761 1761
        int wlp = markExternalPath(wnode, order_map, child_lists,
1762 1762
                                   pred_map, ancestor_map, low_map);
1763 1763

	
1764 1764
        if (wlp > xlp && wlp > ylp) {
1765 1765
          markFacePath(root, root, order_map, node_data);
1766 1766
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1767 1767
          return;
1768 1768
        }
1769 1769

	
1770 1770
        markInternalPath(ipath);
1771 1771
        markPertinentPath(wnode, order_map, node_data, arc_lists,
1772 1772
                          embed_arc, merge_roots);
1773 1773

	
1774 1774
        if (xlp > ylp && xlp > wlp) {
1775 1775
          markFacePath(root, pynode, order_map, node_data);
1776 1776
          markFacePath(wnode, xnode, order_map, node_data);
1777 1777
          markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
1778 1778
          return;
1779 1779
        }
1780 1780

	
1781 1781
        if (ylp > xlp && ylp > wlp) {
1782 1782
          markFacePath(pxnode, root, order_map, node_data);
1783 1783
          markFacePath(ynode, wnode, order_map, node_data);
1784 1784
          markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
1785 1785
          return;
1786 1786
        }
1787 1787

	
1788 1788
        if (pynode != ynode) {
1789 1789
          markFacePath(pxnode, wnode, order_map, node_data);
1790 1790

	
1791 1791
          int minlp = xlp < ylp ? xlp : ylp;
1792 1792
          if (wlp < minlp) minlp = wlp;
1793 1793

	
1794 1794
          int maxlp = xlp > ylp ? xlp : ylp;
1795 1795
          if (wlp > maxlp) maxlp = wlp;
1796 1796

	
1797 1797
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1798 1798
          return;
1799 1799
        }
1800 1800

	
1801 1801
        if (pxnode != xnode) {
1802 1802
          markFacePath(wnode, pynode, order_map, node_data);
1803 1803

	
1804 1804
          int minlp = xlp < ylp ? xlp : ylp;
1805 1805
          if (wlp < minlp) minlp = wlp;
1806 1806

	
1807 1807
          int maxlp = xlp > ylp ? xlp : ylp;
1808 1808
          if (wlp > maxlp) maxlp = wlp;
1809 1809

	
1810 1810
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1811 1811
          return;
1812 1812
        }
1813 1813

	
1814 1814
        markFacePath(root, root, order_map, node_data);
1815 1815
        int minlp = xlp < ylp ? xlp : ylp;
1816 1816
        if (wlp < minlp) minlp = wlp;
1817 1817
        markPredPath(root, order_list[minlp], pred_map);
1818 1818
        return;
1819 1819
      }
1820 1820

	
1821 1821
    }
1822 1822

	
1823 1823
  };
1824 1824

	
1825 1825
  namespace _planarity_bits {
1826 1826

	
1827 1827
    template <typename Graph, typename EmbeddingMap>
1828 1828
    void makeConnected(Graph& graph, EmbeddingMap& embedding) {
1829 1829
      DfsVisitor<Graph> null_visitor;
1830 1830
      DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
1831 1831
      dfs.init();
1832 1832

	
1833 1833
      typename Graph::Node u = INVALID;
1834 1834
      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1835 1835
        if (!dfs.reached(n)) {
1836 1836
          dfs.addSource(n);
1837 1837
          dfs.start();
1838 1838
          if (u == INVALID) {
1839 1839
            u = n;
1840 1840
          } else {
1841 1841
            typename Graph::Node v = n;
1842 1842

	
1843 1843
            typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
1844 1844
            typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
1845 1845

	
1846 1846
            typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
1847 1847

	
1848 1848
            if (ue != INVALID) {
1849 1849
              embedding[e] = embedding[ue];
1850 1850
              embedding[ue] = e;
1851 1851
            } else {
1852 1852
              embedding[e] = e;
1853 1853
            }
1854 1854

	
1855 1855
            if (ve != INVALID) {
1856 1856
              embedding[graph.oppositeArc(e)] = embedding[ve];
1857 1857
              embedding[ve] = graph.oppositeArc(e);
1858 1858
            } else {
1859 1859
              embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
1860 1860
            }
1861 1861
          }
1862 1862
        }
1863 1863
      }
1864 1864
    }
1865 1865

	
1866 1866
    template <typename Graph, typename EmbeddingMap>
1867 1867
    void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
1868 1868
      typename Graph::template ArcMap<bool> processed(graph);
1869 1869

	
1870 1870
      std::vector<typename Graph::Arc> arcs;
1871 1871
      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
1872 1872
        arcs.push_back(e);
1873 1873
      }
1874 1874

	
1875 1875
      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
1876 1876

	
1877 1877
      for (int i = 0; i < int(arcs.size()); ++i) {
1878 1878
        typename Graph::Arc pp = arcs[i];
1879 1879
        if (processed[pp]) continue;
1880 1880

	
1881 1881
        typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
1882 1882
        processed[e] = true;
1883 1883
        visited.set(graph.source(e), true);
1884 1884

	
1885 1885
        typename Graph::Arc p = e, l = e;
1886 1886
        e = embedding[graph.oppositeArc(e)];
1887 1887

	
1888 1888
        while (e != l) {
1889 1889
          processed[e] = true;
1890 1890

	
1891 1891
          if (visited[graph.source(e)]) {
1892 1892

	
1893 1893
            typename Graph::Arc n =
1894 1894
              graph.direct(graph.addEdge(graph.source(p),
1895 1895
                                           graph.target(e)), true);
1896 1896
            embedding[n] = p;
1897 1897
            embedding[graph.oppositeArc(pp)] = n;
1898 1898

	
1899 1899
            embedding[graph.oppositeArc(n)] =
1900 1900
              embedding[graph.oppositeArc(e)];
1901 1901
            embedding[graph.oppositeArc(e)] =
1902 1902
              graph.oppositeArc(n);
1903 1903

	
1904 1904
            p = n;
1905 1905
            e = embedding[graph.oppositeArc(n)];
1906 1906
          } else {
1907 1907
            visited.set(graph.source(e), true);
1908 1908
            pp = p;
1909 1909
            p = e;
1910 1910
            e = embedding[graph.oppositeArc(e)];
1911 1911
          }
1912 1912
        }
1913 1913
        visited.setAll(false);
1914 1914
      }
1915 1915
    }
1916 1916

	
1917 1917

	
1918 1918
    template <typename Graph, typename EmbeddingMap>
1919 1919
    void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
1920 1920

	
1921 1921
      typename Graph::template NodeMap<int> degree(graph);
1922 1922

	
1923 1923
      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1924 1924
        degree[n] = countIncEdges(graph, n);
1925 1925
      }
1926 1926

	
1927 1927
      typename Graph::template ArcMap<bool> processed(graph);
1928 1928
      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
1929 1929

	
1930 1930
      std::vector<typename Graph::Arc> arcs;
1931 1931
      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
1932 1932
        arcs.push_back(e);
1933 1933
      }
1934 1934

	
1935 1935
      for (int i = 0; i < int(arcs.size()); ++i) {
1936 1936
        typename Graph::Arc e = arcs[i];
1937 1937

	
1938 1938
        if (processed[e]) continue;
1939 1939
        processed[e] = true;
1940 1940

	
1941 1941
        typename Graph::Arc mine = e;
1942 1942
        int mind = degree[graph.source(e)];
1943 1943

	
1944 1944
        int face_size = 1;
1945 1945

	
1946 1946
        typename Graph::Arc l = e;
1947 1947
        e = embedding[graph.oppositeArc(e)];
1948 1948
        while (l != e) {
1949 1949
          processed[e] = true;
1950 1950

	
1951 1951
          ++face_size;
1952 1952

	
1953 1953
          if (degree[graph.source(e)] < mind) {
1954 1954
            mine = e;
1955 1955
            mind = degree[graph.source(e)];
1956 1956
          }
1957 1957

	
1958 1958
          e = embedding[graph.oppositeArc(e)];
1959 1959
        }
1960 1960

	
1961 1961
        if (face_size < 4) {
1962 1962
          continue;
1963 1963
        }
1964 1964

	
1965 1965
        typename Graph::Node s = graph.source(mine);
1966 1966
        for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
1967 1967
          visited.set(graph.target(e), true);
1968 1968
        }
1969 1969

	
1970 1970
        typename Graph::Arc oppe = INVALID;
1971 1971

	
1972 1972
        e = embedding[graph.oppositeArc(mine)];
1973 1973
        e = embedding[graph.oppositeArc(e)];
1974 1974
        while (graph.target(e) != s) {
1975 1975
          if (visited[graph.source(e)]) {
1976 1976
            oppe = e;
1977 1977
            break;
1978 1978
          }
1979 1979
          e = embedding[graph.oppositeArc(e)];
1980 1980
        }
1981 1981
        visited.setAll(false);
1982 1982

	
1983 1983
        if (oppe == INVALID) {
1984 1984

	
1985 1985
          e = embedding[graph.oppositeArc(mine)];
1986 1986
          typename Graph::Arc pn = mine, p = e;
1987 1987

	
1988 1988
          e = embedding[graph.oppositeArc(e)];
1989 1989
          while (graph.target(e) != s) {
1990 1990
            typename Graph::Arc n =
1991 1991
              graph.direct(graph.addEdge(s, graph.source(e)), true);
1992 1992

	
1993 1993
            embedding[n] = pn;
1994 1994
            embedding[graph.oppositeArc(n)] = e;
1995 1995
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
1996 1996

	
1997 1997
            pn = n;
1998 1998

	
1999 1999
            p = e;
2000 2000
            e = embedding[graph.oppositeArc(e)];
2001 2001
          }
2002 2002

	
2003 2003
          embedding[graph.oppositeArc(e)] = pn;
2004 2004

	
2005 2005
        } else {
2006 2006

	
2007 2007
          mine = embedding[graph.oppositeArc(mine)];
2008 2008
          s = graph.source(mine);
2009 2009
          oppe = embedding[graph.oppositeArc(oppe)];
2010 2010
          typename Graph::Node t = graph.source(oppe);
2011 2011

	
2012 2012
          typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
2013 2013
          embedding[ce] = mine;
2014 2014
          embedding[graph.oppositeArc(ce)] = oppe;
2015 2015

	
2016 2016
          typename Graph::Arc pn = ce, p = oppe;
2017 2017
          e = embedding[graph.oppositeArc(oppe)];
2018 2018
          while (graph.target(e) != s) {
2019 2019
            typename Graph::Arc n =
2020 2020
              graph.direct(graph.addEdge(s, graph.source(e)), true);
2021 2021

	
2022 2022
            embedding[n] = pn;
2023 2023
            embedding[graph.oppositeArc(n)] = e;
2024 2024
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
2025 2025

	
2026 2026
            pn = n;
2027 2027

	
2028 2028
            p = e;
2029 2029
            e = embedding[graph.oppositeArc(e)];
2030 2030

	
2031 2031
          }
2032 2032
          embedding[graph.oppositeArc(e)] = pn;
2033 2033

	
2034 2034
          pn = graph.oppositeArc(ce), p = mine;
2035 2035
          e = embedding[graph.oppositeArc(mine)];
2036 2036
          while (graph.target(e) != t) {
2037 2037
            typename Graph::Arc n =
2038 2038
              graph.direct(graph.addEdge(t, graph.source(e)), true);
2039 2039

	
2040 2040
            embedding[n] = pn;
2041 2041
            embedding[graph.oppositeArc(n)] = e;
2042 2042
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
2043 2043

	
2044 2044
            pn = n;
2045 2045

	
2046 2046
            p = e;
2047 2047
            e = embedding[graph.oppositeArc(e)];
2048 2048

	
2049 2049
          }
2050 2050
          embedding[graph.oppositeArc(e)] = pn;
2051 2051
        }
2052 2052
      }
2053 2053
    }
2054 2054

	
2055 2055
  }
2056 2056

	
2057 2057
  /// \ingroup planar
2058 2058
  ///
2059 2059
  /// \brief Schnyder's planar drawing algorithm
2060 2060
  ///
2061 2061
  /// The planar drawing algorithm calculates positions for the nodes
2062 2062
  /// in the plane which coordinates satisfy that if the arcs are
2063 2063
  /// represented with straight lines then they will not intersect
2064 2064
  /// each other.
2065 2065
  ///
2066 2066
  /// Scnyder's algorithm embeds the graph on \c (n-2,n-2) size grid,
2067 2067
  /// i.e. each node will be located in the \c [0,n-2]x[0,n-2] square.
2068 2068
  /// The time complexity of the algorithm is O(n).
2069 2069
  template <typename Graph>
2070 2070
  class PlanarDrawing {
2071 2071
  public:
2072 2072

	
2073 2073
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2074 2074

	
2075 2075
    /// \brief The point type for store coordinates
2076 2076
    typedef dim2::Point<int> Point;
2077 2077
    /// \brief The map type for store coordinates
2078 2078
    typedef typename Graph::template NodeMap<Point> PointMap;
2079 2079

	
2080 2080

	
2081 2081
    /// \brief Constructor
2082 2082
    ///
2083 2083
    /// Constructor
2084 2084
    /// \pre The graph should be simple, i.e. loop and parallel arc free.
2085 2085
    PlanarDrawing(const Graph& graph)
2086 2086
      : _graph(graph), _point_map(graph) {}
2087 2087

	
2088 2088
  private:
2089 2089

	
2090 2090
    template <typename AuxGraph, typename AuxEmbeddingMap>
2091 2091
    void drawing(const AuxGraph& graph,
2092 2092
                 const AuxEmbeddingMap& next,
2093 2093
                 PointMap& point_map) {
2094 2094
      TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
2095 2095

	
2096 2096
      typename AuxGraph::template ArcMap<Arc> prev(graph);
2097 2097

	
2098 2098
      for (NodeIt n(graph); n != INVALID; ++n) {
2099 2099
        Arc e = OutArcIt(graph, n);
2100 2100

	
2101 2101
        Arc p = e, l = e;
2102 2102

	
2103 2103
        e = next[e];
2104 2104
        while (e != l) {
2105 2105
          prev[e] = p;
2106 2106
          p = e;
2107 2107
          e = next[e];
2108 2108
        }
2109 2109
        prev[e] = p;
2110 2110
      }
2111 2111

	
2112 2112
      Node anode, bnode, cnode;
2113 2113

	
2114 2114
      {
2115 2115
        Arc e = ArcIt(graph);
2116 2116
        anode = graph.source(e);
2117 2117
        bnode = graph.target(e);
2118 2118
        cnode = graph.target(next[graph.oppositeArc(e)]);
2119 2119
      }
2120 2120

	
2121 2121
      IterableBoolMap<AuxGraph, Node> proper(graph, false);
2122 2122
      typename AuxGraph::template NodeMap<int> conn(graph, -1);
2123 2123

	
2124 2124
      conn[anode] = conn[bnode] = -2;
2125 2125
      {
2126 2126
        for (OutArcIt e(graph, anode); e != INVALID; ++e) {
2127 2127
          Node m = graph.target(e);
2128 2128
          if (conn[m] == -1) {
2129 2129
            conn[m] = 1;
2130 2130
          }
2131 2131
        }
2132 2132
        conn[cnode] = 2;
2133 2133

	
2134 2134
        for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
2135 2135
          Node m = graph.target(e);
2136 2136
          if (conn[m] == -1) {
2137 2137
            conn[m] = 1;
2138 2138
          } else if (conn[m] != -2) {
2139 2139
            conn[m] += 1;
2140 2140
            Arc pe = graph.oppositeArc(e);
2141 2141
            if (conn[graph.target(next[pe])] == -2) {
2142 2142
              conn[m] -= 1;
2143 2143
            }
2144 2144
            if (conn[graph.target(prev[pe])] == -2) {
2145 2145
              conn[m] -= 1;
2146 2146
            }
2147 2147

	
2148 2148
            proper.set(m, conn[m] == 1);
2149 2149
          }
2150 2150
        }
2151 2151
      }
2152 2152

	
2153 2153

	
2154 2154
      typename AuxGraph::template ArcMap<int> angle(graph, -1);
2155 2155

	
2156 2156
      while (proper.trueNum() != 0) {
2157 2157
        Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
2158 2158
        proper.set(n, false);
2159 2159
        conn[n] = -2;
2160 2160

	
2161 2161
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2162 2162
          Node m = graph.target(e);
2163 2163
          if (conn[m] == -1) {
2164 2164
            conn[m] = 1;
2165 2165
          } else if (conn[m] != -2) {
2166 2166
            conn[m] += 1;
2167 2167
            Arc pe = graph.oppositeArc(e);
2168 2168
            if (conn[graph.target(next[pe])] == -2) {
2169 2169
              conn[m] -= 1;
2170 2170
            }
2171 2171
            if (conn[graph.target(prev[pe])] == -2) {
2172 2172
              conn[m] -= 1;
2173 2173
            }
2174 2174

	
2175 2175
            proper.set(m, conn[m] == 1);
2176 2176
          }
2177 2177
        }
2178 2178

	
2179 2179
        {
2180 2180
          Arc e = OutArcIt(graph, n);
2181 2181
          Arc p = e, l = e;
2182 2182

	
2183 2183
          e = next[e];
2184 2184
          while (e != l) {
2185 2185

	
2186 2186
            if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
2187 2187
              Arc f = e;
2188 2188
              angle[f] = 0;
2189 2189
              f = next[graph.oppositeArc(f)];
2190 2190
              angle[f] = 1;
2191 2191
              f = next[graph.oppositeArc(f)];
2192 2192
              angle[f] = 2;
2193 2193
            }
2194 2194

	
2195 2195
            p = e;
2196 2196
            e = next[e];
2197 2197
          }
2198 2198

	
2199 2199
          if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
2200 2200
            Arc f = e;
2201 2201
            angle[f] = 0;
2202 2202
            f = next[graph.oppositeArc(f)];
2203 2203
            angle[f] = 1;
2204 2204
            f = next[graph.oppositeArc(f)];
2205 2205
            angle[f] = 2;
2206 2206
          }
2207 2207
        }
2208 2208
      }
2209 2209

	
2210 2210
      typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
2211 2211
      typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
2212 2212
      typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
2213 2213

	
2214 2214
      typename AuxGraph::template NodeMap<int> apredid(graph, -1);
2215 2215
      typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
2216 2216
      typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
2217 2217

	
2218 2218
      for (ArcIt e(graph); e != INVALID; ++e) {
2219 2219
        if (angle[e] == angle[next[e]]) {
2220 2220
          switch (angle[e]) {
2221 2221
          case 2:
2222 2222
            apred[graph.target(e)] = graph.source(e);
2223 2223
            apredid[graph.target(e)] = graph.id(graph.source(e));
2224 2224
            break;
2225 2225
          case 1:
2226 2226
            bpred[graph.target(e)] = graph.source(e);
2227 2227
            bpredid[graph.target(e)] = graph.id(graph.source(e));
2228 2228
            break;
2229 2229
          case 0:
2230 2230
            cpred[graph.target(e)] = graph.source(e);
2231 2231
            cpredid[graph.target(e)] = graph.id(graph.source(e));
2232 2232
            break;
2233 2233
          }
2234 2234
        }
2235 2235
      }
2236 2236

	
2237 2237
      cpred[anode] = INVALID;
2238 2238
      cpred[bnode] = INVALID;
2239 2239

	
2240 2240
      std::vector<Node> aorder, border, corder;
2241 2241

	
2242 2242
      {
2243 2243
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2244 2244
        std::vector<Node> st;
2245 2245
        for (NodeIt n(graph); n != INVALID; ++n) {
2246 2246
          if (!processed[n] && n != bnode && n != cnode) {
2247 2247
            st.push_back(n);
2248 2248
            processed[n] = true;
2249 2249
            Node m = apred[n];
2250 2250
            while (m != INVALID && !processed[m]) {
2251 2251
              st.push_back(m);
Ignore white space 3072 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20

	
21 21
#include <lemon/planarity.h>
22 22

	
23 23
#include <lemon/smart_graph.h>
24 24
#include <lemon/lgf_reader.h>
25 25
#include <lemon/connectivity.h>
26 26
#include <lemon/dim2.h>
27 27

	
28 28
#include "test_tools.h"
29 29

	
30 30
using namespace lemon;
31 31
using namespace lemon::dim2;
32 32

	
33 33
const int lgfn = 4;
34 34
const std::string lgf[lgfn] = {
35 35
  "@nodes\n"
36 36
  "label\n"
37 37
  "0\n"
38 38
  "1\n"
39 39
  "2\n"
40 40
  "3\n"
41 41
  "4\n"
42 42
  "@edges\n"
43 43
  "     label\n"
44 44
  "0 1  0\n"
45 45
  "0 2  0\n"
46 46
  "0 3  0\n"
47 47
  "0 4  0\n"
48 48
  "1 2  0\n"
49 49
  "1 3  0\n"
50 50
  "1 4  0\n"
51 51
  "2 3  0\n"
52 52
  "2 4  0\n"
53 53
  "3 4  0\n",
54 54

	
55 55
  "@nodes\n"
56 56
  "label\n"
57 57
  "0\n"
58 58
  "1\n"
59 59
  "2\n"
60 60
  "3\n"
61 61
  "4\n"
62 62
  "@edges\n"
63 63
  "     label\n"
64 64
  "0 1  0\n"
65 65
  "0 2  0\n"
66 66
  "0 3  0\n"
67 67
  "0 4  0\n"
68 68
  "1 2  0\n"
69 69
  "1 3  0\n"
70 70
  "2 3  0\n"
71 71
  "2 4  0\n"
72 72
  "3 4  0\n",
73 73

	
74 74
  "@nodes\n"
75 75
  "label\n"
76 76
  "0\n"
77 77
  "1\n"
78 78
  "2\n"
79 79
  "3\n"
80 80
  "4\n"
81 81
  "5\n"
82 82
  "@edges\n"
83 83
  "     label\n"
84 84
  "0 3  0\n"
85 85
  "0 4  0\n"
86 86
  "0 5  0\n"
87 87
  "1 3  0\n"
88 88
  "1 4  0\n"
89 89
  "1 5  0\n"
90 90
  "2 3  0\n"
91 91
  "2 4  0\n"
92 92
  "2 5  0\n",
93 93

	
94 94
  "@nodes\n"
95 95
  "label\n"
96 96
  "0\n"
97 97
  "1\n"
98 98
  "2\n"
99 99
  "3\n"
100 100
  "4\n"
101 101
  "5\n"
102 102
  "@edges\n"
103 103
  "     label\n"
104 104
  "0 3  0\n"
105 105
  "0 4  0\n"
106 106
  "0 5  0\n"
107 107
  "1 3  0\n"
108 108
  "1 4  0\n"
109 109
  "1 5  0\n"
110 110
  "2 3  0\n"
111 111
  "2 5  0\n"
112 112
};
113 113

	
114 114

	
115 115

	
116 116
typedef SmartGraph Graph;
117 117
GRAPH_TYPEDEFS(Graph);
118 118

	
119 119
typedef PlanarEmbedding<SmartGraph> PE;
120 120
typedef PlanarDrawing<SmartGraph> PD;
121 121
typedef PlanarColoring<SmartGraph> PC;
122 122

	
123 123
void checkEmbedding(const Graph& graph, PE& pe) {
124 124
  int face_num = 0;
125 125

	
126 126
  Graph::ArcMap<int> face(graph, -1);
127 127

	
128 128
  for (ArcIt a(graph); a != INVALID; ++a) {
129 129
    if (face[a] == -1) {
130 130
      Arc b = a;
131 131
      while (face[b] == -1) {
132 132
        face[b] = face_num;
133 133
        b = pe.next(graph.oppositeArc(b));
134 134
      }
135 135
      check(face[b] == face_num, "Wrong face");
136 136
      ++face_num;
137 137
    }
138 138
  }
139 139
  check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
140 140
        countEdges(graph) + 1, "Euler test does not passed");
141 141
}
142 142

	
143 143
void checkKuratowski(const Graph& graph, PE& pe) {
144 144
  std::map<int, int> degs;
145 145
  for (NodeIt n(graph); n != INVALID; ++n) {
146 146
    int deg = 0;
147 147
    for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
148 148
      if (pe.kuratowski(e)) {
149 149
        ++deg;
150 150
      }
151 151
    }
152 152
    ++degs[deg];
153 153
  }
154 154
  for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
155 155
    check(it->first == 0 || it->first == 2 ||
156 156
          (it->first == 3 && it->second == 6) ||
157 157
          (it->first == 4 && it->second == 5),
158 158
          "Wrong degree in Kuratowski graph");
159 159
  }
160 160

	
161 161
  // Not full test
162 162
  check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
163 163
}
164 164

	
165 165
bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
166 166
  int l, r;
167 167
  if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
168 168
  if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
169 169
  if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
170 170
  if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
171 171

	
172 172
  l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
173 173
  r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
174 174
  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
175 175
  l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
176 176
  r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
177 177
  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
178 178
  return true;
179 179
}
180 180

	
181 181
bool collinear(Point<int> p, Point<int> q, Point<int> r) {
182 182
  int v;
183 183
  v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
184 184
  if (v != 0) return false;
185 185
  v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
186 186
  if (v < 0) return false;
187 187
  return true;
188 188
}
189 189

	
190 190
void checkDrawing(const Graph& graph, PD& pd) {
191 191
  for (Graph::NodeIt n(graph); n != INVALID; ++n) {
192 192
    Graph::NodeIt m(n);
193 193
    for (++m; m != INVALID; ++m) {
194 194
      check(pd[m] != pd[n], "Two nodes with identical coordinates");
195 195
    }
196 196
  }
197 197

	
198 198
  for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
199 199
    for (Graph::EdgeIt f(e); f != e; ++f) {
200 200
      Point<int> e1 = pd[graph.u(e)];
201 201
      Point<int> e2 = pd[graph.v(e)];
202 202
      Point<int> f1 = pd[graph.u(f)];
203 203
      Point<int> f2 = pd[graph.v(f)];
204 204

	
205 205
      if (graph.u(e) == graph.u(f)) {
206 206
        check(!collinear(e1, e2, f2), "Wrong drawing");
207 207
      } else if (graph.u(e) == graph.v(f)) {
208 208
        check(!collinear(e1, e2, f1), "Wrong drawing");
209 209
      } else if (graph.v(e) == graph.u(f)) {
210 210
        check(!collinear(e2, e1, f2), "Wrong drawing");
211 211
      } else if (graph.v(e) == graph.v(f)) {
212 212
        check(!collinear(e2, e1, f1), "Wrong drawing");
213 213
      } else {
214 214
        check(!intersect(e1, e2, f1, f2), "Wrong drawing");
215 215
      }
216 216
    }
217 217
  }
218 218
}
219 219

	
220 220
void checkColoring(const Graph& graph, PC& pc, int num) {
221 221
  for (NodeIt n(graph); n != INVALID; ++n) {
222 222
    check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
223 223
          "Wrong coloring");
224 224
  }
225 225
  for (EdgeIt e(graph); e != INVALID; ++e) {
226 226
    check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
227 227
          "Wrong coloring");
228 228
  }
229 229
}
230 230

	
231 231
int main() {
232 232

	
233 233
  for (int i = 0; i < lgfn; ++i) {
234 234
    std::istringstream lgfs(lgf[i]);
235 235

	
236 236
    SmartGraph graph;
237 237
    graphReader(graph, lgfs).run();
238 238

	
239 239
    check(simpleGraph(graph), "Test graphs must be simple");
240 240

	
241 241
    PE pe(graph);
242
    if (pe.run()) {
242
    bool planar = pe.run();
243
    check(checkPlanarity(graph) == planar, "Planarity checking failed");
244

	
245
    if (planar) {
243 246
      checkEmbedding(graph, pe);
244 247

	
245 248
      PlanarDrawing<Graph> pd(graph);
246
      pd.run(pe.embedding());
249
      pd.run(pe.embeddingMap());
247 250
      checkDrawing(graph, pd);
248 251

	
249 252
      PlanarColoring<Graph> pc(graph);
250
      pc.runFiveColoring(pe.embedding());
253
      pc.runFiveColoring(pe.embeddingMap());
251 254
      checkColoring(graph, pc, 5);
252 255

	
253 256
    } else {
254 257
      checkKuratowski(graph, pe);
255 258
    }
256 259
  }
257 260

	
258 261
  return 0;
259 262
}
0 comments (0 inline)