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

	
19
#ifndef LEMON_PLANARITY_H
20
#define LEMON_PLANARITY_H
21

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

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

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

	
40
namespace lemon {
41

	
42
  namespace _planarity_bits {
43

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

	
47
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
48

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
135
    template <typename Graph>
136
    struct ArcListNode {
137
      typename Graph::Arc prev, next;
138
    };
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

	
514
  }
515

	
516
  /// \ingroup planar
517
  ///
518
  /// \brief Planarity checking of an undirected simple graph
519
  ///
520
  /// This function implements the Boyer-Myrvold algorithm for
521
  /// planarity checking of an undirected graph. It is a simplified
522
  /// version of the PlanarEmbedding algorithm class because neither
523
  /// the embedding nor the kuratowski subdivisons are not computed.
524
  template <typename GR>
525
  bool checkPlanarity(const GR& graph) {
526
    _planarity_bits::PlanarityChecking<GR> pc(graph);
527
    return pc.run();
528
  }
529

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

	
549
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
550

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

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

	
556
  private:
557

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

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

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

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

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

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

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

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

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

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

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

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

	
592
  public:
593

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

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

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

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

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

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

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

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

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

	
632
      EmbedArc embed_arc(_graph, INVALID);
633

	
634
      MergeRoots merge_roots(_graph);
635

	
636
      ArcLists arc_lists(_graph);
637

	
638
      FlipMap flip_map(_graph, false);
639

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

	
642
        Node node = order_list[i];
643

	
644
        node_data[i].first = INVALID;
645

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

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

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

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

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

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

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

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

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

	
699
      return true;
700
    }
701

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

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

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

	
729
  private:
730

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

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

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

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

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

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

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

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

	
776
      while (true) {
777

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

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

	
784
        int rn = -1;
785

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

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

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

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

	
803
        } else {
804

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

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

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

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

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

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

	
837
        while (n != rn) {
838

	
839
          Node node = order_list[n];
840

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

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

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

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

	
856
              Node parent = order_list[dn];
857

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

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

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

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

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

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

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

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

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

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

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

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

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

	
917
            }
918

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

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

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

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

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

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

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

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

	
952
            }
953

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
1017
        }
1018

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

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

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

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

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

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

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

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

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

	
1052
    }
1053

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

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

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

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

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

	
1077
        node_data[dd].first = ce;
1078

	
1079
      }
1080
    }
1081

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

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

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

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

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

	
1099
      _embedding[prev] = arc;
1100

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

	
1109

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

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

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

	
1121
      return false;
1122
    }
1123

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

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

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

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

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

	
1145
      return low_point;
1146
    }
1147

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

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

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

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

	
1174

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

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

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

	
1195
      while (true) {
1196

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

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

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

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

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

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

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

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

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

	
1232
          znode = cnode;
1233
          return;
1234

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

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

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

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

	
1250
          wnode = cnode;
1251
          return;
1252

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

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

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

	
1265
      }
1266

	
1267
    }
1268

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

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

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

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

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

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

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

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

	
1305
      }
1306

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

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

	
1312
        Node node = qu[i];
1313

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

	
1320
        bool flip = flip_map[node];
1321

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

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

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

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

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

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

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

	
1353
      }
1354
    }
1355

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

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

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

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

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

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

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

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

	
1395
      Node node = wnode;
1396

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

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

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

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

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

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

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

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

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

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

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

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

	
1479

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

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

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

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

	
1509
      return lp;
1510
    }
1511

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

	
1519
        _kuratowski.set(arc, true);
1520

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

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

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

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

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

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

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

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

	
1578
      int rorder = order_map[root];
1579

	
1580
      TypeMap type_map(_graph, 0);
1581

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

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

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

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

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

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

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

	
1619
          return;
1620
        }
1621
      }
1622

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

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

	
1630

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

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

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

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

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

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

	
1660
          return;
1661
        }
1662
      }
1663

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

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

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

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

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

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

	
1725
      // Minor-E*
