lemon/planarity.h
changeset 2519 a7376f7ed899
parent 2500 9d9855af1de1
child 2553 bfced05fa852
equal deleted inserted replaced
3:bf328fe4f55f 4:4ac0ee126ee7
    18 #ifndef LEMON_PLANARITY_H
    18 #ifndef LEMON_PLANARITY_H
    19 #define LEMON_PLANARITY_H
    19 #define LEMON_PLANARITY_H
    20 
    20 
    21 /// \ingroup planar
    21 /// \ingroup planar
    22 /// \file
    22 /// \file
    23 /// \brief Planarity checking, embedding
    23 /// \brief Planarity checking, embedding, drawing and coloring
    24 
    24 
    25 #include <vector>
    25 #include <vector>
    26 #include <list>
    26 #include <list>
    27 
    27 
    28 #include <lemon/dfs.h>
    28 #include <lemon/dfs.h>
       
    29 #include <lemon/bfs.h>
    29 #include <lemon/radix_sort.h>
    30 #include <lemon/radix_sort.h>
    30 #include <lemon/maps.h>
    31 #include <lemon/maps.h>
    31 #include <lemon/path.h>
    32 #include <lemon/path.h>
    32 #include <lemon/iterable_maps.h>
    33 #include <lemon/iterable_maps.h>
    33 #include <lemon/edge_set.h>
    34 #include <lemon/edge_set.h>
       
    35 #include <lemon/bucket_heap.h>
       
    36 #include <lemon/ugraph_adaptor.h>
       
    37 #include <lemon/color.h>
    34 
    38 
    35 
    39 
    36 namespace lemon {
    40 namespace lemon {
    37 
    41 
    38   namespace _planarity_bits {
    42   namespace _planarity_bits {
  2436     const UGraph& _ugraph;
  2440     const UGraph& _ugraph;
  2437     PointMap _point_map;
  2441     PointMap _point_map;
  2438     
  2442     
  2439   };
  2443   };
  2440 
  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   /// such way that there are not adjacent nodes with the same
       
  2474   /// color. The planar graphs can be always colored with four colors,
       
  2475   /// it is proved by Appel and Haken and their proofs provide a
       
  2476   /// quadratic time algorithm for four coloring, but it could not be
       
  2477   /// used to implement efficient algorithm. The five and six coloring
       
  2478   /// can be made in linear time, but in this class the five coloring
       
  2479   /// has 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 such way, that in each phase the node
       
  2489   /// with least outgoing edges to unprocessed nodes is choosen. This
       
  2490   /// order guarantees that at the time of coloring of a node it has
       
  2491   /// at most five already colored adjacents. The five coloring
       
  2492   /// algorithm works in the same way, but if the greedy approach
       
  2493   /// fails to color with five color, ie. the node has five already
       
  2494   /// different colored neighbours, it swaps the colors in one
       
  2495   /// connected two colored set with the Kempe recoloring method.
       
  2496   template <typename UGraph>
       
  2497   class PlanarColoring {
       
  2498   public:
       
  2499 
       
  2500     UGRAPH_TYPEDEFS(typename UGraph);
       
  2501 
       
  2502     /// \brief The map type for store color indexes
       
  2503     typedef typename UGraph::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 ugraph should be simple, ie. loop and parallel edge free. 
       
  2511     PlanarColoring(const UGraph& ugraph)
       
  2512       : _ugraph(ugraph), _color_map(ugraph), _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 five coloring or 
       
  2525     /// six coloring.
       
  2526     IndexMap colorIndexMap() const {
       
  2527       return _color_map;
       
  2528     }
       
  2529 
       
  2530     /// \brief Returns the \e NodeMap of colors
       
  2531     ///
       
  2532     /// Returns the \e NodeMap of colors. The values are five or six
       
  2533     /// distinct \ref lemon::Color "colors".
       
  2534     ColorMap colorMap() const {
       
  2535       return composeMap(_palette, _color_map);
       
  2536     }
       
  2537 
       
  2538     /// \brief Returns the color index of the node
       
  2539     ///
       
  2540     /// Returns the color index of the node. The values are in the
       
  2541     /// range \c [0..4] or \c [0..5] according to the five coloring or
       
  2542     /// six coloring.
       
  2543     int colorIndex(const Node& node) const {
       
  2544       return _color_map[node];
       
  2545     }
       
  2546 
       
  2547     /// \brief Returns the color of the node
       
  2548     ///
       
  2549     /// Returns the color of the node. The values are five or six
       
  2550     /// distinct \ref lemon::Color "colors".
       
  2551     int color(const Node& node) const {
       
  2552       return _palette[_color_map[node]];
       
  2553     }
       
  2554     
       
  2555 
       
  2556     /// \brief Calculates a coloring with at most six colors
       
  2557     ///
       
  2558     /// This function calculates a coloring with at most six colors. The time
       
  2559     /// complexity of this variant is linear in the size of the graph.
       
  2560     /// \return %True when the algorithm could color the graph with six color.
       
  2561     /// If the algorithm fails, then the graph could not be planar.
       
  2562     bool runSixColoring() {
       
  2563       
       
  2564       typename UGraph::template NodeMap<int> heap_index(_ugraph, -1);
       
  2565       BucketHeap<typename UGraph::template NodeMap<int> > heap(heap_index);
       
  2566       
       
  2567       for (NodeIt n(_ugraph); n != INVALID; ++n) {
       
  2568 	_color_map[n] = -2;
       
  2569 	heap.push(n, countOutEdges(_ugraph, 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 (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
       
  2580 	  Node t = _ugraph.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 (OutEdgeIt e(_ugraph, order[i]); e != INVALID; ++e) {
       
  2590 	  Node t = _ugraph.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 NodeSubUGraphAdaptor<const UGraph, const KempeFilter> KempeUGraph;
       
  2617       KempeUGraph kempe_ugraph(_ugraph, filter);
       
  2618       
       
  2619       std::vector<Node> comp;
       
  2620       Bfs<KempeUGraph> bfs(kempe_ugraph);
       
  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 (Edge e = OutEdgeIt(_ugraph, node); e != INVALID; e = embedding[e]) {
       
  2644 	Node t = _ugraph.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 wirst 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 UGraph::template NodeMap<int> heap_index(_ugraph, -1);
       
  2672       BucketHeap<typename UGraph::template NodeMap<int> > heap(heap_index);
       
  2673       
       
  2674       for (NodeIt n(_ugraph); n != INVALID; ++n) {
       
  2675 	_color_map[n] = -2;
       
  2676 	heap.push(n, countOutEdges(_ugraph, 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 (OutEdgeIt e(_ugraph, n); e != INVALID; ++e) {
       
  2687 	  Node t = _ugraph.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 (OutEdgeIt e(_ugraph, order[i]); e != INVALID; ++e) {
       
  2697 	  Node t = _ugraph.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, but it most cases it does
       
  2719     /// not have to use Kempe recoloring method, in this case it is
       
  2720     /// equivalent with the runSixColoring() algorithm.
       
  2721     /// \return %True when the graph is planar.
       
  2722     bool runFiveColoring() {
       
  2723       PlanarEmbedding<UGraph> pe(_ugraph);
       
  2724       if (!pe.run()) return false;
       
  2725       
       
  2726       runFiveColoring(pe.embeddingMap());
       
  2727       return true;
       
  2728     }
       
  2729 
       
  2730   private:
       
  2731     
       
  2732     const UGraph& _ugraph;
       
  2733     IndexMap _color_map;
       
  2734     Palette _palette;
       
  2735   };
       
  2736 
  2441 }
  2737 }
  2442 
  2738 
  2443 #endif
  2739 #endif