156#ifndef UTIL_GRAPH_GRAPH_H_
157#define UTIL_GRAPH_GRAPH_H_
167#include <type_traits>
170#include "absl/base/port.h"
171#include "absl/debugging/leak_check.h"
172#include "absl/log/check.h"
173#include "absl/types/span.h"
192template <
typename NodeIndexType = int32_t,
typename ArcIndexType = int32_t,
193 bool HasNegativeReverseArcs =
false>
281 std::vector<ArcIndexType>* start,
282 std::vector<ArcIndexType>* permutation);
305template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
338 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
349 void Build(std::vector<ArcIndexType>* permutation);
370 NodeIndexType node, ArcIndexType from)
const;
378 NodeIndexType
Tail(ArcIndexType arc)
const;
379 NodeIndexType
Head(ArcIndexType arc)
const;
385 std::vector<ArcIndexType> start_;
386 std::vector<ArcIndexType> next_;
387 std::vector<NodeIndexType> head_;
388 std::vector<NodeIndexType> tail_;
404template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
415 StaticGraph() : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {}
417 : is_built_(false), arc_in_order_(true), last_tail_seen_(0) {
424 template <
class ArcContainer>
426 const ArcContainer& arcs);
431 NodeIndexType
Head(ArcIndexType arc)
const;
432 NodeIndexType
Tail(ArcIndexType arc)
const;
436 NodeIndexType node, ArcIndexType from)
const;
441 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
446 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
449 void Build(std::vector<ArcIndexType>* permutation);
452 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
455 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
460 NodeIndexType last_tail_seen_;
461 std::vector<ArcIndexType> start_;
462 std::vector<NodeIndexType> head_;
463 std::vector<NodeIndexType> tail_;
472template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
474 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
475 static_assert(std::is_signed_v<ArcIndexType>,
"ArcIndexType must be signed");
520 NodeIndexType node)
const;
522 NodeIndexType node, ArcIndexType from)
const;
524 NodeIndexType node, ArcIndexType from)
const;
527 ArcIndexType from)
const;
529 NodeIndexType node, ArcIndexType from)
const;
536 NodeIndexType
Head(ArcIndexType arc)
const;
537 NodeIndexType
Tail(ArcIndexType arc)
const;
542 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
545 void Build(std::vector<ArcIndexType>* permutation);
548 std::vector<ArcIndexType> start_;
549 std::vector<ArcIndexType> reverse_start_;
563template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
565 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
566 static_assert(std::is_signed_v<ArcIndexType>,
"ArcIndexType must be signed");
586 class OutgoingOrOppositeIncomingArcIterator;
587 class OppositeIncomingArcIterator;
588 class IncomingArcIterator;
589 class OutgoingArcIterator;
600 NodeIndexType node)
const;
602 NodeIndexType node, ArcIndexType from)
const;
604 NodeIndexType node, ArcIndexType from)
const;
607 ArcIndexType from)
const;
609 NodeIndexType node, ArcIndexType from)
const;
614 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
618 NodeIndexType
Head(ArcIndexType arc)
const;
619 NodeIndexType
Tail(ArcIndexType arc)
const;
623 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
626 void Build(std::vector<ArcIndexType>* permutation);
629 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
632 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
634 ArcIndexType ReverseArcLimit(NodeIndexType node)
const {
637 return node + 1 < num_nodes_ ? reverse_start_[node + 1] : 0;
641 std::vector<ArcIndexType> start_;
642 std::vector<ArcIndexType> reverse_start_;
643 SVector<NodeIndexType> head_;
644 SVector<ArcIndexType> opposite_;
653template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
655 :
public BaseGraph<NodeIndexType, ArcIndexType, true> {
674 class OutgoingOrOppositeIncomingArcIterator;
675 class OppositeIncomingArcIterator;
676 class IncomingArcIterator;
677 class OutgoingArcIterator;
687 NodeIndexType node)
const;
689 NodeIndexType node, ArcIndexType from)
const;
691 NodeIndexType node, ArcIndexType from)
const;
694 ArcIndexType from)
const;
696 NodeIndexType node, ArcIndexType from)
const;
701 absl::Span<const NodeIndexType>
operator[](NodeIndexType node)
const;
705 NodeIndexType
Head(ArcIndexType arc)
const;
706 NodeIndexType
Tail(ArcIndexType arc)
const;
710 ArcIndexType
AddArc(NodeIndexType tail, NodeIndexType head);
713 void Build(std::vector<ArcIndexType>* permutation);
716 ArcIndexType DirectArcLimit(NodeIndexType node)
const {
719 return node + 1 < num_nodes_ ? start_[node + 1] : num_arcs_;
723 std::vector<ArcIndexType> start_;
724 std::vector<ArcIndexType> reverse_start_;
725 std::vector<ArcIndexType> next_;
742template <
class IntVector,
class Array,
class ElementType>
744 Array* array_to_permute,
745 ElementType unused) {
746 std::vector<ElementType> temp(permutation.size());
747 for (
size_t i = 0; i < permutation.size(); ++i) {
748 temp[i] = (*array_to_permute)[i];
750 for (
size_t i = 0; i < permutation.size(); ++i) {
751 (*array_to_permute)[permutation[i]] = temp[i];
755template <
class IntVector,
class Array>
756void Permute(
const IntVector& permutation, Array* array_to_permute) {
757 if (permutation.empty()) {
761 (*array_to_permute)[0]);
766template <
class IntVector>
768 std::vector<bool>* array_to_permute) {
769 if (permutation.empty()) {
793 SVector() : base_(nullptr), size_(0), capacity_(0) {}
800 if (capacity_ < other.size_) {
804 capacity_ = other.size_;
805 base_ = Allocate(capacity_);
806 CHECK(base_ !=
nullptr);
813 CopyInternal(other, std::is_integral<T>());
830 DCHECK_GE(n, -size_);
836 DCHECK_GE(n, -size_);
842 for (
int i = -n; i < -size_; ++i) {
845 for (
int i = size_; i < n; ++i) {
848 for (
int i = -size_; i < -n; ++i) {
851 for (
int i = n; i < size_; ++i) {
859 T*
data()
const {
return base_; }
862 std::swap(base_, x.base_);
863 std::swap(size_, x.size_);
864 std::swap(capacity_, x.capacity_);
871 const int new_capacity = std::min(n,
max_size());
872 T* new_storage = Allocate(new_capacity);
873 CHECK(new_storage !=
nullptr);
874 T* new_base = new_storage + new_capacity;
877 for (
int i = -size_; i < size_; ++i) {
878 new (new_base + i) T(std::move(base_[i]));
880 int saved_size = size_;
884 capacity_ = new_capacity;
890 void grow(
const T& left = T(),
const T& right = T()) {
891 if (size_ == capacity_) {
897 new (base_ + size_) T(right_copy);
898 new (base_ - size_ - 1) T(left_copy);
901 new (base_ + size_) T(right);
902 new (base_ - size_ - 1) T(left);
907 int size()
const {
return size_; }
911 int max_size()
const {
return std::numeric_limits<int>::max(); }
914 if (base_ ==
nullptr)
return;
917 free(base_ - capacity_);
927 void CopyInternal(
const SVector& other, std::true_type) {
928 std::memcpy(base_ - other.size_, other.base_ - other.size_,
929 2LL * other.size_ *
sizeof(T));
934 void CopyInternal(
const SVector& other, std::false_type) {
935 for (
int i = -size_; i < size_; ++i) {
936 new (base_ + i) T(other.base_[i]);
941 return absl::IgnoreLeak(
945 int NewCapacity(
int delta) {
947 double candidate = 1.3 *
static_cast<double>(capacity_);
948 if (candidate >
static_cast<double>(
max_size())) {
949 candidate =
static_cast<double>(
max_size());
951 int new_capacity =
static_cast<int>(candidate);
952 if (new_capacity > capacity_ + delta) {
955 return capacity_ + delta;
965template <
typename NodeIndexType,
typename ArcIndexType,
966 bool HasNegativeReverseArcs>
968 NodeIndexType, ArcIndexType, HasNegativeReverseArcs>
::AllNodes()
const {
972template <
typename NodeIndexType,
typename ArcIndexType,
973 bool HasNegativeReverseArcs>
980template <
typename NodeIndexType,
typename ArcIndexType,
981 bool HasNegativeReverseArcs>
984 std::numeric_limits<NodeIndexType>::max();
986template <
typename NodeIndexType,
typename ArcIndexType,
987 bool HasNegativeReverseArcs>
990 std::numeric_limits<ArcIndexType>::max();
992template <
typename NodeIndexType,
typename ArcIndexType,
993 bool HasNegativeReverseArcs>
994NodeIndexType
BaseGraph<NodeIndexType, ArcIndexType,
1001template <
typename NodeIndexType,
typename ArcIndexType,
1002 bool HasNegativeReverseArcs>
1003ArcIndexType
BaseGraph<NodeIndexType, ArcIndexType,
1009template <
typename NodeIndexType,
typename ArcIndexType,
1010 bool HasNegativeReverseArcs>
1011void BaseGraph<NodeIndexType, ArcIndexType,
1022template <
typename NodeIndexType,
typename ArcIndexType,
1023 bool HasNegativeReverseArcs>
1026 ArcIndexType sum = 0;
1028 ArcIndexType temp = (*v)[i];
1040template <
typename NodeIndexType,
typename ArcIndexType,
1041 bool HasNegativeReverseArcs>
1044 std::vector<ArcIndexType>* start,
1045 std::vector<ArcIndexType>* permutation) {
1050 int last_tail_seen = 0;
1051 bool permutation_needed =
false;
1053 NodeIndexType tail = (*head)[i];
1054 if (!permutation_needed) {
1055 permutation_needed = tail < last_tail_seen;
1056 last_tail_seen = tail;
1064 if (!permutation_needed) {
1066 (*head)[i] = (*head)[~i];
1068 if (permutation !=
nullptr) {
1069 permutation->clear();
1076 std::vector<ArcIndexType> perm(
num_arcs_);
1078 perm[i] = (*start)[(*head)[i]]++;
1083 (*start)[i] = (*start)[i - 1];
1090 (*head)[perm[i]] = (*head)[~i];
1092 if (permutation !=
nullptr) {
1093 permutation->swap(perm);
1106#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t) \
1107 template <typename NodeIndexType, typename ArcIndexType> \
1108 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1109 c<NodeIndexType, ArcIndexType>::t##Arcs(NodeIndexType node) const { \
1110 return BeginEndWrapper<t##ArcIterator>( \
1111 t##ArcIterator(*this, node), \
1112 t##ArcIterator(*this, node, Base::kNilArc)); \
1114 template <typename NodeIndexType, typename ArcIndexType> \
1115 BeginEndWrapper<typename c<NodeIndexType, ArcIndexType>::t##ArcIterator> \
1116 c<NodeIndexType, ArcIndexType>::t##ArcsStartingFrom( \
1117 NodeIndexType node, ArcIndexType from) const { \
1118 return BeginEndWrapper<t##ArcIterator>( \
1119 t##ArcIterator(*this, node, from), \
1120 t##ArcIterator(*this, node, Base::kNilArc)); \
1125#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name) \
1126 using iterator_category = std::input_iterator_tag; \
1127 using difference_type = ptrdiff_t; \
1128 using pointer = const ArcIndexType*; \
1129 using value_type = ArcIndexType; \
1130 using reference = value_type; \
1131 bool operator!=(const iterator_class_name& other) const { \
1132 return this->index_ != other.index_; \
1134 bool operator==(const iterator_class_name& other) const { \
1135 return this->index_ == other.index_; \
1137 ArcIndexType operator*() const { return this->Index(); } \
1138 void operator++() { this->Next(); }
1144template <
typename NodeIndexType,
typename ArcIndexType>
1153template <
typename NodeIndexType,
typename ArcIndexType>
1155 ArcIndexType arc)
const {
1160template <
typename NodeIndexType,
typename ArcIndexType>
1162 ArcIndexType arc)
const {
1167template <
typename NodeIndexType,
typename ArcIndexType>
1169 NodeIndexType node)
const {
1170 ArcIndexType degree(0);
1171 for (
auto arc ABSL_ATTRIBUTE_UNUSED :
OutgoingArcs(node)) ++degree;
1175template <
typename NodeIndexType,
typename ArcIndexType>
1177 if (node < num_nodes_)
return;
1178 DCHECK(!const_capacities_ || node < node_capacity_);
1179 num_nodes_ = node + 1;
1183template <
typename NodeIndexType,
typename ArcIndexType>
1185 NodeIndexType tail, NodeIndexType head) {
1188 AddNode(tail > head ? tail : head);
1189 head_.push_back(head);
1190 tail_.push_back(tail);
1191 next_.push_back(start_[tail]);
1192 start_[tail] = num_arcs_;
1193 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1197template <
typename NodeIndexType,
typename ArcIndexType>
1199 Base::ReserveNodes(bound);
1200 if (bound <= num_nodes_)
return;
1201 start_.reserve(bound);
1204template <
typename NodeIndexType,
typename ArcIndexType>
1206 Base::ReserveArcs(bound);
1207 if (bound <= num_arcs_)
return;
1208 head_.reserve(bound);
1209 tail_.reserve(bound);
1210 next_.reserve(bound);
1213template <
typename NodeIndexType,
typename ArcIndexType>
1215 std::vector<ArcIndexType>* permutation) {
1216 if (permutation !=
nullptr) {
1217 permutation->clear();
1221template <
typename NodeIndexType,
typename ArcIndexType>
1222class ListGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1225 : graph_(
graph), index_(
graph.start_[node]) {
1231 DCHECK(
graph.IsNodeValid(node));
1235 ArcIndexType Index()
const {
return index_; }
1238 index_ = graph_.next_[index_];
1245 ArcIndexType index_;
1248template <
typename NodeIndexType,
typename ArcIndexType>
1258 : graph_(
graph), index_(
graph.start_[node]) {
1264 DCHECK(
graph.IsNodeValid(node));
1268 NodeIndexType Index()
const {
return graph_.Head(index_); }
1271 index_ = graph_.next_[index_];
1277 return index_ != other.index_;
1279 NodeIndexType operator*()
const {
return Index(); }
1280 void operator++() {
Next(); }
1284 ArcIndexType index_;
1289template <
typename NodeIndexType,
typename ArcIndexType>
1290template <
class ArcContainer>
1293 const ArcContainer& arcs) {
1295 for (
const auto& [from,
to] : arcs) g.AddArc(from,
to);
1302template <
typename NodeIndexType,
typename ArcIndexType>
1303absl::Span<const NodeIndexType>
1305 return absl::Span<const NodeIndexType>(head_.data() + start_[node],
1306 DirectArcLimit(node) - start_[node]);
1309template <
typename NodeIndexType,
typename ArcIndexType>
1311 NodeIndexType node)
const {
1312 return DirectArcLimit(node) - start_[node];
1315template <
typename NodeIndexType,
typename ArcIndexType>
1317 NodeIndexType bound) {
1319 if (bound <= num_nodes_)
return;
1320 start_.reserve(bound);
1323template <
typename NodeIndexType,
typename ArcIndexType>
1325 Base::ReserveArcs(bound);
1326 if (bound <= num_arcs_)
return;
1327 head_.reserve(bound);
1328 tail_.reserve(bound);
1331template <
typename NodeIndexType,
typename ArcIndexType>
1333 if (node < num_nodes_)
return;
1334 DCHECK(!const_capacities_ || node < node_capacity_) << node;
1335 num_nodes_ = node + 1;
1336 start_.resize(num_nodes_, 0);
1339template <
typename NodeIndexType,
typename ArcIndexType>
1341 NodeIndexType tail, NodeIndexType head) {
1345 AddNode(tail > head ? tail : head);
1346 if (arc_in_order_) {
1347 if (tail >= last_tail_seen_) {
1349 last_tail_seen_ = tail;
1351 arc_in_order_ =
false;
1354 tail_.push_back(tail);
1355 head_.push_back(head);
1356 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1360template <
typename NodeIndexType,
typename ArcIndexType>
1362 ArcIndexType arc)
const {
1367template <
typename NodeIndexType,
typename ArcIndexType>
1369 ArcIndexType arc)
const {
1386template <
typename NodeIndexType,
typename ArcIndexType>
1388 std::vector<ArcIndexType>* permutation) {
1390 if (is_built_)
return;
1392 node_capacity_ = num_nodes_;
1393 arc_capacity_ = num_arcs_;
1397 if (arc_in_order_) {
1398 if (permutation !=
nullptr) {
1399 permutation->clear();
1401 this->ComputeCumulativeSum(&start_);
1407 start_.assign(num_nodes_, 0);
1408 for (
int i = 0; i < num_arcs_; ++i) {
1411 this->ComputeCumulativeSum(&start_);
1415 std::vector<ArcIndexType> perm(num_arcs_);
1416 for (
int i = 0;
i < num_arcs_; ++
i) {
1417 perm[
i] = start_[tail_[
i]]++;
1421 CHECK_EQ(tail_.size(),
static_cast<size_t>(num_arcs_));
1423 for (
int i = 0;
i < num_arcs_; ++
i) {
1424 head_[perm[
i]] = tail_[
i];
1427 if (permutation !=
nullptr) {
1428 permutation->swap(perm);
1432 for (
int i = num_nodes_ - 1;
i > 0; --
i) {
1433 start_[
i] = start_[
i - 1];
1438 for (
const NodeIndexType node : Base::AllNodes()) {
1439 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1445template <
typename NodeIndexType,
typename ArcIndexType>
1446class StaticGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1451 : index_(
graph.start_[node]), limit_(
graph.DirectArcLimit(node)) {}
1456 DCHECK_GE(arc,
graph.start_[node]);
1459 bool Ok()
const {
return index_ != limit_; }
1460 ArcIndexType Index()
const {
return index_; }
1476 ArcIndexType index_;
1477 ArcIndexType limit_;
1485 OutgoingOrOppositeIncoming);
1488template <
typename NodeIndexType,
typename ArcIndexType>
1490 NodeIndexType, ArcIndexType>::OutgoingHeadIterator>
1492 NodeIndexType node)
const {
1498template <
typename NodeIndexType,
typename ArcIndexType>
1500 NodeIndexType node)
const {
1501 ArcIndexType degree(0);
1502 for (
auto arc ABSL_ATTRIBUTE_UNUSED :
OutgoingArcs(node)) ++degree;
1506template <
typename NodeIndexType,
typename ArcIndexType>
1508 NodeIndexType node)
const {
1509 ArcIndexType degree(0);
1514template <
typename NodeIndexType,
typename ArcIndexType>
1516 ArcIndexType arc)
const {
1521template <
typename NodeIndexType,
typename ArcIndexType>
1523 ArcIndexType arc)
const {
1528template <
typename NodeIndexType,
typename ArcIndexType>
1530 ArcIndexType arc)
const {
1534template <
typename NodeIndexType,
typename ArcIndexType>
1536 NodeIndexType bound) {
1538 if (bound <= num_nodes_)
return;
1539 start_.reserve(bound);
1540 reverse_start_.reserve(bound);
1543template <
typename NodeIndexType,
typename ArcIndexType>
1545 ArcIndexType bound) {
1547 if (bound <= num_arcs_)
return;
1548 head_.reserve(bound);
1549 next_.reserve(bound);
1552template <
typename NodeIndexType,
typename ArcIndexType>
1554 NodeIndexType node) {
1555 if (node < num_nodes_)
return;
1556 DCHECK(!const_capacities_ || node < node_capacity_);
1557 num_nodes_ = node + 1;
1562template <
typename NodeIndexType,
typename ArcIndexType>
1564 NodeIndexType tail, NodeIndexType head) {
1567 AddNode(tail > head ? tail : head);
1568 head_.grow(tail, head);
1569 next_.grow(reverse_start_[head], start_[tail]);
1570 start_[tail] = num_arcs_;
1571 reverse_start_[head] = ~num_arcs_;
1572 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1576template <
typename NodeIndexType,
typename ArcIndexType>
1578 std::vector<ArcIndexType>* permutation) {
1579 if (permutation !=
nullptr) {
1580 permutation->clear();
1584template <
typename NodeIndexType,
typename ArcIndexType>
1585class ReverseArcListGraph<NodeIndexType, ArcIndexType>::OutgoingArcIterator {
1588 : graph_(
graph), index_(
graph.start_[node]) {
1594 DCHECK(
graph.IsNodeValid(node));
1599 ArcIndexType Index()
const {
return index_; }
1602 index_ = graph_.next_[index_];
1609 ArcIndexType index_;
1612template <
typename NodeIndexType,
typename ArcIndexType>
1619 DCHECK(
graph.IsNodeValid(node));
1622 NodeIndexType node, ArcIndexType arc)
1624 DCHECK(
graph.IsNodeValid(node));
1630 ArcIndexType Index()
const {
return index_; }
1639 const ArcIndexType*
next_;
1643template <
typename NodeIndexType,
typename ArcIndexType>
1657 ArcIndexType Index()
const {
1668template <
typename NodeIndexType,
typename ArcIndexType>
1674 : graph_(
graph), index_(
graph.reverse_start_[node]), node_(node) {
1675 DCHECK(
graph.IsNodeValid(node));
1679 NodeIndexType node, ArcIndexType arc)
1680 : graph_(
graph), index_(arc), node_(node) {
1681 DCHECK(
graph.IsNodeValid(node));
1686 ArcIndexType Index()
const {
return index_; }
1690 index_ = graph_.next_[index_];
1692 index_ = graph_.start_[node_];
1695 index_ = graph_.next_[index_];
1703 ArcIndexType index_;
1704 const NodeIndexType node_;
1707template <
typename NodeIndexType,
typename ArcIndexType>
1711 : graph_(&
graph), index_(
graph.start_[node]) {
1717 DCHECK(
graph.IsNodeValid(node));
1722 ArcIndexType Index()
const {
return graph_->Head(index_); }
1725 index_ = graph_->next_[index_];
1732 ArcIndexType index_;
1740 OutgoingOrOppositeIncoming);
1743template <
typename NodeIndexType,
typename ArcIndexType>
1745 NodeIndexType node)
const {
1746 return DirectArcLimit(node) - start_[node];
1749template <
typename NodeIndexType,
typename ArcIndexType>
1751 NodeIndexType node)
const {
1752 return ReverseArcLimit(node) - reverse_start_[node];
1755template <
typename NodeIndexType,
typename ArcIndexType>
1756absl::Span<const NodeIndexType>
1758 NodeIndexType node)
const {
1759 return absl::Span<const NodeIndexType>(head_.data() + start_[node],
1760 DirectArcLimit(node) - start_[node]);
1763template <
typename NodeIndexType,
typename ArcIndexType>
1765 ArcIndexType arc)
const {
1768 return opposite_[arc];
1771template <
typename NodeIndexType,
typename ArcIndexType>
1773 ArcIndexType arc)
const {
1779template <
typename NodeIndexType,
typename ArcIndexType>
1781 ArcIndexType arc)
const {
1786template <
typename NodeIndexType,
typename ArcIndexType>
1788 ArcIndexType bound) {
1790 if (bound <= num_arcs_)
return;
1791 head_.reserve(bound);
1794template <
typename NodeIndexType,
typename ArcIndexType>
1796 NodeIndexType node) {
1797 if (node < num_nodes_)
return;
1798 DCHECK(!const_capacities_ || node < node_capacity_);
1799 num_nodes_ = node + 1;
1802template <
typename NodeIndexType,
typename ArcIndexType>
1804 NodeIndexType tail, NodeIndexType head) {
1807 AddNode(tail > head ? tail : head);
1811 head_.grow(head, tail);
1812 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
1816template <
typename NodeIndexType,
typename ArcIndexType>
1818 std::vector<ArcIndexType>* permutation) {
1820 if (is_built_)
return;
1822 node_capacity_ = num_nodes_;
1823 arc_capacity_ = num_arcs_;
1828 reverse_start_.assign(num_nodes_, 0);
1829 for (
int i = 0; i < num_arcs_; ++i) {
1830 reverse_start_[head_[i]]++;
1832 this->ComputeCumulativeSum(&reverse_start_);
1836 opposite_.reserve(num_arcs_);
1837 for (
int i = 0; i < num_arcs_; ++i) {
1839 opposite_.grow(0, reverse_start_[head_[i]]++ - num_arcs_);
1843 for (
int i = num_nodes_ - 1; i > 0; --i) {
1844 reverse_start_[i] = reverse_start_[i - 1] - num_arcs_;
1846 if (num_nodes_ != 0) {
1847 reverse_start_[0] = -num_arcs_;
1851 for (
int i = 0;
i < num_arcs_; ++
i) {
1852 opposite_[opposite_[
i]] =
i;
1854 for (
const NodeIndexType node : Base::AllNodes()) {
1855 for (
const ArcIndexType arc : OutgoingArcs(node)) {
1856 head_[opposite_[arc]] = node;
1861template <
typename NodeIndexType,
typename ArcIndexType>
1865 : index_(
graph.start_[node]), limit_(
graph.DirectArcLimit(node)) {}
1870 DCHECK_GE(arc,
graph.start_[node]);
1873 bool Ok()
const {
return index_ != limit_; }
1874 ArcIndexType Index()
const {
return index_; }
1885 ArcIndexType index_;
1886 const ArcIndexType limit_;
1889template <
typename NodeIndexType,
typename ArcIndexType>
1897 DCHECK(
graph.IsNodeValid(node));
1901 NodeIndexType node, ArcIndexType arc)
1904 DCHECK(
graph.IsNodeValid(node));
1909 bool Ok()
const {
return index_ != limit_; }
1910 ArcIndexType Index()
const {
return index_; }
1919 const ArcIndexType
limit_;
1923template <
typename NodeIndexType,
typename ArcIndexType>
1934 : (arc ==
graph.ReverseArcLimit(node)
1935 ?
graph.ReverseArcLimit(node)
1939 ArcIndexType Index()
const {
1940 return this->index_ == this->limit_ ? this->limit_
1950template <
typename NodeIndexType,
typename ArcIndexType>
1957 first_limit_(
graph.ReverseArcLimit(node)),
1958 next_start_(
graph.start_[node]),
1959 limit_(
graph.DirectArcLimit(node)) {
1960 if (index_ == first_limit_) index_ = next_start_;
1961 DCHECK(
graph.IsNodeValid(node));
1962 DCHECK((index_ < first_limit_) || (index_ >= next_start_));
1965 NodeIndexType node, ArcIndexType arc)
1966 : first_limit_(
graph.ReverseArcLimit(node)),
1967 next_start_(
graph.start_[node]),
1968 limit_(
graph.DirectArcLimit(node)) {
1970 DCHECK(
graph.IsNodeValid(node));
1971 DCHECK((index_ >=
graph.reverse_start_[node] && index_ < first_limit_) ||
1972 (index_ >= next_start_));
1975 ArcIndexType Index()
const {
return index_; }
1976 bool Ok()
const {
return index_ != limit_; }
1980 if (index_ == first_limit_) {
1981 index_ = next_start_;
1988 ArcIndexType index_;
1989 const ArcIndexType first_limit_;
1990 const ArcIndexType next_start_;
1991 const ArcIndexType limit_;
1999 OutgoingOrOppositeIncoming);
2002template <
typename NodeIndexType,
typename ArcIndexType>
2004 NodeIndexType node)
const {
2005 return DirectArcLimit(node) - start_[node];
2008template <
typename NodeIndexType,
typename ArcIndexType>
2010 NodeIndexType node)
const {
2011 ArcIndexType degree(0);
2016template <
typename NodeIndexType,
typename ArcIndexType>
2017absl::Span<const NodeIndexType>
2019 NodeIndexType node)
const {
2020 return absl::Span<const NodeIndexType>(head_.data() + start_[node],
2021 DirectArcLimit(node) - start_[node]);
2024template <
typename NodeIndexType,
typename ArcIndexType>
2026 ArcIndexType arc)
const {
2031template <
typename NodeIndexType,
typename ArcIndexType>
2033 ArcIndexType arc)
const {
2039template <
typename NodeIndexType,
typename ArcIndexType>
2041 ArcIndexType arc)
const {
2046template <
typename NodeIndexType,
typename ArcIndexType>
2048 ArcIndexType bound) {
2050 if (bound <= num_arcs_)
return;
2051 head_.reserve(bound);
2054template <
typename NodeIndexType,
typename ArcIndexType>
2056 NodeIndexType node) {
2057 if (node < num_nodes_)
return;
2058 DCHECK(!const_capacities_ || node < node_capacity_);
2059 num_nodes_ = node + 1;
2062template <
typename NodeIndexType,
typename ArcIndexType>
2064 NodeIndexType tail, NodeIndexType head) {
2067 AddNode(tail > head ? tail : head);
2071 head_.grow(head, tail);
2072 DCHECK(!const_capacities_ || num_arcs_ < arc_capacity_);
2076template <
typename NodeIndexType,
typename ArcIndexType>
2078 std::vector<ArcIndexType>* permutation) {
2080 if (is_built_)
return;
2082 node_capacity_ = num_nodes_;
2083 arc_capacity_ = num_arcs_;
2095 reverse_start_.assign(num_nodes_, Base::kNilArc);
2096 next_.reserve(num_arcs_);
2097 for (
const ArcIndexType arc : Base::AllForwardArcs()) {
2098 next_.push_back(reverse_start_[Head(arc)]);
2099 reverse_start_[Head(arc)] = -next_.size();
2103template <
typename NodeIndexType,
typename ArcIndexType>
2109 : index_(
graph.start_[node]), limit_(
graph.DirectArcLimit(node)) {}
2114 DCHECK_GE(arc,
graph.start_[node]);
2117 bool Ok()
const {
return index_ != limit_; }
2118 ArcIndexType Index()
const {
return index_; }
2129 ArcIndexType index_;
2130 ArcIndexType limit_;
2133template <
typename NodeIndexType,
typename ArcIndexType>
2140 DCHECK(
graph.is_built_);
2141 DCHECK(
graph.IsNodeValid(node));
2145 NodeIndexType node, ArcIndexType arc)
2147 DCHECK(
graph.is_built_);
2148 DCHECK(
graph.IsNodeValid(node));
2153 ArcIndexType Index()
const {
return index_; }
2166template <
typename NodeIndexType,
typename ArcIndexType>
2177 ArcIndexType Index()
const {
2186template <
typename NodeIndexType,
typename ArcIndexType>
2193 limit_ =
graph.DirectArcLimit(node);
2194 index_ =
graph.reverse_start_[node];
2195 restart_ =
graph.start_[node];
2201 NodeIndexType node, ArcIndexType arc)
2203 limit_ =
graph.DirectArcLimit(node);
2205 restart_ =
graph.start_[node];
2208 bool Ok()
const {
return index_ != limit_; }
2209 ArcIndexType Index()
const {
return index_; }
2213 index_ = graph_->next_[graph_->OppositeArc(index_)];
2226 ArcIndexType index_;
2227 ArcIndexType restart_;
2228 ArcIndexType limit_;
2234template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2255 NodeIndexType
Head(ArcIndexType arc)
const;
2256 NodeIndexType
Tail(ArcIndexType arc)
const;
2260 ArcIndexType from)
const;
2263 const ::util::math::ConstantDivisor<std::make_unsigned_t<ArcIndexType>>
2267template <
typename NodeIndexType,
typename ArcIndexType>
2269 ArcIndexType arc)
const {
2274template <
typename NodeIndexType,
typename ArcIndexType>
2276 ArcIndexType arc)
const {
2281template <
typename NodeIndexType,
typename ArcIndexType>
2283 NodeIndexType node)
const {
2287template <
typename NodeIndexType,
typename ArcIndexType>
2290 NodeIndexType node)
const {
2291 DCHECK_LT(node, num_nodes_);
2293 static_cast<ArcIndexType
>(num_nodes_) * node,
2294 static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2297template <
typename NodeIndexType,
typename ArcIndexType>
2300 NodeIndexType node, ArcIndexType from)
const {
2301 DCHECK_LT(node, num_nodes_);
2303 from,
static_cast<ArcIndexType
>(num_nodes_) * (node + 1));
2306template <
typename NodeIndexType,
typename ArcIndexType>
2309 NodeIndexType node)
const {
2310 DCHECK_LT(node, num_nodes_);
2317template <
typename NodeIndexType =
int32_t,
typename ArcIndexType =
int32_t>
2319 :
public BaseGraph<NodeIndexType, ArcIndexType, false> {
2333 : left_nodes_(left_nodes),
2334 right_nodes_(right_nodes),
2338 divisor_(right_nodes > 1 ? right_nodes : 2) {
2339 this->
Reserve(left_nodes + right_nodes, left_nodes * right_nodes);
2341 num_nodes_ = left_nodes + right_nodes;
2342 num_arcs_ = left_nodes * right_nodes;
2348 ArcIndexType
GetArc(NodeIndexType left_node, NodeIndexType right_node)
const;
2350 NodeIndexType
Head(ArcIndexType arc)
const;
2351 NodeIndexType
Tail(ArcIndexType arc)
const;
2352 ArcIndexType
OutDegree(NodeIndexType node)
const;
2355 ArcIndexType from)
const;
2359 class OutgoingArcIterator {
2362 : index_(static_cast<ArcIndexType>(
graph.right_nodes_) * node),
2365 : static_cast<ArcIndexType>(
graph.right_nodes_) *
2368 bool Ok()
const {
return index_ < limit_; }
2369 ArcIndexType
Index()
const {
return index_; }
2373 ArcIndexType index_;
2374 const ArcIndexType limit_;
2378 const NodeIndexType left_nodes_;
2379 const NodeIndexType right_nodes_;
2381 const ::util::math::ConstantDivisor<std::make_unsigned_t<ArcIndexType>>
2385template <
typename NodeIndexType,
typename ArcIndexType>
2387 NodeIndexType left_node, NodeIndexType right_node)
const {
2388 DCHECK_LT(left_node, left_nodes_);
2389 DCHECK_GE(right_node, left_nodes_);
2390 DCHECK_LT(right_node, num_nodes_);
2391 return left_node *
static_cast<ArcIndexType
>(right_nodes_) +
2392 (right_node - left_nodes_);
2395template <
typename NodeIndexType,
typename ArcIndexType>
2397 ArcIndexType arc)
const {
2400 return right_nodes_ > 1 ? left_nodes_ + arc % divisor_ : left_nodes_;
2403template <
typename NodeIndexType,
typename ArcIndexType>
2405 ArcIndexType arc)
const {
2408 return right_nodes_ > 1 ? arc / divisor_ : arc;
2411template <
typename NodeIndexType,
typename ArcIndexType>
2413 NodeIndexType node)
const {
2414 return (node < left_nodes_) ? right_nodes_ : 0;
2417template <
typename NodeIndexType,
typename ArcIndexType>
2420 NodeIndexType node)
const {
2421 if (node < left_nodes_) {
2423 static_cast<ArcIndexType
>(right_nodes_) * node,
2424 static_cast<ArcIndexType
>(right_nodes_) * (node + 1));
2430template <
typename NodeIndexType,
typename ArcIndexType>
2433 NodeIndexType node, ArcIndexType from)
const {
2434 if (node < left_nodes_) {
2436 from,
static_cast<ArcIndexType
>(right_nodes_) * (node + 1));
2442template <
typename NodeIndexType,
typename ArcIndexType>
2445 NodeIndexType node)
const {
2446 if (node < left_nodes_) {
2458#undef DEFINE_RANGE_BASED_ARC_ITERATION
2459#undef DEFINE_STL_ITERATOR_FUNCTIONS
const ::util::math::ConstantDivisor< std::make_unsigned_t< int64_t > > divisor_
void ComputeCumulativeSum(std::vector< ArcIndexType > *v)
Functions commented when defined because they are implementation details.
NodeIndexType num_nodes() const
bool IsArcValid(ArcIndexType arc) const
NodeIndexType node_capacity() const
Capacity reserved for future nodes, always >= num_nodes_.
ArcIndexType arc_capacity() const
Capacity reserved for future arcs, always >= num_arcs_.
static constexpr bool kHasNegativeReverseArcs
IntegerRange< ArcIndex > AllForwardArcs() const
ArcIndexType arc_capacity_
BaseGraph(const BaseGraph &)=default
virtual void ReserveNodes(NodeIndexType bound)
NodeIndexType size() const
static const NodeIndexType kNilNode
virtual void ReserveArcs(ArcIndexType bound)
void Reserve(NodeIndexType node_capacity, ArcIndexType arc_capacity)
NodeIndexType node_capacity_
BaseGraph & operator=(const BaseGraph &)=default
ArcIndexType num_arcs() const
Returns the number of valid arcs in the graph.
IntegerRange< NodeIndex > AllNodes() const
BaseGraph implementation -------------------------------------------------—.
void BuildStartAndForwardHead(SVector< NodeIndexType > *head, std::vector< ArcIndexType > *start, std::vector< ArcIndexType > *permutation)
virtual ~BaseGraph()=default
bool IsNodeValid(NodeIndexType node) const
Returns true if the given node is a valid node of the graph.
static const ArcIndexType kNilArc
OutgoingArcIterator(const CompleteBipartiteGraph &graph, NodeIndexType node)
ArcIndexType Index() const
ArcIndexType GetArc(NodeIndexType left_node, NodeIndexType right_node) const
NodeIndexType Tail(ArcIndexType arc) const
CompleteBipartiteGraph(NodeIndexType left_nodes, NodeIndexType right_nodes)
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
const ::util::math::ConstantDivisor< std::make_unsigned_t< ArcIndexType > > divisor_
ArcIndexType OutDegree(NodeIndexType node) const
IntegerRange< ArcIndexType > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
IntegerRange< ArcIndexType > OutgoingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
IntegerRange< NodeIndexType > operator[](NodeIndexType node) const
CompleteGraph(NodeIndexType num_nodes)
Builds a complete graph with num_nodes nodes.
NodeIndexType Head(ArcIndexType arc) const
OutgoingArcIterator(const ListGraph &graph, NodeIndexType node)
OutgoingHeadIterator(const ListGraph &graph, NodeIndexType node)
std::input_iterator_tag iterator_category
ptrdiff_t difference_type
const NodeIndexType * pointer
const NodeIndexType & reference
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
ListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
bool IsArcValid(ArcIndexType arc) const
void Build(std::vector< ArcIndexType > *permutation)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
void AddNode(NodeIndexType node)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Tail(ArcIndexType arc) const
Returns the tail/head of a valid arc.
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ArcIndexType OutDegree(NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
void ReserveNodes(NodeIndexType bound) override
void ReserveArcs(ArcIndexType bound) override
IncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
const ArcIndexType * next_
OppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
OutgoingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
OutgoingHeadIterator(const ReverseArcListGraph &graph, NodeIndexType node)
OutgoingOrOppositeIncomingArcIterator(const ReverseArcListGraph &graph, NodeIndexType node)
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
bool IsArcValid(ArcIndexType arc) const
BeginEndWrapper< OutgoingHeadIterator > operator[](NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
void Build(std::vector< ArcIndexType > *permutation)
void ReserveArcs(ArcIndexType bound) override
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
ReverseArcListGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
ArcIndexType OutDegree(NodeIndexType node) const
ReverseArcListGraph<>::OutDegree() and InDegree() work in O(degree).
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void ReserveNodes(NodeIndexType bound) override
ArcIndexType InDegree(NodeIndexType node) const
IncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
const ReverseArcMixedGraph * graph_
OppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
OutgoingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
OutgoingArcIterator(const OutgoingArcIterator &)=default
OutgoingOrOppositeIncomingArcIterator(const ReverseArcMixedGraph &graph, NodeIndexType node)
bool IsArcValid(ArcIndexType arc) const
NodeIndexType Tail(ArcIndexType arc) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
NodeIndexType Head(ArcIndexType arc) const
ReverseArcMixedGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
void Build(std::vector< ArcIndexType > *permutation)
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void ReserveArcs(ArcIndexType bound) override
ArcIndexType OutDegree(NodeIndexType node) const
ArcIndexType InDegree(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
IncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
const ArcIndexType limit_
OppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
OutgoingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
OutgoingOrOppositeIncomingArcIterator(const ReverseArcStaticGraph &graph, NodeIndexType node)
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
NodeIndexType Tail(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
bool IsArcValid(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
BeginEndWrapper< OutgoingOrOppositeIncomingArcIterator > OutgoingOrOppositeIncomingArcs(NodeIndexType node) const
ArcIndexType OppositeArc(ArcIndexType arc) const
BeginEndWrapper< IncomingArcIterator > IncomingArcs(NodeIndexType node) const
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcs(NodeIndexType node) const
void Build(std::vector< ArcIndexType > *permutation)
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
NodeIndexType Head(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void ReserveArcs(ArcIndexType bound) override
ArcIndexType OutDegree(NodeIndexType node) const
ReverseArcStaticGraph<>::OutDegree() and InDegree() work in O(1).
ArcIndexType InDegree(NodeIndexType node) const
ReverseArcStaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
BeginEndWrapper< OppositeIncomingArcIterator > OppositeIncomingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
void AddNode(NodeIndexType node)
const T & operator[](int n) const
SVector & operator=(SVector &&other) noexcept
SVector(const SVector &other)
Copy constructor and assignment operator.
SVector(SVector &&other) noexcept
Move constructor and move assignment operator.
void swap(SVector< T > &x) noexcept
void grow(const T &left=T(), const T &right=T())
SVector & operator=(const SVector &other)
OutgoingArcIterator(const StaticGraph &graph, NodeIndexType node)
OutgoingArcIterator(const OutgoingArcIterator &)=default
absl::Span< const NodeIndexType > operator[](NodeIndexType node) const
ArcIndexType AddArc(NodeIndexType tail, NodeIndexType head)
static StaticGraph FromArcs(NodeIndexType num_nodes, const ArcContainer &arcs)
Shortcut to directly create a finalized graph, i.e. Build() is called.
bool IsArcValid(ArcIndexType arc) const
BeginEndWrapper< OutgoingArcIterator > OutgoingArcs(NodeIndexType node) const
ArcIndexType OutDegree(NodeIndexType node) const
NodeIndexType Tail(ArcIndexType arc) const
void ReserveArcs(ArcIndexType bound) override
void ReserveNodes(NodeIndexType bound) override
void AddNode(NodeIndexType node)
BeginEndWrapper< OutgoingArcIterator > OutgoingArcsStartingFrom(NodeIndexType node, ArcIndexType from) const
StaticGraph(NodeIndexType num_nodes, ArcIndexType arc_capacity)
void Build(std::vector< ArcIndexType > *permutation)
NodeIndexType Head(ArcIndexType arc) const
#define DEFINE_RANGE_BASED_ARC_ITERATION(c, t)
#define DEFINE_STL_ITERATOR_FUNCTIONS(iterator_class_name)
dual_gradient T(y - `dual_solution`) class DiagonalTrustRegionProblemFromQp
A collections of i/o utilities for the Graph classes in ./graph.h.
void Permute(const IntVector &permutation, Array *array_to_permute)
void PermuteWithExplicitElementType(const IntVector &permutation, Array *array_to_permute, ElementType unused)
ListGraph Graph
Defining the simplest Graph interface as Graph for convenience.
trees with all degrees equal to