gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Doc improvements for planarity related tools (#62)
0 1 0
default
1 file changed with 94 insertions and 76 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -473,301 +473,308 @@
473 473

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

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

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

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

	
491 491
      }
492 492

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

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

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

	
504 504
        return false;
505 505
      }
506 506

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

	
512 512
    };
513 513

	
514 514
  }
515 515

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

	
530 530
  /// \ingroup planar
531 531
  ///
532 532
  /// \brief Planar embedding of an undirected simple graph
533 533
  ///
534 534
  /// This class implements the Boyer-Myrvold algorithm for planar
535
  /// embedding of an undirected graph. The planar embedding is an
535
  /// embedding of an undirected simple graph. The planar embedding is an
536 536
  /// ordering of the outgoing edges of the nodes, which is a possible
537 537
  /// configuration to draw the graph in the plane. If there is not
538
  /// 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.
538
  /// such ordering then the graph contains a K<sub>5</sub> (full graph
539
  /// with 5 nodes) or a K<sub>3,3</sub> (complete bipartite graph on
540
  /// 3 Red and 3 Blue nodes) subdivision.
541 541
  ///
542 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$.
543
  /// Kuratowski subdivision. The running time of the algorithm is O(n).
544
  ///
545
  /// \see PlanarDrawing, checkPlanarity()
545 546
  template <typename Graph>
546 547
  class PlanarEmbedding {
547 548
  private:
548 549

	
549 550
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
550 551

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

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

	
556 557
  private:
557 558

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

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

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

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

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

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

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

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

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

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

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

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

	
592 593
  public:
593 594

	
594
    /// \brief The map for store of embedding
595
    /// \brief The map type for storing the embedding
596
    ///
597
    /// The map type for storing the embedding.
598
    /// \see embeddingMap()
595 599
    typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
596 600

	
597 601
    /// \brief Constructor
598 602
    ///
599
    /// \note The graph should be simple, i.e. parallel and loop arc
600
    /// free.
603
    /// Constructor.
604
    /// \pre The graph must be simple, i.e. it should not
605
    /// contain parallel or loop arcs.
601 606
    PlanarEmbedding(const Graph& graph)
602 607
      : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
603 608

	
604
    /// \brief Runs the algorithm.
609
    /// \brief Run the algorithm.
605 610
    ///
606
    /// Runs the algorithm.
607
    /// \param kuratowski If the parameter is false, then the
611
    /// This function runs the algorithm.
612
    /// \param kuratowski If this parameter is set to \c false, then the
608 613
    /// algorithm does not compute a Kuratowski subdivision.
609
    ///\return %True when the graph is planar.
614
    /// \return \c true if the graph is planar.
610 615
    bool run(bool kuratowski = true) {
611 616
      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
612 617

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

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

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

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

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

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

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

	
634 639
      MergeRoots merge_roots(_graph);
635 640

	
636 641
      ArcLists arc_lists(_graph);
637 642

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

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

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

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

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

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

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

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

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

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

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

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

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

	
699 704
      return true;
700 705
    }
701 706

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

	
711
    /// \brief Gives back the calculated embedding map
716
    /// \brief Give back the calculated embedding map
712 717
    ///
713
    /// The returned map contains the successor of each arc in the
714
    /// graph.
718
    /// This function gives back the calculated embedding map, which
719
    /// contains the successor of each arc in the cyclic order of the
720
    /// outgoing arcs of its source node.
715 721
    const EmbeddingMap& embeddingMap() const {
716 722
      return _embedding;
717 723
    }
718 724

	
719
    /// \brief Gives back true if the undirected arc is in the
720
    /// kuratowski subdivision
725
    /// \brief Give back \c true if the given edge is in the Kuratowski
726
    /// subdivision
721 727
    ///
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) {
728
    /// This function gives back \c true if the given edge is in the found
729
    /// Kuratowski subdivision.
730
    /// \pre The \c run() function must be called with \c true parameter
731
    /// before using this function.
732
    bool kuratowski(const Edge& edge) const {
726 733
      return _kuratowski[edge];
727 734
    }
728 735

	
729 736
  private:
730 737

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

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

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

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

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

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

	
770 777
      int na, nb;
771 778
      bool da, db;
772 779

	
773 780
      na = nb = order_map[node];
... ...
@@ -2014,119 +2021,122 @@
2014 2021
          embedding[graph.oppositeArc(ce)] = oppe;
2015 2022

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

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

	
2026 2033
            pn = n;
2027 2034

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

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

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

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

	
2044 2051
            pn = n;
2045 2052

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

	
2049 2056
          }
2050 2057
          embedding[graph.oppositeArc(e)] = pn;