1726
      {
1727

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
1821
    }
1822

	
1823
  };
1824

	
1825
  namespace _planarity_bits {
1826

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
1917

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

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

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

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

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

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

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

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

	
1944
        int face_size = 1;
1945

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

	
1951
          ++face_size;
1952

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

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

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

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

	
1970
        typename Graph::Arc oppe = INVALID;
1971

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

	
1983
        if (oppe == INVALID) {
1984

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

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

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

	
1997
            pn = n;
1998

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

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

	
2005
        } else {
2006

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

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

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

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

	
2026
            pn = n;
2027

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

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

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

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

	
2044
            pn = n;
2045

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

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

	
2055
  }
2056

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

	
2073
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2074

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

	
2080

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

	
2088
  private:
2089

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

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

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

	
2101
        Arc p = e, l = e;
2102

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

	
2112
      Node anode, bnode, cnode;
2113

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

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

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

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

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

	
2153

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
2242
      {
2243
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2244
        std::vector<Node> st;
2245
        for (NodeIt n(graph); n != INVALID; ++n) {
2246
          if (!processed[n] && n != bnode && n != cnode) {
2247
            st.push_back(n);
2248
            processed[n] = true;
2249
            Node m = apred[n];
2250
            while (m != INVALID && !processed[m]) {
2251
              st.push_back(m);
2252
              processed[m] = true;
2253
              m = apred[m];
2254
            }
2255
            while (!st.empty()) {
2256
              aorder.push_back(st.back());
2257
              st.pop_back();
2258
            }
2259
          }
2260
        }
2261
      }
2262

	
2263
      {
2264
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2265
        std::vector<Node> st;
2266
        for (NodeIt n(graph); n != INVALID; ++n) {
2267
          if (!processed[n] && n != cnode && n != anode) {
2268
            st.push_back(n);
2269
            processed[n] = true;
2270
            Node m = bpred[n];
2271
            while (m != INVALID && !processed[m]) {
2272
              st.push_back(m);
2273
              processed[m] = true;
2274
              m = bpred[m];
2275
            }
2276
            while (!st.empty()) {
2277
              border.push_back(st.back());
2278
              st.pop_back();
2279
            }
2280
          }
2281
        }
2282
      }
2283

	
2284
      {
2285
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2286
        std::vector<Node> st;
2287
        for (NodeIt n(graph); n != INVALID; ++n) {
2288
          if (!processed[n] && n != anode && n != bnode) {
2289
            st.push_back(n);
2290
            processed[n] = true;
2291
            Node m = cpred[n];
2292
            while (m != INVALID && !processed[m]) {
2293
              st.push_back(m);
2294
              processed[m] = true;
2295
              m = cpred[m];
2296
            }
2297
            while (!st.empty()) {
2298
              corder.push_back(st.back());
2299
              st.pop_back();
2300
            }
2301
          }
2302
        }
2303
      }
2304

	
2305
      typename AuxGraph::template NodeMap<int> atree(graph, 0);
2306
      for (int i = aorder.size() - 1; i >= 0; --i) {
2307
        Node n = aorder[i];
2308
        atree[n] = 1;
2309
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2310
          if (apred[graph.target(e)] == n) {
2311
            atree[n] += atree[graph.target(e)];
2312
          }
2313
        }
2314
      }
2315

	
2316
      typename AuxGraph::template NodeMap<int> btree(graph, 0);
2317
      for (int i = border.size() - 1; i >= 0; --i) {
2318
        Node n = border[i];
2319
        btree[n] = 1;
2320
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2321
          if (bpred[graph.target(e)] == n) {
2322
            btree[n] += btree[graph.target(e)];
2323
          }
2324
        }
2325
      }
2326

	
2327
      typename AuxGraph::template NodeMap<int> apath(graph, 0);
2328
      apath[bnode] = apath[cnode] = 1;
2329
      typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
2330
      apath_btree[bnode] = btree[bnode];
