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 ↑
Show white space 24 line context
... ...
@@ -509,48 +509,49 @@
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:
... ...
@@ -582,40 +583,44 @@
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

	
... ...
@@ -690,48 +695,50 @@
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;
... ...
@@ -2050,47 +2057,50 @@
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);
... ...
@@ -2357,42 +2367,43 @@
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);
... ...
@@ -2414,32 +2425,33 @@
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 {
... ...
@@ -2461,113 +2473,116 @@
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

	
... ...
@@ -2651,29 +2666,32 @@
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;
... ...
@@ -2702,30 +2720,30 @@
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;
0 comments (0 inline)