2051 2058
        }
2052 2059
      }
2053 2060
    }
2054 2061

	
2055 2062
  }
2056 2063

	
2057 2064
  /// \ingroup planar
2058 2065
  ///
2059 2066
  /// \brief Schnyder's planar drawing algorithm
2060 2067
  ///
2061 2068
  /// 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
2069
  /// in the plane. These coordinates satisfy that if the edges are
2070
  /// represented with straight lines, then they will not intersect
2064 2071
  /// each other.
2065 2072
  ///
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.
2073
  /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid,
2074
  /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square.
2068 2075
  /// The time complexity of the algorithm is O(n).
2076
  ///
2077
  /// \see PlanarEmbedding
2069 2078
  template <typename Graph>
2070 2079
  class PlanarDrawing {
2071 2080
  public:
2072 2081

	
2073 2082
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2074 2083

	
2075
    /// \brief The point type for store coordinates
2084
    /// \brief The point type for storing coordinates
2076 2085
    typedef dim2::Point<int> Point;
2077
    /// \brief The map type for store coordinates
2086
    /// \brief The map type for storing the coordinates of the nodes
2078 2087
    typedef typename Graph::template NodeMap<Point> PointMap;
2079 2088

	
2080 2089

	
2081 2090
    /// \brief Constructor
2082 2091
    ///
2083 2092
    /// Constructor
2084
    /// \pre The graph should be simple, i.e. loop and parallel arc free.
2093
    /// \pre The graph must be simple, i.e. it should not
2094
    /// contain parallel or loop arcs.
2085 2095
    PlanarDrawing(const Graph& graph)
2086 2096
      : _graph(graph), _point_map(graph) {}
2087 2097

	
2088 2098
  private:
2089 2099

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

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

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

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

	
2103 2113
        e = next[e];
2104 2114
        while (e != l) {
2105 2115
          prev[e] = p;
2106 2116
          p = e;
2107 2117
          e = next[e];
2108 2118
        }
2109 2119
        prev[e] = p;
2110 2120
      }
2111 2121

	
2112 2122
      Node anode, bnode, cnode;
2113 2123

	
2114 2124
      {
2115 2125
        Arc e = ArcIt(graph);
2116 2126
        anode = graph.source(e);
2117 2127
        bnode = graph.target(e);
2118 2128
        cnode = graph.target(next[graph.oppositeArc(e)]);
2119 2129
      }
2120 2130

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

	
2124 2134
      conn[anode] = conn[bnode] = -2;
2125 2135
      {
2126 2136
        for (OutArcIt e(graph, anode); e != INVALID; ++e) {
2127 2137
          Node m = graph.target(e);
2128 2138
          if (conn[m] == -1) {
2129 2139
            conn[m] = 1;
2130 2140
          }
2131 2141
        }
2132 2142
        conn[cnode] = 2;
... ...
@@ -2321,289 +2331,294 @@
2321 2331
          if (bpred[graph.target(e)] == n) {
2322 2332
            btree[n] += btree[graph.target(e)];
2323 2333
          }
2324 2334
        }
2325 2335
      }
2326 2336

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

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

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

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

	
2365 2375
    }
2366 2376

	
2367 2377
  public:
2368 2378

	
2369
    /// \brief Calculates the node positions
2379
    /// \brief Calculate the node positions
2370 2380
    ///
2371
    /// This function calculates the node positions.
2372
    /// \return %True if the graph is planar.
2381
    /// This function calculates the node positions on the plane.
2382
    /// \return \c true if the graph is planar.
2373 2383
    bool run() {
2374 2384
      PlanarEmbedding<Graph> pe(_graph);
2375 2385
      if (!pe.run()) return false;
2376 2386

	
2377 2387
      run(pe);
2378 2388
      return true;
2379 2389
    }
2380 2390

	
2381
    /// \brief Calculates the node positions according to a
2391
    /// \brief Calculate the node positions according to a
2382 2392
    /// combinatorical embedding
2383 2393
    ///
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.
2394
    /// This function calculates the node positions on the plane.
2395
    /// The given \c embedding map should contain a valid combinatorical
2396
    /// embedding, i.e. a valid cyclic order of the arcs.
2397
    /// It can be computed using PlanarEmbedding.
2387 2398
    template <typename EmbeddingMap>