2331
      for (int i = 1; i < int(aorder.size()); ++i) {
2332
        Node n = aorder[i];
2333
        apath[n] = apath[apred[n]] + 1;
2334
        apath_btree[n] = btree[n] + apath_btree[apred[n]];
2335
      }
2336

	
2337
      typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
2338
      bpath_atree[anode] = atree[anode];
2339
      for (int i = 1; i < int(border.size()); ++i) {
2340
        Node n = border[i];
2341
        bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
2342
      }
2343

	
2344
      typename AuxGraph::template NodeMap<int> cpath(graph, 0);
2345
      cpath[anode] = cpath[bnode] = 1;
2346
      typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
2347
      cpath_atree[anode] = atree[anode];
2348
      typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
2349
      cpath_btree[bnode] = btree[bnode];
2350
      for (int i = 1; i < int(corder.size()); ++i) {
2351
        Node n = corder[i];
2352
        cpath[n] = cpath[cpred[n]] + 1;
2353
        cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
2354
        cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
2355
      }
2356

	
2357
      typename AuxGraph::template NodeMap<int> third(graph);
2358
      for (NodeIt n(graph); n != INVALID; ++n) {
2359
        point_map[n].x =
2360
          bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
2361
        point_map[n].y =
2362
          cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
2363
      }
2364

	
2365
    }
2366

	
2367
  public:
2368

	
2369
    /// \brief Calculates the node positions
2370
    ///
2371
    /// This function calculates the node positions.
2372
    /// \return %True if the graph is planar.
2373
    bool run() {
2374
      PlanarEmbedding<Graph> pe(_graph);
2375
      if (!pe.run()) return false;
2376

	
2377
      run(pe);
2378
      return true;
2379
    }
2380

	
2381
    /// \brief Calculates the node positions according to a
2382
    /// combinatorical embedding
2383
    ///
2384
    /// This function calculates the node locations. The \c embedding
2385
    /// parameter should contain a valid combinatorical embedding, i.e.
2386
    /// a valid cyclic order of the arcs.
2387
    template <typename EmbeddingMap>
2388
    void run(const EmbeddingMap& embedding) {
2389
      typedef SmartEdgeSet<Graph> AuxGraph;
2390

	
2391
      if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
2392
        drawing(_graph, embedding, _point_map);
2393
        return;
2394
      }
2395

	
2396
      AuxGraph aux_graph(_graph);
2397
      typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
2398
        aux_embedding(aux_graph);
2399

	
2400
      {
2401

	
2402
        typename Graph::template EdgeMap<typename AuxGraph::Edge>
2403
          ref(_graph);
2404

	
2405
        for (EdgeIt e(_graph); e != INVALID; ++e) {
2406
          ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
2407
        }
2408

	
2409
        for (EdgeIt e(_graph); e != INVALID; ++e) {
2410
          Arc ee = embedding[_graph.direct(e, true)];
2411
          aux_embedding[aux_graph.direct(ref[e], true)] =
2412
            aux_graph.direct(ref[ee], _graph.direction(ee));
2413
          ee = embedding[_graph.direct(e, false)];
2414
          aux_embedding[aux_graph.direct(ref[e], false)] =
2415
            aux_graph.direct(ref[ee], _graph.direction(ee));
2416
        }
2417
      }
2418
      _planarity_bits::makeConnected(aux_graph, aux_embedding);
2419
      _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
2420
      _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
2421
      drawing(aux_graph, aux_embedding, _point_map);
2422
    }
2423

	
2424
    /// \brief The coordinate of the given node
2425
    ///
2426
    /// The coordinate of the given node.
2427
    Point operator[](const Node& node) const {
2428
      return _point_map[node];
2429
    }
2430

	
2431
    /// \brief Returns the grid embedding in a \e NodeMap.
2432
    ///
2433
    /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> .
2434
    const PointMap& coords() const {
2435
      return _point_map;
2436
    }
2437

	
2438
  private:
2439

	
2440
    const Graph& _graph;
2441
    PointMap _point_map;
