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>
209 IntegerRange<NodeIndex>
AllNodes()
const;
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;
356 BeginEndWrapper<OutgoingArcIterator>
OutgoingArcs(NodeIndexType node)
const;
361 NodeIndexType node, ArcIndexType from)
const;
366 BeginEndWrapper<OutgoingHeadIterator>
operator[](NodeIndexType node)
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>
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;
420 BeginEndWrapper<OutgoingArcIterator>
OutgoingArcs(NodeIndexType node)
const;
422 NodeIndexType node, ArcIndexType from)
const;
427 BeginEndWrapper<NodeIndexType const*>
operator[](NodeIndexType node)
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;
498 BeginEndWrapper<OutgoingArcIterator>
OutgoingArcs(NodeIndexType node)
const;
499 BeginEndWrapper<IncomingArcIterator>
IncomingArcs(NodeIndexType node)
const;
500 BeginEndWrapper<OutgoingOrOppositeIncomingArcIterator>
503 NodeIndexType node)
const;
505 NodeIndexType node, ArcIndexType from)
const;
507 NodeIndexType node, ArcIndexType from)
const;
508 BeginEndWrapper<OutgoingOrOppositeIncomingArcIterator>
510 ArcIndexType from)
const;
512 NodeIndexType node, ArcIndexType from)
const;
517 BeginEndWrapper<OutgoingHeadIterator>
operator[](NodeIndexType node)
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;
576 BeginEndWrapper<OutgoingArcIterator>
OutgoingArcs(NodeIndexType node)
const;
577 BeginEndWrapper<IncomingArcIterator>
IncomingArcs(NodeIndexType node)
const;
578 BeginEndWrapper<OutgoingOrOppositeIncomingArcIterator>
581 NodeIndexType node)
const;
583 NodeIndexType node, ArcIndexType from)
const;
585 NodeIndexType node, ArcIndexType from)
const;
586 BeginEndWrapper<OutgoingOrOppositeIncomingArcIterator>
588 ArcIndexType from)
const;
590 NodeIndexType node, ArcIndexType from)
const;
595 BeginEndWrapper<NodeIndexType const*>
operator[](NodeIndexType node)
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;
663 BeginEndWrapper<OutgoingArcIterator>
OutgoingArcs(NodeIndexType node)
const;
664 BeginEndWrapper<IncomingArcIterator>
IncomingArcs(NodeIndexType node)
const;
665 BeginEndWrapper<OutgoingOrOppositeIncomingArcIterator>
668 NodeIndexType node)
const;
670 NodeIndexType node, ArcIndexType from)
const;
672 NodeIndexType node, ArcIndexType from)
const;
673 BeginEndWrapper<OutgoingOrOppositeIncomingArcIterator>
675 ArcIndexType from)
const;
677 NodeIndexType node, ArcIndexType from)
const;
682 BeginEndWrapper<NodeIndexType const*>
operator[](NodeIndexType node)
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>
930 return IntegerRange<NodeIndexType>(0, num_nodes_);
933 template <
typename NodeIndexType,
typename ArcIndexType,
bool HasReverseArcs>
934 IntegerRange<ArcIndexType>
936 return IntegerRange<ArcIndexType>(0, num_arcs_);
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 {
1099 return BeginEndWrapper<OutgoingHeadIterator>(
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>
1173 class ListGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1176 : graph_(graph), index_(graph.start_[node]) {
1177 DCHECK(graph.IsNodeValid(node));
1181 : graph_(graph), index_(arc) {
1182 DCHECK(graph.IsNodeValid(node));
1186 ArcIndexType Index()
const {
return index_; }
1189 index_ = graph_.next_[index_];
1196 ArcIndexType index_;
1199 template <
typename NodeIndexType,
typename ArcIndexType>
1200 class ListGraph<NodeIndexType, ArcIndexType>::OutgoingHeadIterator {
1209 : graph_(graph), index_(graph.start_[node]) {
1210 DCHECK(graph.IsNodeValid(node));
1214 : graph_(graph), index_(arc) {
1215 DCHECK(graph.IsNodeValid(node));
1219 NodeIndexType Index()
const {
return graph_.Head(index_); }
1222 index_ = graph_.next_[index_];
1228 return index_ != other.index_;
1230 NodeIndexType operator*()
const {
return Index(); }
1231 void operator++() {
Next(); }
1235 ArcIndexType index_;
1242 template <
typename NodeIndexType,
typename ArcIndexType>
1243 BeginEndWrapper<NodeIndexType const*>
1245 NodeIndexType node)
const {
1246 return BeginEndWrapper<NodeIndexType 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>
1387 class StaticGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
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 {
1432 return BeginEndWrapper<OutgoingHeadIterator>(
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>
1524 class ReverseArcListGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1527 : graph_(graph), index_(graph.start_[node]) {
1528 DCHECK(graph.IsNodeValid(node));
1532 : graph_(graph), index_(arc) {
1533 DCHECK(graph.IsNodeValid(node));
1538 ArcIndexType Index()
const {
return index_; }
1541 index_ = graph_.next_[index_];
1548 ArcIndexType index_;
1551 template <
typename NodeIndexType,
typename ArcIndexType>
1553 ArcIndexType>::OppositeIncomingArcIterator {
1557 : graph_(graph), index_(graph.reverse_start_[node]) {
1558 DCHECK(graph.IsNodeValid(node));
1561 NodeIndexType node, ArcIndexType arc)
1562 : graph_(graph), index_(arc) {
1563 DCHECK(graph.IsNodeValid(node));
1569 ArcIndexType Index()
const {
return index_; }
1572 index_ = graph_.next_[index_];
1579 ArcIndexType index_;
1582 template <
typename NodeIndexType,
typename ArcIndexType>
1595 ArcIndexType Index()
const {
1598 : this->graph_.OppositeArc(this->index_);
1604 template <
typename NodeIndexType,
typename ArcIndexType>
1606 ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
1610 : graph_(graph), index_(graph.reverse_start_[node]), node_(node) {
1611 DCHECK(graph.IsNodeValid(node));
1615 NodeIndexType node, ArcIndexType arc)
1616 : graph_(graph), index_(arc), node_(node) {
1617 DCHECK(graph.IsNodeValid(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>
1644 class ReverseArcListGraph<NodeIndexType, ArcIndexType>::OutgoingHeadIterator {
1647 : graph_(&graph), index_(graph.start_[node]) {
1648 DCHECK(graph.IsNodeValid(node));
1652 : graph_(&graph), index_(arc) {
1653 DCHECK(graph.IsNodeValid(node));
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>
1696 BeginEndWrapper<NodeIndexType const*>
1698 NodeIndexType node)
const {
1699 return BeginEndWrapper<NodeIndexType 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>
1802 class ReverseArcStaticGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
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>
1830 ArcIndexType>::OppositeIncomingArcIterator {
1835 limit_(graph.ReverseArcLimit(node)),
1836 index_(graph.reverse_start_[node]) {
1837 DCHECK(graph.IsNodeValid(node));
1838 DCHECK_LE(index_, limit_);
1841 NodeIndexType node, ArcIndexType arc)
1842 : graph_(graph), limit_(graph.ReverseArcLimit(node)), index_(arc) {
1843 DCHECK(graph.IsNodeValid(node));
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_; }
1859 const ArcIndexType limit_;
1860 ArcIndexType index_;
1863 template <
typename NodeIndexType,
typename ArcIndexType>
1872 arc == graph.ReverseArcLimit(node)
1873 ? graph.ReverseArcLimit(node)
1876 ArcIndexType Index()
const {
1877 return this->index_ == this->limit_
1879 : this->graph_.OppositeArc(this->index_);
1885 template <
typename NodeIndexType,
typename ArcIndexType>
1887 NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
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_;
1896 DCHECK(graph.IsNodeValid(node));
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)) {
1905 DCHECK(graph.IsNodeValid(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>
1955 BeginEndWrapper<NodeIndexType const*>
1957 NodeIndexType node)
const {
1958 return BeginEndWrapper<NodeIndexType 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>
2042 class ReverseArcMixedGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
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>
2070 ArcIndexType>::OppositeIncomingArcIterator {
2075 DCHECK(graph.is_built_);
2076 DCHECK(graph.IsNodeValid(node));
2077 index_ = graph.reverse_start_[node];
2080 NodeIndexType node, ArcIndexType arc)
2081 : graph_(&graph), index_(arc) {
2082 DCHECK(graph.is_built_);
2083 DCHECK(graph.IsNodeValid(node));
2088 ArcIndexType Index()
const {
return index_; }
2091 index_ = graph_->next_[~index_];
2098 ArcIndexType index_;
2101 template <
typename NodeIndexType,
typename ArcIndexType>
2111 ArcIndexType Index()
const {
2114 : this->graph_->OppositeArc(this->index_);
2120 template <
typename NodeIndexType,
typename ArcIndexType>
2122 NodeIndexType, ArcIndexType>::OutgoingOrOppositeIncomingArcIterator {
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];
2140 DCHECK(arc ==
Base::kNilArc || arc == limit_ || graph.Tail(arc) == 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>
2172 class CompleteGraph :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
2173 typedef BaseGraph<NodeIndexType, ArcIndexType, false> Base;
2189 NodeIndexType
Head(ArcIndexType arc)
const;
2190 NodeIndexType
Tail(ArcIndexType arc)
const;
2191 ArcIndexType
OutDegree(NodeIndexType node)
const;
2192 IntegerRange<ArcIndexType>
OutgoingArcs(NodeIndexType node)
const;
2194 ArcIndexType from)
const;
2195 IntegerRange<NodeIndexType>
operator[](NodeIndexType node)
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>
2219 IntegerRange<ArcIndexType>
2221 NodeIndexType node)
const {
2222 DCHECK_LT(node, num_nodes_);
2223 return IntegerRange<ArcIndexType>(
2224 static_cast<ArcIndexType>(num_nodes_) * node,
2225 static_cast<ArcIndexType>(num_nodes_) * (node + 1));
2228 template <
typename NodeIndexType,
typename ArcIndexType>
2229 IntegerRange<ArcIndexType>
2231 NodeIndexType node, ArcIndexType from)
const {
2232 DCHECK_LT(node, num_nodes_);
2233 return IntegerRange<ArcIndexType>(
2234 from, static_cast<ArcIndexType>(num_nodes_) * (node + 1));
2237 template <
typename NodeIndexType,
typename ArcIndexType>
2238 IntegerRange<NodeIndexType>
2240 NodeIndexType node)
const {
2241 DCHECK_LT(node, num_nodes_);
2242 return IntegerRange<NodeIndexType>(0, 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;
2274 IntegerRange<ArcIndexType>
OutgoingArcs(NodeIndexType node)
const;
2276 ArcIndexType from)
const;
2277 IntegerRange<NodeIndexType>
operator[](NodeIndexType node)
const;
2280 class OutgoingArcIterator {
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>
2322 IntegerRange<ArcIndexType>
2324 NodeIndexType node)
const {
2325 if (node < left_nodes_) {
2326 return IntegerRange<ArcIndexType>(right_nodes_ * node,
2327 right_nodes_ * (node + 1));
2329 return IntegerRange<ArcIndexType>(0, 0);
2333 template <
typename NodeIndexType,
typename ArcIndexType>
2334 IntegerRange<ArcIndexType>
2336 NodeIndexType node, ArcIndexType from)
const {
2337 if (node < left_nodes_) {
2338 return IntegerRange<ArcIndexType>(from, right_nodes_ * (node + 1));
2340 return IntegerRange<ArcIndexType>(0, 0);
2344 template <
typename NodeIndexType,
typename ArcIndexType>
2345 IntegerRange<NodeIndexType>
2347 NodeIndexType node)
const {
2348 if (node < left_nodes_) {
2349 return IntegerRange<NodeIndexType>(left_nodes_, left_nodes_ + right_nodes_);
2351 return IntegerRange<NodeIndexType>(0, 0);
2356 typedef ListGraph<>
Graph;
2360 #undef DEFINE_RANGE_BASED_ARC_ITERATION 2361 #undef DEFINE_STL_ITERATOR_FUNCTIONS 2363 #endif // UTIL_GRAPH_GRAPH_H_
DEFINE_RANGE_BASED_ARC_ITERATION(ListGraph, Outgoing, Base::kNilArc)
ListGraph implementation -------------------------------------------------—.
IntegerRange< ArcIndex > AllForwardArcs() const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
IncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
SVector & operator=(const SVector &other)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
CompleteGraph(NodeIndexType num_nodes)
Builds a complete graph with num_nodes nodes.
void ComputeCumulativeSum(std::vector< ArcIndexType > *v)
Functions commented when defined because they are implementation details.
static const NodeIndexType kNilNode
Constants that will never be a valid node or arc.
ArcIndexType OutDegree(NodeIndexType node) const
ArcIndexType max_end_arc_index() const
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
This loops over the heads of the OutgoingArcs(node).
void swap(SVector< T > &x)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in c...
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
SVector & operator=(SVector &&other)
void grow(const T &left=T(), const T &right=T())
NOTE(user): This doesn't currently support movable-only objects, but we could fix that.
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void FreezeCapacities()
FreezeCapacities() makes any future attempt to change the graph capacities crash in DEBUG mode.
NodeIndexType Tail(ArcIndexType arc) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
Extends the ListGraph by also storing the reverse arcs.
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
Reserve space for the graph at construction and do not allow it to grow beyond that,...
ListGraph Graph
Defining the simplest Graph interface as Graph for convenience.
void ReserveArcs(ArcIndexType bound) override
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
ArcIndexType InDegree(NodeIndexType node) const
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
This loops over the heads of the OutgoingArcs(node).
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
virtual void ReserveArcs(ArcIndexType bound)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType OutDegree(NodeIndexType node) const
StaticGraph with reverse arc.
void Build()
Some graph implementations need to be finalized with Build() before they can be used.
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType num_nodes() const
Returns the number of valid nodes in the graph.
void ReserveArcs(ArcIndexType bound) override
ArcIndexType OppositeArc(ArcIndexType arc) const
NodeIndexType Tail(ArcIndexType arc) const
Returns the tail/head of a valid arc.
CompleteBipartiteGraph implementation ------------------------------------— Nodes and arcs are implic...
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
void AddNode(NodeIndexType node)
void ReserveArcs(ArcIndexType bound) override
NodeIndexType node_capacity() const
Capacity reserved for future nodes, always >= num_nodes_.
NodeIndexType Head(ArcIndexType arc) const
OutgoingArcIterator(const StaticGraph &graph, NodeIndexType node)
ArcIndexType OutDegree(NodeIndexType node) const
void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
Arc iterations functions over the arcs touching a node (see the top-level comment for the different t...
CompleteBipartiteGraph(NodeIndexType left_nodes, NodeIndexType right_nodes)
Builds a complete bipartite graph from a set of left nodes to a set of right nodes.
bool IsArcValid(ArcIndexType arc) const
Returns true if the given arc is a valid arc of the graph.
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
void AddNode(NodeIndexType node)
ArcIndexType InDegree(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
void AddNode(NodeIndexType node)
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
void AddNode(NodeIndexType node)
void ReserveArcs(ArcIndexType bound) override
static const ArcIndexType kNilArc
void AddNode(NodeIndexType node)
If node is not a valid node, sets num_nodes_ to node + 1 so that the given node becomes valid.
void PermuteWithExplicitElementType(const IntVector &permutation, Array *array_to_permute, ElementType unused)
Permutes the elements of array_to_permute: element #i will be moved to position permutation[i].
false
This is useful for wrapping iterators of a class that support many different iterations.
Most efficient implementation of a graph without reverse arcs:
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
void BuildStartAndForwardHead(SVector< NodeIndexType > *head, std::vector< ArcIndexType > *start, std::vector< ArcIndexType > *permutation)
Given the tail of arc #i in (*head)[i] and the head of arc #i in (*head)[~i].
NodeIndexType Head(ArcIndexType arc) const
ArcIndexType InDegree(NodeIndexType node) const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
void Permute(const IntVector &permutation, Array *array_to_permute)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
Advanced usage.
ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
void ReserveNodes(NodeIndexType bound) override
Changes the graph capacities.
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
Allows to iterate over the forward arcs that verify Tail(arc) == node.
ArcIndexType Index() const
const NodeIndexType * pointer
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
Adds an arc to the graph and returns its current index which will always be num_arcs() - 1.
ReverseArcMixedGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
void ReserveNodes(NodeIndexType bound) override
Changes the graph capacities.
void ReserveArcs(ArcIndexType bound) override
ArcIndexType arc_capacity() const
Capacity reserved for future arcs, always >= num_arcs_.
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
This loops over the heads of the OutgoingArcs(node).
ArcIndexType OutDegree(NodeIndexType node) const
ReverseArcStaticGraph<>::OutDegree() and ::InDegree() work in O(1).
OutgoingArcIterator(const CompleteBipartiteGraph &graph, NodeIndexType node)
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
virtual void ReserveNodes(NodeIndexType bound)
Changes the graph capacities.
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
IntegerRange< NodeIndex > AllNodes() const
Allows nice range-based for loop: for (const NodeIndex node : graph.AllNodes()) { ....
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType arc_capacity_
bool IsNodeValid(NodeIndexType node) const
Returns true if the given node is a valid node of the graph.
ArcIndexType num_arcs() const
Returns the number of valid arcs in the graph.
#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name)
Adapt our old iteration style to support range-based for loops.
std::input_iterator_tag iterator_category
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
OutgoingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
This loops over the heads of the OutgoingArcs(node).
IncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper(Iterator begin, Iterator end)
ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
const NodeIndexType & reference
NodeIndexType NodeIndex
Typedef so you can use Graph::NodeIndex and Graph::ArcIndex to be generic but also to improve the rea...
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void ReserveNodes(NodeIndexType bound) override
Changes the graph capacities.
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
void GroupForwardArcsByFunctor(const A &a, B *b)
ArcIndexType OutDegree(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
Base class of all Graphs implemented here.
ptrdiff_t difference_type
SVector(const SVector &other)
Copy constructor and assignment operator.
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType OppositeArc(ArcIndexType arc) const
Returns the opposite arc of a given arc.
OutgoingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
SVector(SVector &&other)
Move constructor and move assignment operator.
NodeIndexType node_capacity_
ArcIndexType OutDegree(NodeIndexType node) const
Graph jargon: the "degree" of a node is its number of arcs.
Basic graph implementation without reverse arc.
This graph is a mix between the ReverseArcListGraph and the ReverseArcStaticGraph.
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
IncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
const T & operator[](int n) const
BeginEndWrapper< NodeIndexType const * > operator[](NodeIndexType node) const
This loops over the heads of the OutgoingArcs(node).
ArcIndexType OutDegree(NodeIndexType node) const
ReverseArcListGraph<>::OutDegree() and ::InDegree() work in O(degree).
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const