2388 2399
    void run(const EmbeddingMap& embedding) {
2389 2400
      typedef SmartEdgeSet<Graph> AuxGraph;
2390 2401

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

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

	
2400 2411
      {
2401 2412

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

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

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

	
2424 2435
    /// \brief The coordinate of the given node
2425 2436
    ///
2426
    /// The coordinate of the given node.
2437
    /// This function returns the coordinate of the given node.
2427 2438
    Point operator[](const Node& node) const {
2428 2439
      return _point_map[node];
2429 2440
    }
2430 2441

	
2431
    /// \brief Returns the grid embedding in a \e NodeMap.
2442
    /// \brief Return the grid embedding in a node map
2432 2443
    ///
2433
    /// Returns the grid embedding in a \e NodeMap of \c dim2::Point<int> .
2444
    /// This function returns the grid embedding in a node map of
2445
    /// \c dim2::Point<int> coordinates.
2434 2446
    const PointMap& coords() const {
2435 2447
      return _point_map;
2436 2448
    }
2437 2449

	
2438 2450
  private:
2439 2451

	
2440 2452
    const Graph& _graph;
2441 2453
    PointMap _point_map;
2442 2454

	
2443 2455
  };
2444 2456

	
2445 2457
  namespace _planarity_bits {
2446 2458

	
2447 2459
    template <typename ColorMap>
2448 2460
    class KempeFilter {
2449 2461
    public:
2450 2462
      typedef typename ColorMap::Key Key;
2451 2463
      typedef bool Value;
2452 2464

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

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

	
2462 2474
    private:
2463 2475
      const ColorMap& _color_map;
2464 2476
      typename ColorMap::Value _first, _second;
2465 2477
    };
2466 2478
  }
2467 2479

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

	
2500 2511
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2501 2512

	
2502
    /// \brief The map type for store color indexes
2513
    /// \brief The map type for storing color indices
2503 2514
    typedef typename Graph::template NodeMap<int> IndexMap;
2504
    /// \brief The map type for store colors
2515
    /// \brief The map type for storing colors
2516
    ///
2517
    /// The map type for storing colors.
2518
    /// \see Palette, Color
2505 2519
    typedef ComposeMap<Palette, IndexMap> ColorMap;
2506 2520

	
2507 2521
    /// \brief Constructor
2508 2522
    ///
2509
    /// Constructor
2510
    /// \pre The graph should be simple, i.e. loop and parallel arc free.
2523
    /// Constructor.
2524
    /// \pre The graph must be simple, i.e. it should not
2525
    /// contain parallel or loop arcs.
2511 2526
    PlanarColoring(const Graph& graph)
2512 2527
      : _graph(graph), _color_map(graph), _palette(0) {
2513 2528
      _palette.add(Color(1,0,0));
2514 2529
      _palette.add(Color(0,1,0));
2515 2530
      _palette.add(Color(0,0,1));
2516 2531
      _palette.add(Color(1,1,0));
2517 2532
      _palette.add(Color(1,0,1));
2518 2533
      _palette.add(Color(0,1,1));
2519 2534
    }
2520 2535

	
2521
    /// \brief Returns the \e NodeMap of color indexes
2536
    /// \brief Return the node map of color indices
2522 2537
    ///
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.
2538
    /// This function returns the node map of color indices. The values are
2539
    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
2525 2540
    IndexMap colorIndexMap() const {
2526 2541
      return _color_map;
2527 2542
    }
2528 2543

	
2529
    /// \brief Returns the \e NodeMap of colors
2544
    /// \brief Return the node map of colors
2530 2545
    ///
2531
    /// Returns the \e NodeMap of colors. The values are five or six
2532
    /// distinct \ref lemon::Color "colors".
2546
    /// This function returns the node map of colors. The values are among
2547
    /// five or six distinct \ref lemon::Color "colors".
2533 2548
    ColorMap colorMap() const {
2534 2549
      return composeMap(_palette, _color_map);
2535 2550
    }
2536 2551

	
2537
    /// \brief Returns the color index of the node
2552
    /// \brief Return the color index of the node
2538 2553
    ///
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.
2554
    /// This function returns the color index of the given node. The value is
2555
    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
2541 2556
    int colorIndex(const Node& node) const {
2542 2557
      return _color_map[node];
2543 2558
    }
2544 2559

	
2545
    /// \brief Returns the color of the node
2560
    /// \brief Return the color of the node
2546 2561
    ///
2547
    /// Returns the color of the node. The values are five or six
2548
    /// distinct \ref lemon::Color "colors".
2562
    /// This function returns the color of the given node. The value is among
2563
    /// five or six distinct \ref lemon::Color "colors".
2549 2564
    Color color(const Node& node) const {
2550 2565
      return _palette[_color_map[node]];
2551 2566
    }
2552 2567

	
2553 2568

	
2554
    /// \brief Calculates a coloring with at most six colors
2569
    /// \brief Calculate a coloring with at most six colors
2555 2570
    ///
2556 2571
    /// This function calculates a coloring with at most six colors. The time
2557 2572
    /// 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.
2573
    /// \return \c true if the algorithm could color the graph with six colors.
2574
    /// If the algorithm fails, then the graph is not planar.
2575
    /// \note This function can return \c true if the graph is not
2576
    /// planar, but it can be colored with at most six colors.
2562 2577
    bool runSixColoring() {
2563 2578

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

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

	
2572 2587
      std::vector<Node> order;
2573 2588

	
2574 2589
      while (!heap.empty()) {
2575 2590
        Node n = heap.top();
2576 2591
        heap.pop();
2577 2592
        _color_map[n] = -1;
2578 2593
        order.push_back(n);
2579 2594
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2580 2595
          Node t = _graph.runningNode(e);
2581 2596
          if (_color_map[t] == -2) {
2582 2597
            heap.decrease(t, heap[t] - 1);
2583 2598
          }
2584 2599
        }
2585 2600
      }
2586 2601

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

	
2608 2623
  private:
2609 2624

	
... ...
@@ -2615,123 +2630,126 @@
2615 2630

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

	
2619 2634
      std::vector<Node> comp;
2620 2635
      Bfs<KempeGraph> bfs(kempe_graph);
2621 2636
      bfs.init();
2622 2637
      bfs.addSource(u);
2623 2638
      while (!bfs.emptyQueue()) {
2624 2639
        Node n = bfs.nextNode();
2625 2640
        if (n == v) return false;
2626 2641
        comp.push_back(n);
2627 2642
        bfs.processNextNode();
2628 2643
      }
2629 2644

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

	
2635 2650
      return true;
2636 2651
    }