2442

	
2443
  };
2444

	
2445
  namespace _planarity_bits {
2446

	
2447
    template <typename ColorMap>
2448
    class KempeFilter {
2449
    public:
2450
      typedef typename ColorMap::Key Key;
2451
      typedef bool Value;
2452

	
2453
      KempeFilter(const ColorMap& color_map,
2454
                  const typename ColorMap::Value& first,
2455
                  const typename ColorMap::Value& second)
2456
        : _color_map(color_map), _first(first), _second(second) {}
2457

	
2458
      Value operator[](const Key& key) const {
2459
        return _color_map[key] == _first || _color_map[key] == _second;
2460
      }
2461

	
2462
    private:
2463
      const ColorMap& _color_map;
2464
      typename ColorMap::Value _first, _second;
2465
    };
2466
  }
2467

	
2468
  /// \ingroup planar
2469
  ///
2470
  /// \brief Coloring planar graphs
2471
  ///
2472
  /// The graph coloring problem is the coloring of the graph nodes
2473
  /// that there are not adjacent nodes with the same color. The
2474
  /// planar graphs can be always colored with four colors, it is
2475
  /// proved by Appel and Haken and their proofs provide a quadratic
2476
  /// time algorithm for four coloring, but it could not be used to
2477
  /// implement efficient algorithm. The five and six coloring can be
2478
  /// made in linear time, but in this class the five coloring has
2479
  /// quadratic worst case time complexity. The two coloring (if
2480
  /// possible) is solvable with a graph search algorithm and it is
2481
  /// implemented in \ref bipartitePartitions() function in LEMON. To
2482
  /// decide whether the planar graph is three colorable is
2483
  /// NP-complete.
2484
  ///
2485
  /// This class contains member functions for calculate colorings
2486
  /// with five and six colors. The six coloring algorithm is a simple
2487
  /// greedy coloring on the backward minimum outgoing order of nodes.
2488
  /// This order can be computed as in each phase the node with least
2489
  /// outgoing arcs to unprocessed nodes is chosen. This order
2490
  /// guarantees that when a node is chosen for coloring it has at
2491
  /// most five already colored adjacents. The five coloring algorithm
2492
  /// use the same method, but if the greedy approach fails to color
2493
  /// with five colors, i.e. the node has five already different
2494
  /// colored neighbours, it swaps the colors in one of the connected
2495
  /// two colored sets with the Kempe recoloring method.
2496
  template <typename Graph>
