... | ... |
@@ -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 |
|
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 |
/// |
|
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 |
|
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 |
|
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 |
|
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 |
|
707 |
/// \brief Give back the successor of an arc |
|
703 | 708 |
/// |
704 |
/// |
|
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 |
|
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 |
|
2084 |
/// \brief The point type for storing coordinates |
|
2076 | 2085 |
typedef dim2::Point<int> Point; |
2077 |
/// \brief The map type for |
|
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 |
|
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 |
|
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 |
|
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 |
/// |
|
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 |
/// |
|
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 |
|
2442 |
/// \brief Return the grid embedding in a node map |
|
2432 | 2443 |
/// |
2433 |
/// |
|
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 |
/// |
|
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 |
|
2513 |
/// \brief The map type for storing color indices |
|
2503 | 2514 |
typedef typename Graph::template NodeMap<int> IndexMap; |
2504 |
/// \brief The map type for |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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)