155 #ifndef UTIL_GRAPH_GRAPH_H_
156 #define UTIL_GRAPH_GRAPH_H_
165 #include "ortools/base/integral_types.h"
166 #include "ortools/base/logging.h"
167 #include "ortools/base/macros.h"
173 template <
typename T>
182 template <
typename NodeIndexType = int32,
typename ArcIndexType = int32,
183 bool HasReverseArcs =
false>
263 template <
typename A,
typename B>
265 LOG(FATAL) <<
"Not supported";
273 std::vector<ArcIndexType>* start,
274 std::vector<ArcIndexType>* permutation);
296 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
321 void AddNode(NodeIndexType node);
329 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
340 void Build(std::vector<ArcIndexType>* permutation);
343 class OutgoingArcIterator;
344 class OutgoingHeadIterator;
351 ArcIndexType
OutDegree(NodeIndexType node)
const;
361 NodeIndexType node, ArcIndexType from)
const;
369 NodeIndexType
Tail(ArcIndexType arc)
const;
370 NodeIndexType
Head(ArcIndexType arc)
const;
376 std::vector<ArcIndexType> start_;
377 std::vector<ArcIndexType> next_;
378 std::vector<NodeIndexType> head_;
379 std::vector<NodeIndexType> tail_;
395 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
406 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
408 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
415 class OutgoingArcIterator;
417 NodeIndexType
Head(ArcIndexType arc)
const;
418 NodeIndexType
Tail(ArcIndexType arc)
const;
419 ArcIndexType
OutDegree(NodeIndexType node)
const;
422 NodeIndexType node, ArcIndexType from)
const;
431 void AddNode(NodeIndexType node);
432 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
435 void Build(std::vector<ArcIndexType>* permutation);
438 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
446 NodeIndexType last_tail_seen_;
447 std::vector<ArcIndexType> start_;
448 std::vector<NodeIndexType> head_;
449 std::vector<NodeIndexType> tail_;
458 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
460 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
482 class OutgoingOrOppositeIncomingArcIterator;
483 class OppositeIncomingArcIterator;
484 class IncomingArcIterator;
485 class OutgoingArcIterator;
486 class OutgoingHeadIterator;
489 ArcIndexType
OutDegree(NodeIndexType node)
const;
490 ArcIndexType
InDegree(NodeIndexType node)
const;
503 NodeIndexType node)
const;
505 NodeIndexType node, ArcIndexType from)
const;
507 NodeIndexType node, ArcIndexType from)
const;
510 ArcIndexType from)
const;
512 NodeIndexType node, ArcIndexType from)
const;
519 NodeIndexType
Head(ArcIndexType arc)
const;
520 NodeIndexType
Tail(ArcIndexType arc)
const;
524 void AddNode(NodeIndexType node);
525 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
528 void Build(std::vector<ArcIndexType>* permutation);
531 std::vector<ArcIndexType> start_;
532 std::vector<ArcIndexType> reverse_start_;
546 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
548 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
567 class OutgoingOrOppositeIncomingArcIterator;
568 class OppositeIncomingArcIterator;
569 class IncomingArcIterator;
570 class OutgoingArcIterator;
573 ArcIndexType
OutDegree(NodeIndexType node)
const;
574 ArcIndexType
InDegree(NodeIndexType node)
const;
581 NodeIndexType node)
const;
583 NodeIndexType node, ArcIndexType from)
const;
585 NodeIndexType node, ArcIndexType from)
const;
588 ArcIndexType from)
const;
590 NodeIndexType node, ArcIndexType from)
const;
599 NodeIndexType
Head(ArcIndexType arc)
const;
600 NodeIndexType
Tail(ArcIndexType arc)
const;
603 void AddNode(NodeIndexType node);
604 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
607 void Build(std::vector<ArcIndexType>* permutation);
610 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
615 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
618 return node + 1 <
num_nodes_ ? reverse_start_[node + 1] : 0;
622 std::vector<ArcIndexType> start_;
623 std::vector<ArcIndexType> reverse_start_;
624 SVector<NodeIndexType> head_;
625 SVector<ArcIndexType> opposite_;
634 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
636 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
655 class OutgoingOrOppositeIncomingArcIterator;
656 class OppositeIncomingArcIterator;
657 class IncomingArcIterator;
658 class OutgoingArcIterator;
660 ArcIndexType
OutDegree(NodeIndexType node)
const;
661 ArcIndexType
InDegree(NodeIndexType node)
const;
668 NodeIndexType node)
const;
670 NodeIndexType node, ArcIndexType from)
const;
672 NodeIndexType node, ArcIndexType from)
const;
675 ArcIndexType from)
const;
677 NodeIndexType node, ArcIndexType from)
const;
686 NodeIndexType
Head(ArcIndexType arc)
const;
687 NodeIndexType
Tail(ArcIndexType arc)
const;
690 void AddNode(NodeIndexType node);
691 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
694 void Build(std::vector<ArcIndexType>* permutation);
697 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
704 std::vector<ArcIndexType> start_;
705 std::vector<ArcIndexType> reverse_start_;
706 std::vector<ArcIndexType> next_;
707 SVector<NodeIndexType> head_;
723 template <
class IntVector,
class Array,
class ElementType>
725 Array* array_to_permute,
726 ElementType unused) {
727 std::vector<ElementType> temp(permutation.size());
728 for (
int i = 0; i < permutation.size(); ++i) {
729 temp[i] = (*array_to_permute)[i];
731 for (
int i = 0; i < permutation.size(); ++i) {
732 (*array_to_permute)[permutation[i]] = temp[i];
736 template <
class IntVector,
class Array>
737 void Permute(
const IntVector& permutation, Array* array_to_permute) {
738 if (permutation.empty()) {
742 (*array_to_permute)[0]);
747 template <
class IntVector>
749 std::vector<bool>* array_to_permute) {
750 if (permutation.empty()) {
771 template <
typename T>
774 SVector() : base_(nullptr), size_(0), capacity_(0) {}
781 if (capacity_ < other.size_) {
785 capacity_ = other.size_;
786 base_ = static_cast<T*>(malloc(2LL * capacity_ *
sizeof(T)));
787 CHECK(base_ !=
nullptr);
794 for (
int i = -size_; i < size_; ++i) {
795 new (base_ + i) T(other.base_[i]);
813 DCHECK_GE(n, -size_);
819 DCHECK_GE(n, -size_);
825 for (
int i = -n; i < -size_; ++i) {
828 for (
int i = size_; i < n; ++i) {
831 for (
int i = -size_; i < -n; ++i) {
834 for (
int i = n; i < size_; ++i) {
842 T*
data()
const {
return base_; }
845 std::swap(base_, x.base_);
846 std::swap(size_, x.size_);
847 std::swap(capacity_, x.capacity_);
854 const int new_capacity = std::min(n,
max_size());
855 T* new_storage = static_cast<T*>(malloc(2LL * new_capacity *
sizeof(T)));
856 CHECK(new_storage !=
nullptr);
857 T* new_base = new_storage + new_capacity;
860 for (
int i = -size_; i < size_; ++i) {
861 new (new_base + i) T(std::move(base_[i]));
863 int saved_size = size_;
867 capacity_ = new_capacity;
873 void grow(
const T& left = T(),
const T& right = T()) {
874 if (size_ == capacity_) {
880 new (base_ + size_) T(right_copy);
881 new (base_ - size_ - 1) T(left_copy);
884 new (base_ + size_) T(right);
885 new (base_ - size_ - 1) T(left);
890 int size()
const {
return size_; }
894 int max_size()
const {
return std::numeric_limits<int>::max(); }
897 if (base_ ==
nullptr)
return;
900 free(base_ - capacity_);
907 int NewCapacity(
int delta) {
909 double candidate = 1.3 * static_cast<double>(capacity_);
910 if (candidate > static_cast<double>(
max_size())) {
911 candidate = static_cast<double>(
max_size());
913 int new_capacity = static_cast<int>(candidate);
914 if (new_capacity > capacity_ + delta) {
917 return capacity_ + delta;
927 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
928 IntegerRange<NodeIndexType>
933 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
939 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
942 std::numeric_limits<NodeIndexType>::max();
944 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
947 std::numeric_limits<ArcIndexType>::max();
949 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
954 return node_capacity_ > num_nodes_ ? node_capacity_ : num_nodes_;
957 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
961 return arc_capacity_ > num_arcs_ ? arc_capacity_ : num_arcs_;
964 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
965 void BaseGraph<NodeIndexType, ArcIndexType,
966 HasReverseArcs>::FreezeCapacities() {
969 const_capacities_ =
true;
970 node_capacity_ = std::max(node_capacity_, num_nodes_);
971 arc_capacity_ = std::max(arc_capacity_, num_arcs_);
976 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
979 ArcIndexType sum = 0;
980 for (
int i = 0; i < num_nodes_; ++i) {
981 ArcIndexType temp = (*v)[i];
985 DCHECK(sum == num_arcs_);
993 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
996 std::vector<ArcIndexType>* start,
997 std::vector<ArcIndexType>* permutation) {
1001 start->assign(num_nodes_, 0);
1002 int last_tail_seen = 0;
1003 bool permutation_needed =
false;
1004 for (
int i = 0; i < num_arcs_; ++i) {
1005 NodeIndexType tail = (*head)[i];
1006 if (!permutation_needed) {
1007 permutation_needed = tail < last_tail_seen;
1008 last_tail_seen = tail;
1012 ComputeCumulativeSum(start);
1016 if (!permutation_needed) {
1017 for (
int i = 0; i < num_arcs_; ++i) {
1018 (*head)[i] = (*head)[~i];
1020 if (permutation !=
nullptr) {
1021 permutation->clear();
1028 std::vector<ArcIndexType> perm(num_arcs_);
1029 for (
int i = 0; i < num_arcs_; ++i) {
1030 perm[i] = (*start)[(*head)[i]]++;
1034 for (
int i = num_nodes_ - 1; i > 0; --i) {
1035 (*start)[i] = (*start)[i - 1];
1041 for (
int i = 0; i < num_arcs_; ++i) {
1042 (*head)[perm[i]] = (*head)[~i];
1044 if (permutation !=
nullptr) {
1045 permutation->swap(perm);
1058 #define DEFINE_RANGE_BASED_ARC_ITERATION(c, t, e) \
1059 template <typename NodeIndexType, typename ArcIndexType> \
1060 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1061 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1062 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node), \
1063 t##ArcIterator(*this, node, e)); \
1065 template <typename NodeIndexType, typename ArcIndexType> \
1066 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1067 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1068 NodeIndexType node, ArcIndexType from) const { \
1069 return BeginEndWrapper<t##ArcIterator>(t##ArcIterator(*this, node, from), \
1070 t##ArcIterator(*this, node, e)); \
1075 #define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1076 using iterator_category = std::input_iterator_tag; \
1077 using difference_type = ptrdiff_t; \
1078 using pointer = const ArcIndexType*; \
1079 using reference = const ArcIndexType&; \
1080 using value_type = ArcIndexType; \
1081 bool operator!=(const iterator_class_name& other) const { \
1082 return this->index_ != other.index_; \
1084 bool operator==(const iterator_class_name& other) const { \
1085 return this->index_ == other.index_; \
1087 ArcIndexType operator*() const { return this->Index(); } \
1088 void operator++() { this->Next(); }
1094 template <
typename NodeIndexType,
typename ArcIndexType>
1096 typename ListGraph<NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1098 NodeIndexType node)
const {
1104 template <
typename NodeIndexType,
typename ArcIndexType>
1106 ArcIndexType arc)
const {
1107 DCHECK(IsArcValid(arc));
1111 template <
typename NodeIndexType,
typename ArcIndexType>
1113 ArcIndexType arc)
const {
1114 DCHECK(IsArcValid(arc));
1118 template <
typename NodeIndexType,
typename ArcIndexType>
1120 NodeIndexType node)
const {
1121 ArcIndexType degree(0);
1122 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1126 template <
typename NodeIndexType,
typename ArcIndexType>
1128 if (node < num_nodes_)
return;
1129 DCHECK(!const_capacities_ || node < node_capacity_);
1130 num_nodes_ = node + 1;
1131 start_.resize(num_nodes_, Base::kNilArc);
1134 template <
typename NodeIndexType,
typename ArcIndexType>
1136 NodeIndexType tail, NodeIndexType head) {
1139 AddNode(tail > head ? tail : head);
1140 head_.push_back(head);
1141 tail_.push_back(tail);
1142 next_.push_back(start_[tail]);
1143 start_[tail] = num_arcs_;
1144 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1148 template <
typename NodeIndexType,
typename ArcIndexType>
1150 Base::ReserveNodes(bound);
1151 if (bound <= num_nodes_)
return;
1152 start_.reserve(bound);
1155 template <
typename NodeIndexType,
typename ArcIndexType>
1157 Base::ReserveArcs(bound);
1158 if (bound <= num_arcs_)
return;
1159 head_.reserve(bound);
1160 tail_.reserve(bound);
1161 next_.reserve(bound);
1164 template <
typename NodeIndexType,
typename ArcIndexType>
1166 std::vector<ArcIndexType>* permutation) {
1167 if (permutation !=
nullptr) {
1168 permutation->clear();
1172 template <
typename NodeIndexType,
typename ArcIndexType>
1176 : graph_(graph), index_(graph.start_[node]) {
1181 : graph_(graph), index_(arc) {
1186 ArcIndexType
Index()
const {
return index_; }
1189 index_ = graph_.next_[index_];
1196 ArcIndexType index_;
1199 template <
typename NodeIndexType,
typename ArcIndexType>
1209 : graph_(graph), index_(graph.start_[node]) {
1214 : graph_(graph), index_(arc) {
1219 NodeIndexType
Index()
const {
return graph_.Head(index_); }
1222 index_ = graph_.next_[index_];
1228 return index_ != other.index_;
1235 ArcIndexType index_;
1242 template <
typename NodeIndexType,
typename ArcIndexType>
1245 NodeIndexType node)
const {
1247 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1250 template <
typename NodeIndexType,
typename ArcIndexType>
1252 NodeIndexType node)
const {
1253 return DirectArcLimit(node) - start_[node];
1256 template <
typename NodeIndexType,
typename ArcIndexType>
1258 NodeIndexType bound) {
1259 Base::ReserveNodes(bound);
1260 if (bound <= num_nodes_)
return;
1261 start_.reserve(bound);
1264 template <
typename NodeIndexType,
typename ArcIndexType>
1266 Base::ReserveArcs(bound);
1267 if (bound <= num_arcs_)
return;
1268 head_.reserve(bound);
1269 tail_.reserve(bound);
1272 template <
typename NodeIndexType,
typename ArcIndexType>
1274 if (node < num_nodes_)
return;
1275 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1276 num_nodes_ = node + 1;
1277 start_.resize(num_nodes_, 0);
1280 template <
typename NodeIndexType,
typename ArcIndexType>
1282 NodeIndexType tail, NodeIndexType head) {
1286 AddNode(tail > head ? tail : head);
1287 if (arc_in_order_) {
1288 if (tail >= last_tail_seen_) {
1290 last_tail_seen_ = tail;
1292 arc_in_order_ =
false;
1295 tail_.push_back(tail);
1296 head_.push_back(head);
1297 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1301 template <
typename NodeIndexType,
typename ArcIndexType>
1303 ArcIndexType arc)
const {
1304 DCHECK(IsArcValid(arc));
1308 template <
typename NodeIndexType,
typename ArcIndexType>
1310 ArcIndexType arc)
const {
1311 DCHECK(IsArcValid(arc));
1327 template <
typename NodeIndexType,
typename ArcIndexType>
1329 std::vector<ArcIndexType>* permutation) {
1331 if (is_built_)
return;
1333 node_capacity_ = num_nodes_;
1334 arc_capacity_ = num_arcs_;
1335 this->FreezeCapacities();
1338 if (arc_in_order_) {
1339 if (permutation !=
nullptr) {
1340 permutation->clear();
1342 this->ComputeCumulativeSum(&start_);
1348 start_.assign(num_nodes_, 0);
1349 for (
int i = 0; i < num_arcs_; ++i) {
1352 this->ComputeCumulativeSum(&start_);
1356 std::vector<ArcIndexType> perm(num_arcs_);
1357 for (
int i = 0; i < num_arcs_; ++i) {
1358 perm[i] = start_[tail_[i]]++;
1362 CHECK_EQ(tail_.size(), num_arcs_);
1364 for (
int i = 0; i < num_arcs_; ++i) {
1365 head_[perm[i]] = tail_[i];
1368 if (permutation !=
nullptr) {
1369 permutation->swap(perm);
1373 for (
int i = num_nodes_ - 1; i > 0; --i) {
1374 start_[i] = start_[i - 1];
1379 for (
const NodeIndexType node : Base::AllNodes()) {
1380 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1386 template <
typename NodeIndexType,
typename ArcIndexType>
1390 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1393 : index_(arc), limit_(graph.DirectArcLimit(node)) {
1394 DCHECK_GE(arc, graph.start_[node]);
1397 bool Ok()
const {
return index_ < limit_; }
1398 ArcIndexType
Index()
const {
return index_; }
1414 ArcIndexType index_;
1415 const ArcIndexType limit_;
1423 OutgoingOrOppositeIncoming, Base::kNilArc);
1427 template <
typename NodeIndexType,
typename ArcIndexType>
1429 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1431 NodeIndexType node)
const {
1437 template <
typename NodeIndexType,
typename ArcIndexType>
1439 NodeIndexType node)
const {
1440 ArcIndexType degree(0);
1441 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OutgoingArcs(node)) ++degree;
1445 template <
typename NodeIndexType,
typename ArcIndexType>
1447 NodeIndexType node)
const {
1448 ArcIndexType degree(0);
1449 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1453 template <
typename NodeIndexType,
typename ArcIndexType>
1455 ArcIndexType arc)
const {
1456 DCHECK(IsArcValid(arc));
1460 template <
typename NodeIndexType,
typename ArcIndexType>
1462 ArcIndexType arc)
const {
1463 DCHECK(IsArcValid(arc));
1467 template <
typename NodeIndexType,
typename ArcIndexType>
1469 ArcIndexType arc)
const {
1470 return head_[OppositeArc(arc)];
1473 template <
typename NodeIndexType,
typename ArcIndexType>
1475 NodeIndexType bound) {
1476 Base::ReserveNodes(bound);
1477 if (bound <= num_nodes_)
return;
1478 start_.reserve(bound);
1479 reverse_start_.reserve(bound);
1482 template <
typename NodeIndexType,
typename ArcIndexType>
1484 ArcIndexType bound) {
1485 Base::ReserveArcs(bound);
1486 if (bound <= num_arcs_)
return;
1487 head_.reserve(bound);
1488 next_.reserve(bound);
1491 template <
typename NodeIndexType,
typename ArcIndexType>
1493 NodeIndexType node) {
1494 if (node < num_nodes_)
return;
1495 DCHECK(!const_capacities_ || node < node_capacity_);
1496 num_nodes_ = node + 1;
1497 start_.resize(num_nodes_, Base::kNilArc);
1498 reverse_start_.resize(num_nodes_, Base::kNilArc);
1501 template <
typename NodeIndexType,
typename ArcIndexType>
1503 NodeIndexType tail, NodeIndexType head) {
1506 AddNode(tail > head ? tail : head);
1507 head_.grow(tail, head);
1508 next_.grow(reverse_start_[head], start_[tail]);
1509 start_[tail] = num_arcs_;
1510 reverse_start_[head] = ~num_arcs_;
1511 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1515 template <
typename NodeIndexType,
typename ArcIndexType>
1517 std::vector<ArcIndexType>* permutation) {
1518 if (permutation !=
nullptr) {
1519 permutation->clear();
1523 template <
typename NodeIndexType,
typename ArcIndexType>
1527 : graph_(graph), index_(graph.start_[node]) {
1532 : graph_(graph), index_(arc) {
1538 ArcIndexType
Index()
const {
return index_; }
1541 index_ = graph_.next_[index_];
1548 ArcIndexType index_;
1551 template <
typename NodeIndexType,
typename ArcIndexType>
1557 : graph_(graph), index_(graph.reverse_start_[node]) {
1561 NodeIndexType node, ArcIndexType arc)
1562 : graph_(graph), index_(arc) {
1569 ArcIndexType
Index()
const {
return index_; }
1572 index_ = graph_.next_[index_];
1582 template <
typename NodeIndexType,
typename ArcIndexType>
1598 : this->graph_.OppositeArc(this->index_);
1604 template <
typename NodeIndexType,
typename ArcIndexType>
1610 : graph_(graph), index_(graph.reverse_start_[node]), node_(node) {
1615 NodeIndexType node, ArcIndexType arc)
1616 : graph_(graph), index_(arc), node_(node) {
1622 ArcIndexType
Index()
const {
return index_; }
1626 index_ = graph_.next_[index_];
1628 index_ = graph_.start_[node_];
1631 index_ = graph_.next_[index_];
1639 ArcIndexType index_;
1640 const NodeIndexType node_;
1643 template <
typename NodeIndexType,
typename ArcIndexType>
1647 : graph_(&graph), index_(graph.start_[node]) {
1652 : graph_(&graph), index_(arc) {
1658 ArcIndexType
Index()
const {
return graph_->Head(index_); }
1661 index_ = graph_->next_[index_];
1668 ArcIndexType index_;
1674 DirectArcLimit(node));
1676 ReverseArcLimit(node));
1678 OutgoingOrOppositeIncoming,
1679 DirectArcLimit(node));
1681 ReverseArcLimit(node));
1683 template <
typename NodeIndexType,
typename ArcIndexType>
1685 NodeIndexType node)
const {
1686 return DirectArcLimit(node) - start_[node];
1689 template <
typename NodeIndexType,
typename ArcIndexType>
1691 NodeIndexType node)
const {
1692 return ReverseArcLimit(node) - reverse_start_[node];
1695 template <
typename NodeIndexType,
typename ArcIndexType>
1698 NodeIndexType node)
const {
1700 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1703 template <
typename NodeIndexType,
typename ArcIndexType>
1705 ArcIndexType arc)
const {
1707 DCHECK(IsArcValid(arc));
1708 return opposite_[arc];
1711 template <
typename NodeIndexType,
typename ArcIndexType>
1713 ArcIndexType arc)
const {
1715 DCHECK(IsArcValid(arc));
1719 template <
typename NodeIndexType,
typename ArcIndexType>
1721 ArcIndexType arc)
const {
1723 return head_[OppositeArc(arc)];
1726 template <
typename NodeIndexType,
typename ArcIndexType>
1728 ArcIndexType bound) {
1729 Base::ReserveArcs(bound);
1730 if (bound <= num_arcs_)
return;
1731 head_.reserve(bound);
1734 template <
typename NodeIndexType,
typename ArcIndexType>
1736 NodeIndexType node) {
1737 if (node < num_nodes_)
return;
1738 DCHECK(!const_capacities_ || node < node_capacity_);
1739 num_nodes_ = node + 1;
1742 template <
typename NodeIndexType,
typename ArcIndexType>
1744 NodeIndexType tail, NodeIndexType head) {
1747 AddNode(tail > head ? tail : head);
1751 head_.grow(head, tail);
1752 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1756 template <
typename NodeIndexType,
typename ArcIndexType>
1758 std::vector<ArcIndexType>* permutation) {
1760 if (is_built_)
return;
1762 node_capacity_ = num_nodes_;
1763 arc_capacity_ = num_arcs_;
1764 this->FreezeCapacities();
1765 this->BuildStartAndForwardHead(&head_, &start_, permutation);
1768 reverse_start_.assign(num_nodes_, 0);
1769 for (
int i = 0; i < num_arcs_; ++i) {
1770 reverse_start_[head_[i]]++;
1772 this->ComputeCumulativeSum(&reverse_start_);
1776 opposite_.reserve(num_arcs_);
1777 for (
int i = 0; i < num_arcs_; ++i) {
1779 opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_);
1783 for (
int i = num_nodes_ - 1; i > 0; --i) {
1784 reverse_start_[i] = reverse_start_[i - 1] - num_arcs_;
1786 if (num_nodes_ != 0) {
1787 reverse_start_[0] = -num_arcs_;
1791 for (
int i = 0; i < num_arcs_; ++i) {
1792 opposite_[opposite_[i]] = i;
1794 for (
const NodeIndexType node : Base::AllNodes()) {
1795 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1796 head_[opposite_[arc]] = node;
1801 template <
typename NodeIndexType,
typename ArcIndexType>
1805 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
1808 : index_(arc), limit_(graph.DirectArcLimit(node)) {
1809 DCHECK_GE(arc, graph.start_[node]);
1812 bool Ok()
const {
return index_ < limit_; }
1813 ArcIndexType
Index()
const {
return index_; }
1824 ArcIndexType index_;
1825 const ArcIndexType limit_;
1828 template <
typename NodeIndexType,
typename ArcIndexType>
1835 limit_(graph.ReverseArcLimit(node)),
1836 index_(graph.reverse_start_[node]) {
1838 DCHECK_LE(index_, limit_);
1841 NodeIndexType node, ArcIndexType arc)
1842 : graph_(graph), limit_(graph.ReverseArcLimit(node)), index_(arc) {
1844 DCHECK_GE(index_, graph.reverse_start_[node]);
1845 DCHECK_LE(index_, limit_);
1848 bool Ok()
const {
return index_ < limit_; }
1849 ArcIndexType
Index()
const {
return index_; }
1863 template <
typename NodeIndexType,
typename ArcIndexType>
1872 arc == graph.ReverseArcLimit(node)
1873 ? graph.ReverseArcLimit(node)
1877 return this->index_ == this->limit_
1879 : this->graph_.OppositeArc(this->index_);
1885 template <
typename NodeIndexType,
typename ArcIndexType>
1891 : index_(graph.reverse_start_[node]),
1892 first_limit_(graph.ReverseArcLimit(node)),
1893 next_start_(graph.start_[node]),
1894 limit_(graph.DirectArcLimit(node)) {
1895 if (index_ == first_limit_) index_ = next_start_;
1897 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1900 NodeIndexType node, ArcIndexType arc)
1902 first_limit_(graph.ReverseArcLimit(node)),
1903 next_start_(graph.start_[node]),
1904 limit_(graph.DirectArcLimit(node)) {
1906 DCHECK((index_ >= graph.reverse_start_[node] && index_ < first_limit_) ||
1907 (index_ >= next_start_));
1910 ArcIndexType
Index()
const {
return index_; }
1911 bool Ok()
const {
return index_ < limit_; }
1915 if (index_ == first_limit_) {
1916 index_ = next_start_;
1923 ArcIndexType index_;
1924 const ArcIndexType first_limit_;
1925 const ArcIndexType next_start_;
1926 const ArcIndexType limit_;
1932 DirectArcLimit(node));
1935 OutgoingOrOppositeIncoming,
1936 DirectArcLimit(node));
1940 template <
typename NodeIndexType,
typename ArcIndexType>
1942 NodeIndexType node)
const {
1943 return DirectArcLimit(node) - start_[node];
1946 template <
typename NodeIndexType,
typename ArcIndexType>
1948 NodeIndexType node)
const {
1949 ArcIndexType degree(0);
1950 for (
auto arc ABSL_ATTRIBUTE_UNUSED : OppositeIncomingArcs(node)) ++degree;
1954 template <
typename NodeIndexType,
typename ArcIndexType>
1957 NodeIndexType node)
const {
1959 head_.data() + start_[node], head_.data() + DirectArcLimit(node));
1962 template <
typename NodeIndexType,
typename ArcIndexType>
1964 ArcIndexType arc)
const {
1965 DCHECK(IsArcValid(arc));
1969 template <
typename NodeIndexType,
typename ArcIndexType>
1971 ArcIndexType arc)
const {
1973 DCHECK(IsArcValid(arc));
1977 template <
typename NodeIndexType,
typename ArcIndexType>
1979 ArcIndexType arc)
const {
1981 return head_[OppositeArc(arc)];
1984 template <
typename NodeIndexType,
typename ArcIndexType>
1986 ArcIndexType bound) {
1987 Base::ReserveArcs(bound);
1988 if (bound <= num_arcs_)
return;
1989 head_.reserve(bound);
1992 template <
typename NodeIndexType,
typename ArcIndexType>
1994 NodeIndexType node) {
1995 if (node < num_nodes_)
return;
1996 DCHECK(!const_capacities_ || node < node_capacity_);
1997 num_nodes_ = node + 1;
2000 template <
typename NodeIndexType,
typename ArcIndexType>
2002 NodeIndexType tail, NodeIndexType head) {
2005 AddNode(tail > head ? tail : head);
2009 head_.grow(head, tail);
2010 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
2014 template <
typename NodeIndexType,
typename ArcIndexType>
2016 std::vector<ArcIndexType>* permutation) {
2018 if (is_built_)
return;
2020 node_capacity_ = num_nodes_;
2021 arc_capacity_ = num_arcs_;
2022 this->FreezeCapacities();
2023 this->BuildStartAndForwardHead(&head_, &start_, permutation);
2026 for (
const NodeIndexType node : Base::AllNodes()) {
2027 for (
const ArcIndexType arc : OutgoingArcs(node)) {
2033 reverse_start_.assign(num_nodes_, Base::kNilArc);
2034 next_.reserve(num_arcs_);
2035 for (
const ArcIndexType arc : Base::AllForwardArcs()) {
2036 next_.push_back(reverse_start_[Head(arc)]);
2037 reverse_start_[Head(arc)] = -next_.size();
2041 template <
typename NodeIndexType,
typename ArcIndexType>
2045 : index_(graph.start_[node]), limit_(graph.DirectArcLimit(node)) {}
2048 : index_(arc), limit_(graph.DirectArcLimit(node)) {
2049 DCHECK_GE(arc, graph.start_[node]);
2052 bool Ok()
const {
return index_ < limit_; }
2053 ArcIndexType
Index()
const {
return index_; }
2064 ArcIndexType index_;
2065 const ArcIndexType limit_;
2068 template <
typename NodeIndexType,
typename ArcIndexType>
2075 DCHECK(graph.is_built_);
2077 index_ = graph.reverse_start_[node];
2080 NodeIndexType node, ArcIndexType arc)
2081 : graph_(&graph), index_(arc) {
2082 DCHECK(graph.is_built_);
2088 ArcIndexType
Index()
const {
return index_; }
2091 index_ = graph_->next_[~index_];
2101 template <
typename NodeIndexType,
typename ArcIndexType>
2114 : this->graph_->OppositeArc(this->index_);
2120 template <
typename NodeIndexType,
typename ArcIndexType>
2127 limit_ = graph.DirectArcLimit(node);
2128 index_ = graph.reverse_start_[node];
2129 restart_ = graph.start_[node];
2135 NodeIndexType node, ArcIndexType arc)
2137 limit_ = graph.DirectArcLimit(node);
2139 restart_ = graph.start_[node];
2144 return index_ < limit_;
2146 ArcIndexType
Index()
const {
return index_; }
2150 index_ = graph_->next_[graph_->OppositeArc(index_)];
2163 ArcIndexType index_;
2164 ArcIndexType restart_;
2165 ArcIndexType limit_;
2171 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
2189 NodeIndexType
Head(ArcIndexType arc)
const;
2190 NodeIndexType
Tail(ArcIndexType arc)
const;
2191 ArcIndexType
OutDegree(NodeIndexType node)
const;
2194 ArcIndexType from)
const;
2198 template <
typename NodeIndexType,
typename ArcIndexType>
2200 ArcIndexType arc)
const {
2201 DCHECK(this->IsArcValid(arc));
2202 return arc % num_nodes_;
2205 template <
typename NodeIndexType,
typename ArcIndexType>
2207 ArcIndexType arc)
const {
2208 DCHECK(this->IsArcValid(arc));
2209 return arc / num_nodes_;
2212 template <
typename NodeIndexType,
typename ArcIndexType>
2214 NodeIndexType node)
const {
2218 template <
typename NodeIndexType,
typename ArcIndexType>
2221 NodeIndexType node)
const {
2222 DCHECK_LT(node, num_nodes_);
2224 static_cast<ArcIndexType>(num_nodes_) * node,
2225 static_cast<ArcIndexType>(num_nodes_) * (node + 1));
2228 template <
typename NodeIndexType,
typename ArcIndexType>
2231 NodeIndexType node, ArcIndexType from)
const {
2232 DCHECK_LT(node, num_nodes_);
2234 from, static_cast<ArcIndexType>(num_nodes_) * (node + 1));
2237 template <
typename NodeIndexType,
typename ArcIndexType>
2240 NodeIndexType node)
const {
2241 DCHECK_LT(node, num_nodes_);
2248 template <
typename NodeIndexType =
int32,
typename ArcIndexType =
int32>
2250 :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
2264 : left_nodes_(left_nodes), right_nodes_(right_nodes) {
2265 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
2271 NodeIndexType
Head(ArcIndexType arc)
const;
2272 NodeIndexType
Tail(ArcIndexType arc)
const;
2273 ArcIndexType
OutDegree(NodeIndexType node)
const;
2276 ArcIndexType from)
const;
2283 : index_(graph.right_nodes_ * node),
2284 limit_(node >= graph.left_nodes_ ? index_
2285 : graph.right_nodes_ * (node + 1)) {}
2287 bool Ok()
const {
return index_ < limit_; }
2288 ArcIndexType
Index()
const {
return index_; }
2292 ArcIndexType index_;
2293 const ArcIndexType limit_;
2297 const NodeIndexType left_nodes_;
2298 const NodeIndexType right_nodes_;
2301 template <
typename NodeIndexType,
typename ArcIndexType>
2303 ArcIndexType arc)
const {
2304 DCHECK(this->IsArcValid(arc));
2305 return left_nodes_ + arc % right_nodes_;
2308 template <
typename NodeIndexType,
typename ArcIndexType>
2310 ArcIndexType arc)
const {
2311 DCHECK(this->IsArcValid(arc));
2312 return arc / right_nodes_;
2315 template <
typename NodeIndexType,
typename ArcIndexType>
2317 NodeIndexType node)
const {
2318 return (node < left_nodes_) ? right_nodes_ : 0;
2321 template <
typename NodeIndexType,
typename ArcIndexType>
2324 NodeIndexType node)
const {
2325 if (node < left_nodes_) {
2327 right_nodes_ * (node + 1));
2333 template <
typename NodeIndexType,
typename ArcIndexType>
2336 NodeIndexType node, ArcIndexType from)
const {
2337 if (node < left_nodes_) {
2344 template <
typename NodeIndexType,
typename ArcIndexType>
2347 NodeIndexType node)
const {
2348 if (node < left_nodes_) {
2360 #undef DEFINE_RANGE_BASED_ARC_ITERATION
2361 #undef DEFINE_STL_ITERATOR_FUNCTIONS
2363 #endif // UTIL_GRAPH_GRAPH_H_