2497
  class PlanarColoring {
2498
  public:
2499

	
2500
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2501

	
2502
    /// \brief The map type for store color indexes
2503
    typedef typename Graph::template NodeMap<int> IndexMap;
2504
    /// \brief The map type for store colors
2505
    typedef ComposeMap<Palette, IndexMap> ColorMap;
2506

	
2507
    /// \brief Constructor
2508
    ///
2509
    /// Constructor
2510
    /// \pre The graph should be simple, i.e. loop and parallel arc free.
2511
    PlanarColoring(const Graph& graph)
2512
      : _graph(graph), _color_map(graph), _palette(0) {
2513
      _palette.add(Color(1,0,0));
2514
      _palette.add(Color(0,1,0));
2515
      _palette.add(Color(0,0,1));
2516
      _palette.add(Color(1,1,0));
2517
      _palette.add(Color(1,0,1));
2518
      _palette.add(Color(0,1,1));
2519
    }
2520

	
2521
    /// \brief Returns the \e NodeMap of color indexes
2522
    ///
2523
    /// Returns the \e NodeMap of color indexes. The values are in the
2524
    /// range \c [0..4] or \c [0..5] according to the coloring method.
2525
    IndexMap colorIndexMap() const {
2526
      return _color_map;
2527
    }
2528

	
2529
    /// \brief Returns the \e NodeMap of colors
2530
    ///
2531
    /// Returns the \e NodeMap of colors. The values are five or six
2532
    /// distinct \ref lemon::Color "colors".
2533
    ColorMap colorMap() const {
2534
      return composeMap(_palette, _color_map);
2535
    }
2536

	
2537
    /// \brief Returns the color index of the node
2538
    ///
2539
    /// Returns the color index of the node. The values are in the
2540
    /// range \c [0..4] or \c [0..5] according to the coloring method.
2541
    int colorIndex(const Node& node) const {
2542
      return _color_map[node];
2543
    }
2544

	
2545
    /// \brief Returns the color of the node
2546
    ///
2547
    /// Returns the color of the node. The values are five or six
2548
    /// distinct \ref lemon::Color "colors".
2549
    Color color(const Node& node) const {
2550
      return _palette[_color_map[node]];
2551
    }
2552

	
2553

	
2554
    /// \brief Calculates a coloring with at most six colors
2555
    ///
2556
    /// This function calculates a coloring with at most six colors. The time
2557
    /// complexity of this variant is linear in the size of the graph.
2558
    /// \return %True when the algorithm could color the graph with six color.
2559
    /// If the algorithm fails, then the graph could not be planar.
2560
    /// \note This function can return true if the graph is not
2561
    /// planar but it can be colored with 6 colors.
2562
    bool runSixColoring() {
2563

	
2564
      typename Graph::template NodeMap<int> heap_index(_graph, -1);
2565
      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
2566

	
2567
      for (NodeIt n(_graph); n != INVALID; ++n) {
2568
        _color_map[n] = -2;
2569
        heap.push(n, countOutArcs(_graph, n));
2570
      }
2571

	
2572
      std::vector<Node> order;
2573

	
2574
      while (!heap.empty()) {
2575
        Node n = heap.top();
2576
        heap.pop();
2577
        _color_map[n] = -1;
2578
        order.push_back(n);
2579
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2580
          Node t = _graph.runningNode(e);
2581
          if (_color_map[t] == -2) {
2582
            heap.decrease(t, heap[t] - 1);
2583
          }
2584
        }
2585
      }
2586

	
2587
      for (int i = order.size() - 1; i >= 0; --i) {
2588
        std::vector<bool> forbidden(6, false);
2589
        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
2590
          Node t = _graph.runningNode(e);
2591
          if (_color_map[t] != -1) {
2592
            forbidden[_color_map[t]] = true;
2593
          }
2594
        }
2595
               for (int k = 0; k < 6; ++k) {
2596
          if (!forbidden[k]) {
2597
            _color_map[order[i]] = k;
2598
            break;
2599
          }
2600
        }
2601
        if (_color_map[order[i]] == -1) {
2602
          return false;
2603
        }
2604
      }
2605
      return true;
2606
    }
2607

	
2608
  private:
2609

	
2610
    bool recolor(const Node& u, const Node& v) {
2611
      int ucolor = _color_map[u];
2612
      int vcolor = _color_map[v];
2613
      typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
2614
      KempeFilter filter(_color_map, ucolor, vcolor);
2615

	
2616
      typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
2617
      KempeGraph kempe_graph(_graph, filter);
2618

	
2619
      std::vector<Node> comp;
2620
      Bfs<KempeGraph> bfs(kempe_graph);
2621
      bfs.init();
2622
      bfs.addSource(u);
2623
      while (!bfs.emptyQueue()) {
2624
        Node n = bfs.nextNode();
2625
        if (n == v) return false;
2626
        comp.push_back(n);
2627
        bfs.processNextNode();
2628
      }
2629

	
2630
      int scolor = ucolor + vcolor;
2631
      for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
2632
        _color_map[comp[i]] = scolor - _color_map[comp[i]];
2633
      }
2634

	
2635
      return true;
2636
    }
2637

	
2638
    template <typename EmbeddingMap>
2639
    void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
2640
      std::vector<Node> nodes;
2641
      nodes.reserve(4);
2642

	
2643
      for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
2644
        Node t = _graph.target(e);
2645
        if (_color_map[t] != -1) {
2646
          nodes.push_back(t);
2647
          if (nodes.size() == 4) break;
2648
        }
