14 #ifndef OR_TOOLS_GRAPH_EBERT_GRAPH_H_
15 #define OR_TOOLS_GRAPH_EBERT_GRAPH_H_
177 #include "absl/strings/str_cat.h"
187 template <
typename NodeIndexType,
typename ArcIndexType>
189 template <
typename NodeIndexType,
typename ArcIndexType>
190 class ForwardEbertGraph;
191 template <
typename NodeIndexType,
typename ArcIndexType>
192 class ForwardStaticGraph;
212 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
286 const NodeIndexType
head)
const {
288 arc = ThisAsDerived()->NextOutgoingArc(
tail, arc)) {
297 NodeIndexType
Head(
const ArcIndexType arc)
const {
298 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
306 return absl::StrCat(
static_cast<int64>(node));
314 return absl::StrCat(
static_cast<int64>(arc));
329 void Next() { head_ = graph_.NextNode(head_); }
332 NodeIndexType
Index()
const {
return head_; }
336 const DerivedGraph& graph_;
352 void Next() { arc_ = graph_.NextArc(arc_); }
355 ArcIndexType
Index()
const {
return arc_; }
359 const DerivedGraph& graph_;
387 DCHECK(&iterator.graph_ == &graph_);
388 node_ = iterator.node_;
389 arc_ = iterator.arc_;
397 arc_ = graph_.NextOutgoingArc(node_, arc_);
402 ArcIndexType
Index()
const {
return arc_; }
407 bool CheckInvariant()
const {
411 DCHECK(graph_.IsOutgoing(arc_, node_));
416 const DerivedGraph& graph_;
458 NodeIndexType
NextNode(
const NodeIndexType node)
const {
460 const NodeIndexType next_node = node + 1;
472 ArcIndexType
NextArc(
const ArcIndexType arc)
const {
473 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
474 const ArcIndexType next_arc = arc + 1;
481 return ThisAsDerived()->FindNextOutgoingArc(
482 ThisAsDerived()->FirstOutgoingOrOppositeIncomingArc(node));
507 inline const DerivedGraph* ThisAsDerived()
const {
508 return static_cast<const DerivedGraph*
>(
this);
513 inline DerivedGraph* ThisAsDerived() {
514 return static_cast<DerivedGraph*
>(
this);
518 template <
typename NodeIndexType,
typename ArcIndexType>
526 return head_[
a] < head_[
b];
533 template <
typename NodeIndexType,
typename ArcIndexType>
536 ForwardStaticGraph<NodeIndexType, ArcIndexType> > {
579 annotation_handler_(annotation_handler) {}
587 ArcIndexType destination)
const override {
622 const NodeIndexType num_nodes,
const ArcIndexType num_arcs,
623 const bool sort_arcs_by_head,
624 std::vector<std::pair<NodeIndexType, NodeIndexType> >* client_input_arcs,
629 client_cycle_handler) {
630 max_num_arcs_ = num_arcs;
631 num_arcs_ = num_arcs;
632 max_num_nodes_ = num_nodes;
635 std::vector<std::pair<NodeIndexType, NodeIndexType> >& input_arcs =
646 first_incident_arc_.
SetAll(0);
648 first_incident_arc_[
kFirstNode + input_arcs[arc].first] += 1;
652 num_nodes_,
static_cast<NodeIndexType
>(input_arcs[arc].first + 1));
654 num_nodes_,
static_cast<NodeIndexType
>(input_arcs[arc].second + 1));
657 for (NodeIndexType node = 0; node < num_nodes; ++node) {
658 ArcIndexType degree = first_incident_arc_[
kFirstNode + node];
659 first_incident_arc_[
kFirstNode + node] = next_arc;
664 std::unique_ptr<ArcIndexType[]> arc_permutation;
665 if (client_cycle_handler !=
nullptr) {
667 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
668 NodeIndexType
tail = input_arcs[input_arc].first;
669 NodeIndexType
head = input_arcs[input_arc].second;
674 arc_permutation[
kFirstArc + arc] = input_arc;
678 if (
sizeof(input_arcs[0].first) >=
sizeof(first_incident_arc_[0])) {
682 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
683 NodeIndexType
tail = input_arcs[input_arc].first;
686 input_arcs[input_arc].first =
static_cast<NodeIndexType
>(arc);
688 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
690 static_cast<ArcIndexType
>(input_arcs[input_arc].first);
691 NodeIndexType
head = input_arcs[input_arc].second;
697 for (ArcIndexType input_arc = 0; input_arc < num_arcs; ++input_arc) {
698 NodeIndexType
tail = input_arcs[input_arc].first;
699 NodeIndexType
head = input_arcs[input_arc].second;
710 for (NodeIndexType node =
kFirstNode + num_nodes; node > 0;
712 first_incident_arc_[node] = first_incident_arc_[node - 1];
715 if (sort_arcs_by_head) {
716 ArcIndexType begin = first_incident_arc_[
kFirstNode];
717 if (client_cycle_handler !=
nullptr) {
718 for (NodeIndexType node = 0; node < num_nodes; ++node) {
719 ArcIndexType end = first_incident_arc_[node + 1];
721 &arc_permutation[begin], &arc_permutation[end],
727 for (NodeIndexType node = 0; node < num_nodes; ++node) {
728 ArcIndexType end = first_incident_arc_[node + 1];
733 ArcIndexType begin_index = (begin < num_arcs ? begin : begin - 1);
734 ArcIndexType begin_offset = (begin < num_arcs ? 0 : 1);
735 ArcIndexType end_index = (end > 0 ? end - 1 : end);
736 ArcIndexType end_offset = (end > 0 ? 1 : 0);
737 std::sort(&head_[begin_index] + begin_offset,
738 &head_[end_index] + end_offset);
743 if (client_cycle_handler !=
nullptr && num_arcs > 0) {
756 NodeIndexType
Tail(
const ArcIndexType arc)
const {
759 return (*tail_)[arc];
763 bool IsIncoming(ArcIndexType arc, NodeIndexType node)
const {
764 return Head(arc) == node;
784 return ((tail_ !=
nullptr) && (arc >=
kFirstArc) &&
785 (arc <= tail_->max_index()));
789 ArcIndexType arc)
const {
793 if (arc < first_incident_arc_[node + 1]) {
803 std::string result =
"Arcs:(node) :\n";
804 for (ArcIndexType arc =
kFirstArc; arc < num_arcs_; ++arc) {
805 result +=
" " + ArcDebugString(arc) +
":(" + NodeDebugString(head_[arc]) +
808 result +=
"Node:First arc :\n";
809 for (NodeIndexType node =
kFirstNode; node <= num_nodes_; ++node) {
810 result +=
" " + NodeDebugString(node) +
":" +
811 ArcDebugString(first_incident_arc_[node]) +
"\n";
820 if (tail_ ==
nullptr) {
821 if (!RepresentationClean()) {
830 tail_->Reserve(
kFirstArc, max_num_arcs_ - 1);
832 for (; node_it.
Ok(); node_it.
Next()) {
833 NodeIndexType node = node_it.
Index();
835 for (; arc_it.
Ok(); arc_it.
Next()) {
836 (*tail_)[arc_it.
Index()] = node;
849 for (ArcIndexType arc =
kFirstArc; arc < num_arcs_; ++arc) {
857 bool IsDirect()
const {
return true; }
858 bool RepresentationClean()
const {
return true; }
859 bool IsOutgoing(
const NodeIndexType node,
860 const ArcIndexType unused_arc)
const {
865 ArcIndexType FirstOutgoingOrOppositeIncomingArc(NodeIndexType node)
const {
866 DCHECK(RepresentationClean());
868 ArcIndexType result = first_incident_arc_[node];
869 return ((result != first_incident_arc_[node + 1]) ? result :
kNilArc);
873 ArcIndexType FindNextOutgoingArc(ArcIndexType arc)
const {
893 std::unique_ptr<ZVector<NodeIndexType> > tail_;
897 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
902 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
908 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
913 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
918 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
925 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
947 template <
typename NodeIndexType,
typename ArcIndexType,
typename DerivedGraph>
949 :
public StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph> {
951 friend class StarGraphBase<NodeIndexType, ArcIndexType, DerivedGraph>;
978 bool Reserve(NodeIndexType new_max_num_nodes, ArcIndexType new_max_num_arcs) {
979 if (new_max_num_nodes < 0 || new_max_num_nodes >
kMaxNumNodes) {
982 if (new_max_num_arcs < 0 || new_max_num_arcs >
kMaxNumArcs) {
990 ThisAsDerived()->ReserveInternal(new_max_num_nodes, new_max_num_arcs);
1014 ThisAsDerived()->RecordArc(arc,
tail,
head);
1021 template <
typename ArcIndexTypeStrictWeakOrderingFunctor>
1023 const ArcIndexTypeStrictWeakOrderingFunctor& compare,
1025 std::unique_ptr<ArcIndexType[]> arc_permutation(
1031 arc_permutation[i] = i;
1044 ThisAsDerived()->BuildRepresentation();
1052 DerivedGraph* graph)
1053 : annotation_handler_(annotation_handler),
1059 if (annotation_handler_ !=
nullptr) {
1062 head_temp_ = graph_->Head(source);
1063 tail_temp_ = graph_->Tail(source);
1067 ArcIndexType destination)
const override {
1068 if (annotation_handler_ !=
nullptr) {
1071 graph_->SetHead(destination, graph_->Head(source));
1072 graph_->SetTail(destination, graph_->Tail(source));
1076 if (annotation_handler_ !=
nullptr) {
1079 graph_->SetHead(destination, head_temp_);
1080 graph_->SetTail(destination, tail_temp_);
1087 void SetSeen(ArcIndexType* permutation_element)
const override {
1088 *permutation_element =
kNilArc;
1091 bool Unseen(ArcIndexType permutation_element)
const override {
1092 return permutation_element !=
kNilArc;
1099 DerivedGraph* graph_;
1100 NodeIndexType head_temp_;
1101 NodeIndexType tail_temp_;
1114 LOG(DFATAL) <<
"Could not reserve memory for "
1124 const NodeIndexType node)
const {
1133 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
1139 const ArcIndexType arc)
const {
1140 DCHECK(ThisAsDerived()->CheckArcValidity(arc));
1141 DCHECK(ThisAsDerived()->IsDirect(arc));
1157 inline const DerivedGraph* ThisAsDerived()
const {
1158 return static_cast<const DerivedGraph*
>(
this);
1163 inline DerivedGraph* ThisAsDerived() {
1164 return static_cast<DerivedGraph*
>(
this);
1177 void SetHead(
const ArcIndexType arc,
const NodeIndexType
head) {
1185 template <
typename NodeIndexType,
typename ArcIndexType>
1188 EbertGraph<NodeIndexType, ArcIndexType> > {
1228 EbertGraph(NodeIndexType max_num_nodes, ArcIndexType max_num_arcs) {
1229 Initialize(max_num_nodes, max_num_arcs);
1242 node_(graph_.StartNode(node)),
1243 arc_(graph_.StartArc(
1244 graph_.FirstOutgoingOrOppositeIncomingArc(node))) {
1245 DCHECK(CheckInvariant());
1251 NodeIndexType node, ArcIndexType arc)
1253 node_(graph_.StartNode(node)),
1254 arc_(graph_.StartArc(arc)) {
1255 DCHECK(CheckInvariant());
1260 DCHECK(&iterator.graph_ == &graph_);
1261 node_ = iterator.node_;
1262 arc_ = iterator.arc_;
1270 arc_ = graph_.NextAdjacentArc(arc_);
1271 DCHECK(CheckInvariant());
1275 ArcIndexType
Index()
const {
return arc_; }
1280 bool CheckInvariant()
const {
1291 NodeIndexType node_;
1302 node_(graph_.StartNode(node)),
1303 arc_(graph_.StartArc(graph_.FirstIncomingArc(node))) {
1304 DCHECK(CheckInvariant());
1312 node_(graph_.StartNode(node)),
1314 : graph_.StartArc(graph_.
Opposite(arc))) {
1315 DCHECK(CheckInvariant());
1320 DCHECK(&iterator.graph_ == &graph_);
1321 node_ = iterator.node_;
1322 arc_ = iterator.arc_;
1330 arc_ = graph_.NextIncomingArc(arc_);
1331 DCHECK(CheckInvariant());
1342 bool CheckInvariant()
const {
1353 NodeIndexType node_;
1364 return (arc ==
kNilArc) || (arc >= -max_num_arcs_ && arc < max_num_arcs_);
1372 return (arc !=
kNilArc) && (arc >= -max_num_arcs_ && arc < max_num_arcs_);
1376 NodeIndexType
Tail(
const ArcIndexType arc)
const {
1410 const ArcIndexType opposite = ~arc;
1419 return arc !=
kNilArc && arc >= 0;
1425 return arc !=
kNilArc && arc < 0;
1430 NodeIndexType node)
const {
1431 return Tail(arc) == node;
1436 return IsDirect(arc) && Head(arc) == node;
1450 for (ArcIndexType arc =
kFirstArc; arc < max_num_arcs_; ++arc) {
1453 representation_clean_ =
true;
1459 DCHECK(representation_clean_);
1460 std::string result =
"Arcs:(node, next arc) :\n";
1461 for (ArcIndexType arc = -num_arcs_; arc < num_arcs_; ++arc) {
1462 result +=
" " + ArcDebugString(arc) +
":(" + NodeDebugString(head_[arc]) +
1463 "," + ArcDebugString(next_adjacent_arc_[arc]) +
")\n";
1465 result +=
"Node:First arc :\n";
1466 for (NodeIndexType node =
kFirstNode; node < num_nodes_; ++node) {
1467 result +=
" " + NodeDebugString(node) +
":" +
1468 ArcDebugString(first_incident_arc_[node]) +
"\n";
1481 void ReserveInternal(NodeIndexType new_max_num_nodes,
1482 ArcIndexType new_max_num_arcs) {
1483 head_.
Reserve(-new_max_num_arcs, new_max_num_arcs - 1);
1484 next_adjacent_arc_.
Reserve(-new_max_num_arcs, new_max_num_arcs - 1);
1485 for (ArcIndexType arc = -new_max_num_arcs; arc < -max_num_arcs_; ++arc) {
1489 for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) {
1496 ArcIndexType FirstIncomingArc(
const NodeIndexType node)
const {
1499 return FindNextIncomingArc(FirstOutgoingOrOppositeIncomingArc(node));
1503 ArcIndexType NextIncomingArc(
const ArcIndexType arc)
const {
1506 return FindNextIncomingArc(NextAdjacentArc(arc));
1511 void RecordArc(ArcIndexType arc, NodeIndexType
tail, NodeIndexType
head) {
1520 void SetTail(
const ArcIndexType arc,
const NodeIndexType
tail) {
1521 representation_clean_ =
false;
1526 void Attach(ArcIndexType arc) {
1530 next_adjacent_arc_.
Set(arc, first_incident_arc_[
tail]);
1531 first_incident_arc_.
Set(
tail, arc);
1532 const NodeIndexType
head = head_[arc];
1539 ArcIndexType FindNextOutgoingArc(ArcIndexType arc)
const {
1542 arc = NextAdjacentArc(arc);
1549 ArcIndexType FindNextIncomingArc(ArcIndexType arc)
const {
1552 arc = NextAdjacentArc(arc);
1561 template <
typename NodeIndexType,
typename ArcIndexType>
1564 ForwardEbertGraph<NodeIndexType, ArcIndexType> > {
1604 Initialize(max_num_nodes, max_num_arcs);
1626 return (tail_ !=
nullptr) && (arc >=
kFirstArc) &&
1627 (arc <= tail_->max_index());
1631 NodeIndexType
Tail(
const ArcIndexType arc)
const {
1634 return (*tail_)[arc];
1639 return IsDirect(arc) && Head(arc) == node;
1649 for (ArcIndexType arc =
kFirstArc; arc < max_num_arcs_; ++arc) {
1651 Attach((*tail_)[arc], arc);
1653 representation_clean_ =
true;
1660 if (tail_ ==
nullptr) {
1661 if (!representation_clean_) {
1670 tail_->Reserve(
kFirstArc, max_num_arcs_ - 1);
1672 for (; node_it.
Ok(); node_it.
Next()) {
1673 NodeIndexType node = node_it.
Index();
1675 for (; arc_it.
Ok(); arc_it.
Next()) {
1676 (*tail_)[arc_it.
Index()] = node;
1689 for (ArcIndexType arc =
kFirstArc; arc < num_arcs_; ++arc) {
1699 DCHECK(representation_clean_);
1700 std::string result =
"Arcs:(node, next arc) :\n";
1701 for (ArcIndexType arc =
kFirstArc; arc < num_arcs_; ++arc) {
1702 result +=
" " + ArcDebugString(arc) +
":(" + NodeDebugString(head_[arc]) +
1703 "," + ArcDebugString(next_adjacent_arc_[arc]) +
")\n";
1705 result +=
"Node:First arc :\n";
1706 for (NodeIndexType node =
kFirstNode; node < num_nodes_; ++node) {
1707 result +=
" " + NodeDebugString(node) +
":" +
1708 ArcDebugString(first_incident_arc_[node]) +
"\n";
1722 void ReserveTailArray(ArcIndexType new_max_num_arcs) {
1723 if (tail_ !=
nullptr) {
1727 if (tail_->Reserve(
kFirstArc, new_max_num_arcs - 1)) {
1728 for (ArcIndexType arc = tail_->max_index() + 1; arc < new_max_num_arcs;
1759 void ReserveInternal(NodeIndexType new_max_num_nodes,
1760 ArcIndexType new_max_num_arcs) {
1763 for (ArcIndexType arc = max_num_arcs_; arc < new_max_num_arcs; ++arc) {
1767 ReserveTailArray(new_max_num_arcs);
1772 void RecordArc(ArcIndexType arc, NodeIndexType
tail, NodeIndexType
head) {
1780 void SetTail(
const ArcIndexType arc,
const NodeIndexType
tail) {
1783 representation_clean_ =
false;
1784 tail_->Set(arc,
tail);
1788 void Attach(NodeIndexType
tail, ArcIndexType arc) {
1791 next_adjacent_arc_.
Set(arc, first_incident_arc_[
tail]);
1792 first_incident_arc_.
Set(
tail, arc);
1793 const NodeIndexType
head = head_[arc];
1797 if (tail_ !=
nullptr) {
1799 tail_->Set(arc,
tail);
1804 ArcIndexType FindNextOutgoingArc(ArcIndexType arc)
const {
1813 bool IsOutgoing(
const ArcIndex unused_arc,
1821 bool IsDirect(
const ArcIndex unused_arc)
const {
return true; }
1838 std::unique_ptr<ZVector<NodeIndexType> > tail_;
1847 template <
typename GraphType>
1853 template <
typename NodeIndexType,
typename ArcIndexType>
1859 template <
typename NodeIndexType,
typename ArcIndexType>
1865 namespace or_internal {
1871 template <
typename GraphType,
bool has_reverse_arcs>
1881 template <
typename GraphType>
1894 template <
typename GraphType,
bool has_reverse_arcs>
1904 template <
typename GraphType>
1915 template <
typename GraphType>
1923 tail_array_builder(graph_);
1924 return tail_array_builder.BuildTailArray();
1930 tail_array_releaser(graph_);
1931 tail_array_releaser.ReleaseTailArray();
1938 template <
typename GraphType>
1946 return ((graph_.Tail(
a) < graph_.Tail(
b)) ||
1947 ((graph_.Tail(
a) == graph_.Tail(
b)) &&
1948 (graph_.Head(
a) < graph_.Head(
b))));
1952 const GraphType& graph_;
1955 namespace or_internal {
1962 template <
typename GraphType,
bool is_dynamic>
1968 : num_arcs_(0), sort_arcs_(sort_arcs) {
1969 Reserve(max_num_nodes, max_num_arcs);
1977 if (num_arcs_ < max_num_arcs_ &&
1978 tail < GraphType::kFirstNode + max_num_nodes_ &&
1979 head < GraphType::kFirstNode + max_num_nodes_) {
1981 arcs_.push_back(std::make_pair(
tail,
head));
1986 return GraphType::kNilArc;
1992 client_cycle_handler) {
1993 GraphType* graph =
new GraphType(max_num_nodes_, num_arcs_, sort_arcs_,
1994 &arcs_, client_cycle_handler);
2002 max_num_nodes_ = new_max_num_nodes;
2003 max_num_arcs_ = new_max_num_arcs;
2004 arcs_.reserve(new_max_num_arcs);
2013 std::pair<typename GraphType::NodeIndex, typename GraphType::NodeIndex> >
2016 const bool sort_arcs_;
2022 template <
typename GraphType>
2028 : graph_(new GraphType(max_num_nodes, max_num_arcs)),
2029 sort_arcs_(sort_arcs) {}
2033 return graph_->Reserve(new_max_num_nodes, new_max_num_arcs);
2043 client_cycle_handler) {
2048 graph_->GroupForwardArcsByFunctor(arc_ordering, client_cycle_handler);
2051 GraphType* result = graph_;
2057 GraphType*
const graph_;
2058 const bool sort_arcs_;
2063 template <
typename GraphType>
2066 GraphType, graph_traits<GraphType>::is_dynamic> {
2073 num_nodes, num_arcs, sort_arcs) {}
2087 template <
typename GraphType>
2089 if (line_graph ==
nullptr) {
2090 LOG(DFATAL) <<
"line_graph must not be NULL";
2093 if (line_graph->num_nodes() != 0) {
2094 LOG(DFATAL) <<
"line_graph must be empty";
2097 typedef typename GraphType::ArcIterator ArcIterator;
2098 typedef typename GraphType::OutgoingArcIterator OutgoingArcIterator;
2101 for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2102 arc_iterator.Next()) {
2105 for (OutgoingArcIterator iterator(graph,
head); iterator.Ok();
2110 line_graph->Reserve(graph.num_arcs(), num_arcs);
2111 for (ArcIterator arc_iterator(graph); arc_iterator.Ok();
2112 arc_iterator.Next()) {
2115 for (OutgoingArcIterator iterator(graph,
head); iterator.Ok();
2117 line_graph->AddArc(arc, iterator.Index());
2124 #endif // OR_TOOLS_GRAPH_EBERT_GRAPH_H_