2637 2652

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

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

	
2651 2666
      int color = _color_map[nodes[0]];
2652 2667
      if (recolor(nodes[0], nodes[2])) {
2653 2668
        _color_map[node] = color;
2654 2669
      } else {
2655 2670
        color = _color_map[nodes[1]];
2656 2671
        recolor(nodes[1], nodes[3]);
2657 2672
        _color_map[node] = color;
2658 2673
      }
2659 2674
    }
2660 2675

	
2661 2676
  public:
2662 2677

	
2663
    /// \brief Calculates a coloring with at most five colors
2678
    /// \brief Calculate a coloring with at most five colors
2664 2679
    ///
2665 2680
    /// This function calculates a coloring with at most five
2666 2681
    /// colors. The worst case time complexity of this variant is
2667 2682
    /// quadratic in the size of the graph.
2683
    /// \param embedding This map should contain a valid combinatorical
2684
    /// embedding, i.e. a valid cyclic order of the arcs.
2685
    /// It can be computed using PlanarEmbedding.
2668 2686
    template <typename EmbeddingMap>
2669 2687
    void runFiveColoring(const EmbeddingMap& embedding) {
2670 2688

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

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

	
2679 2697
      std::vector<Node> order;
2680 2698

	
2681 2699
      while (!heap.empty()) {
2682 2700
        Node n = heap.top();
2683 2701
        heap.pop();
2684 2702
        _color_map[n] = -1;
2685 2703
        order.push_back(n);
2686 2704
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2687 2705
          Node t = _graph.runningNode(e);
2688 2706
          if (_color_map[t] == -2) {
2689 2707
            heap.decrease(t, heap[t] - 1);
2690 2708
          }
2691 2709
        }
2692 2710
      }
2693 2711

	
2694 2712
      for (int i = order.size() - 1; i >= 0; --i) {
2695 2713
        std::vector<bool> forbidden(5, false);
2696 2714
        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
2697 2715
          Node t = _graph.runningNode(e);
2698 2716
          if (_color_map[t] != -1) {
2699 2717
            forbidden[_color_map[t]] = true;
2700 2718
          }
2701 2719
        }
2702 2720
        for (int k = 0; k < 5; ++k) {
2703 2721
          if (!forbidden[k]) {
2704 2722
            _color_map[order[i]] = k;
2705 2723
            break;
2706 2724
          }
2707 2725
        }
2708 2726
        if (_color_map[order[i]] == -1) {
2709 2727
          kempeRecoloring(order[i], embedding);
2710 2728
        }
2711 2729
      }
2712 2730
    }
2713 2731

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

	
2724 2742
      runFiveColoring(pe.embeddingMap());
2725 2743
      return true;
2726 2744
    }
2727 2745

	
2728 2746
  private:
2729 2747

	
2730 2748
    const Graph& _graph;
2731 2749
    IndexMap _color_map;
2732 2750
    Palette _palette;
2733 2751
  };
2734 2752

	
2735 2753
}
2736 2754

	
2737 2755
#endif
0 comments (0 inline)