2649
      }
2650

	
2651
      int color = _color_map[nodes[0]];
2652
      if (recolor(nodes[0], nodes[2])) {
2653
        _color_map[node] = color;
2654
      } else {
2655
        color = _color_map[nodes[1]];
2656
        recolor(nodes[1], nodes[3]);
2657
        _color_map[node] = color;
2658
      }
2659
    }
2660

	
2661
  public:
2662

	
2663
    /// \brief Calculates a coloring with at most five colors
2664
    ///
2665
    /// This function calculates a coloring with at most five
2666
    /// colors. The worst case time complexity of this variant is
2667
    /// quadratic in the size of the graph.
2668
    template <typename EmbeddingMap>
2669
    void runFiveColoring(const EmbeddingMap& embedding) {
2670

	
2671
      typename Graph::template NodeMap<int> heap_index(_graph, -1);
2672
      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
2673

	
2674
      for (NodeIt n(_graph); n != INVALID; ++n) {
2675
        _color_map[n] = -2;
2676
        heap.push(n, countOutArcs(_graph, n));
2677
      }
2678

	
2679
      std::vector<Node> order;
2680

	
2681
      while (!heap.empty()) {
2682
        Node n = heap.top();
2683
        heap.pop();
2684
        _color_map[n] = -1;
2685
        order.push_back(n);
2686
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2687
          Node t = _graph.runningNode(e);
2688
          if (_color_map[t] == -2) {
2689
            heap.decrease(t, heap[t] - 1);
2690
          }
2691
        }
2692
      }
2693

	
2694
      for (int i = order.size() - 1; i >= 0; --i) {
2695
        std::vector<bool> forbidden(5, false);
2696
        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
2697
          Node t = _graph.runningNode(e);
2698
          if (_color_map[t] != -1) {
2699
            forbidden[_color_map[t]] = true;
2700
          }
2701
        }
2702
        for (int k = 0; k < 5; ++k) {
2703
          if (!forbidden[k]) {
2704
            _color_map[order[i]] = k;
2705
            break;
2706
          }
2707
        }
2708
        if (_color_map[order[i]] == -1) {
2709
          kempeRecoloring(order[i], embedding);
2710
        }
2711
      }
2712
    }
2713

	
2714
    /// \brief Calculates a coloring with at most five colors
2715
    ///
2716
    /// This function calculates a coloring with at most five
2717
    /// colors. The worst case time complexity of this variant is
2718
    /// quadratic in the size of the graph.
2719
    /// \return %True when the graph is planar.
2720
    bool runFiveColoring() {
2721
      PlanarEmbedding<Graph> pe(_graph);
2722
      if (!pe.run()) return false;
2723

	
2724
      runFiveColoring(pe.embeddingMap());
2725
      return true;
2726
    }
2727

	
2728
  private:
2729

	
2730
    const Graph& _graph;
2731
    IndexMap _color_map;
2732
    Palette _palette;
2733
  };
2734

	
2735
}
2736

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

	
19
#include <iostream>
20

	
21
#include <lemon/planarity.h>
22

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

	
28
#include "test_tools.h"
29

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

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

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

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

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

	
114

	
115

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
231
int main() {
232

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

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

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

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

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

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

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

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

	
261
  return 0;
262
}
Ignore white space 6 line context
... ...
@@ -112,2 +112,3 @@
112 112
	lemon/path.h \
113
	lemon/planarity.h \
113 114
	lemon/preflow.h \
Ignore white space 6 line context
... ...
@@ -86,8 +86,8 @@
86 86

	
87
      MapIt() {}
87
      MapIt() : map(NULL) {}
88 88

	
89
      MapIt(Invalid i) : Parent(i) { }
89
      MapIt(Invalid i) : Parent(i), map(NULL) {}
90 90

	
91
      explicit MapIt(Map& _map) : map(_map) {
92
        map.notifier()->first(*this);
91
      explicit MapIt(Map& _map) : map(&_map) {
92
        map->notifier()->first(*this);
93 93
      }
... ...
@@ -95,6 +95,6 @@
95 95
      MapIt(const Map& _map, const Item& item)
96
        : Parent(item), map(_map) {}
96
        : Parent(item), map(&_map) {}
97 97

	
98 98
      MapIt& operator++() {
99
        map.notifier()->next(*this);
99
        map->notifier()->next(*this);
100 100
        return *this;
... ...
@@ -103,3 +103,3 @@
103 103
      typename MapTraits<Map>::ConstReturnValue operator*() const {
104
        return map[*this];
104
        return (*map)[*this];
105 105
      }
... ...
@@ -107,3 +107,3 @@
107 107
      typename MapTraits<Map>::ReturnValue operator*() {
108
        return map[*this];
108
        return (*map)[*this];
109 109
      }
... ...
@@ -111,3 +111,3 @@
111 111
      void set(const Value& value) {
112
        map.set(*this, value);
112
        map->set(*this, value);
113 113
      }
... ...
@@ -115,3 +115,3 @@
115 115
    protected:
116
      Map& map;
116
      Map* map;
117 117

	
... ...
@@ -126,8 +126,8 @@
126 126

	
127
      ConstMapIt() {}
127
      ConstMapIt() : map(NULL) {}
128 128

	
129
      ConstMapIt(Invalid i) : Parent(i) { }
129
      ConstMapIt(Invalid i) : Parent(i), map(NULL) {}
130 130

	
131
      explicit ConstMapIt(Map& _map) : map(_map) {
132
        map.notifier()->first(*this);
131
      explicit ConstMapIt(Map& _map) : map(&_map) {
132
        map->notifier()->first(*this);
133 133
      }
... ...
@@ -138,3 +138,3 @@
138 138
      ConstMapIt& operator++() {
139
        map.notifier()->next(*this);
139
        map->notifier()->next(*this);
140 140
        return *this;
... ...
@@ -147,3 +147,3 @@
147 147
    protected:
148
      const Map& map;
148
      const Map* map;
149 149
    };
... ...
@@ -154,9 +154,9 @@
154 154
    public:
155
      ItemIt() : map(NULL) {}
155 156

	
156
      ItemIt() {}
157 157

	
158
      ItemIt(Invalid i) : Parent(i) { }
158
      ItemIt(Invalid i) : Parent(i), map(NULL) {}
159 159

	
160
      explicit ItemIt(Map& _map) : map(_map) {
161
        map.notifier()->first(*this);
160
      explicit ItemIt(Map& _map) : map(&_map) {
161
        map->notifier()->first(*this);
162 162
      }
... ...
@@ -164,6 +164,6 @@
164 164
      ItemIt(const Map& _map, const Item& item)
165
        : Parent(item), map(_map) {}
165
        : Parent(item), map(&_map) {}
166 166

	
167 167
      ItemIt& operator++() {
168
        map.notifier()->next(*this);
168
        map->notifier()->next(*this);
169 169
        return *this;
... ...
@@ -172,3 +172,3 @@
172 172
    protected:
173
      const Map& map;
173
      const Map* map;
174 174

	
... ...
@@ -233,8 +233,8 @@
233 233

	
234
      MapIt() {}
234
      MapIt() : map(NULL) {}
235 235

	
236
      MapIt(Invalid i) : Parent(i) { }
236
      MapIt(Invalid i) : Parent(i), map(NULL) { }
237 237

	
238
      explicit MapIt(Map& _map) : map(_map) {
239
        map.graph.first(*this);
238
      explicit MapIt(Map& _map) : map(&_map) {
239
        map->graph.first(*this);
240 240
      }
... ...
@@ -242,6 +242,6 @@
242 242
      MapIt(const Map& _map, const Item& item)
243
        : Parent(item), map(_map) {}
243
        : Parent(item), map(&_map) {}
244 244

	
245 245
      MapIt& operator++() {
246
        map.graph.next(*this);
246
        map->graph.next(*this);
247 247
        return *this;
... ...
@@ -250,3 +250,3 @@
250 250
      typename MapTraits<Map>::ConstReturnValue operator*() const {
251
        return map[*this];
251
        return (*map)[*this];
252 252
      }
... ...
@@ -254,3 +254,3 @@
254 254
      typename MapTraits<Map>::ReturnValue operator*() {
255
        return map[*this];
255
        return (*map)[*this];
256 256
      }
... ...
@@ -258,3 +258,3 @@
258 258
      void set(const Value& value) {
259
        map.set(*this, value);
259
        map->set(*this, value);
260 260
      }
... ...
@@ -262,3 +262,3 @@
262 262
    protected:
263
      Map& map;
263
      Map* map;
264 264

	
... ...
@@ -273,8 +273,8 @@
273 273

	
274
      ConstMapIt() {}
274
      ConstMapIt() : map(NULL) {}
275 275

	
276
      ConstMapIt(Invalid i) : Parent(i) { }
276
      ConstMapIt(Invalid i) : Parent(i), map(NULL) { }
277 277

	
278
      explicit ConstMapIt(Map& _map) : map(_map) {
279
        map.graph.first(*this);
278
      explicit ConstMapIt(Map& _map) : map(&_map) {
279
        map->graph.first(*this);
280 280
      }
... ...
@@ -282,6 +282,6 @@
282 282
      ConstMapIt(const Map& _map, const Item& item)
283
        : Parent(item), map(_map) {}
283
        : Parent(item), map(&_map) {}
284 284

	
285 285
      ConstMapIt& operator++() {
286
        map.graph.next(*this);
286
        map->graph.next(*this);
287 287
        return *this;
... ...
@@ -290,3 +290,3 @@
290 290
      typename MapTraits<Map>::ConstReturnValue operator*() const {
291
        return map[*this];
291
        return (*map)[*this];
292 292
      }
... ...
@@ -294,3 +294,3 @@
294 294
    protected:
295
      const Map& map;
295
      const Map* map;
296 296
    };
... ...
@@ -301,9 +301,9 @@
301 301
    public:
302
      ItemIt() : map(NULL) {}
302 303

	
303
      ItemIt() {}
304 304

	
305
      ItemIt(Invalid i) : Parent(i) { }
305
      ItemIt(Invalid i) : Parent(i), map(NULL) { }
306 306

	
307
      explicit ItemIt(Map& _map) : map(_map) {
308
        map.graph.first(*this);
307
      explicit ItemIt(Map& _map) : map(&_map) {
308
        map->graph.first(*this);
309 309
      }
... ...
@@ -311,6 +311,6 @@
311 311
      ItemIt(const Map& _map, const Item& item)
312
        : Parent(item), map(_map) {}
312
        : Parent(item), map(&_map) {}
313 313

	
314 314
      ItemIt& operator++() {
315
        map.graph.next(*this);
315
        map->graph.next(*this);
316 316
        return *this;
... ...
@@ -319,3 +319,3 @@
319 319
    protected:
320
      const Map& map;
320
      const Map* map;
321 321

	
Ignore white space 6 line context
... ...
@@ -741,3 +741,3 @@
741 741
      items.clear();
742
      classes.clear;
742
      classes.clear();
743 743
      firstClass = firstFreeClass = firstFreeItem = -1;
Show white space 6 line context
... ...
@@ -36,2 +36,3 @@
36 36
  path_test
37
  planarity_test
37 38
  preflow_test
Ignore white space 6 line context
... ...
@@ -38,2 +38,3 @@
38 38
	test/path_test \
39
	test/planarity_test \
39 40
	test/preflow_test \
... ...
@@ -87,2 +88,3 @@
87 88
test_path_test_SOURCES = test/path_test.cc
89
test_planarity_test_SOURCES = test/planarity_test.cc
88 90
test_preflow_test_SOURCES = test/preflow_test.cc
0 comments (0 inline)